1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ 2 /* 3 * This file is part of the LibreOffice project. 4 * 5 * This Source Code Form is subject to the terms of the Mozilla Public 6 * License, v. 2.0. If a copy of the MPL was not distributed with this 7 * file, You can obtain one at http://mozilla.org/MPL/2.0/. 8 * 9 * This file incorporates work covered by the following license notice: 10 * 11 * Licensed to the Apache Software Foundation (ASF) under one or more 12 * contributor license agreements. See the NOTICE file distributed 13 * with this work for additional information regarding copyright 14 * ownership. The ASF licenses this file to you under the Apache 15 * License, Version 2.0 (the "License"); you may not use this file 16 * except in compliance with the License. You may obtain a copy of 17 * the License at http://www.apache.org/licenses/LICENSE-2.0 . 18 */ 19 20 #include <sal/config.h> 21 22 #include <osl/endian.h> 23 #include <utility> 24 #include <vcl/svapp.hxx> 25 #include <unotools/tempfile.hxx> 26 #include <comphelper/diagnose_ex.hxx> 27 #include <tools/UnitConversion.hxx> 28 #include <editeng/eeitem.hxx> 29 #include <editeng/editdata.hxx> 30 #include <sot/storage.hxx> 31 #include <sot/storinfo.hxx> 32 #include <sot/stg.hxx> 33 #include <com/sun/star/embed/Aspects.hpp> 34 #include <com/sun/star/embed/XEmbeddedObject.hpp> 35 #include <com/sun/star/frame/XModel.hpp> 36 #include <com/sun/star/office/XAnnotation.hpp> 37 #include <com/sun/star/office/XAnnotationAccess.hpp> 38 #include <com/sun/star/text/XText.hpp> 39 #include <com/sun/star/geometry/RealPoint2D.hpp> 40 #include <com/sun/star/util/DateTime.hpp> 41 #include <com/sun/star/drawing/BitmapMode.hpp> 42 #include <filter/msfilter/svdfppt.hxx> 43 #include <svx/xflgrit.hxx> 44 #include <svx/xbtmpit.hxx> 45 #include <svx/svdtrans.hxx> 46 #include <svx/svdmodel.hxx> 47 #include <svx/svdpage.hxx> 48 #include <svx/svdobj.hxx> 49 #include <svx/svdogrp.hxx> 50 #include <svx/svdorect.hxx> 51 #include <svx/svdopage.hxx> 52 #include <svx/svdograf.hxx> 53 #include <svx/svdopath.hxx> 54 #include <svx/svdotable.hxx> 55 #include <svx/xfillit0.hxx> 56 #include <svx/xflbstit.hxx> 57 #include <svx/xflbmtit.hxx> 58 #include <svx/xflclit.hxx> 59 #include <svx/xfltrit.hxx> 60 #include <editeng/outlobj.hxx> 61 #include <editeng/numdef.hxx> 62 #include <svx/sdasitm.hxx> 63 #include <svx/sdmetitm.hxx> 64 #include <svx/sdtagitm.hxx> 65 #include <svx/sdtditm.hxx> 66 #include <svx/sdtfsitm.hxx> 67 #include <svx/sdtmfitm.hxx> 68 #include <svx/xlineit0.hxx> 69 #include <svx/xlnclit.hxx> 70 #include <svx/xlnwtit.hxx> 71 #include <editeng/hngpnctitem.hxx> 72 #include <editeng/forbiddenruleitem.hxx> 73 #include <svx/svdoashp.hxx> 74 #include <editeng/tstpitem.hxx> 75 #include <editeng/editids.hrc> 76 77 #include <editeng/adjustitem.hxx> 78 #include <editeng/escapementitem.hxx> 79 #include <editeng/colritem.hxx> 80 #include <editeng/fhgtitem.hxx> 81 #include <editeng/wghtitem.hxx> 82 #include <editeng/postitem.hxx> 83 #include <editeng/udlnitem.hxx> 84 #include <editeng/crossedoutitem.hxx> 85 #include <editeng/shdditem.hxx> 86 #include <editeng/charreliefitem.hxx> 87 #include <editeng/fontitem.hxx> 88 #include <svx/svdoutl.hxx> 89 #include <editeng/lspcitem.hxx> 90 #include <editeng/ulspitem.hxx> 91 #include <editeng/lrspitem.hxx> 92 #include <editeng/numitem.hxx> 93 #include <vcl/gdimtf.hxx> 94 #include <vcl/BitmapReadAccess.hxx> 95 #include <svx/svditer.hxx> 96 #include <editeng/flditem.hxx> 97 #include <tools/zcodec.hxx> 98 #include <filter/msfilter/svxmsbas.hxx> 99 #include <sfx2/objsh.hxx> 100 #include <editeng/brushitem.hxx> 101 #include <editeng/langitem.hxx> 102 #include <svx/svdoole2.hxx> 103 #include <toolkit/helper/vclunohelper.hxx> 104 #include <com/sun/star/container/XIndexContainer.hpp> 105 #include <com/sun/star/drawing/XControlShape.hpp> 106 #include <com/sun/star/form/XFormComponent.hpp> 107 #include <com/sun/star/beans/XPropertySet.hpp> 108 #include <com/sun/star/drawing/XDrawPagesSupplier.hpp> 109 #include <com/sun/star/drawing/XMasterPagesSupplier.hpp> 110 #include <com/sun/star/awt/Size.hpp> 111 #include <com/sun/star/drawing/FillStyle.hpp> 112 #include <com/sun/star/drawing/TextVerticalAdjust.hpp> 113 #include <editeng/frmdiritem.hxx> 114 #include <svx/sdtfchim.hxx> 115 #include <com/sun/star/awt/Gradient.hpp> 116 #include <com/sun/star/table/XMergeableCellRange.hpp> 117 #include <com/sun/star/table/BorderLine2.hpp> 118 #include <com/sun/star/table/BorderLineStyle.hpp> 119 #include <com/sun/star/lang/XMultiServiceFactory.hpp> 120 #include <svtools/embedhlp.hxx> 121 #include <o3tl/enumrange.hxx> 122 #include <o3tl/safeint.hxx> 123 #include <o3tl/sorted_vector.hxx> 124 #include <sal/log.hxx> 125 126 #include <algorithm> 127 #include <cassert> 128 #include <rtl/strbuf.hxx> 129 #include <tools/time.hxx> 130 #include <memory> 131 132 // PPT ColorScheme Slots 133 #define PPT_COLSCHEME (0x08000000) 134 #define PPT_COLSCHEME_HINTERGRUND (0x08000000) 135 #define PPT_COLSCHEME_TEXT_UND_ZEILEN (0x08000001) 136 #define PPT_COLSCHEME_TITELTEXT (0x08000003) 137 #define PPT_COLSCHEME_A_UND_HYPERLINK (0x08000006) 138 139 #define ANSI_CHARSET 0 140 #define SYMBOL_CHARSET 2 141 142 /* Font Families */ 143 #define FF_ROMAN 0x10 144 #define FF_SWISS 0x20 145 #define FF_MODERN 0x30 146 #define FF_SCRIPT 0x40 147 #define FF_DECORATIVE 0x50 148 149 #define DEFAULT_PITCH 0x00 150 #define FIXED_PITCH 0x01 151 #define VARIABLE_PITCH 0x02 152 153 using namespace ::com::sun::star ; 154 using namespace uno ; 155 using namespace beans ; 156 using namespace drawing ; 157 using namespace container ; 158 using namespace table ; 159 160 PowerPointImportParam::PowerPointImportParam( SvStream& rDocStrm ) : 161 rDocStream ( rDocStrm ), 162 nImportFlags ( 0 ) 163 { 164 } 165 166 SvStream& ReadPptCurrentUserAtom( SvStream& rIn, PptCurrentUserAtom& rAtom ) 167 { 168 DffRecordHeader aHd; 169 ReadDffRecordHeader( rIn, aHd ); 170 if ( aHd.nRecType == PPT_PST_CurrentUserAtom ) 171 { 172 sal_uInt32 nLen; 173 sal_uInt16 nUserNameLen(0), nPad; 174 rIn.ReadUInt32( nLen ) 175 .ReadUInt32( rAtom.nMagic ) 176 .ReadUInt32( rAtom.nCurrentUserEdit ) 177 .ReadUInt16( nUserNameLen ) 178 .ReadUInt16( rAtom.nDocFileVersion ) 179 .ReadUChar( rAtom.nMajorVersion ) 180 .ReadUChar( rAtom.nMinorVersion ) 181 .ReadUInt16( nPad ); 182 rAtom.aCurrentUser = SvxMSDffManager::MSDFFReadZString( rIn, nUserNameLen, true ); 183 } 184 aHd.SeekToEndOfRecord( rIn ); 185 return rIn; 186 } 187 188 void PptSlidePersistAtom::Clear() 189 { 190 nReserved = nPsrReference = nFlags = nNumberTexts = nSlideId = 0; 191 } 192 193 SvStream& ReadPptSlidePersistAtom( SvStream& rIn, PptSlidePersistAtom& rAtom ) 194 { 195 DffRecordHeader aHd; 196 ReadDffRecordHeader( rIn, aHd ); 197 rIn 198 .ReadUInt32( rAtom.nPsrReference ) 199 .ReadUInt32( rAtom.nFlags ) 200 .ReadUInt32( rAtom.nNumberTexts ) 201 .ReadUInt32( rAtom.nSlideId ); 202 aHd.SeekToEndOfRecord( rIn ); 203 return rIn; 204 } 205 206 PptSlidePersistList::PptSlidePersistList() {} 207 208 PptSlidePersistList::~PptSlidePersistList() {} 209 210 sal_uInt16 PptSlidePersistList::FindPage(sal_uInt32 nId) const 211 { 212 for ( size_t i=0; i < mvEntries.size(); i++ ) 213 { 214 if (mvEntries[ i ]->GetSlideId() == nId) return i; 215 } 216 return PPTSLIDEPERSIST_ENTRY_NOTFOUND; 217 } 218 219 SvStream& ReadPptInteractiveInfoAtom( SvStream& rIn, PptInteractiveInfoAtom& rAtom ) 220 { 221 rIn.ReadUInt32( rAtom.nSoundRef ) 222 .ReadUInt32( rAtom.nExHyperlinkId ) 223 .ReadUChar( rAtom.nAction ) 224 .ReadUChar( rAtom.nOleVerb ) 225 .ReadUChar( rAtom.nJump ) 226 .ReadUChar( rAtom.nFlags ) 227 .ReadUChar( rAtom.nHyperlinkType ) 228 .ReadUChar( rAtom.nUnknown1 ) 229 .ReadUChar( rAtom.nUnknown2 ) 230 .ReadUChar( rAtom.nUnknown3 ); 231 return rIn; 232 } 233 234 SvStream& ReadPptExOleObjAtom( SvStream& rIn, PptExOleObjAtom& rAtom ) 235 { 236 sal_uInt32 nDummy1; 237 sal_uInt32 nDummy2; 238 sal_uInt32 nDummy4; 239 240 rIn.ReadUInt32( rAtom.nAspect ) 241 .ReadUInt32( nDummy1 ) 242 .ReadUInt32( rAtom.nId ) 243 .ReadUInt32( nDummy2 ) 244 .ReadUInt32( rAtom.nPersistPtr ) 245 .ReadUInt32( nDummy4 ); 246 return rIn; 247 } 248 249 SvStream& ReadPptDocumentAtom(SvStream& rIn, PptDocumentAtom& rAtom) 250 { 251 // Actual format: 252 // 00 aSlidePageSizeXY 8 253 // 08 aNotesPageSizeXY 8 254 // 16 aZoomRatio (OLE) 8 255 // 24 nNotesMasterPersist 4 256 // 28 nHandoutMasterPersist 4 257 // 32 n1stPageNumber 2 258 // 34 ePageFormat 2 259 // 36 bEmbeddedTrueType 1 260 // 37 bOmitTitlePlace 1 261 // 38 bRightToLeft 1 262 // 39 bShowComments 1 263 264 DffRecordHeader aHd; 265 sal_Int32 nSlideX(0), nSlideY(0), nNoticeX(0), nNoticeY(0), nDummy; 266 sal_uInt16 nSlidePageFormat(0); 267 sal_Int8 nEmbeddedTrueType(0), nTitlePlaceHoldersOmitted(0), nRightToLeft(0), nShowComments(0); 268 269 ReadDffRecordHeader( rIn, aHd ); 270 rIn 271 .ReadInt32( nSlideX ).ReadInt32( nSlideY ) 272 .ReadInt32( nNoticeX ).ReadInt32( nNoticeY ) 273 .ReadInt32( nDummy ).ReadInt32( nDummy ) // skip ZoomRatio 274 .ReadUInt32( rAtom.nNotesMasterPersist ) 275 .ReadUInt32( rAtom.nHandoutMasterPersist ) 276 .ReadUInt16( rAtom.n1stPageNumber ) 277 .ReadUInt16( nSlidePageFormat ) 278 .ReadSChar( nEmbeddedTrueType ) 279 .ReadSChar( nTitlePlaceHoldersOmitted ) 280 .ReadSChar( nRightToLeft ) 281 .ReadSChar( nShowComments ); 282 // clamp dodgy data to avoid overflow in later calculations 283 const sal_Int32 nPageClamp = SAL_MAX_INT32/5; 284 rAtom.aSlidesPageSize.setWidth( std::clamp<sal_Int32>(nSlideX, -nPageClamp, nPageClamp) ); 285 rAtom.aSlidesPageSize.setHeight( std::clamp<sal_Int32>(nSlideY, -nPageClamp, nPageClamp) ); 286 const sal_Int32 nNoteClamp = 65536; 287 rAtom.aNotesPageSize.setWidth( std::clamp<sal_Int32>(nNoticeX, -nNoteClamp, nNoteClamp) ); 288 rAtom.aNotesPageSize.setHeight( std::clamp<sal_Int32>(nNoticeY, -nNoteClamp, nNoteClamp) ); 289 rAtom.eSlidesPageFormat = static_cast<PptPageFormat>(nSlidePageFormat); 290 rAtom.bEmbeddedTrueType = nEmbeddedTrueType; 291 rAtom.bTitlePlaceholdersOmitted = nTitlePlaceHoldersOmitted; 292 rAtom.bRightToLeft = nRightToLeft; 293 rAtom.bShowComments = nShowComments; 294 aHd.SeekToEndOfRecord( rIn ); 295 return rIn; 296 } 297 298 void PptSlideLayoutAtom::Clear() 299 { 300 eLayout = PptSlideLayout::TITLESLIDE; 301 for (PptPlaceholder & i : aPlaceholderId) 302 i = PptPlaceholder::NONE; 303 } 304 305 SvStream& ReadPptSlideLayoutAtom( SvStream& rIn, PptSlideLayoutAtom& rAtom ) 306 { 307 sal_Int32 nTmp; 308 rIn.ReadInt32(nTmp); 309 rAtom.eLayout = static_cast<PptSlideLayout>(nTmp); 310 static_assert(sizeof(rAtom.aPlaceholderId) == 8, "wrong size of serialized array"); 311 rIn.ReadBytes(rAtom.aPlaceholderId, 8); 312 return rIn; 313 } 314 315 SvStream& ReadPptSlideAtom( SvStream& rIn, PptSlideAtom& rAtom ) 316 { 317 DffRecordHeader aHd; 318 ReadDffRecordHeader( rIn, aHd ); 319 ReadPptSlideLayoutAtom( rIn, rAtom.aLayout ); 320 rIn.ReadUInt32( rAtom.nMasterId ) 321 .ReadUInt32( rAtom.nNotesId ) 322 .ReadUInt16( rAtom.nFlags ); 323 aHd.SeekToEndOfRecord( rIn ); 324 return rIn; 325 } 326 327 void PptSlideAtom::Clear() 328 { 329 nMasterId = nNotesId = 0; 330 nFlags = 0; 331 } 332 333 SvStream& ReadPptNotesAtom( SvStream& rIn, PptNotesAtom& rAtom ) 334 { 335 DffRecordHeader aHd; 336 ReadDffRecordHeader( rIn, aHd ); 337 rIn 338 .ReadUInt32( rAtom.nSlideId ) 339 .ReadUInt16( rAtom.nFlags ); 340 aHd.SeekToEndOfRecord( rIn ); 341 return rIn; 342 } 343 344 void PptNotesAtom::Clear() 345 { 346 nSlideId = 0; 347 nFlags = 0; 348 } 349 350 PptColorSchemeAtom::PptColorSchemeAtom() 351 { 352 } 353 354 Color PptColorSchemeAtom::GetColor( sal_uInt16 nNum ) const 355 { 356 Color aRetval; 357 if ( nNum < 8 ) 358 { 359 nNum <<= 2; 360 aRetval.SetRed( aData[ nNum++ ] ); 361 aRetval.SetGreen( aData[ nNum++ ] ); 362 aRetval.SetBlue( aData[ nNum++ ] ); 363 } 364 return aRetval; 365 } 366 367 SvStream& ReadPptColorSchemeAtom( SvStream& rIn, PptColorSchemeAtom& rAtom ) 368 { 369 DffRecordHeader aHd; 370 ReadDffRecordHeader( rIn, aHd ); 371 rIn.ReadBytes(rAtom.aData, 32); 372 aHd.SeekToEndOfRecord( rIn ); 373 return rIn; 374 } 375 376 SvStream& ReadPptFontEntityAtom( SvStream& rIn, PptFontEntityAtom& rAtom ) 377 { 378 DffRecordHeader aHd; 379 ReadDffRecordHeader( rIn, aHd ); 380 sal_Unicode nTemp, cData[ 32 ]; 381 rIn.ReadBytes(cData, 64); 382 383 sal_uInt8 lfCharset, lfPitchAndFamily; 384 385 rIn.ReadUChar( lfCharset ) 386 .ReadUChar( rAtom.lfClipPrecision ) 387 .ReadUChar( rAtom.lfQuality ) 388 .ReadUChar( lfPitchAndFamily ); 389 390 switch( lfCharset ) 391 { 392 case SYMBOL_CHARSET : 393 rAtom.eCharSet = RTL_TEXTENCODING_SYMBOL; 394 break; 395 case ANSI_CHARSET : 396 rAtom.eCharSet = RTL_TEXTENCODING_MS_1252; 397 break; 398 399 default : 400 rAtom.eCharSet = osl_getThreadTextEncoding(); 401 } 402 switch ( lfPitchAndFamily & 0xf0 ) 403 { 404 case FF_ROMAN: 405 rAtom.eFamily = FAMILY_ROMAN; 406 break; 407 408 case FF_SWISS: 409 rAtom.eFamily = FAMILY_SWISS; 410 break; 411 412 case FF_MODERN: 413 rAtom.eFamily = FAMILY_MODERN; 414 break; 415 416 case FF_SCRIPT: 417 rAtom.eFamily = FAMILY_SCRIPT; 418 break; 419 420 case FF_DECORATIVE: 421 rAtom.eFamily = FAMILY_DECORATIVE; 422 break; 423 424 default: 425 rAtom.eFamily = FAMILY_DONTKNOW; 426 break; 427 } 428 429 switch ( lfPitchAndFamily & 0x0f ) 430 { 431 case FIXED_PITCH: 432 rAtom.ePitch = PITCH_FIXED; 433 break; 434 435 case DEFAULT_PITCH: 436 case VARIABLE_PITCH: 437 default: 438 rAtom.ePitch = PITCH_VARIABLE; 439 break; 440 } 441 sal_uInt16 i; 442 for ( i = 0; i < 32; i++ ) 443 { 444 nTemp = cData[ i ]; 445 if ( !nTemp ) 446 break; 447 #ifdef OSL_BIGENDIAN 448 cData[ i ] = ( nTemp >> 8 ) | ( nTemp << 8 ); 449 #endif 450 } 451 rAtom.aName = OUString(cData, i); 452 OutputDevice* pDev = Application::GetDefaultDevice(); 453 rAtom.bAvailable = pDev->IsFontAvailable( rAtom.aName ); 454 aHd.SeekToEndOfRecord( rIn ); 455 return rIn; 456 } 457 458 SvStream& ReadPptUserEditAtom( SvStream& rIn, PptUserEditAtom& rAtom ) 459 { 460 sal_Int16 lastViewType = 0; 461 ReadDffRecordHeader( rIn, rAtom.aHd ); 462 rIn 463 .ReadInt32( rAtom.nLastSlideID ) 464 .ReadUInt32( rAtom.nVersion ) 465 .ReadUInt32( rAtom.nOffsetLastEdit ) 466 .ReadUInt32( rAtom.nOffsetPersistDirectory ) 467 .ReadUInt32( rAtom.nDocumentRef ) 468 .ReadUInt32( rAtom.nMaxPersistWritten ) 469 .ReadInt16( lastViewType ); 470 rAtom.eLastViewType = static_cast<PptViewTypeEnum>(lastViewType); 471 rAtom.aHd.SeekToEndOfRecord(rIn); 472 return rIn; 473 } 474 475 void PptOEPlaceholderAtom::Clear() 476 { 477 nPlacementId = 0; 478 nPlaceholderSize = 0; 479 nPlaceholderId = PptPlaceholder::NONE; 480 } 481 482 SvStream& ReadPptOEPlaceholderAtom( SvStream& rIn, PptOEPlaceholderAtom& rAtom ) 483 { 484 rIn.ReadUInt32( rAtom.nPlacementId ); 485 sal_uInt8 nTmp; 486 rIn.ReadUChar(nTmp); 487 rAtom.nPlaceholderId = static_cast<PptPlaceholder>(nTmp); 488 rIn.ReadUChar( rAtom.nPlaceholderSize ); 489 return rIn; 490 } 491 492 PptSlidePersistEntry::PptSlidePersistEntry() : 493 nSlidePersistStartOffset( 0 ), 494 nSlidePersistEndOffset ( 0 ), 495 nBackgroundOffset ( 0 ), 496 nDrawingDgId ( 0xffffffff ), 497 ePageKind ( PPT_MASTERPAGE ), 498 bNotesMaster ( false ), 499 bHandoutMaster ( false ), 500 bStarDrawFiller ( false ) 501 { 502 HeaderFooterOfs[ 0 ] = HeaderFooterOfs[ 1 ] = HeaderFooterOfs[ 2 ] = HeaderFooterOfs[ 3 ] = 0; 503 } 504 505 PptSlidePersistEntry::~PptSlidePersistEntry() 506 { 507 } 508 509 SdrEscherImport::SdrEscherImport( PowerPointImportParam& rParam, const OUString& rBaseURL ) : 510 SvxMSDffManager ( rParam.rDocStream, rBaseURL ), 511 nStreamLen ( 0 ), 512 rImportParam ( rParam ) 513 { 514 } 515 516 SdrEscherImport::~SdrEscherImport() 517 { 518 } 519 520 const PptSlideLayoutAtom* SdrEscherImport::GetSlideLayoutAtom() const 521 { 522 return nullptr; 523 } 524 525 bool SdrEscherImport::ReadString( OUString& rStr ) const 526 { 527 bool bRet = false; 528 DffRecordHeader aStrHd; 529 ReadDffRecordHeader( rStCtrl, aStrHd ); 530 if (aStrHd.nRecType == PPT_PST_TextBytesAtom 531 || aStrHd.nRecType == PPT_PST_TextCharsAtom 532 || aStrHd.nRecType == PPT_PST_CString) 533 { 534 bool bUniCode = 535 (aStrHd.nRecType == PPT_PST_TextCharsAtom 536 || aStrHd.nRecType == PPT_PST_CString); 537 sal_uLong nBytes = aStrHd.nRecLen; 538 rStr = MSDFFReadZString( rStCtrl, nBytes, bUniCode ); 539 bRet = aStrHd.SeekToEndOfRecord( rStCtrl ); 540 } 541 else 542 aStrHd.SeekToBegOfRecord( rStCtrl ); 543 return bRet; 544 } 545 546 bool SdrEscherImport::GetColorFromPalette(sal_uInt16 /*nNum*/, Color& /*rColor*/) const 547 { 548 return false; 549 } 550 551 bool SdrEscherImport::SeekToShape( SvStream& /*rSt*/, SvxMSDffClientData* /*pClientData*/, sal_uInt32 /*nId*/) const 552 { 553 return false; 554 } 555 556 const PptFontEntityAtom* SdrEscherImport::GetFontEnityAtom( sal_uInt32 nNum ) const 557 { 558 if (m_xFonts && nNum < m_xFonts->size()) 559 return &(*m_xFonts)[ nNum ]; 560 return nullptr; 561 } 562 563 SdrObject* SdrEscherImport::ReadObjText( PPTTextObj* /*pTextObj*/, SdrObject* pObj, SdPageCapsule /*pPage*/) const 564 { 565 return pObj; 566 } 567 568 void SdrEscherImport::ProcessClientAnchor2( SvStream& rSt, DffRecordHeader& rHd, DffObjData& rObj ) 569 { 570 sal_Int32 l, t, r, b; 571 if ( rHd.nRecLen == 16 ) 572 { 573 rSt.ReadInt32( l ).ReadInt32( t ).ReadInt32( r ).ReadInt32( b ); 574 } 575 else 576 { 577 sal_Int16 ls, ts, rs, bs; 578 rSt.ReadInt16( ts ).ReadInt16( ls ).ReadInt16( rs ).ReadInt16( bs ); // the order of coordinates is a bit strange... 579 l = ls; 580 t = ts; 581 r = rs; 582 b = bs; 583 } 584 if (!rSt.good()) 585 { 586 SAL_WARN("filter.ms", "ProcessClientAnchor2: short read"); 587 return; 588 } 589 Scale( l ); 590 Scale( t ); 591 Scale( r ); 592 Scale( b ); 593 rObj.aChildAnchor = tools::Rectangle( l, t, r, b ); 594 rObj.bChildAnchor = true; 595 }; 596 597 void SdrEscherImport::RecolorGraphic( SvStream& rSt, sal_uInt32 nRecLen, Graphic& rGraphic ) 598 { 599 if ( rGraphic.GetType() != GraphicType::GdiMetafile ) 600 return; 601 602 sal_uInt16 nX, nGlobalColorsCount, nFillColorsCount; 603 604 rSt.ReadUInt16( nX ) 605 .ReadUInt16( nGlobalColorsCount ) 606 .ReadUInt16( nFillColorsCount ) 607 .ReadUInt16( nX ) 608 .ReadUInt16( nX ) 609 .ReadUInt16( nX ); 610 611 if ( ( nGlobalColorsCount > 64 ) || ( nFillColorsCount > 64 ) ) 612 return; 613 614 if ( static_cast<sal_uInt32>( ( nGlobalColorsCount + nFillColorsCount ) * 44 + 12 ) != nRecLen ) 615 return; 616 617 sal_uInt32 OriginalGlobalColors[ 64 ]; 618 sal_uInt32 NewGlobalColors[ 64 ]; 619 620 sal_uInt32 i, j, nGlobalColorsChanged, nFillColorsChanged; 621 nGlobalColorsChanged = nFillColorsChanged = 0; 622 623 sal_uInt32* pCurrentOriginal = OriginalGlobalColors; 624 sal_uInt32* pCurrentNew = NewGlobalColors; 625 sal_uInt32* pCount = &nGlobalColorsChanged; 626 i = nGlobalColorsCount; 627 628 for ( j = 0; j < 2; j++ ) 629 { 630 for ( ; i > 0; i-- ) 631 { 632 sal_uInt64 nPos = rSt.Tell(); 633 sal_uInt16 nChanged; 634 rSt.ReadUInt16( nChanged ); 635 if ( nChanged & 1 ) 636 { 637 sal_uInt8 nDummy, nRed, nGreen, nBlue; 638 sal_uInt32 nColor = 0; 639 sal_uInt32 nIndex; 640 rSt.ReadUChar( nDummy ) 641 .ReadUChar( nRed ) 642 .ReadUChar( nDummy ) 643 .ReadUChar( nGreen ) 644 .ReadUChar( nDummy ) 645 .ReadUChar( nBlue ) 646 .ReadUInt32( nIndex ); 647 648 if ( nIndex < 8 ) 649 { 650 Color aColor = MSO_CLR_ToColor( nIndex << 24 ); 651 nRed = aColor.GetRed(); 652 nGreen = aColor.GetGreen(); 653 nBlue = aColor.GetBlue(); 654 } 655 nColor = nRed | ( nGreen << 8 ) | ( nBlue << 16 ); 656 *pCurrentNew++ = nColor; 657 rSt.ReadUChar( nDummy ) 658 .ReadUChar( nRed ) 659 .ReadUChar( nDummy ) 660 .ReadUChar( nGreen ) 661 .ReadUChar( nDummy ) 662 .ReadUChar( nBlue ); 663 nColor = nRed | ( nGreen << 8 ) | ( nBlue << 16 ); 664 *pCurrentOriginal++ = nColor; 665 (*pCount)++; 666 } 667 rSt.Seek( nPos + 44 ); 668 } 669 pCount = &nFillColorsChanged; 670 i = nFillColorsCount; 671 } 672 if ( !(nGlobalColorsChanged || nFillColorsChanged) ) 673 return; 674 675 std::unique_ptr<Color[]> pSearchColors(new Color[ nGlobalColorsChanged ]); 676 std::unique_ptr<Color[]> pReplaceColors(new Color[ nGlobalColorsChanged ]); 677 678 for ( j = 0; j < nGlobalColorsChanged; j++ ) 679 { 680 sal_uInt32 nSearch = OriginalGlobalColors[ j ]; 681 sal_uInt32 nReplace = NewGlobalColors[ j ]; 682 683 pSearchColors[ j ].SetRed( static_cast<sal_uInt8>(nSearch) ); 684 pSearchColors[ j ].SetGreen( static_cast<sal_uInt8>( nSearch >> 8 ) ); 685 pSearchColors[ j ].SetBlue( static_cast<sal_uInt8>( nSearch >> 16 ) ); 686 687 pReplaceColors[ j ].SetRed( static_cast<sal_uInt8>(nReplace) ); 688 pReplaceColors[ j ].SetGreen( static_cast<sal_uInt8>( nReplace >> 8 ) ); 689 pReplaceColors[ j ].SetBlue( static_cast<sal_uInt8>( nReplace >> 16 ) ); 690 } 691 GDIMetaFile aGdiMetaFile( rGraphic.GetGDIMetaFile() ); 692 aGdiMetaFile.ReplaceColors( pSearchColors.get(), pReplaceColors.get(), 693 nGlobalColorsChanged ); 694 rGraphic = aGdiMetaFile; 695 } 696 697 sal_uLong DffPropSet::SanitizeEndPos(SvStream &rIn, sal_uLong nEndRecPos) 698 { 699 auto nStreamLen = rIn.Tell() + rIn.remainingSize(); 700 if (nEndRecPos > nStreamLen) 701 { 702 SAL_WARN("filter.ms", "Parsing error: " << nStreamLen << 703 " max end pos, but " << nEndRecPos << " claimed, truncating"); 704 nEndRecPos = nStreamLen; 705 } 706 return nEndRecPos; 707 } 708 709 void ProcessData::NotifyFreeObj(SdrObject* pObj) 710 { 711 if (rPersistEntry.xSolverContainer) 712 { 713 for (auto & pPtr : rPersistEntry.xSolverContainer->aCList) 714 { 715 if (pPtr->pAObj == pObj) 716 pPtr->pAObj = nullptr; 717 if (pPtr->pBObj == pObj) 718 pPtr->pBObj = nullptr; 719 if (pPtr->pCObj == pObj) 720 pPtr->pCObj = nullptr; 721 } 722 } 723 } 724 725 /* ProcessObject is called from ImplSdPPTImport::ProcessObj to handle all application specific things, 726 such as the import of text, animation effects, header footer and placeholder. 727 728 The parameter pOriginalObj is the object as it was imported by our general escher import, it must either 729 be deleted or it can be returned to be inserted into the sdr page. 730 */ 731 rtl::Reference<SdrObject> SdrEscherImport::ProcessObj( SvStream& rSt, DffObjData& rObjData, SvxMSDffClientData& rClientData, tools::Rectangle& rTextRect, SdrObject* pOriginalObj ) 732 { 733 if ( dynamic_cast<const SdrObjCustomShape* >(pOriginalObj) != nullptr ) 734 pOriginalObj->SetMergedItem( SdrTextFixedCellHeightItem( true ) ); 735 736 // we are initializing our return value with the object that was imported by our escher import 737 rtl::Reference<SdrObject> pRet = pOriginalObj; 738 739 ProcessData& rData = static_cast<ProcessData&>(rClientData); 740 PptSlidePersistEntry& rPersistEntry = rData.rPersistEntry; 741 742 if ( ! (rObjData.nSpFlags & ShapeFlag::Group) ) // sj: #114758# ... 743 { 744 PptOEPlaceholderAtom aPlaceholderAtom; 745 746 if ( maShapeRecords.SeekToContent( rSt, DFF_msofbtClientData, SEEK_FROM_CURRENT_AND_RESTART ) ) 747 { 748 sal_Int16 nHeaderFooterInstance = -1; 749 DffRecordHeader aClientDataHd; 750 auto nEndRecPos = SanitizeEndPos(rSt, maShapeRecords.Current()->GetRecEndFilePos()); 751 while ( ( rSt.GetError() == ERRCODE_NONE ) && ( rSt.Tell() < nEndRecPos ) ) 752 { 753 ReadDffRecordHeader( rSt, aClientDataHd ); 754 switch ( aClientDataHd.nRecType ) 755 { 756 // importing header/footer object from master page 757 case PPT_PST_OEPlaceholderAtom : 758 { 759 ReadPptOEPlaceholderAtom( rSt, aPlaceholderAtom ); 760 if ( nHeaderFooterInstance == -1 ) 761 { 762 switch ( aPlaceholderAtom.nPlaceholderId ) 763 { 764 case PptPlaceholder::MASTERSLIDENUMBER : nHeaderFooterInstance++; 765 [[fallthrough]]; 766 case PptPlaceholder::MASTERFOOTER : nHeaderFooterInstance++; 767 [[fallthrough]]; 768 case PptPlaceholder::MASTERHEADER : nHeaderFooterInstance++; 769 [[fallthrough]]; 770 case PptPlaceholder::MASTERDATE : nHeaderFooterInstance++; break; 771 default: break; 772 773 } 774 if ( ! ( nHeaderFooterInstance & 0xfffc ) ) // is this a valid instance ( 0->3 ) 775 rPersistEntry.HeaderFooterOfs[ nHeaderFooterInstance ] = rObjData.rSpHd.GetRecBegFilePos(); 776 } 777 } 778 break; 779 780 case PPT_PST_RecolorInfoAtom : 781 { 782 if ( auto pSdrGrafObj = dynamic_cast<SdrGrafObj* >(pRet.get()) ) 783 if ( pSdrGrafObj->HasGDIMetaFile() ) 784 { 785 Graphic aGraphic( pSdrGrafObj->GetGraphic() ); 786 RecolorGraphic( rSt, aClientDataHd.nRecLen, aGraphic ); 787 pSdrGrafObj->SetGraphic( aGraphic ); 788 } 789 } 790 break; 791 } 792 if (!aClientDataHd.SeekToEndOfRecord(rSt)) 793 break; 794 } 795 } 796 if ( ( aPlaceholderAtom.nPlaceholderId == PptPlaceholder::NOTESSLIDEIMAGE ) && !rPersistEntry.bNotesMaster ) 797 { 798 sal_uInt16 nPageNum = pSdrModel->GetPageCount(); 799 if ( nPageNum > 0 ) 800 nPageNum--; 801 802 // replacing the object which we will return with a SdrPageObj 803 pRet = new SdrPageObj( 804 *pSdrModel, 805 rObjData.aBoundRect, 806 pSdrModel->GetPage(nPageNum - 1)); 807 } 808 else 809 { 810 // try to load some ppt text 811 PPTTextObj aTextObj( rSt, static_cast<SdrPowerPointImport&>(*this), rPersistEntry, &rObjData ); 812 if ( aTextObj.Count() || aTextObj.GetOEPlaceHolderAtom() ) 813 { 814 bool bVerticalText = false; 815 // and if the text object is not empty, it must be applied to pRet, the object we 816 // initially got from our escher import 817 Degree100 nTextRotationAngle(0); 818 if ( IsProperty( DFF_Prop_txflTextFlow ) ) 819 { 820 auto eTextFlow = GetPropertyValue(DFF_Prop_txflTextFlow, 0) & 0xFFFF; 821 switch( eTextFlow ) 822 { 823 case mso_txflBtoT : // Bottom to Top non-@ 824 nTextRotationAngle += 9000_deg100; 825 break; 826 case mso_txflTtoBA : /* #68110# */ // Top to Bottom @-font 827 case mso_txflTtoBN : // Top to Bottom non-@ 828 case mso_txflVertN : // Vertical, non-@, top to bottom 829 bVerticalText = !bVerticalText; // nTextRotationAngle += 27000; 830 break; 831 // case mso_txflHorzN : // Horizontal non-@, normal 832 // case mso_txflHorzA : // Horizontal @-font, normal 833 default: break; 834 } 835 } 836 sal_Int32 nFontDirection = GetPropertyValue( DFF_Prop_cdirFont, mso_cdir0 ); 837 if ( ( nFontDirection == 1 ) || ( nFontDirection == 3 ) ) 838 { 839 bVerticalText = !bVerticalText; 840 } 841 const bool bFail = o3tl::checked_multiply<sal_Int32>(nFontDirection, 9000, nFontDirection); 842 if (!bFail) 843 nTextRotationAngle -= Degree100(nFontDirection); 844 else 845 SAL_WARN("filter.ms", "Parsing error: bad fontdirection: " << nFontDirection); 846 aTextObj.SetVertical( bVerticalText ); 847 if ( pRet ) 848 { 849 bool bDeleteSource = aTextObj.GetOEPlaceHolderAtom() != nullptr; 850 if ( bDeleteSource && dynamic_cast<const SdrGrafObj* >(pRet.get()) == nullptr // we are not allowed to get 851 && dynamic_cast<const SdrObjGroup* >(pRet.get()) == nullptr // grouped placeholder objects 852 && dynamic_cast<const SdrOle2Obj* >(pRet.get()) == nullptr ) 853 { 854 pRet = nullptr; 855 } 856 } 857 sal_uInt32 nTextFlags = aTextObj.GetTextFlags(); 858 sal_Int32 nTextLeft = GetPropertyValue( DFF_Prop_dxTextLeft, 25 * 3600 ); // 0.25 cm (emu) 859 sal_Int32 nTextRight = GetPropertyValue( DFF_Prop_dxTextRight, 25 * 3600 ); // 0.25 cm (emu) 860 sal_Int32 nTextTop = GetPropertyValue( DFF_Prop_dyTextTop, 13 * 3600 ); // 0.13 cm (emu) 861 sal_Int32 nTextBottom = GetPropertyValue( DFF_Prop_dyTextBottom, 13 * 3600 ); 862 ScaleEmu( nTextLeft ); 863 ScaleEmu( nTextRight ); 864 ScaleEmu( nTextTop ); 865 ScaleEmu( nTextBottom ); 866 867 sal_Int32 nMinFrameWidth = 0; 868 sal_Int32 nMinFrameHeight = 0; 869 bool bAutoGrowWidth, bAutoGrowHeight; 870 871 SdrTextVertAdjust eTVA; 872 SdrTextHorzAdjust eTHA; 873 874 nTextFlags &= PPT_TEXTOBJ_FLAGS_PARA_ALIGNMENT_USED_LEFT | PPT_TEXTOBJ_FLAGS_PARA_ALIGNMENT_USED_RIGHT 875 | PPT_TEXTOBJ_FLAGS_PARA_ALIGNMENT_USED_CENTER | PPT_TEXTOBJ_FLAGS_PARA_ALIGNMENT_USED_BLOCK; 876 877 if ( bVerticalText ) 878 { 879 eTVA = SDRTEXTVERTADJUST_BLOCK; 880 eTHA = SDRTEXTHORZADJUST_CENTER; 881 882 // read text anchor 883 auto eTextAnchor = GetPropertyValue(DFF_Prop_anchorText, mso_anchorTop); 884 885 switch( eTextAnchor ) 886 { 887 case mso_anchorTop: 888 case mso_anchorTopCentered: 889 case mso_anchorTopBaseline: 890 case mso_anchorTopCenteredBaseline: 891 eTHA = SDRTEXTHORZADJUST_RIGHT; 892 break; 893 894 case mso_anchorMiddle : 895 case mso_anchorMiddleCentered: 896 eTHA = SDRTEXTHORZADJUST_CENTER; 897 break; 898 899 case mso_anchorBottom: 900 case mso_anchorBottomCentered: 901 case mso_anchorBottomBaseline: 902 case mso_anchorBottomCenteredBaseline: 903 eTHA = SDRTEXTHORZADJUST_LEFT; 904 break; 905 } 906 switch ( eTextAnchor ) 907 { 908 case mso_anchorTopCentered : 909 case mso_anchorMiddleCentered : 910 case mso_anchorBottomCentered : 911 case mso_anchorTopCenteredBaseline: 912 case mso_anchorBottomCenteredBaseline: 913 { 914 // check if it is sensible to use the centered alignment 915 const sal_uInt32 nMask = PPT_TEXTOBJ_FLAGS_PARA_ALIGNMENT_USED_LEFT | PPT_TEXTOBJ_FLAGS_PARA_ALIGNMENT_USED_CENTER | PPT_TEXTOBJ_FLAGS_PARA_ALIGNMENT_USED_RIGHT | PPT_TEXTOBJ_FLAGS_PARA_ALIGNMENT_USED_BLOCK; 916 switch (nTextFlags & nMask) 917 { 918 case PPT_TEXTOBJ_FLAGS_PARA_ALIGNMENT_USED_LEFT: 919 case PPT_TEXTOBJ_FLAGS_PARA_ALIGNMENT_USED_CENTER: 920 case PPT_TEXTOBJ_FLAGS_PARA_ALIGNMENT_USED_RIGHT: 921 case PPT_TEXTOBJ_FLAGS_PARA_ALIGNMENT_USED_BLOCK: 922 eTVA = SDRTEXTVERTADJUST_CENTER; // If the textobject has only one type of alignment, then the text has not to be displayed using the full width; 923 break; 924 } 925 break; 926 } 927 default: 928 break; 929 } 930 nMinFrameWidth = rTextRect.GetWidth() - ( nTextLeft + nTextRight ); 931 } 932 else 933 { 934 eTVA = SDRTEXTVERTADJUST_CENTER; 935 eTHA = SDRTEXTHORZADJUST_BLOCK; 936 937 // read text anchor 938 auto eTextAnchor = GetPropertyValue(DFF_Prop_anchorText, mso_anchorTop); 939 940 switch( eTextAnchor ) 941 { 942 case mso_anchorTop: 943 case mso_anchorTopCentered: 944 case mso_anchorTopBaseline: 945 case mso_anchorTopCenteredBaseline: 946 eTVA = SDRTEXTVERTADJUST_TOP; 947 break; 948 949 case mso_anchorMiddle : 950 case mso_anchorMiddleCentered: 951 eTVA = SDRTEXTVERTADJUST_CENTER; 952 break; 953 954 case mso_anchorBottom: 955 case mso_anchorBottomCentered: 956 case mso_anchorBottomBaseline: 957 case mso_anchorBottomCenteredBaseline: 958 eTVA = SDRTEXTVERTADJUST_BOTTOM; 959 break; 960 } 961 switch ( eTextAnchor ) 962 { 963 case mso_anchorTopCentered : 964 case mso_anchorMiddleCentered : 965 case mso_anchorBottomCentered : 966 case mso_anchorTopCenteredBaseline: 967 case mso_anchorBottomCenteredBaseline: 968 { 969 // check if it is sensible to use the centered alignment 970 const sal_uInt32 nMask = PPT_TEXTOBJ_FLAGS_PARA_ALIGNMENT_USED_LEFT | PPT_TEXTOBJ_FLAGS_PARA_ALIGNMENT_USED_CENTER | PPT_TEXTOBJ_FLAGS_PARA_ALIGNMENT_USED_RIGHT | PPT_TEXTOBJ_FLAGS_PARA_ALIGNMENT_USED_BLOCK; 971 switch (nTextFlags & nMask) 972 { 973 case PPT_TEXTOBJ_FLAGS_PARA_ALIGNMENT_USED_LEFT: 974 case PPT_TEXTOBJ_FLAGS_PARA_ALIGNMENT_USED_CENTER: 975 case PPT_TEXTOBJ_FLAGS_PARA_ALIGNMENT_USED_RIGHT: 976 case PPT_TEXTOBJ_FLAGS_PARA_ALIGNMENT_USED_BLOCK: 977 eTHA = SDRTEXTHORZADJUST_CENTER; // If the textobject has only one type of alignment, then the text has not to be displayed using the full width; 978 break; 979 } 980 break; 981 } 982 default: 983 break; 984 } 985 nMinFrameHeight = rTextRect.GetHeight() - ( nTextTop + nTextBottom ); 986 } 987 988 SdrObjKind eTextKind = SdrObjKind::Rectangle; 989 if ( ( aPlaceholderAtom.nPlaceholderId == PptPlaceholder::NOTESSLIDEIMAGE ) 990 || ( aPlaceholderAtom.nPlaceholderId == PptPlaceholder::MASTERNOTESSLIDEIMAGE ) ) 991 { 992 aTextObj.SetInstance( TSS_Type::Notes ); 993 eTextKind = SdrObjKind::TitleText; 994 } 995 else if ( ( aPlaceholderAtom.nPlaceholderId == PptPlaceholder::MASTERNOTESBODYIMAGE ) 996 || ( aPlaceholderAtom.nPlaceholderId == PptPlaceholder::NOTESBODY ) ) 997 { 998 aTextObj.SetInstance( TSS_Type::Notes ); 999 eTextKind = SdrObjKind::Text; 1000 } 1001 1002 TSS_Type nDestinationInstance = aTextObj.GetInstance(); 1003 if ( rPersistEntry.ePageKind == PPT_MASTERPAGE ) 1004 { 1005 if ( !rPersistEntry.pPresentationObjects ) 1006 { 1007 rPersistEntry.pPresentationObjects.reset( new sal_uInt32[ PPT_STYLESHEETENTRIES ] ); 1008 memset( rPersistEntry.pPresentationObjects.get(), 0, PPT_STYLESHEETENTRIES * 4 ); 1009 } 1010 if ( !rPersistEntry.pPresentationObjects[ static_cast<int>(nDestinationInstance) ] ) 1011 rPersistEntry.pPresentationObjects[ static_cast<int>(nDestinationInstance) ] = rObjData.rSpHd.GetRecBegFilePos(); 1012 } 1013 switch ( nDestinationInstance ) 1014 { 1015 case TSS_Type::PageTitle : 1016 case TSS_Type::Title : 1017 { 1018 if ( GetSlideLayoutAtom()->eLayout == PptSlideLayout::TITLEMASTERSLIDE ) 1019 nDestinationInstance = TSS_Type::Title; 1020 else 1021 nDestinationInstance = TSS_Type::PageTitle; 1022 } 1023 break; 1024 case TSS_Type::Body : 1025 case TSS_Type::HalfBody : 1026 case TSS_Type::QuarterBody : 1027 nDestinationInstance = TSS_Type::Body; 1028 break; 1029 default: break; 1030 } 1031 aTextObj.SetDestinationInstance( nDestinationInstance ); 1032 1033 bool bAutoFit = false; // auto-scale text into shape box 1034 switch ( aTextObj.GetInstance() ) 1035 { 1036 case TSS_Type::PageTitle : 1037 case TSS_Type::Title : eTextKind = SdrObjKind::TitleText; break; 1038 case TSS_Type::Subtitle : eTextKind = SdrObjKind::Text; break; 1039 case TSS_Type::Body : 1040 case TSS_Type::HalfBody : 1041 case TSS_Type::QuarterBody : eTextKind = SdrObjKind::OutlineText; bAutoFit = true; break; 1042 default: break; 1043 } 1044 if ( aTextObj.GetDestinationInstance() != TSS_Type::TextInShape ) 1045 { 1046 if ( !aTextObj.GetOEPlaceHolderAtom() || aTextObj.GetOEPlaceHolderAtom()->nPlaceholderId == PptPlaceholder::NONE ) 1047 { 1048 aTextObj.SetDestinationInstance( TSS_Type::TextInShape ); 1049 eTextKind = SdrObjKind::Rectangle; 1050 } 1051 } 1052 rtl::Reference<SdrObject> pTObj; 1053 bool bWordWrap = GetPropertyValue(DFF_Prop_WrapText, mso_wrapSquare) != mso_wrapNone; 1054 bool bFitShapeToText = ( GetPropertyValue( DFF_Prop_FitTextToShape, 0 ) & 2 ) != 0; 1055 1056 if ( dynamic_cast<const SdrObjCustomShape* >(pRet.get()) != nullptr && ( eTextKind == SdrObjKind::Rectangle ) ) 1057 { 1058 bAutoGrowHeight = bFitShapeToText; 1059 bAutoGrowWidth = !bWordWrap; 1060 pTObj = pRet; 1061 pRet = nullptr; 1062 } 1063 else 1064 { 1065 if ( dynamic_cast<const SdrObjCustomShape* >(pRet.get()) != nullptr ) 1066 { 1067 pRet = nullptr; 1068 } 1069 pTObj = new SdrRectObj( 1070 *pSdrModel, 1071 eTextKind != SdrObjKind::Rectangle ? eTextKind : SdrObjKind::Text); 1072 SfxItemSet aSet( pSdrModel->GetItemPool() ); 1073 if ( !pRet ) 1074 ApplyAttributes( rSt, aSet, rObjData ); 1075 pTObj->SetMergedItemSet( aSet ); 1076 if ( pRet ) 1077 { 1078 pTObj->SetMergedItem( XLineStyleItem( drawing::LineStyle_NONE ) ); 1079 pTObj->SetMergedItem( XFillStyleItem( drawing::FillStyle_NONE ) ); 1080 } 1081 if ( bVerticalText ) 1082 { 1083 bAutoGrowWidth = bFitShapeToText; 1084 bAutoGrowHeight = false; 1085 } 1086 else 1087 { 1088 bAutoGrowWidth = false; 1089 1090 // #119885# re-activating bFitShapeToText here, could not find deeper explanations 1091 // for it (it was from 2005). Keeping the old comment here for reference 1092 // old comment: // bFitShapeToText; can't be used, because we cut the text if it is too height, 1093 bAutoGrowHeight = bFitShapeToText; 1094 } 1095 } 1096 pTObj->SetMergedItem( SvxFrameDirectionItem( bVerticalText ? SvxFrameDirection::Vertical_RL_TB : SvxFrameDirection::Horizontal_LR_TB, EE_PARA_WRITINGDIR ) ); 1097 1098 //Autofit text only if there is no auto grow height and width 1099 //See fdo#41245 1100 if (bAutoFit && !bAutoGrowHeight && !bAutoGrowWidth) 1101 { 1102 pTObj->SetMergedItem( SdrTextFitToSizeTypeItem(drawing::TextFitToSizeType_AUTOFIT) ); 1103 } 1104 1105 if ( dynamic_cast<const SdrObjCustomShape* >(pTObj.get()) == nullptr ) 1106 { 1107 pTObj->SetMergedItem( makeSdrTextAutoGrowWidthItem( bAutoGrowWidth ) ); 1108 pTObj->SetMergedItem( makeSdrTextAutoGrowHeightItem( bAutoGrowHeight ) ); 1109 } 1110 else 1111 { 1112 pTObj->SetMergedItem( makeSdrTextWordWrapItem( bWordWrap ) ); 1113 pTObj->SetMergedItem( makeSdrTextAutoGrowHeightItem( bFitShapeToText ) ); 1114 } 1115 1116 pTObj->SetMergedItem( SdrTextVertAdjustItem( eTVA ) ); 1117 pTObj->SetMergedItem( SdrTextHorzAdjustItem( eTHA ) ); 1118 1119 if ( nMinFrameHeight < 0 ) 1120 nMinFrameHeight = 0; 1121 if ( dynamic_cast<const SdrObjCustomShape* >(pTObj.get()) == nullptr ) 1122 pTObj->SetMergedItem( makeSdrTextMinFrameHeightItem( nMinFrameHeight ) ); 1123 1124 if ( nMinFrameWidth < 0 ) 1125 nMinFrameWidth = 0; 1126 if ( dynamic_cast<const SdrObjCustomShape* >(pTObj.get()) == nullptr ) 1127 pTObj->SetMergedItem( makeSdrTextMinFrameWidthItem( nMinFrameWidth ) ); 1128 1129 // set margins at the borders of the textbox 1130 pTObj->SetMergedItem( makeSdrTextLeftDistItem( nTextLeft ) ); 1131 pTObj->SetMergedItem( makeSdrTextRightDistItem( nTextRight ) ); 1132 pTObj->SetMergedItem( makeSdrTextUpperDistItem( nTextTop ) ); 1133 pTObj->SetMergedItem( makeSdrTextLowerDistItem( nTextBottom ) ); 1134 pTObj->SetMergedItem( SdrTextFixedCellHeightItem( true ) ); 1135 1136 if ( dynamic_cast<const SdrObjCustomShape* >(pTObj.get()) == nullptr ) 1137 pTObj->SetSnapRect( rTextRect ); 1138 pTObj = ReadObjText( &aTextObj, pTObj.get(), rData.pPage ); 1139 1140 if ( pTObj ) 1141 { 1142 /* check if our new snaprect makes trouble, 1143 because we do not display the ADJUST_BLOCK 1144 properly if the textsize is bigger than the 1145 snaprect of the object. Then we will use 1146 ADJUST_CENTER instead of ADJUST_BLOCK. 1147 */ 1148 if ( dynamic_cast<const SdrObjCustomShape* >(pTObj.get()) == nullptr && !bFitShapeToText && !bWordWrap ) 1149 { 1150 SdrTextObj* pText = dynamic_cast<SdrTextObj*>( pTObj.get() ); 1151 if ( pText ) 1152 { 1153 if ( bVerticalText ) 1154 { 1155 if ( eTVA == SDRTEXTVERTADJUST_BLOCK ) 1156 { 1157 Size aTextSize( pText->GetTextSize() ); 1158 aTextSize.AdjustWidth(nTextLeft + nTextRight ); 1159 aTextSize.AdjustHeight(nTextTop + nTextBottom ); 1160 if ( rTextRect.GetHeight() < aTextSize.Height() ) 1161 pTObj->SetMergedItem( SdrTextVertAdjustItem( SDRTEXTVERTADJUST_CENTER ) ); 1162 } 1163 } 1164 else 1165 { 1166 if ( eTHA == SDRTEXTHORZADJUST_BLOCK ) 1167 { 1168 Size aTextSize( pText->GetTextSize() ); 1169 aTextSize.AdjustWidth(nTextLeft + nTextRight ); 1170 aTextSize.AdjustHeight(nTextTop + nTextBottom ); 1171 if ( rTextRect.GetWidth() < aTextSize.Width() ) 1172 pTObj->SetMergedItem( SdrTextHorzAdjustItem( SDRTEXTHORZADJUST_CENTER ) ); 1173 } 1174 } 1175 } 1176 } 1177 // rotate text with shape? 1178 Degree100 nAngle = ( rObjData.nSpFlags & ShapeFlag::FlipV ) ? -mnFix16Angle : mnFix16Angle; // #72116# vertical flip -> rotate by using the other way 1179 nAngle += nTextRotationAngle; 1180 1181 if ( dynamic_cast< const SdrObjCustomShape* >(pTObj.get()) == nullptr ) 1182 { 1183 if ( rObjData.nSpFlags & ShapeFlag::FlipV ) 1184 { 1185 pTObj->Rotate( rTextRect.Center(), 18000_deg100, 0.0, -1.0 ); 1186 } 1187 if ( rObjData.nSpFlags & ShapeFlag::FlipH ) 1188 nAngle = 36000_deg100 - nAngle; 1189 if ( nAngle ) 1190 pTObj->NbcRotate( rObjData.aBoundRect.Center(), nAngle ); 1191 } 1192 if ( pRet ) 1193 { 1194 rtl::Reference<SdrObject> pGroup = new SdrObjGroup(*pSdrModel); 1195 pGroup->GetSubList()->NbcInsertObject( pRet.get() ); 1196 pGroup->GetSubList()->NbcInsertObject( pTObj.get() ); 1197 pRet = pGroup; 1198 } 1199 else 1200 pRet = pTObj.get(); 1201 } 1202 } 1203 } 1204 } 1205 else 1206 { 1207 if ( maShapeRecords.SeekToContent( rSt, DFF_msofbtUDefProp, SEEK_FROM_CURRENT_AND_RESTART ) ) 1208 { 1209 maShapeRecords.Current()->SeekToBegOfRecord( rSt ); 1210 DffPropertyReader aSecPropSet( *this ); 1211 aSecPropSet.ReadPropSet( rSt, &rClientData ); 1212 sal_Int32 nTableProperties = aSecPropSet.GetPropertyValue( DFF_Prop_tableProperties, 0 ); 1213 if ( nTableProperties & 3 ) 1214 { 1215 if ( aSecPropSet.SeekToContent( DFF_Prop_tableRowProperties, rSt ) ) 1216 { 1217 sal_Int16 i, nReadRowCount = 0; 1218 rSt.ReadInt16( nReadRowCount ).ReadInt16( i ).ReadInt16( i ); 1219 if (nReadRowCount > 0) 1220 { 1221 const size_t nMinRecordSize = 4; 1222 const size_t nMaxRecords = rSt.remainingSize() / nMinRecordSize; 1223 1224 auto nRowCount = o3tl::make_unsigned(nReadRowCount); 1225 if (nRowCount > nMaxRecords) 1226 { 1227 SAL_WARN("filter.ms", "Parsing error: " << nMaxRecords << 1228 " max possible entries, but " << nRowCount << " claimed, truncating"); 1229 nRowCount = nMaxRecords; 1230 } 1231 if (nRowCount > 0) 1232 { 1233 std::unique_ptr<sal_uInt32[]> pTableArry(new sal_uInt32[ nRowCount + 2 ]); 1234 pTableArry[ 0 ] = nTableProperties; 1235 pTableArry[ 1 ] = nRowCount; 1236 for (decltype(nRowCount) nRow = 0; nRow < nRowCount; ++nRow) 1237 rSt.ReadUInt32(pTableArry[nRow + 2]); 1238 rData.pTableRowProperties = std::move(pTableArry); 1239 } 1240 } 1241 } 1242 } 1243 } 1244 } 1245 if ( pRet ) // sj: #i38501#, and taking care of connections to group objects 1246 { 1247 if ( rObjData.nSpFlags & ShapeFlag::Background ) 1248 { 1249 pRet->NbcSetSnapRect( tools::Rectangle( Point(), rData.pPage.page->GetSize() ) ); // set size 1250 } 1251 if (rPersistEntry.xSolverContainer) 1252 { 1253 for (auto & pPtr : rPersistEntry.xSolverContainer->aCList) 1254 { 1255 if ( rObjData.nShapeId == pPtr->nShapeC ) 1256 pPtr->pCObj = pRet.get(); 1257 else 1258 { 1259 SdrObject* pConnectObj = pRet.get(); 1260 if ( pOriginalObj && dynamic_cast< const SdrObjGroup* >(pRet.get()) != nullptr ) 1261 { /* check if the original object from the escherimport is part of the group object, 1262 if this is the case, we will use the original object to connect to */ 1263 SdrObjListIter aIter( *pRet, SdrIterMode::DeepWithGroups ); 1264 while( aIter.IsMore() ) 1265 { 1266 SdrObject* pPartObj = aIter.Next(); 1267 if ( pPartObj == pOriginalObj ) 1268 { 1269 pConnectObj = pPartObj; 1270 break; 1271 } 1272 } 1273 } 1274 if ( rObjData.nShapeId == pPtr->nShapeA ) 1275 { 1276 pPtr->pAObj = pConnectObj; 1277 pPtr->nSpFlagsA = rObjData.nSpFlags; 1278 } 1279 if ( rObjData.nShapeId == pPtr->nShapeB ) 1280 { 1281 pPtr->pBObj = pConnectObj; 1282 pPtr->nSpFlagsB = rObjData.nSpFlags; 1283 } 1284 } 1285 } 1286 } 1287 if ( rPersistEntry.ePageKind == PPT_MASTERPAGE ) 1288 { // maybe the escher clusterlist is not correct, but we have to got the right page by using the 1289 // spMaster property, so we are patching the table 1290 if ( rPersistEntry.nDrawingDgId != 0xffffffff ) 1291 { 1292 sal_uInt32 nSec = ( rObjData.nShapeId >> 10 ) - 1; 1293 if ( !maFidcls.empty() && ( nSec < mnIdClusters ) ) 1294 maFidcls[ nSec ].dgid = rPersistEntry.nDrawingDgId; // insert the correct drawing id; 1295 } 1296 } 1297 if ( GetPropertyValue( DFF_Prop_fNoFillHitTest, 0 ) & 0x10 ) 1298 { 1299 if (GetPropertyValue(DFF_Prop_fillType, mso_fillSolid) == mso_fillBackground) 1300 { 1301 rData.aBackgroundColoredObjects.push_back( pRet ); 1302 } 1303 } 1304 } 1305 return pRet; 1306 } 1307 1308 SdrPowerPointImport::SdrPowerPointImport( PowerPointImportParam& rParam, const OUString& rBaseURL ) : 1309 SdrEscherImport ( rParam, rBaseURL ), 1310 m_bOk ( rStCtrl.GetErrorCode() == ERRCODE_NONE ), 1311 m_nPersistPtrCnt ( 0 ), 1312 m_pDefaultSheet ( nullptr ), 1313 m_nCurrentPageNum ( 0 ), 1314 m_nDocStreamPos ( 0 ), 1315 m_nPageColorsNum ( 0xFFFF ), 1316 m_ePageColorsKind ( PPT_MASTERPAGE ), 1317 m_eCurrentPageKind ( PPT_MASTERPAGE ) 1318 { 1319 if ( m_bOk ) 1320 { 1321 nStreamLen = rStCtrl.TellEnd(); 1322 1323 // try to allocate the UserEditAtom via CurrentUserAtom 1324 sal_uInt32 nCurrentUserEdit = rParam.aCurrentUserAtom.nCurrentUserEdit; 1325 if (nCurrentUserEdit && checkSeek(rStCtrl, nCurrentUserEdit)) 1326 { 1327 ReadPptUserEditAtom( rStCtrl, m_aUserEditAtom ); 1328 } 1329 if ( !m_aUserEditAtom.nOffsetPersistDirectory ) 1330 { // if there is no UserEditAtom try to search the last one 1331 1332 rStCtrl.Seek( 0 ); 1333 DffRecordManager aPptRecManager; // contains all first level container and atoms 1334 aPptRecManager.Consume( rStCtrl, nStreamLen ); 1335 DffRecordHeader* pHd; 1336 for ( pHd = aPptRecManager.Last(); pHd; pHd = aPptRecManager.Prev() ) 1337 { 1338 if ( pHd->nRecType == PPT_PST_UserEditAtom ) 1339 { 1340 pHd->SeekToBegOfRecord( rStCtrl ); 1341 ReadPptUserEditAtom( rStCtrl, m_aUserEditAtom ); 1342 break; 1343 } 1344 } 1345 if ( !pHd ) 1346 m_bOk = false; 1347 } 1348 } 1349 if ( rStCtrl.GetError() != ERRCODE_NONE ) 1350 m_bOk = false; 1351 1352 if ( m_bOk ) 1353 { 1354 m_nPersistPtrCnt = m_aUserEditAtom.nMaxPersistWritten + 1; 1355 if ( ( m_nPersistPtrCnt >> 2 ) > nStreamLen ) // sj: at least m_nPersistPtrCnt is not allowed to be greater than filesize 1356 m_bOk = false; // (it should not be greater than the PPT_PST_PersistPtrIncrementalBlock, but 1357 // we are reading this block later, so we do not have access yet) 1358 1359 if ( m_bOk && ( m_nPersistPtrCnt < ( SAL_MAX_UINT32 / sizeof( sal_uInt32 ) ) -1 ) ) 1360 m_pPersistPtr.reset( new (std::nothrow) sal_uInt32[ m_nPersistPtrCnt + 1 ] ); 1361 if ( !m_pPersistPtr ) 1362 m_bOk = false; 1363 if ( m_bOk ) 1364 { 1365 memset( m_pPersistPtr.get(), 0x00, (m_nPersistPtrCnt+1) * sizeof(sal_uInt32) ); 1366 1367 // SJ: new search mechanism from bottom to top (Issue 21122) 1368 PptUserEditAtom aCurrentEditAtom( m_aUserEditAtom ); 1369 sal_uInt32 nCurrentEditAtomStrmPos = aCurrentEditAtom.aHd.GetRecEndFilePos(); 1370 while( nCurrentEditAtomStrmPos ) 1371 { 1372 sal_uInt32 nPersistIncPos = aCurrentEditAtom.nOffsetPersistDirectory; 1373 if (nPersistIncPos && checkSeek(rStCtrl, nPersistIncPos)) 1374 { 1375 DffRecordHeader aPersistHd; 1376 ReadDffRecordHeader( rStCtrl, aPersistHd ); 1377 if ( aPersistHd.nRecType == PPT_PST_PersistPtrIncrementalBlock ) 1378 { 1379 sal_uLong nPibLen = aPersistHd.GetRecEndFilePos(); 1380 while (m_bOk && rStCtrl.good() && (rStCtrl.Tell() < nPibLen)) 1381 { 1382 sal_uInt32 nOfs(0); 1383 rStCtrl.ReadUInt32( nOfs ); 1384 sal_uInt32 nCnt = nOfs; 1385 nOfs &= 0x000FFFFF; 1386 nCnt >>= 20; 1387 while (m_bOk && rStCtrl.good() && (nCnt > 0) && (nOfs <= m_nPersistPtrCnt)) 1388 { 1389 sal_uInt32 nPt(0); 1390 rStCtrl.ReadUInt32( nPt ); 1391 if ( !m_pPersistPtr[ nOfs ] ) 1392 { 1393 m_pPersistPtr[ nOfs ] = nPt; 1394 if ( m_pPersistPtr[ nOfs ] > nStreamLen ) 1395 { 1396 m_bOk = false; 1397 OSL_FAIL("SdrPowerPointImport::Ctor(): Invalid Entry in Persist-Directory!"); 1398 } 1399 } 1400 nCnt--; 1401 nOfs++; 1402 } 1403 if ( m_bOk && nCnt > 0 ) 1404 { 1405 OSL_FAIL("SdrPowerPointImport::Ctor(): Not all entries of Persist-Directory read!"); 1406 m_bOk = false; 1407 } 1408 } 1409 } 1410 } 1411 nCurrentEditAtomStrmPos = aCurrentEditAtom.nOffsetLastEdit < nCurrentEditAtomStrmPos ? aCurrentEditAtom.nOffsetLastEdit : 0; 1412 if (nCurrentEditAtomStrmPos && checkSeek(rStCtrl, nCurrentEditAtomStrmPos)) 1413 { 1414 ReadPptUserEditAtom( rStCtrl, aCurrentEditAtom ); 1415 } 1416 } 1417 } 1418 } 1419 if ( rStCtrl.GetError() != ERRCODE_NONE ) 1420 m_bOk = false; 1421 if ( m_bOk ) 1422 { // check Document PersistEntry 1423 m_nDocStreamPos = m_aUserEditAtom.nDocumentRef; 1424 if ( m_nDocStreamPos > m_nPersistPtrCnt ) 1425 { 1426 OSL_FAIL("SdrPowerPointImport::Ctor(): m_aUserEditAtom.nDocumentRef invalid!"); 1427 m_bOk = false; 1428 } 1429 } 1430 if ( m_bOk ) 1431 { // check Document FilePos 1432 m_nDocStreamPos = m_pPersistPtr[ m_nDocStreamPos ]; 1433 if ( m_nDocStreamPos >= nStreamLen ) 1434 { 1435 OSL_FAIL("SdrPowerPointImport::Ctor(): m_nDocStreamPos >= nStreamLen!"); 1436 m_bOk = false; 1437 } 1438 } 1439 if ( m_bOk ) 1440 { 1441 rStCtrl.Seek( m_nDocStreamPos ); 1442 aDocRecManager.Consume( rStCtrl ); 1443 1444 DffRecordHeader aDocHd; 1445 ReadDffRecordHeader( rStCtrl, aDocHd ); 1446 // read DocumentAtom 1447 DffRecordHeader aDocAtomHd; 1448 ReadDffRecordHeader( rStCtrl, aDocAtomHd ); 1449 if ( aDocHd.nRecType == PPT_PST_Document && aDocAtomHd.nRecType == PPT_PST_DocumentAtom ) 1450 { 1451 aDocAtomHd.SeekToBegOfRecord( rStCtrl ); 1452 ReadPptDocumentAtom( rStCtrl, aDocAtom ); 1453 } 1454 else 1455 m_bOk = false; 1456 1457 if ( m_bOk ) 1458 { 1459 if (!m_xFonts) 1460 ReadFontCollection(); 1461 1462 // reading TxPF, TxSI 1463 PPTTextParagraphStyleAtomInterpreter aTxPFStyle; 1464 PPTTextSpecInfoAtomInterpreter aTxSIStyle; // styles (default language setting ... ) 1465 1466 DffRecordHeader* pEnvHd = aDocRecManager.GetRecordHeader( PPT_PST_Environment ); 1467 if ( pEnvHd ) 1468 { 1469 pEnvHd->SeekToContent( rStCtrl ); 1470 DffRecordHeader aTxPFStyleRecHd; 1471 if ( SeekToRec( rStCtrl, PPT_PST_TxPFStyleAtom, pEnvHd->GetRecEndFilePos(), &aTxPFStyleRecHd ) ) 1472 aTxPFStyle.Read( rStCtrl, aTxPFStyleRecHd ); 1473 1474 pEnvHd->SeekToContent( rStCtrl ); 1475 DffRecordHeader aTxSIStyleRecHd; 1476 if ( SeekToRec( rStCtrl, PPT_PST_TxSIStyleAtom, pEnvHd->GetRecEndFilePos(), &aTxSIStyleRecHd ) ) 1477 { 1478 aTxSIStyle.Read( rStCtrl, aTxSIStyleRecHd, PPT_PST_TxSIStyleAtom ); 1479 #ifdef DBG_UTIL 1480 if ( !aTxSIStyle.bValid ) 1481 { 1482 if (!(rImportParam.nImportFlags & PPT_IMPORTFLAGS_NO_TEXT_ASSERT )) 1483 { 1484 OSL_FAIL( "SdrTextSpecInfoAtomInterpreter::Ctor(): parsing error, this document needs to be analysed (SJ)" ); 1485 } 1486 } 1487 #endif 1488 } 1489 } 1490 1491 // TODO:: PPT_PST_TxPFStyleAtom 1492 1493 // read SlidePersists 1494 m_pMasterPages.reset( new PptSlidePersistList ); 1495 m_pSlidePages.reset( new PptSlidePersistList ); 1496 m_pNotePages.reset( new PptSlidePersistList ); 1497 1498 // now always creating the handout page, it will be the first in our masterpage list 1499 std::unique_ptr<PptSlidePersistEntry> pE(new PptSlidePersistEntry); 1500 pE->aPersistAtom.nPsrReference = aDocAtom.nHandoutMasterPersist; 1501 pE->bHandoutMaster = true; 1502 if ( !aDocAtom.nHandoutMasterPersist ) 1503 pE->bStarDrawFiller = true; // this is a dummy master page 1504 m_pMasterPages->insert(m_pMasterPages->begin(), std::move(pE)); 1505 1506 DffRecordHeader* pSlideListWithTextHd = aDocRecManager.GetRecordHeader( PPT_PST_SlideListWithText ); 1507 PptSlidePersistEntry* pPreviousPersist = nullptr; 1508 DffRecordHeader* pSlideListHd = aDocRecManager.GetRecordHeader(PPT_PST_List); 1509 sal_uLong nPSTList = 0; 1510 if (pSlideListHd) nPSTList = pSlideListHd->GetRecBegFilePos(); 1511 sal_uInt16 nRealPageNum = 0; 1512 // Normal PPT document has order of Master slides - Presentation slides - Note slides 1513 // for document with the order of Master slides - Note slides - Presentation slides 1514 // we need to swap the later two sections 1515 bool notePresentationSwap = false; 1516 for (sal_uInt16 nPageListNum = 0; 1517 pSlideListWithTextHd && nPageListNum < 3; ++nPageListNum) 1518 { 1519 pSlideListWithTextHd->SeekToContent( rStCtrl ); 1520 PptSlidePersistList* pPageList = nullptr; 1521 sal_uInt32 nSlideListWithTextHdEndOffset = pSlideListWithTextHd->GetRecEndFilePos(); 1522 nRealPageNum = nPageListNum; 1523 while ( SeekToRec( rStCtrl, PPT_PST_SlidePersistAtom, nSlideListWithTextHdEndOffset ) ) 1524 { 1525 if ( pPreviousPersist ) 1526 pPreviousPersist->nSlidePersistEndOffset = rStCtrl.Tell(); 1527 std::unique_ptr<PptSlidePersistEntry> pE2(new PptSlidePersistEntry); 1528 ReadPptSlidePersistAtom( rStCtrl, pE2->aPersistAtom ); 1529 pE2->nSlidePersistStartOffset = rStCtrl.Tell(); 1530 // Note/Presentation section swap 1531 if (nPageListNum == 1 && pE2->nSlidePersistStartOffset < nPSTList) 1532 { 1533 notePresentationSwap = true; 1534 } 1535 if (notePresentationSwap) 1536 { 1537 if (nPageListNum == 1) nRealPageNum = 2; 1538 else if (nPageListNum == 2) nRealPageNum = 1; 1539 } 1540 1541 pE2->ePageKind = PptPageKind(nRealPageNum); 1542 pPreviousPersist = pE2.get(); 1543 if (!pPageList) 1544 { 1545 pPageList = GetPageList(PptPageKind(nRealPageNum)); 1546 } 1547 pPageList->push_back(std::move(pE2)); 1548 } 1549 if ( pPreviousPersist ) 1550 pPreviousPersist->nSlidePersistEndOffset = nSlideListWithTextHdEndOffset; 1551 pSlideListWithTextHd = aDocRecManager.GetRecordHeader( PPT_PST_SlideListWithText, SEEK_FROM_CURRENT ); 1552 } 1553 1554 // we will ensure that there is at least one master page 1555 if (m_pMasterPages->size() == 1) // -> there is only a handout page available 1556 { 1557 std::unique_ptr<PptSlidePersistEntry> pE2(new PptSlidePersistEntry); 1558 pE2->bStarDrawFiller = true; // this is a dummy master page 1559 m_pMasterPages->insert(m_pMasterPages->begin() + 1, std::move(pE2)); 1560 } 1561 1562 // now we will insert at least one notes master for each master page 1563 sal_uInt16 nMasterPage; 1564 sal_uInt16 nMasterPages = m_pMasterPages->size() - 1; 1565 for ( nMasterPage = 0; nMasterPage < nMasterPages; nMasterPage++ ) 1566 { 1567 std::unique_ptr<PptSlidePersistEntry> pE2(new PptSlidePersistEntry); 1568 pE2->bNotesMaster = true; 1569 pE2->bStarDrawFiller = true; // this is a dummy master page 1570 if ( !nMasterPage && aDocAtom.nNotesMasterPersist ) 1571 { // special treatment for the first notes master 1572 pE2->aPersistAtom.nPsrReference = aDocAtom.nNotesMasterPersist; 1573 pE2->bStarDrawFiller = false; // this is a dummy master page 1574 } 1575 m_pMasterPages->insert(m_pMasterPages->begin() + ((nMasterPage + 1) << 1), std::move(pE2)); 1576 } 1577 1578 // read for each page the SlideAtom respectively the NotesAtom if it exists 1579 for (sal_uInt16 nPageListNum = 0; nPageListNum < 3; ++nPageListNum) 1580 { 1581 PptSlidePersistList* pPageList = GetPageList( PptPageKind( nPageListNum ) ); 1582 for ( size_t nPageNum = 0; nPageNum < pPageList->size(); nPageNum++ ) 1583 { 1584 PptSlidePersistEntry& rE2 = (*pPageList)[ nPageNum ]; 1585 sal_uLong nPersist = rE2.aPersistAtom.nPsrReference; 1586 if ( ( nPersist > 0 ) && ( nPersist < m_nPersistPtrCnt ) ) 1587 { 1588 sal_uLong nFPos = m_pPersistPtr[ nPersist ]; 1589 if ( nFPos < nStreamLen ) 1590 { 1591 rStCtrl.Seek( nFPos ); 1592 DffRecordHeader aSlideHd; 1593 ReadDffRecordHeader( rStCtrl, aSlideHd ); 1594 if ( SeekToRec( rStCtrl, PPT_PST_SlideAtom, aSlideHd.GetRecEndFilePos() ) ) 1595 ReadPptSlideAtom( rStCtrl, rE2.aSlideAtom ); 1596 else if ( SeekToRec( rStCtrl, PPT_PST_NotesAtom, aSlideHd.GetRecEndFilePos() ) ) 1597 ReadPptNotesAtom( rStCtrl, rE2.aNotesAtom ); 1598 aSlideHd.SeekToContent( rStCtrl ); 1599 1600 DffRecordHeader aPPTDrawingHd; 1601 if ( SeekToRec( rStCtrl, PPT_PST_PPDrawing, aSlideHd.GetRecEndFilePos(), &aPPTDrawingHd ) ) 1602 { 1603 DffRecordHeader aPPTDgContainer; 1604 if ( SeekToRec( rStCtrl, DFF_msofbtDgContainer, aPPTDrawingHd.GetRecEndFilePos(), &aPPTDgContainer ) ) 1605 { 1606 if ( SeekToRec( rStCtrl, DFF_msofbtDg, aPPTDrawingHd.GetRecEndFilePos() ) ) 1607 { 1608 DffRecordHeader aDgRecordHeader; 1609 ReadDffRecordHeader( rStCtrl, aDgRecordHeader ); 1610 rE2.nDrawingDgId = aDgRecordHeader.nRecInstance; 1611 aDgRecordHeader.SeekToEndOfRecord( rStCtrl ); 1612 } 1613 if ( SeekToRec( rStCtrl, DFF_msofbtSolverContainer, aPPTDgContainer.GetRecEndFilePos() ) ) 1614 { 1615 rE2.xSolverContainer.reset(new SvxMSDffSolverContainer); 1616 ReadSvxMSDffSolverContainer(rStCtrl, *rE2.xSolverContainer); 1617 } 1618 aPPTDgContainer.SeekToBegOfRecord( rStCtrl ); 1619 SetDgContainer( rStCtrl ); // set this, so that the escherimport is knowing of our drawings 1620 } 1621 } 1622 // office xp is supporting more than one stylesheet 1623 if ( ( rE2.ePageKind == PPT_MASTERPAGE ) && ( rE2.aSlideAtom.nMasterId == 0 ) && !rE2.bNotesMaster ) 1624 { 1625 PPTTextSpecInfo aTxSI( 0 ); 1626 if ( aTxSIStyle.bValid && !aTxSIStyle.aList.empty() ) 1627 aTxSI = aTxSIStyle.aList[ 0 ]; 1628 1629 rE2.xStyleSheet = std::make_unique<PPTStyleSheet>(aSlideHd, rStCtrl, *this, aTxPFStyle, aTxSI); 1630 m_pDefaultSheet = rE2.xStyleSheet.get(); 1631 } 1632 if ( SeekToRec( rStCtrl, PPT_PST_ColorSchemeAtom, aSlideHd.GetRecEndFilePos() ) ) 1633 ReadPptColorSchemeAtom( rStCtrl, rE2.aColorScheme ); 1634 else 1635 { 1636 OSL_FAIL( "SdrPowerPointImport::Ctor(): could not get SlideColorScheme! (SJ)" ); 1637 } 1638 } 1639 else 1640 { 1641 OSL_FAIL("SdrPowerPointImport::Ctor(): Persist entry is flawed! (SJ)"); 1642 } 1643 } 1644 } 1645 } 1646 DffRecordHeader* pHeadersFootersHd = aDocRecManager.GetRecordHeader( PPT_PST_HeadersFooters ); 1647 if ( pHeadersFootersHd ) 1648 { 1649 HeaderFooterEntry aNormalMaster, aNotesMaster; 1650 for ( ; pHeadersFootersHd; pHeadersFootersHd = aDocRecManager.GetRecordHeader( PPT_PST_HeadersFooters, SEEK_FROM_CURRENT ) ) 1651 { 1652 if ( pHeadersFootersHd->nRecInstance == 3 ) // normal master 1653 ImportHeaderFooterContainer( *pHeadersFootersHd, aNormalMaster ); 1654 else if ( pHeadersFootersHd->nRecInstance == 4 ) // notes master 1655 ImportHeaderFooterContainer( *pHeadersFootersHd, aNotesMaster ); 1656 } 1657 for (size_t i = 0; i < m_pMasterPages->size(); i++) 1658 { 1659 if ((*m_pMasterPages)[ i ].bNotesMaster) 1660 (*m_pMasterPages)[ i ].xHeaderFooterEntry.reset(new HeaderFooterEntry(aNotesMaster)); 1661 else 1662 (*m_pMasterPages)[ i ].xHeaderFooterEntry.reset(new HeaderFooterEntry(aNormalMaster)); 1663 } 1664 } 1665 } 1666 } 1667 if ( ( rStCtrl.GetError() != ERRCODE_NONE ) || ( m_pDefaultSheet == nullptr ) ) 1668 m_bOk = false; 1669 m_pPPTStyleSheet = m_pDefaultSheet; 1670 rStCtrl.Seek( 0 ); 1671 } 1672 1673 SdrPowerPointImport::~SdrPowerPointImport() 1674 { 1675 m_pMasterPages.reset(); 1676 m_pSlidePages.reset(); 1677 m_pNotePages.reset(); 1678 } 1679 1680 bool PPTConvertOCXControls::ReadOCXStream( tools::SvRef<SotStorage>& rSrc, 1681 css::uno::Reference< css::drawing::XShape > *pShapeRef ) 1682 { 1683 bool bRes = false; 1684 uno::Reference< form::XFormComponent > xFComp; 1685 if ( mpPPTImporter && mpPPTImporter->ReadFormControl( rSrc, xFComp ) ) 1686 { 1687 if ( xFComp.is() ) 1688 { 1689 css::awt::Size aSz; // not used in import 1690 bRes = InsertControl( xFComp, aSz,pShapeRef, false/*bFloatingCtrl*/); 1691 } 1692 } 1693 return bRes; 1694 } 1695 1696 bool PPTConvertOCXControls::InsertControl( 1697 const css::uno::Reference< css::form::XFormComponent > &rFComp, 1698 const css::awt::Size& rSize, 1699 css::uno::Reference< css::drawing::XShape > *pShape, 1700 bool /*bFloatingCtrl*/) 1701 { 1702 bool bRetValue = false; 1703 try 1704 { 1705 css::uno::Reference< css::drawing::XShape > xShape; 1706 1707 const css::uno::Reference< css::container::XIndexContainer > & rFormComps = 1708 GetFormComps(); 1709 1710 css::uno::Any aTmp( &rFComp, cppu::UnoType<css::form::XFormComponent>::get() ); 1711 1712 rFormComps->insertByIndex( rFormComps->getCount(), aTmp ); 1713 1714 const css::uno::Reference< css::lang::XMultiServiceFactory > & rServiceFactory = 1715 GetServiceFactory(); 1716 if( rServiceFactory.is() ) 1717 { 1718 css::uno::Reference< css::uno::XInterface > xCreate = rServiceFactory 1719 ->createInstance( "com.sun.star.drawing.ControlShape" ); 1720 if( xCreate.is() ) 1721 { 1722 xShape.set(xCreate, css::uno::UNO_QUERY); 1723 if ( xShape.is() ) 1724 { 1725 xShape->setSize(rSize); 1726 // set the Control-Model at the Control-Shape 1727 css::uno::Reference< css::drawing::XControlShape > xControlShape( xShape, 1728 css::uno::UNO_QUERY ); 1729 css::uno::Reference< css::awt::XControlModel > xControlModel( rFComp, 1730 css::uno::UNO_QUERY ); 1731 if ( xControlShape.is() && xControlModel.is() ) 1732 { 1733 xControlShape->setControl( xControlModel ); 1734 if (pShape) 1735 *pShape = xShape; 1736 bRetValue = true; 1737 } 1738 } 1739 } 1740 } 1741 } 1742 catch( ... ) 1743 { 1744 bRetValue = false; 1745 } 1746 return bRetValue; 1747 }; 1748 void PPTConvertOCXControls::GetDrawPage() 1749 { 1750 if( xDrawPage.is() || !mxModel.is() ) 1751 return; 1752 1753 css::uno::Reference< css::drawing::XDrawPages > xDrawPages; 1754 switch( ePageKind ) 1755 { 1756 case PPT_SLIDEPAGE : 1757 case PPT_NOTEPAGE : 1758 { 1759 css::uno::Reference< css::drawing::XDrawPagesSupplier > 1760 xDrawPagesSupplier( mxModel, css::uno::UNO_QUERY); 1761 if ( xDrawPagesSupplier.is() ) 1762 xDrawPages = xDrawPagesSupplier->getDrawPages(); 1763 } 1764 break; 1765 1766 case PPT_MASTERPAGE : 1767 { 1768 css::uno::Reference< css::drawing::XMasterPagesSupplier > 1769 xMasterPagesSupplier( mxModel, css::uno::UNO_QUERY); 1770 if ( xMasterPagesSupplier.is() ) 1771 xDrawPages = xMasterPagesSupplier->getMasterPages(); 1772 } 1773 break; 1774 } 1775 if ( xDrawPages.is() && xDrawPages->getCount() ) 1776 { 1777 xDrawPages->getCount(); 1778 css::uno::Any aAny( xDrawPages->getByIndex( xDrawPages->getCount() - 1 ) ); 1779 aAny >>= xDrawPage; 1780 } 1781 } 1782 1783 static bool SdrPowerPointOLEDecompress( SvStream& rOutput, SvStream& rInput, sal_uInt32 nInputSize ) 1784 { 1785 sal_uInt32 nOldPos = rInput.Tell(); 1786 std::unique_ptr<char[]> pBuf(new char[ nInputSize ]); 1787 rInput.ReadBytes(pBuf.get(), nInputSize); 1788 ZCodec aZCodec( 0x8000, 0x8000 ); 1789 aZCodec.BeginCompression(); 1790 SvMemoryStream aSource( pBuf.get(), nInputSize, StreamMode::READ ); 1791 aZCodec.Decompress( aSource, rOutput ); 1792 const bool bSuccess(0 != aZCodec.EndCompression()); 1793 rInput.Seek( nOldPos ); 1794 return bSuccess; 1795 } 1796 1797 // #i32596# - add new parameter <_nCalledByGroup> 1798 rtl::Reference<SdrObject> SdrPowerPointImport::ImportOLE( sal_uInt32 nOLEId, 1799 const Graphic& rGraf, 1800 const tools::Rectangle& rBoundRect, 1801 const tools::Rectangle& rVisArea, 1802 const int /*_nCalledByGroup*/ ) const 1803 { 1804 rtl::Reference<SdrObject> pRet; 1805 1806 sal_uInt32 nOldPos = rStCtrl.Tell(); 1807 1808 Graphic aGraphic( rGraf ); 1809 1810 if ( const_cast<SdrPowerPointImport*>(this)->maShapeRecords.SeekToContent( rStCtrl, DFF_msofbtClientData, SEEK_FROM_CURRENT_AND_RESTART ) ) 1811 { 1812 DffRecordHeader aPlaceHd; 1813 1814 auto nEndRecPos = SanitizeEndPos(rStCtrl, const_cast<SdrPowerPointImport*>(this)->maShapeRecords.Current()->GetRecEndFilePos()); 1815 while ( ( rStCtrl.GetError() == ERRCODE_NONE ) 1816 && ( rStCtrl.Tell() < nEndRecPos ) ) 1817 { 1818 ReadDffRecordHeader( rStCtrl, aPlaceHd ); 1819 if ( aPlaceHd.nRecType == PPT_PST_RecolorInfoAtom ) 1820 { 1821 const_cast<SdrPowerPointImport*>(this)->RecolorGraphic( rStCtrl, aPlaceHd.nRecLen, aGraphic ); 1822 break; 1823 } 1824 else 1825 { 1826 if (!aPlaceHd.SeekToEndOfRecord(rStCtrl)) 1827 break; 1828 } 1829 } 1830 } 1831 1832 for (PPTOleEntry& rOe : const_cast<SdrPowerPointImport*>(this)->aOleObjectList) 1833 { 1834 if ( rOe.nId != nOLEId ) 1835 continue; 1836 1837 rStCtrl.Seek( rOe.nRecHdOfs ); 1838 1839 DffRecordHeader aHd; 1840 ReadDffRecordHeader( rStCtrl, aHd ); 1841 1842 sal_uInt32 nLen = aHd.nRecLen - 4; 1843 if ( static_cast<sal_Int32>(nLen) > 0 ) 1844 { 1845 bool bSuccess = false; 1846 1847 rStCtrl.SeekRel( 4 ); 1848 1849 ::utl::TempFile aTmpFile; 1850 aTmpFile.EnableKillingFile(); 1851 1852 if ( aTmpFile.IsValid() ) 1853 { 1854 SvStream* pDest = aTmpFile.GetStream(StreamMode::TRUNC | StreamMode::WRITE); 1855 if (pDest) 1856 { 1857 bSuccess = SdrPowerPointOLEDecompress( *pDest, rStCtrl, nLen ); 1858 } 1859 aTmpFile.CloseStream(); 1860 } 1861 if ( bSuccess ) 1862 { 1863 SvStream* pDest = aTmpFile.GetStream(StreamMode::READ); 1864 Storage* pObjStor = pDest ? new Storage( *pDest, true ) : nullptr; 1865 if (pObjStor) 1866 { 1867 tools::SvRef<SotStorage> xObjStor( new SotStorage( pObjStor ) ); 1868 if ( xObjStor.is() && !xObjStor->GetError() ) 1869 { 1870 if ( xObjStor->GetClassName() == SvGlobalName() ) 1871 { 1872 xObjStor->SetClass( SvGlobalName( pObjStor->GetClassId() ), pObjStor->GetFormat(), pObjStor->GetUserName() ); 1873 } 1874 tools::SvRef<SotStorageStream> xSrcTst = xObjStor->OpenSotStream( "\1Ole" ); 1875 if ( xSrcTst.is() ) 1876 { 1877 sal_uInt8 aTestA[ 10 ]; 1878 bool bGetItAsOle = (sizeof(aTestA) == xSrcTst->ReadBytes(aTestA, sizeof(aTestA))); 1879 if ( !bGetItAsOle ) 1880 { // maybe there is a contents stream in here 1881 xSrcTst = xObjStor->OpenSotStream( "Contents", StreamMode::READWRITE | StreamMode::NOCREATE ); 1882 bGetItAsOle = (xSrcTst.is() && 1883 sizeof(aTestA) == xSrcTst->ReadBytes(aTestA, sizeof(aTestA))); 1884 } 1885 if ( bGetItAsOle ) 1886 { 1887 OUString aNm; 1888 // if ( nSvxMSDffOLEConvFlags ) 1889 { 1890 uno::Reference < embed::XStorage > xDestStorage( rOe.pShell->GetStorage() ); 1891 uno::Reference < embed::XEmbeddedObject > xObj = 1892 CheckForConvertToSOObj(nSvxMSDffOLEConvFlags, *xObjStor, xDestStorage, rGraf, rVisArea, maBaseURL); 1893 if( xObj.is() ) 1894 { 1895 rOe.pShell->getEmbeddedObjectContainer().InsertEmbeddedObject( xObj, aNm ); 1896 1897 svt::EmbeddedObjectRef aObj( xObj, rOe.nAspect ); 1898 1899 // TODO/LATER: need MediaType for Graphic 1900 aObj.SetGraphic( rGraf, OUString() ); 1901 pRet = new SdrOle2Obj( 1902 *pSdrModel, 1903 aObj, 1904 aNm, 1905 rBoundRect); 1906 } 1907 } 1908 if ( !pRet && ( rOe.nType == PPT_PST_ExControl ) ) 1909 { 1910 uno::Reference< frame::XModel > xModel( rOe.pShell->GetModel() ); 1911 PPTConvertOCXControls aPPTConvertOCXControls( this, xModel, m_eCurrentPageKind ); 1912 css::uno::Reference< css::drawing::XShape > xShape; 1913 if ( aPPTConvertOCXControls.ReadOCXStream( xObjStor, &xShape ) ) 1914 pRet = SdrObject::getSdrObjectFromXShape(xShape); 1915 1916 } 1917 if ( !pRet ) 1918 { 1919 aNm = rOe.pShell->getEmbeddedObjectContainer().CreateUniqueObjectName(); 1920 1921 // object is not an own object 1922 const css::uno::Reference < css::embed::XStorage >& rStorage = rOe.pShell->GetStorage(); 1923 if (rStorage.is()) 1924 { 1925 tools::SvRef<SotStorage> xTarget = SotStorage::OpenOLEStorage(rStorage, aNm, StreamMode::READWRITE); 1926 if (xObjStor.is() && xTarget.is()) 1927 { 1928 xObjStor->CopyTo(xTarget.get()); 1929 if (!xTarget->GetError()) 1930 xTarget->Commit(); 1931 } 1932 xTarget.clear(); 1933 } 1934 1935 uno::Reference < embed::XEmbeddedObject > xObj = 1936 rOe.pShell->getEmbeddedObjectContainer().GetEmbeddedObject( aNm ); 1937 if ( xObj.is() ) 1938 { 1939 if ( rOe.nAspect != embed::Aspects::MSOLE_ICON ) 1940 { 1941 //TODO/LATER: keep on hacking?! 1942 // we don't want to be modified 1943 //xInplaceObj->EnableSetModified( sal_False ); 1944 if ( rVisArea.IsEmpty() ) 1945 { 1946 MapUnit aMapUnit = VCLUnoHelper::UnoEmbed2VCLMapUnit( xObj->getMapUnit( rOe.nAspect ) ); 1947 Size aSize( OutputDevice::LogicToLogic( aGraphic.GetPrefSize(), 1948 aGraphic.GetPrefMapMode(), MapMode( aMapUnit ) ) ); 1949 1950 awt::Size aSz; 1951 aSz.Width = aSize.Width(); 1952 aSz.Height = aSize.Height(); 1953 xObj->setVisualAreaSize( rOe.nAspect, aSz ); 1954 } 1955 else 1956 { 1957 awt::Size aSize( rVisArea.GetSize().Width(), rVisArea.GetSize().Height() ); 1958 xObj->setVisualAreaSize( rOe.nAspect, aSize ); 1959 } 1960 //xInplaceObj->EnableSetModified( sal_True ); 1961 } 1962 1963 svt::EmbeddedObjectRef aObj( xObj, rOe.nAspect ); 1964 1965 // TODO/LATER: need MediaType for Graphic 1966 aObj.SetGraphic( aGraphic, OUString() ); 1967 1968 pRet = new SdrOle2Obj( 1969 *pSdrModel, 1970 aObj, 1971 aNm, 1972 rBoundRect); 1973 } 1974 } 1975 } 1976 } 1977 } 1978 } 1979 aTmpFile.CloseStream(); 1980 } 1981 } 1982 } 1983 rStCtrl.Seek( nOldPos ); 1984 1985 return pRet; 1986 } 1987 1988 std::unique_ptr<SvMemoryStream> SdrPowerPointImport::ImportExOleObjStg( sal_uInt32 nPersistPtr, sal_uInt32& nOleId ) const 1989 { 1990 std::unique_ptr<SvMemoryStream> pRet; 1991 if ( nPersistPtr && ( nPersistPtr < m_nPersistPtrCnt ) ) 1992 { 1993 sal_uInt32 nOldPos, nOfs = m_pPersistPtr[ nPersistPtr ]; 1994 nOldPos = rStCtrl.Tell(); 1995 rStCtrl.Seek( nOfs ); 1996 DffRecordHeader aHd; 1997 ReadDffRecordHeader( rStCtrl, aHd ); 1998 if ( aHd.nRecType == DFF_PST_ExOleObjStg ) 1999 { 2000 sal_uInt32 nLen = aHd.nRecLen - 4; 2001 if ( static_cast<sal_Int32>(nLen) > 0 ) 2002 { 2003 rStCtrl.ReadUInt32( nOleId ); 2004 pRet.reset(new SvMemoryStream); 2005 ZCodec aZCodec( 0x8000, 0x8000 ); 2006 aZCodec.BeginCompression(); 2007 aZCodec.Decompress( rStCtrl, *pRet ); 2008 if ( !aZCodec.EndCompression() ) 2009 { 2010 pRet.reset(); 2011 } 2012 } 2013 } 2014 rStCtrl.Seek( nOldPos ); 2015 } 2016 return pRet; 2017 } 2018 2019 void SdrPowerPointImport::SeekOle( SfxObjectShell* pShell, sal_uInt32 nFilterOptions ) 2020 { 2021 if ( !pShell ) 2022 return; 2023 2024 DffRecordHeader* pHd; 2025 2026 sal_uInt32 nOldPos = rStCtrl.Tell(); 2027 if ( nFilterOptions & 1 ) 2028 { 2029 pHd = aDocRecManager.GetRecordHeader( PPT_PST_List ); 2030 if ( pHd ) 2031 { 2032 // we try to locate the basic atom 2033 pHd->SeekToContent( rStCtrl ); 2034 if ( SeekToRec( rStCtrl, PPT_PST_VBAInfo, pHd->GetRecEndFilePos(), pHd ) ) 2035 { 2036 if ( SeekToRec( rStCtrl, PPT_PST_VBAInfoAtom, pHd->GetRecEndFilePos(), pHd ) ) 2037 { 2038 sal_uInt32 nPersistPtr, nIDoNotKnow1, nIDoNotKnow2; 2039 rStCtrl.ReadUInt32( nPersistPtr ) 2040 .ReadUInt32( nIDoNotKnow1 ) 2041 .ReadUInt32( nIDoNotKnow2 ); 2042 2043 sal_uInt32 nOleId; 2044 std::unique_ptr<SvMemoryStream> pBas = ImportExOleObjStg( nPersistPtr, nOleId ); 2045 if ( pBas ) 2046 { 2047 tools::SvRef<SotStorage> xSource( new SotStorage( pBas.release(), true ) ); 2048 tools::SvRef<SotStorage> xDest( new SotStorage( new SvMemoryStream(), true ) ); 2049 if ( xSource.is() && xDest.is() ) 2050 { 2051 // is this a visual basic storage ? 2052 tools::SvRef<SotStorage> xSubStorage = xSource->OpenSotStorage( "VBA", 2053 StreamMode::READWRITE | StreamMode::NOCREATE | StreamMode::SHARE_DENYALL ); 2054 if( xSubStorage.is() && ( ERRCODE_NONE == xSubStorage->GetError() ) ) 2055 { 2056 tools::SvRef<SotStorage> xMacros = xDest->OpenSotStorage( "MACROS" ); 2057 if ( xMacros.is() ) 2058 { 2059 SvStorageInfoList aList; 2060 xSource->FillInfoList( &aList ); 2061 SvStorageInfoList::size_type i; 2062 2063 bool bCopied = true; 2064 for ( i = 0; i < aList.size(); i++ ) // copy all entries 2065 { 2066 const SvStorageInfo& rInfo = aList[ i ]; 2067 if ( !xSource->CopyTo( rInfo.GetName(), xMacros.get(), rInfo.GetName() ) ) 2068 bCopied = false; 2069 } 2070 if ( i && bCopied ) 2071 { 2072 uno::Reference < embed::XStorage > xDoc( pShell->GetStorage() ); 2073 if ( xDoc.is() ) 2074 { 2075 tools::SvRef<SotStorage> xVBA = SotStorage::OpenOLEStorage( xDoc, SvxImportMSVBasic::GetMSBasicStorageName() ); 2076 if ( xVBA.is() && ( xVBA->GetError() == ERRCODE_NONE ) ) 2077 { 2078 tools::SvRef<SotStorage> xSubVBA = xVBA->OpenSotStorage( "_MS_VBA_Overhead" ); 2079 if ( xSubVBA.is() && ( xSubVBA->GetError() == ERRCODE_NONE ) ) 2080 { 2081 tools::SvRef<SotStorageStream> xOriginal = xSubVBA->OpenSotStream( "_MS_VBA_Overhead2" ); 2082 if ( xOriginal.is() && ( xOriginal->GetError() == ERRCODE_NONE ) ) 2083 { 2084 if ( nPersistPtr && ( nPersistPtr < m_nPersistPtrCnt ) ) 2085 { 2086 rStCtrl.Seek( m_pPersistPtr[ nPersistPtr ] ); 2087 ReadDffRecordHeader( rStCtrl, *pHd ); 2088 2089 xOriginal->WriteUInt32( nIDoNotKnow1 ) 2090 .WriteUInt32( nIDoNotKnow2 ); 2091 2092 sal_uInt32 nToCopy, nBufSize; 2093 nToCopy = pHd->nRecLen; 2094 std::unique_ptr<sal_uInt8[]> pBuf(new sal_uInt8[ 0x40000 ]); // 256KB Buffer 2095 while ( nToCopy ) 2096 { 2097 nBufSize = ( nToCopy >= 0x40000 ) ? 0x40000 : nToCopy; 2098 rStCtrl.ReadBytes(pBuf.get(), nBufSize); 2099 xOriginal->WriteBytes(pBuf.get(), nBufSize); 2100 nToCopy -= nBufSize; 2101 } 2102 } 2103 } 2104 } 2105 } 2106 xVBA->Commit(); 2107 } 2108 } 2109 } 2110 } 2111 } 2112 } 2113 } 2114 } 2115 } 2116 } 2117 pHd = aDocRecManager.GetRecordHeader( PPT_PST_ExObjList ); 2118 if ( pHd ) 2119 { 2120 DffRecordHeader* pExEmbed = nullptr; 2121 2122 pHd->SeekToBegOfRecord( rStCtrl ); 2123 DffRecordManager aExObjListManager( rStCtrl ); 2124 sal_uInt16 i, nRecType(PPT_PST_ExEmbed); 2125 2126 for ( i = 0; i < 2; i++ ) 2127 { 2128 switch ( i ) 2129 { 2130 case 0 : nRecType = PPT_PST_ExEmbed; break; 2131 case 1 : nRecType = PPT_PST_ExControl; break; 2132 } 2133 for ( pExEmbed = aExObjListManager.GetRecordHeader( nRecType ); 2134 pExEmbed; pExEmbed = aExObjListManager.GetRecordHeader( nRecType, SEEK_FROM_CURRENT ) ) 2135 { 2136 pExEmbed->SeekToContent( rStCtrl ); 2137 2138 DffRecordHeader aExOleAtHd; 2139 if ( SeekToRec( rStCtrl, PPT_PST_ExOleObjAtom, pExEmbed->GetRecEndFilePos(), &aExOleAtHd ) ) 2140 { 2141 PptExOleObjAtom aAt; 2142 ReadPptExOleObjAtom( rStCtrl, aAt ); 2143 2144 if ( aAt.nPersistPtr && ( aAt.nPersistPtr < m_nPersistPtrCnt ) ) 2145 { 2146 rStCtrl.Seek( m_pPersistPtr[ aAt.nPersistPtr ] ); 2147 DffRecordHeader aHd; 2148 ReadDffRecordHeader( rStCtrl, aHd ); 2149 if ( aHd.nRecType == DFF_PST_ExOleObjStg ) 2150 { 2151 sal_uInt32 nId; 2152 rStCtrl.ReadUInt32( nId ); 2153 aOleObjectList.emplace_back( 2154 aAt.nId, aHd.nFilePos, pShell, nRecType, aAt.nAspect ); 2155 } 2156 } 2157 } 2158 } 2159 } 2160 } 2161 rStCtrl.Seek( nOldPos ); 2162 } 2163 2164 bool SdrPowerPointImport::ReadFontCollection() 2165 { 2166 bool bRet = false; 2167 DffRecordHeader* pEnvHd = aDocRecManager.GetRecordHeader( PPT_PST_Environment ); 2168 if ( pEnvHd ) 2169 { 2170 sal_uInt64 nOldFPos = rStCtrl.Tell(); // remember FilePos for restoring it later 2171 pEnvHd->SeekToContent( rStCtrl ); 2172 DffRecordHeader aListHd; 2173 if ( SeekToRec( rStCtrl, PPT_PST_FontCollection, pEnvHd->GetRecEndFilePos(), &aListHd ) ) 2174 { 2175 sal_uInt16 nCount2 = 0; 2176 while ( SeekToRec( rStCtrl, PPT_PST_FontEntityAtom, aListHd.GetRecEndFilePos() ) ) 2177 { 2178 bRet = true; 2179 if (!m_xFonts) 2180 m_xFonts.emplace(); 2181 PptFontEntityAtom aFontAtom; 2182 ReadPptFontEntityAtom( rStCtrl, aFontAtom ); 2183 2184 vcl::Font aFont; 2185 aFont.SetCharSet( aFontAtom.eCharSet ); 2186 aFont.SetFamilyName( aFontAtom.aName ); 2187 aFont.SetFamily( aFontAtom.eFamily ); 2188 aFont.SetPitch( aFontAtom.ePitch ); 2189 aFont.SetFontHeight( 100 ); 2190 2191 // following block is necessary, because our old PowerPoint export did not set the 2192 // correct charset 2193 if ( aFontAtom.aName.equalsIgnoreAsciiCase( "Wingdings" ) || 2194 aFontAtom.aName.equalsIgnoreAsciiCase( "Wingdings 2" ) || 2195 aFontAtom.aName.equalsIgnoreAsciiCase( "Wingdings 3" ) || 2196 aFontAtom.aName.equalsIgnoreAsciiCase( "Monotype Sorts" ) || 2197 aFontAtom.aName.equalsIgnoreAsciiCase( "Monotype Sorts 2" ) || 2198 aFontAtom.aName.equalsIgnoreAsciiCase( "Webdings" ) || 2199 aFontAtom.aName.equalsIgnoreAsciiCase( "StarBats" ) || 2200 aFontAtom.aName.equalsIgnoreAsciiCase( "StarMath" ) || 2201 aFontAtom.aName.equalsIgnoreAsciiCase( "ZapfDingbats" ) ) 2202 { 2203 aFontAtom.eCharSet = RTL_TEXTENCODING_SYMBOL; 2204 }; 2205 m_xFonts->insert(m_xFonts->begin() + nCount2++, std::move(aFontAtom)); 2206 } 2207 } 2208 rStCtrl.Seek( nOldFPos ); // restore FilePos 2209 } 2210 return bRet; 2211 } 2212 2213 PptSlidePersistList* SdrPowerPointImport::GetPageList(PptPageKind ePageKind) const 2214 { 2215 switch (ePageKind) 2216 { 2217 case PPT_MASTERPAGE: 2218 return m_pMasterPages.get(); 2219 case PPT_SLIDEPAGE: 2220 return m_pSlidePages.get(); 2221 case PPT_NOTEPAGE: 2222 return m_pNotePages.get(); 2223 } 2224 return nullptr; 2225 } 2226 2227 SdrOutliner* SdrPowerPointImport::GetDrawOutliner( SdrTextObj const * pSdrText ) 2228 { 2229 if ( !pSdrText ) 2230 return nullptr; 2231 else 2232 return &pSdrText->ImpGetDrawOutliner(); 2233 } 2234 2235 2236 SdrObject* SdrPowerPointImport::ReadObjText( PPTTextObj* pTextObj, SdrObject* pSdrObj, SdPageCapsule pPage ) const 2237 { 2238 SdrTextObj* pText = dynamic_cast<SdrTextObj*>( pSdrObj ); 2239 if ( pText ) 2240 { 2241 if ( !ApplyTextObj( pTextObj, pText, pPage, nullptr, nullptr ) ) 2242 pSdrObj = nullptr; 2243 } 2244 return pSdrObj; 2245 } 2246 2247 SdrObject* SdrPowerPointImport::ApplyTextObj( PPTTextObj* pTextObj, SdrTextObj* pSdrText, SdPageCapsule /*pPage*/, 2248 SfxStyleSheet* pSheet, SfxStyleSheet** ppStyleSheetAry ) const 2249 { 2250 SdrTextObj* pText = pSdrText; 2251 if ( pTextObj->Count() ) 2252 { 2253 TSS_Type nDestinationInstance = pTextObj->GetDestinationInstance() ; 2254 SdrOutliner& rOutliner = pText->ImpGetDrawOutliner(); 2255 bool bUndoEnabled = rOutliner.IsUndoEnabled(); 2256 rOutliner.EnableUndo(false); 2257 2258 if ( ( pText->GetObjInventor() == SdrInventor::Default ) && ( pText->GetObjIdentifier() == SdrObjKind::TitleText ) ) // Outliner-Style for Title-Text object?!? (->of DL) 2259 rOutliner.Init( OutlinerMode::TitleObject ); // Outliner reset 2260 2261 bool bOldUpdateMode = rOutliner.SetUpdateLayout( false ); 2262 if ( pSheet ) 2263 { 2264 if ( rOutliner.GetStyleSheet( 0 ) != pSheet ) 2265 rOutliner.SetStyleSheet( 0, pSheet ); 2266 } 2267 rOutliner.SetVertical( pTextObj->GetVertical() ); 2268 for ( PPTParagraphObj* pPara = pTextObj->First(); pPara; pPara = pTextObj->Next() ) 2269 { 2270 sal_uInt32 nTextSize = pPara->GetTextSize(); 2271 if ( ! ( nTextSize & 0xffff0000 ) ) 2272 { 2273 PPTPortionObj* pPortion; 2274 std::unique_ptr<sal_Unicode[]> pParaText(new sal_Unicode[ nTextSize ]); 2275 sal_Int32 nCurrentIndex = 0; 2276 for ( pPortion = pPara->First(); pPortion; pPortion = pPara->Next() ) 2277 { 2278 if ( pPortion->mpFieldItem ) 2279 pParaText[ nCurrentIndex++ ] = ' '; 2280 else 2281 { 2282 sal_Int32 nCharacters = pPortion->Count(); 2283 const sal_Unicode* pSource = pPortion->maString.getStr(); 2284 sal_Unicode* pDest = pParaText.get() + nCurrentIndex; 2285 2286 sal_uInt32 nFont; 2287 pPortion->GetAttrib( PPT_CharAttr_Font, nFont, pTextObj->GetInstance() ); 2288 const PptFontEntityAtom* pFontEnityAtom = GetFontEnityAtom( nFont ); 2289 if ( pFontEnityAtom && ( pFontEnityAtom->eCharSet == RTL_TEXTENCODING_SYMBOL ) ) 2290 { 2291 sal_Unicode nUnicode; 2292 for (sal_Int32 i = 0; i < nCharacters; i++ ) 2293 { 2294 nUnicode = pSource[ i ]; 2295 if ( ! ( nUnicode & 0xff00 ) ) 2296 nUnicode |= 0xf000; 2297 pDest[ i ] = nUnicode; 2298 } 2299 } 2300 else 2301 memcpy( pDest, pSource, nCharacters << 1 ); 2302 nCurrentIndex += nCharacters; 2303 } 2304 } 2305 sal_Int32 nParaIndex = pTextObj->GetCurrentIndex(); 2306 SfxStyleSheet* pS = ppStyleSheetAry ? ppStyleSheetAry[ pPara->mxParaSet->mnDepth ] : pSheet; 2307 2308 ESelection aSelection( nParaIndex, 0, nParaIndex, 0 ); 2309 rOutliner.Insert( OUString(), nParaIndex, pPara->mxParaSet->mnDepth ); 2310 rOutliner.QuickInsertText( OUString(pParaText.get(), nCurrentIndex), aSelection ); 2311 rOutliner.SetParaAttribs( nParaIndex, rOutliner.GetEmptyItemSet() ); 2312 if ( pS ) 2313 rOutliner.SetStyleSheet( nParaIndex, pS ); 2314 2315 for ( pPortion = pPara->First(); pPortion; pPortion = pPara->Next() ) 2316 { 2317 SfxItemSet aPortionAttribs( rOutliner.GetEmptyItemSet() ); 2318 std::unique_ptr<SvxFieldItem> pFieldItem(pPortion->GetTextField()); 2319 if ( pFieldItem ) 2320 { 2321 rOutliner.QuickInsertField( *pFieldItem, ESelection( nParaIndex, aSelection.nEndPos, nParaIndex, aSelection.nEndPos + 1 ) ); 2322 aSelection.nEndPos++; 2323 } 2324 else 2325 { 2326 const sal_Unicode *pF, *pPtr = pPortion->maString.getStr(); 2327 const sal_Unicode *pMax = pPtr + pPortion->maString.getLength(); 2328 sal_Int32 nLen; 2329 for ( pF = pPtr; pPtr < pMax; pPtr++ ) 2330 { 2331 if ( *pPtr == 0xb ) 2332 { 2333 nLen = pPtr - pF; 2334 if ( nLen ) 2335 aSelection.nEndPos = 2336 sal::static_int_cast< sal_uInt16 >( 2337 aSelection.nEndPos + nLen ); 2338 pF = pPtr + 1; 2339 rOutliner.QuickInsertLineBreak( ESelection( nParaIndex, aSelection.nEndPos, nParaIndex, aSelection.nEndPos + 1 ) ); 2340 aSelection.nEndPos++; 2341 } 2342 } 2343 nLen = pPtr - pF; 2344 if ( nLen ) 2345 aSelection.nEndPos = sal::static_int_cast< sal_uInt16 >( 2346 aSelection.nEndPos + nLen ); 2347 } 2348 pPortion->ApplyTo( aPortionAttribs, const_cast<SdrPowerPointImport&>(*this), nDestinationInstance, pTextObj ); 2349 rOutliner.QuickSetAttribs( aPortionAttribs, aSelection ); 2350 aSelection.nStartPos = aSelection.nEndPos; 2351 } 2352 std::optional< sal_Int16 > oStartNumbering; 2353 SfxItemSet aParagraphAttribs( rOutliner.GetEmptyItemSet() ); 2354 pPara->ApplyTo( aParagraphAttribs, oStartNumbering, *this, nDestinationInstance ); 2355 2356 sal_uInt32 nIsBullet2 = 0; //, nInstance = nDestinationInstance != 0xffffffff ? nDestinationInstance : pTextObj->GetInstance(); 2357 pPara->GetAttrib( PPT_ParaAttr_BulletOn, nIsBullet2, nDestinationInstance ); 2358 if ( !nIsBullet2 ) 2359 aParagraphAttribs.Put( SfxBoolItem( EE_PARA_BULLETSTATE, false ) ); 2360 else 2361 aParagraphAttribs.Put( SfxInt16Item(EE_PARA_OUTLLEVEL, pPara->mxParaSet->mnDepth)); 2362 2363 if ( !aSelection.nStartPos ) // in PPT empty paragraphs never gets a bullet 2364 { 2365 aParagraphAttribs.Put( SfxBoolItem( EE_PARA_BULLETSTATE, false ) ); 2366 } 2367 aSelection.nStartPos = 0; 2368 rOutliner.QuickSetAttribs( aParagraphAttribs, aSelection ); 2369 } 2370 } 2371 std::optional<OutlinerParaObject> pNewText = rOutliner.CreateParaObject(); 2372 rOutliner.Clear(); 2373 rOutliner.SetUpdateLayout( bOldUpdateMode ); 2374 rOutliner.EnableUndo(bUndoEnabled); 2375 pText->SetOutlinerParaObject( std::move(pNewText) ); 2376 } 2377 return pText; 2378 } 2379 2380 bool SdrPowerPointImport::SeekToDocument( DffRecordHeader* pRecHd ) const 2381 { 2382 bool bRet; 2383 sal_uInt64 nOldFPos = rStCtrl.Tell(); // remember FilePos for restoring it, if the situation should happen 2384 rStCtrl.Seek( m_nDocStreamPos ); 2385 DffRecordHeader aDocHd; 2386 ReadDffRecordHeader( rStCtrl, aDocHd ); 2387 bRet = aDocHd.nRecType == PPT_PST_Document; 2388 if ( bRet ) 2389 { 2390 if ( pRecHd ) 2391 *pRecHd = aDocHd; 2392 else 2393 aDocHd.SeekToBegOfRecord( rStCtrl ); 2394 } 2395 if ( !bRet ) 2396 rStCtrl.Seek( nOldFPos ); // restore FilePos 2397 return bRet; 2398 } 2399 2400 bool SdrPowerPointImport::SeekToContentOfProgTag( sal_Int32 nVersion, SvStream& rSt, 2401 const DffRecordHeader& rSourceHd, DffRecordHeader& rContentHd ) 2402 { 2403 bool bRetValue = false; 2404 sal_uInt32 nOldPos = rSt.Tell(); 2405 2406 DffRecordHeader aProgTagsHd, aProgTagBinaryDataHd; 2407 rSourceHd.SeekToContent( rSt ); 2408 bool bFound = rSourceHd.nRecType == PPT_PST_ProgTags; 2409 if ( !bFound ) 2410 bFound = SeekToRec( rSt, PPT_PST_ProgTags, rSourceHd.GetRecEndFilePos(), &aProgTagsHd ); 2411 if ( bFound ) 2412 { 2413 while( SeekToRec( rSt, PPT_PST_ProgBinaryTag, aProgTagsHd.GetRecEndFilePos(), &aProgTagBinaryDataHd ) ) 2414 { 2415 ReadDffRecordHeader( rSt, rContentHd ); 2416 if ( rContentHd.nRecType == PPT_PST_CString ) 2417 { 2418 sal_uInt16 n = 6; 2419 sal_uInt32 i = rContentHd.nRecLen >> 1; 2420 if ( i > n ) 2421 { 2422 OUString aPre = read_uInt16s_ToOUString(rSt, n); 2423 n = static_cast<sal_uInt16>( i - 6 ); 2424 OUString aSuf = read_uInt16s_ToOUString(rSt, n); 2425 sal_Int32 nV = aSuf.toInt32(); 2426 if ( ( nV == nVersion ) && ( aPre == "___PPT" ) ) 2427 { 2428 if (!rContentHd.SeekToEndOfRecord(rSt)) 2429 { 2430 break; 2431 } 2432 ReadDffRecordHeader( rSt, rContentHd ); 2433 if ( rContentHd.nRecType == PPT_PST_BinaryTagData ) 2434 { 2435 bRetValue = true; 2436 break; 2437 } 2438 } 2439 } 2440 } 2441 if (!aProgTagBinaryDataHd.SeekToEndOfRecord(rSt)) 2442 break; 2443 } 2444 } 2445 if ( !bRetValue ) 2446 rSt.Seek( nOldPos ); 2447 return bRetValue; 2448 } 2449 2450 sal_uInt32 SdrPowerPointImport::GetCurrentPageId() 2451 { 2452 PptSlidePersistList* pList = GetPageList( m_eCurrentPageKind ); 2453 if ( pList && m_nCurrentPageNum < pList->size() ) 2454 return (*pList)[ m_nCurrentPageNum ].aPersistAtom.nSlideId; 2455 return 0; 2456 } 2457 2458 bool SdrPowerPointImport::SeekToCurrentPage( DffRecordHeader* pRecHd ) const 2459 { 2460 bool bRet = false; 2461 PptSlidePersistList* pList = GetPageList( m_eCurrentPageKind ); 2462 if ( pList && ( m_nCurrentPageNum < pList->size() ) ) 2463 { 2464 sal_uLong nPersist = (*pList)[ m_nCurrentPageNum ].aPersistAtom.nPsrReference; 2465 if ( nPersist > 0 && nPersist < m_nPersistPtrCnt ) 2466 { 2467 sal_uLong nFPos = m_pPersistPtr[ nPersist ]; 2468 if ( nFPos < nStreamLen ) 2469 { 2470 rStCtrl.Seek( nFPos ); 2471 if ( pRecHd ) 2472 ReadDffRecordHeader( rStCtrl, *pRecHd ); 2473 bRet = true; 2474 } 2475 } 2476 } 2477 return bRet; 2478 } 2479 2480 sal_uInt16 SdrPowerPointImport::GetPageCount( PptPageKind ePageKind ) const 2481 { 2482 PptSlidePersistList* pList = GetPageList( ePageKind ); 2483 if ( pList ) 2484 return pList->size(); 2485 return 0; 2486 } 2487 2488 void SdrPowerPointImport::SetPageNum( sal_uInt16 nPageNum, PptPageKind eKind ) 2489 { 2490 m_eCurrentPageKind = eKind; 2491 m_nCurrentPageNum = nPageNum; 2492 2493 m_pPPTStyleSheet = nullptr; 2494 2495 bool bHasMasterPage = true; 2496 sal_uInt16 nMasterIndex = 0; 2497 2498 if ( eKind == PPT_MASTERPAGE ) 2499 nMasterIndex = nPageNum; 2500 else 2501 { 2502 if ( HasMasterPage( nPageNum, eKind ) ) 2503 nMasterIndex = GetMasterPageIndex( nPageNum, eKind ); 2504 else 2505 bHasMasterPage = false; 2506 } 2507 if ( bHasMasterPage ) 2508 { 2509 PptSlidePersistList* pPageList = GetPageList( PPT_MASTERPAGE ); 2510 if ( pPageList && nMasterIndex < pPageList->size() ) 2511 { 2512 PptSlidePersistEntry* pMasterPersist = &(*pPageList)[ nMasterIndex ]; 2513 if (!pMasterPersist->xStyleSheet && pMasterPersist->aSlideAtom.nMasterId) 2514 { 2515 nMasterIndex = m_pMasterPages->FindPage( pMasterPersist->aSlideAtom.nMasterId ); 2516 if ( nMasterIndex != PPTSLIDEPERSIST_ENTRY_NOTFOUND ) 2517 pMasterPersist = &(*pPageList)[ nMasterIndex ]; 2518 } 2519 m_pPPTStyleSheet = pMasterPersist->xStyleSheet.get(); 2520 } 2521 } 2522 if ( !m_pPPTStyleSheet ) 2523 m_pPPTStyleSheet = m_pDefaultSheet; 2524 } 2525 2526 Size SdrPowerPointImport::GetPageSize() const 2527 { 2528 Size aRet( IsNoteOrHandout( m_nCurrentPageNum ) ? aDocAtom.GetNotesPageSize() : aDocAtom.GetSlidesPageSize() ); 2529 Scale( aRet ); 2530 // PPT works with units of 576 dpi in any case. To avoid inaccuracies 2531 // I do round the last decimal digit away. 2532 if ( nMapMul > 2 * nMapDiv ) 2533 { 2534 MapUnit eMap = pSdrModel->GetScaleUnit(); 2535 bool bInch = IsInch( eMap ); 2536 tools::Long nInchMul = 1, nInchDiv = 1; 2537 if ( bInch ) 2538 { // temporarily convert size (for rounding it) from inch to metric units 2539 Fraction aFact(GetMapFactor(eMap,MapUnit::Map100thMM).X()); 2540 nInchMul = aFact.GetNumerator(); 2541 nInchDiv = aFact.GetDenominator(); 2542 aRet.setWidth( BigMulDiv( aRet.Width(), nInchMul, nInchDiv ) ); 2543 aRet.setHeight( BigMulDiv( aRet.Height(), nInchMul, nInchDiv ) ); 2544 } 2545 aRet.AdjustWidth(5 ); aRet.setWidth( aRet.Width() / 10 ); aRet.setWidth( aRet.Width() * 10 ); 2546 aRet.AdjustHeight(5 ); aRet.setHeight( aRet.Height() / 10 ); aRet.setHeight( aRet.Height() * 10 ); 2547 if ( bInch ) 2548 { 2549 aRet.setWidth( BigMulDiv( aRet.Width(), nInchDiv, nInchMul ) ); 2550 aRet.setHeight( BigMulDiv( aRet.Height(), nInchDiv, nInchMul ) ); 2551 } 2552 } 2553 return aRet; 2554 } 2555 2556 bool SdrPowerPointImport::GetColorFromPalette( sal_uInt16 nNum, Color& rColor ) const 2557 { 2558 if ( m_nPageColorsNum != m_nCurrentPageNum || m_ePageColorsKind != m_eCurrentPageKind ) 2559 { 2560 sal_uInt16 nSlideFlags = 0; 2561 PptSlidePersistList* pPageList = GetPageList( m_eCurrentPageKind ); 2562 if ( pPageList && ( m_nCurrentPageNum < pPageList->size() ) ) 2563 { 2564 assert( !pPageList->is_null( m_nCurrentPageNum ) ); 2565 const PptSlidePersistEntry& rE = (*pPageList)[ m_nCurrentPageNum ]; 2566 nSlideFlags = rE.aSlideAtom.nFlags; 2567 if ( ! ( nSlideFlags & 2 ) ) 2568 const_cast<SdrPowerPointImport*>(this)->m_aPageColors = rE.aColorScheme; 2569 } 2570 if ( nSlideFlags & 2 ) // follow master colorscheme? 2571 { 2572 PptSlidePersistList* pPageList2 = GetPageList( PPT_MASTERPAGE ); 2573 if ( pPageList2 ) 2574 { 2575 PptSlidePersistEntry* pMasterPersist = nullptr; 2576 if ( m_eCurrentPageKind == PPT_MASTERPAGE ) 2577 pMasterPersist = &(*pPageList2)[ m_nCurrentPageNum ]; 2578 else 2579 { 2580 if ( HasMasterPage( m_nCurrentPageNum, m_eCurrentPageKind ) ) 2581 { 2582 sal_uInt16 nMasterNum = GetMasterPageIndex( m_nCurrentPageNum, m_eCurrentPageKind ); 2583 if ( nMasterNum < pPageList2->size() ) 2584 pMasterPersist = &(*pPageList2)[ nMasterNum ]; 2585 } 2586 } 2587 if ( pMasterPersist ) 2588 { 2589 while( (pMasterPersist->aSlideAtom.nFlags & 2) // it is possible that a masterpage 2590 && pMasterPersist->aSlideAtom.nMasterId ) // itself is following a master colorscheme 2591 { 2592 auto nOrigMasterId = pMasterPersist->aSlideAtom.nMasterId; 2593 sal_uInt16 nNextMaster = m_pMasterPages->FindPage(nOrigMasterId); 2594 if (nNextMaster == PPTSLIDEPERSIST_ENTRY_NOTFOUND) 2595 break; 2596 pMasterPersist = &(*pPageList2)[ nNextMaster ]; 2597 if (pMasterPersist->aSlideAtom.nMasterId == nOrigMasterId) 2598 { 2599 SAL_WARN("filter.ms", "loop in atom chain"); 2600 break; 2601 } 2602 } 2603 const_cast<SdrPowerPointImport*>(this)->m_aPageColors = pMasterPersist->aColorScheme; 2604 } 2605 } 2606 } 2607 // register current color scheme 2608 const_cast<SdrPowerPointImport*>(this)->m_nPageColorsNum = m_nCurrentPageNum; 2609 const_cast<SdrPowerPointImport*>(this)->m_ePageColorsKind = m_eCurrentPageKind; 2610 } 2611 rColor = m_aPageColors.GetColor( nNum ); 2612 return true; 2613 } 2614 2615 bool SdrPowerPointImport::SeekToShape( SvStream& rSt, SvxMSDffClientData* pClientData, sal_uInt32 nId ) const 2616 { 2617 bool bRet = SvxMSDffManager::SeekToShape( rSt, pClientData, nId ); 2618 if (!bRet && pClientData) 2619 { 2620 ProcessData& rData = *static_cast<ProcessData*>(pClientData); 2621 PptSlidePersistEntry& rPersistEntry = rData.rPersistEntry; 2622 if ( rPersistEntry.ePageKind == PPT_SLIDEPAGE ) 2623 { 2624 if ( HasMasterPage( m_nCurrentPageNum, m_eCurrentPageKind ) ) 2625 { 2626 sal_uInt16 nMasterNum = GetMasterPageIndex( m_nCurrentPageNum, m_eCurrentPageKind ); 2627 PptSlidePersistList* pPageList = GetPageList( PPT_MASTERPAGE ); 2628 if ( pPageList && ( nMasterNum < pPageList->size() ) ) 2629 { 2630 assert( !pPageList->is_null( nMasterNum ) ); 2631 const PptSlidePersistEntry& rPersist = (*pPageList)[ nMasterNum ]; // get the masterpage's persistentry 2632 if ( rPersist.pPresentationObjects ) 2633 { 2634 sal_uInt32 nCurrent(0); 2635 DffRecordList* pCList = maShapeRecords.pCList; // we got a backup of the current position 2636 if ( pCList ) 2637 nCurrent = pCList->nCurrent; 2638 if ( const_cast<SdrPowerPointImport*>(this)->maShapeRecords.SeekToContent( rSt, DFF_msofbtClientData, SEEK_FROM_CURRENT_AND_RESTART ) ) 2639 { 2640 sal_uInt32 nStreamPos = rSt.Tell(); 2641 PPTTextObj aTextObj( rSt, const_cast<SdrPowerPointImport&>(*this), rPersistEntry, nullptr ); 2642 if ( aTextObj.Count() || aTextObj.GetOEPlaceHolderAtom() ) 2643 { 2644 sal_uInt32 nShapePos = 0; 2645 switch ( aTextObj.GetInstance() ) 2646 { 2647 case TSS_Type::Title : 2648 nShapePos = rPersist.pPresentationObjects[ int(TSS_Type::PageTitle) ]; 2649 break; 2650 case TSS_Type::PageTitle : 2651 nShapePos = rPersist.pPresentationObjects[ int(TSS_Type::PageTitle) ]; 2652 break; 2653 case TSS_Type::Subtitle : 2654 case TSS_Type::HalfBody : 2655 case TSS_Type::QuarterBody : 2656 case TSS_Type::Body : 2657 nShapePos = rPersist.pPresentationObjects[ int(TSS_Type::Body) ]; 2658 break; 2659 default: break; 2660 } 2661 if ( nShapePos ) 2662 { 2663 rSt.Seek( nShapePos ); 2664 bRet = true; 2665 } 2666 } 2667 if ( !bRet ) 2668 rSt.Seek( nStreamPos ); 2669 } 2670 if ( pCList ) // restoring 2671 pCList->nCurrent = nCurrent; 2672 const_cast<SdrPowerPointImport*>(this)->maShapeRecords.pCList = pCList; 2673 } 2674 } 2675 } 2676 } 2677 } 2678 return bRet; 2679 } 2680 2681 rtl::Reference<SdrPage> SdrPowerPointImport::MakeBlankPage( bool bMaster ) const 2682 { 2683 rtl::Reference<SdrPage> pRet = pSdrModel->AllocPage( bMaster ); 2684 pRet->SetSize( GetPageSize() ); 2685 2686 return pRet; 2687 } 2688 2689 static void ImportComment10( SvxMSDffManager const & rMan, SvStream& rStCtrl, SdrPage* pPage, DffRecordHeader const & rComment10Hd ) 2690 { 2691 OUString sAuthor; 2692 OUString sText; 2693 OUString sInitials; 2694 2695 sal_Int32 nIndex = 0; 2696 util::DateTime aDateTime; 2697 sal_Int32 nPosX = 0; 2698 sal_Int32 nPosY = 0; 2699 2700 2701 auto nEndRecPos = DffPropSet::SanitizeEndPos(rStCtrl, rComment10Hd.GetRecEndFilePos()); 2702 while ( ( rStCtrl.GetError() == ERRCODE_NONE ) && ( rStCtrl.Tell() < nEndRecPos ) ) 2703 { 2704 DffRecordHeader aCommentHd; 2705 ReadDffRecordHeader( rStCtrl, aCommentHd ); 2706 switch( aCommentHd.nRecType ) 2707 { 2708 case PPT_PST_CString : 2709 { 2710 OUString aString = SvxMSDffManager::MSDFFReadZString( rStCtrl, 2711 aCommentHd.nRecLen, true ); 2712 switch ( aCommentHd.nRecInstance ) 2713 { 2714 case 0 : sAuthor = aString; break; 2715 case 1 : sText = aString; break; 2716 case 2 : sInitials = aString; break; 2717 } 2718 } 2719 break; 2720 2721 case PPT_PST_CommentAtom10 : 2722 { 2723 sal_uInt16 millisec = 0; 2724 rStCtrl.ReadInt32( nIndex ) 2725 .ReadInt16( aDateTime.Year ) 2726 .ReadUInt16( aDateTime.Month ) 2727 .ReadUInt16( aDateTime.Day ) // DayOfWeek 2728 .ReadUInt16( aDateTime.Day ) 2729 .ReadUInt16( aDateTime.Hours ) 2730 .ReadUInt16( aDateTime.Minutes ) 2731 .ReadUInt16( aDateTime.Seconds ) 2732 .ReadUInt16( millisec ) 2733 .ReadInt32( nPosX ) 2734 .ReadInt32( nPosY ); 2735 2736 aDateTime.NanoSeconds = millisec * ::tools::Time::nanoPerMilli; 2737 } 2738 break; 2739 } 2740 if (!aCommentHd.SeekToEndOfRecord(rStCtrl)) 2741 break; 2742 } 2743 Point aPosition( nPosX, nPosY ); 2744 rMan.Scale( aPosition ); 2745 2746 try 2747 { 2748 uno::Reference< office::XAnnotationAccess > xAnnotationAccess( pPage->getUnoPage(), UNO_QUERY_THROW ); 2749 uno::Reference< office::XAnnotation > xAnnotation( xAnnotationAccess->createAndInsertAnnotation() ); 2750 xAnnotation->setPosition( geometry::RealPoint2D( aPosition.X() / 100.0, aPosition.Y() / 100.0 ) ); 2751 xAnnotation->setAuthor( sAuthor ); 2752 xAnnotation->setDateTime( aDateTime ); 2753 xAnnotation->setInitials( sInitials ); 2754 uno::Reference< text::XText > xText( xAnnotation->getTextRange() ); 2755 xText->setString( sText ); 2756 } 2757 catch( const uno::Exception& ) 2758 { 2759 2760 } 2761 } 2762 2763 2764 // be sure not to import masterpages with this method 2765 void SdrPowerPointImport::ImportPage( SdrPage* pRet, const PptSlidePersistEntry* pMasterPersist ) 2766 { 2767 sal_uInt32 nOldPos = rStCtrl.Tell(); 2768 PptSlidePersistList* pList = GetPageList( m_eCurrentPageKind ); 2769 if ( ( !pList ) || ( pList->size() <= m_nCurrentPageNum ) ) 2770 return; 2771 PptSlidePersistEntry& rSlidePersist = (*pList)[ m_nCurrentPageNum ]; 2772 if ( rSlidePersist.bStarDrawFiller ) 2773 return; 2774 2775 DffRecordHeader aPageHd; 2776 if ( SeekToCurrentPage( &aPageHd ) ) 2777 { 2778 rSlidePersist.xHeaderFooterEntry.reset(new HeaderFooterEntry(pMasterPersist)); 2779 ProcessData aProcessData( rSlidePersist, SdPageCapsule(pRet) ); 2780 auto nEndRecPos = SanitizeEndPos(rStCtrl, aPageHd.GetRecEndFilePos()); 2781 while ( ( rStCtrl.GetError() == ERRCODE_NONE ) && ( rStCtrl.Tell() < nEndRecPos ) ) 2782 { 2783 DffRecordHeader aHd; 2784 ReadDffRecordHeader( rStCtrl, aHd ); 2785 switch ( aHd.nRecType ) 2786 { 2787 case PPT_PST_HeadersFooters : 2788 { 2789 ImportHeaderFooterContainer(aHd, *rSlidePersist.xHeaderFooterEntry); 2790 } 2791 break; 2792 2793 case PPT_PST_ProgTags : 2794 { 2795 DffRecordHeader aContentDataHd; 2796 if ( SeekToContentOfProgTag( 10, rStCtrl, aHd, aContentDataHd ) ) 2797 { 2798 DffRecordHeader aComment10Hd; 2799 while( ( rStCtrl.GetError() == ERRCODE_NONE ) && SeekToRec( rStCtrl, PPT_PST_Comment10, aContentDataHd.GetRecEndFilePos(), &aComment10Hd ) ) 2800 { 2801 ImportComment10( *this, rStCtrl, pRet, aComment10Hd ); 2802 if (!aComment10Hd.SeekToEndOfRecord(rStCtrl)) 2803 break; 2804 } 2805 } 2806 } 2807 break; 2808 2809 case PPT_PST_PPDrawing : 2810 { 2811 DffRecordHeader aPPDrawHd; 2812 if ( SeekToRec( rStCtrl, DFF_msofbtDgContainer, aHd.GetRecEndFilePos(), &aPPDrawHd ) ) 2813 { 2814 sal_uInt32 nPPDrawOfs = rStCtrl.Tell(); 2815 2816 // importing the background object before importing the page 2817 auto nPPEndRecPos = SanitizeEndPos(rStCtrl, aPPDrawHd.GetRecEndFilePos()); 2818 while ( ( rStCtrl.GetError() == ERRCODE_NONE ) && ( rStCtrl.Tell() < nPPEndRecPos ) ) 2819 { 2820 DffRecordHeader aEscherObjListHd; 2821 ReadDffRecordHeader( rStCtrl, aEscherObjListHd ); 2822 switch ( aEscherObjListHd.nRecType ) 2823 { 2824 case DFF_msofbtSpContainer : 2825 { 2826 tools::Rectangle aPageSize( Point(), pRet->GetSize() ); 2827 if ( rSlidePersist.aSlideAtom.nFlags & 4 ) // follow master background? 2828 { 2829 if ( HasMasterPage( m_nCurrentPageNum, m_eCurrentPageKind ) ) 2830 { 2831 sal_uInt16 nMasterNum = GetMasterPageIndex( m_nCurrentPageNum, m_eCurrentPageKind ); 2832 PptSlidePersistList* pPageList = GetPageList( PPT_MASTERPAGE ); 2833 PptSlidePersistEntry* pE = &(*pPageList)[ nMasterNum ]; 2834 while( ( pE->aSlideAtom.nFlags & 4 ) && pE->aSlideAtom.nMasterId ) 2835 { 2836 auto nOrigMasterId = pE->aSlideAtom.nMasterId; 2837 sal_uInt16 nNextMaster = m_pMasterPages->FindPage(nOrigMasterId); 2838 if ( nNextMaster == PPTSLIDEPERSIST_ENTRY_NOTFOUND ) 2839 break; 2840 else 2841 pE = &(*pPageList)[ nNextMaster ]; 2842 if (pE->aSlideAtom.nMasterId == nOrigMasterId) 2843 { 2844 SAL_WARN("filter.ms", "loop in atom chain"); 2845 break; 2846 } 2847 } 2848 if ( pE->nBackgroundOffset ) 2849 { 2850 // do not follow master colorscheme? 2851 sal_uInt32 nPos = rStCtrl.Tell(); 2852 rStCtrl.Seek( pE->nBackgroundOffset ); 2853 rSlidePersist.pBObj = ImportObj( rStCtrl, aProcessData, aPageSize, aPageSize, /*nCalledByGroup*/0, /*pShapeId*/nullptr ); 2854 rStCtrl.Seek( nPos ); 2855 } 2856 } 2857 } 2858 else 2859 { 2860 DffRecordHeader aShapeHd; 2861 ReadDffRecordHeader( rStCtrl, aShapeHd ); 2862 if ( aShapeHd.nRecType == DFF_msofbtSp ) 2863 { 2864 sal_uInt32 nSpFlags; 2865 rStCtrl.ReadUInt32( nSpFlags ).ReadUInt32( nSpFlags ); 2866 if (rStCtrl.good() && ShapeFlag(nSpFlags) & ShapeFlag::Background) 2867 { 2868 aEscherObjListHd.SeekToBegOfRecord( rStCtrl ); 2869 rSlidePersist.pBObj = ImportObj( rStCtrl, aProcessData, aPageSize, aPageSize, /*nCalledByGroup*/0, /*pShapeId*/nullptr ); 2870 } 2871 } 2872 } 2873 } 2874 break; 2875 } 2876 if ( aEscherObjListHd.nRecType == DFF_msofbtSpContainer ) 2877 break; 2878 if (!aEscherObjListHd.SeekToEndOfRecord(rStCtrl)) 2879 break; 2880 } 2881 2882 // now importing page 2883 rStCtrl.Seek( nPPDrawOfs ); 2884 auto nHdEndRecPos = SanitizeEndPos(rStCtrl, aPPDrawHd.GetRecEndFilePos()); 2885 while ( ( rStCtrl.GetError() == ERRCODE_NONE ) && ( rStCtrl.Tell() < nHdEndRecPos ) ) 2886 { 2887 DffRecordHeader aEscherObjListHd; 2888 ReadDffRecordHeader( rStCtrl, aEscherObjListHd ); 2889 switch ( aEscherObjListHd.nRecType ) 2890 { 2891 case DFF_msofbtSpgrContainer : 2892 { 2893 DffRecordHeader aShapeHd; 2894 if ( SeekToRec( rStCtrl, DFF_msofbtSpContainer, aEscherObjListHd.GetRecEndFilePos(), &aShapeHd ) ) 2895 { 2896 if (!aShapeHd.SeekToEndOfRecord(rStCtrl)) 2897 { 2898 break; 2899 } 2900 auto nListEndRecPos = SanitizeEndPos(rStCtrl, aEscherObjListHd.GetRecEndFilePos()); 2901 while ( ( rStCtrl.GetError() == ERRCODE_NONE ) && ( rStCtrl.Tell() < nListEndRecPos ) ) 2902 { 2903 ReadDffRecordHeader( rStCtrl, aShapeHd ); 2904 if ( ( aShapeHd.nRecType == DFF_msofbtSpContainer ) || ( aShapeHd.nRecType == DFF_msofbtSpgrContainer ) ) 2905 { 2906 tools::Rectangle aEmpty; 2907 aShapeHd.SeekToBegOfRecord( rStCtrl ); 2908 sal_Int32 nShapeId; 2909 aProcessData.pTableRowProperties.reset(); 2910 rtl::Reference<SdrObject> pObj = ImportObj( rStCtrl, aProcessData, aEmpty, aEmpty, 0, &nShapeId ); 2911 if ( pObj ) 2912 { 2913 if ( aProcessData.pTableRowProperties ) 2914 pObj = CreateTable(pObj.get(), aProcessData.pTableRowProperties.get(), aProcessData.rPersistEntry.xSolverContainer.get(), aProcessData.aBackgroundColoredObjects); 2915 2916 pRet->NbcInsertObject( pObj.get() ); 2917 2918 if( nShapeId ) 2919 insertShapeId( nShapeId, pObj.get() ); 2920 } 2921 } 2922 bool bSuccess = aShapeHd.SeekToEndOfRecord(rStCtrl); 2923 if (!bSuccess) 2924 break; 2925 } 2926 } 2927 } 2928 break; 2929 } 2930 if ( aEscherObjListHd.nRecType == DFF_msofbtSpgrContainer ) 2931 break; 2932 if (!aEscherObjListHd.SeekToEndOfRecord(rStCtrl)) 2933 break; 2934 } 2935 2936 // Handle shapes where the fill matches the background 2937 // fill (mso_fillBackground). 2938 if (rSlidePersist.ePageKind == PPT_SLIDEPAGE) 2939 { 2940 if (!aProcessData.aBackgroundColoredObjects.empty()) 2941 { 2942 if (!rSlidePersist.pBObj) 2943 { 2944 for (auto const & pObject : aProcessData.aBackgroundColoredObjects) 2945 { 2946 // The shape wants a background, but the slide doesn't have 2947 // one: default to white. 2948 SfxItemSet aNewSet(*pObject->GetMergedItemSet().GetPool()); 2949 aNewSet.Put(XFillStyleItem(css::drawing::FillStyle_SOLID)); 2950 aNewSet.Put(XFillColorItem(OUString(), COL_WHITE)); 2951 pObject->SetMergedItemSet(aNewSet); 2952 } 2953 } 2954 } 2955 } 2956 2957 if ( rSlidePersist.pBObj ) 2958 { 2959 // #i99386# transfer the attributes from the temporary BackgroundObject 2960 // to the Page and delete it. 2961 pRet->getSdrPageProperties().ClearItem(); 2962 pRet->getSdrPageProperties().PutItemSet(rSlidePersist.pBObj->GetMergedItemSet()); 2963 if (rSlidePersist.xSolverContainer) 2964 { 2965 for (auto & pPtr : rSlidePersist.xSolverContainer->aCList) 2966 { 2967 // check connections to the group object 2968 if (pPtr->pAObj == rSlidePersist.pBObj.get()) 2969 pPtr->pAObj = nullptr; 2970 if (pPtr->pBObj == rSlidePersist.pBObj.get()) 2971 pPtr->pBObj = nullptr; 2972 if (pPtr->pCObj == rSlidePersist.pBObj.get()) 2973 pPtr->pCObj = nullptr; 2974 } 2975 } 2976 rSlidePersist.pBObj.clear(); 2977 } 2978 } 2979 } 2980 break; 2981 } 2982 if (!aHd.SeekToEndOfRecord(rStCtrl)) 2983 break; 2984 } 2985 if (rSlidePersist.xSolverContainer) 2986 SolveSolver(*rSlidePersist.xSolverContainer); 2987 } 2988 rStCtrl.Seek( nOldPos ); 2989 } 2990 2991 const PptSlideLayoutAtom* SdrPowerPointImport::GetSlideLayoutAtom() const 2992 { 2993 PptSlidePersistList* pPageList = GetPageList( m_eCurrentPageKind ); 2994 if ( pPageList && m_nCurrentPageNum < pPageList->size() ) 2995 { 2996 assert( !pPageList->is_null( m_nCurrentPageNum ) ); 2997 return &(*pPageList)[ m_nCurrentPageNum ].aSlideAtom.aLayout; 2998 } 2999 return nullptr; 3000 } 3001 3002 bool SdrPowerPointImport::IsNoteOrHandout( sal_uInt16 nPageNum ) const 3003 { 3004 bool bNote = m_eCurrentPageKind == PPT_NOTEPAGE; 3005 if ( m_eCurrentPageKind == PPT_MASTERPAGE ) 3006 bNote = ( nPageNum & 1 ) == 0; 3007 return bNote; 3008 } 3009 3010 sal_uInt32 SdrPowerPointImport::GetMasterPageId( sal_uInt16 nPageNum, PptPageKind ePageKind ) const 3011 { 3012 PptSlidePersistList* pPageList = GetPageList( ePageKind ); 3013 if ( pPageList && nPageNum < pPageList->size() ) 3014 return (*pPageList)[ nPageNum ].aSlideAtom.nMasterId; 3015 return 0; 3016 } 3017 3018 sal_uInt32 SdrPowerPointImport::GetNotesPageId( sal_uInt16 nPageNum ) const 3019 { 3020 PptSlidePersistList* pPageList=GetPageList( PPT_SLIDEPAGE ); 3021 if ( pPageList && nPageNum < pPageList->size() ) 3022 return (*pPageList)[ nPageNum ].aSlideAtom.nNotesId; 3023 return 0; 3024 } 3025 3026 bool SdrPowerPointImport::HasMasterPage( sal_uInt16 nPageNum, PptPageKind ePageKind ) const 3027 { 3028 if ( ePageKind == PPT_NOTEPAGE ) 3029 return aDocAtom.nNotesMasterPersist != 0; 3030 if ( ePageKind == PPT_MASTERPAGE ) 3031 return false; 3032 return GetMasterPageId( nPageNum, ePageKind ) != 0; 3033 } 3034 3035 sal_uInt16 SdrPowerPointImport::GetMasterPageIndex( sal_uInt16 nPageNum, PptPageKind ePageKind ) const 3036 { 3037 sal_uInt16 nIdx = 0; 3038 if ( ePageKind == PPT_NOTEPAGE ) 3039 return 2; 3040 sal_uInt32 nId = GetMasterPageId( nPageNum, ePageKind ); 3041 if (nId && m_pMasterPages) 3042 { 3043 nIdx = m_pMasterPages->FindPage( nId ); 3044 if ( nIdx == PPTSLIDEPERSIST_ENTRY_NOTFOUND ) 3045 nIdx = 0; 3046 } 3047 return nIdx; 3048 } 3049 3050 rtl::Reference<SdrObject> SdrPowerPointImport::ImportPageBackgroundObject( const SdrPage& rPage, sal_uInt32& nBgFileOffset ) 3051 { 3052 rtl::Reference<SdrObject> pRet; 3053 std::optional<SfxItemSet> pSet; 3054 sal_uInt64 nOldFPos = rStCtrl.Tell(); // remember FilePos for restoring it later 3055 DffRecordHeader aPageHd; 3056 if ( SeekToCurrentPage( &aPageHd ) ) 3057 { // and now search for the background attributes of the Page 3058 sal_uLong nPageRecEnd = aPageHd.GetRecEndFilePos(); 3059 DffRecordHeader aPPDrawHd; 3060 if ( SeekToRec( rStCtrl, PPT_PST_PPDrawing, nPageRecEnd, &aPPDrawHd ) ) 3061 { 3062 sal_uLong nPPDrawEnd = aPPDrawHd.GetRecEndFilePos(); 3063 DffRecordHeader aEscherF002Hd; 3064 if ( SeekToRec( rStCtrl, DFF_msofbtDgContainer, nPPDrawEnd, &aEscherF002Hd ) ) 3065 { 3066 sal_uLong nEscherF002End = aEscherF002Hd.GetRecEndFilePos(); 3067 DffRecordHeader aEscherObjectHd; 3068 if ( SeekToRec( rStCtrl, DFF_msofbtSpContainer, nEscherF002End, &aEscherObjectHd ) ) 3069 { 3070 nBgFileOffset = aEscherObjectHd.GetRecBegFilePos(); 3071 //sal_uLong nEscherObjectEnd = aEscherObjectHd.GetRecEndFilePos(); 3072 //DffRecordHeader aEscherPropertiesHd; 3073 if ( SeekToRec( rStCtrl, DFF_msofbtOPT,nEscherF002End ) ) 3074 { 3075 ReadDffPropSet( rStCtrl, static_cast<DffPropertyReader&>(*this) ); 3076 mnFix16Angle = Fix16ToAngle( GetPropertyValue( DFF_Prop_Rotation, 0 ) ); 3077 sal_uInt32 nColor = GetPropertyValue( DFF_Prop_fillColor, 0xffffff ); 3078 pSet.emplace( pSdrModel->GetItemPool() ); 3079 DffObjData aObjData( aEscherObjectHd, tools::Rectangle( 0, 0, 28000, 21000 ), 0 ); 3080 ApplyAttributes( rStCtrl, *pSet, aObjData ); 3081 Color aColor( MSO_CLR_ToColor( nColor ) ); 3082 pSet->Put( XFillColorItem( OUString(), aColor ) ); 3083 } 3084 } 3085 } 3086 } 3087 } 3088 rStCtrl.Seek( nOldFPos ); // restore FilePos 3089 if ( !pSet ) 3090 { 3091 pSet.emplace( pSdrModel->GetItemPool() ); 3092 pSet->Put( XFillStyleItem( drawing::FillStyle_NONE ) ); 3093 } 3094 pSet->Put( XLineStyleItem( drawing::LineStyle_NONE ) ); 3095 tools::Rectangle aRect( 3096 rPage.GetLeftBorder(), 3097 rPage.GetUpperBorder(), 3098 rPage.GetWidth() - rPage.GetRightBorder(), 3099 rPage.GetHeight() - rPage.GetLowerBorder()); 3100 3101 pRet = new SdrRectObj( 3102 *pSdrModel, 3103 aRect); 3104 3105 pRet->SetMergedItemSet(*pSet); 3106 pRet->SetMarkProtect( true ); 3107 pRet->SetMoveProtect( true ); 3108 pRet->SetResizeProtect( true ); 3109 return pRet; 3110 } 3111 3112 HeaderFooterEntry::HeaderFooterEntry( const PptSlidePersistEntry* pMPE ) : 3113 pMasterPersist ( pMPE ), 3114 nAtom ( 0 ) 3115 { 3116 if ( pMPE ) 3117 { 3118 HeaderFooterEntry* pMHFE = pMPE->xHeaderFooterEntry.get(); 3119 if ( pMHFE ) 3120 { 3121 nAtom = pMPE->xHeaderFooterEntry->nAtom; 3122 pPlaceholder[ 0 ] = pMHFE->pPlaceholder[ 0 ]; 3123 pPlaceholder[ 1 ] = pMHFE->pPlaceholder[ 1 ]; 3124 pPlaceholder[ 2 ] = pMHFE->pPlaceholder[ 2 ]; 3125 pPlaceholder[ 3 ] = pMHFE->pPlaceholder[ 3 ]; 3126 } 3127 } 3128 } 3129 3130 sal_uInt32 HeaderFooterEntry::IsToDisplay( sal_uInt32 nInstance ) 3131 { 3132 sal_uInt32 nMask = 0; 3133 switch ( nInstance ) 3134 { 3135 case 0 : nMask = 0x010000; break; 3136 case 1 : nMask = 0x100000; break; 3137 case 2 : nMask = 0x200000; break; 3138 case 3 : nMask = 0x080000; break; 3139 } 3140 return ( nAtom & nMask ); 3141 } 3142 3143 // The following method checks if the slide is using a different colorscheme than 3144 // its master, if this is the fact, then the HeaderFooter must probably be 3145 // imported as real sdrobject. In this case, the return value is the offset to the 3146 // master header footer object, so it can be re-loaded with a different color set 3147 sal_uInt32 HeaderFooterEntry::NeedToImportInstance( const sal_uInt32 nInstance, const PptSlidePersistEntry& rSlidePersist ) 3148 { 3149 sal_uInt32 nRet = 0; 3150 if ( pMasterPersist ) 3151 { 3152 if ( !( rSlidePersist.aSlideAtom.nFlags & 2 ) ) 3153 { // not following the master persist, so we have to check if the colors are changed 3154 if ( memcmp( &rSlidePersist.aColorScheme, &pMasterPersist->aColorScheme, 32 ) ) 3155 { 3156 nRet = pMasterPersist->HeaderFooterOfs[ nInstance ]; 3157 } 3158 } 3159 } 3160 return nRet; 3161 } 3162 3163 void SdrEscherImport::ImportHeaderFooterContainer( DffRecordHeader const & rHd, HeaderFooterEntry& rE ) 3164 { 3165 rHd.SeekToContent( rStCtrl ); 3166 auto nEndRecPos = SanitizeEndPos(rStCtrl, rHd.GetRecEndFilePos()); 3167 while ( ( rStCtrl.GetError() == ERRCODE_NONE ) && ( rStCtrl.Tell() < nEndRecPos ) ) 3168 { 3169 DffRecordHeader aHd; 3170 ReadDffRecordHeader( rStCtrl, aHd ); 3171 switch ( aHd.nRecType ) 3172 { 3173 case PPT_PST_HeadersFootersAtom : 3174 rStCtrl.ReadUInt32( rE.nAtom ); 3175 break; 3176 3177 case PPT_PST_CString : 3178 { 3179 if ( aHd.nRecInstance < 4 ) 3180 { 3181 rE.pPlaceholder[ aHd.nRecInstance ] = MSDFFReadZString( rStCtrl, 3182 aHd.nRecLen, true ); 3183 } 3184 } 3185 break; 3186 } 3187 if (!aHd.SeekToEndOfRecord(rStCtrl)) 3188 break; 3189 } 3190 } 3191 3192 PPTBuGraEntry::PPTBuGraEntry( Graphic aGraphic, sal_uInt32 nInst ) : 3193 nInstance ( nInst ), 3194 aBuGra (std::move( aGraphic )) {} 3195 3196 PPTExtParaLevel::PPTExtParaLevel() 3197 : mnExtParagraphMask( 0 ) 3198 , mnBuBlip( 0xffff ) 3199 , mnHasAnm( 0 ) 3200 , mnAnmScheme( 0 ) 3201 , mpfPP10Ext( 0 ) 3202 , mnExtCharacterMask( 0 ) 3203 , mcfPP10Ext( 0 ) 3204 , mbSet( false ) 3205 {} 3206 3207 SvStream& ReadPPTExtParaLevel( SvStream& rIn, PPTExtParaLevel& rLevel ) 3208 { 3209 rLevel.mbSet = true; 3210 rIn.ReadUInt32( rLevel.mnExtParagraphMask ); 3211 if ( rLevel.mnExtParagraphMask & 0x00800000 ) 3212 rIn.ReadUInt16( rLevel.mnBuBlip ); 3213 if ( rLevel.mnExtParagraphMask & 0x02000000 ) 3214 rIn.ReadUInt16( rLevel.mnHasAnm ); 3215 if ( rLevel.mnExtParagraphMask & 0x01000000 ) 3216 rIn.ReadUInt32( rLevel.mnAnmScheme ); 3217 if ( rLevel.mnExtParagraphMask & 0x04000000 ) 3218 rIn.ReadUInt32( rLevel.mpfPP10Ext ); 3219 rIn.ReadUInt32( rLevel.mnExtCharacterMask ); 3220 if ( rLevel.mnExtCharacterMask & 0x100000 ) 3221 rIn.ReadUInt32( rLevel.mcfPP10Ext ); 3222 return rIn; 3223 } 3224 3225 bool PPTExtParaProv::GetGraphic( sal_uInt32 nInstance, Graphic& rGraph ) const 3226 { 3227 bool bRetValue = false; 3228 PPTBuGraEntry* pPtr = nullptr; 3229 if ( nInstance < aBuGraList.size() ) 3230 { 3231 pPtr = aBuGraList[ nInstance ].get(); 3232 if ( pPtr->nInstance == nInstance ) 3233 bRetValue = true; 3234 } 3235 if ( !bRetValue ) 3236 { 3237 for (std::unique_ptr<PPTBuGraEntry> const & i : aBuGraList) 3238 { 3239 pPtr = i.get(); 3240 if ( pPtr->nInstance == nInstance ) 3241 { 3242 bRetValue = true; 3243 break; 3244 } 3245 } 3246 } 3247 if ( bRetValue ) 3248 rGraph = pPtr->aBuGra; 3249 return bRetValue; 3250 } 3251 3252 PPTExtParaProv::PPTExtParaProv( SdrPowerPointImport& rMan, SvStream& rSt, const DffRecordHeader* pHd ) : 3253 bStyles ( false ) 3254 { 3255 sal_uInt32 nOldPos = rSt.Tell(); 3256 3257 // here we have to get the graphical bullets... 3258 3259 DffRecordHeader aHd; 3260 DffRecordHeader aContentDataHd; 3261 3262 const DffRecordHeader* pListHd = rMan.aDocRecManager.GetRecordHeader( PPT_PST_List ); 3263 if( pListHd ) 3264 pListHd->SeekToContent( rSt ); 3265 if ( pListHd && SdrPowerPointImport::SeekToContentOfProgTag( 9, rSt, *pListHd, aContentDataHd ) ) 3266 { 3267 auto nEndRecPos = DffPropSet::SanitizeEndPos(rSt, aContentDataHd.GetRecEndFilePos()); 3268 while ( ( rSt.GetError() == ERRCODE_NONE ) && ( rSt.Tell() < nEndRecPos ) ) 3269 { 3270 ReadDffRecordHeader( rSt, aHd ); 3271 switch ( aHd.nRecType ) 3272 { 3273 case PPT_PST_ExtendedBuGraContainer : 3274 { 3275 auto nHdEndRecPos = DffPropSet::SanitizeEndPos(rSt, aHd.GetRecEndFilePos()); 3276 while ( ( rSt.GetError() == ERRCODE_NONE ) && ( rSt.Tell() < nHdEndRecPos ) ) 3277 { 3278 DffRecordHeader aBuGraAtomHd; 3279 ReadDffRecordHeader( rSt, aBuGraAtomHd ); 3280 if ( aBuGraAtomHd.nRecType == PPT_PST_ExtendedBuGraAtom ) 3281 { 3282 sal_uInt16 nType; 3283 rSt.ReadUInt16( nType ); 3284 Graphic aGraphic; 3285 if ( SvxMSDffManager::GetBLIPDirect( rSt, aGraphic ) ) 3286 { 3287 sal_uInt32 nInstance = aBuGraAtomHd.nRecInstance; 3288 PPTBuGraEntry* pBuGra = new PPTBuGraEntry( std::move(aGraphic), nInstance ); 3289 size_t n = 0; 3290 size_t nBuGraCount = aBuGraList.size(); 3291 if ( nBuGraCount ) 3292 { 3293 if ( aBuGraList[ nBuGraCount - 1 ]->nInstance < nInstance ) 3294 n = nBuGraCount; 3295 else 3296 { // maybe the instances are not sorted, we sort it 3297 for ( n = 0; n < nBuGraCount; n++ ) 3298 { // sorting fields ( hi >> lo ) 3299 if ( aBuGraList[ n ]->nInstance < nInstance ) 3300 break; 3301 } 3302 } 3303 } 3304 if ( n < nBuGraCount ) { 3305 aBuGraList.emplace( aBuGraList.begin() + n, pBuGra ); 3306 } else { 3307 aBuGraList.emplace_back( pBuGra ); 3308 } 3309 } 3310 #ifdef DBG_UTIL 3311 else OSL_FAIL( "PPTExParaProv::PPTExParaProv - bullet graphic is not valid (SJ)" ); 3312 #endif 3313 } 3314 #ifdef DBG_UTIL 3315 else OSL_FAIL( "PPTExParaProv::PPTExParaProv - unknown atom interpreting the PPT_PST_ExtendedBuGraContainer (SJ)" ); 3316 #endif 3317 if (!aBuGraAtomHd.SeekToEndOfRecord(rSt)) 3318 break; 3319 } 3320 } 3321 break; 3322 3323 case PPT_PST_ExtendedPresRuleContainer : 3324 aExtendedPresRules.Consume( rSt, aHd.GetRecEndFilePos() ); 3325 break; 3326 #ifdef DBG_UTIL 3327 default : 3328 OSL_FAIL( "PPTExParaProv::PPTExParaProv - unknown atom reading ppt2000 num rules (SJ)" ); 3329 break; 3330 case PPT_PST_MasterText : // first seen in: ms-tt02.ppt 3331 case PPT_PST_SrKinsoku : 3332 case PPT_PST_TextDefaults9Atom : 3333 case PPT_PST_PresentationAdvisorFlags9Atom : 3334 case PPT_PST_HtmlDocInfo9Atom : 3335 case PPT_PST_GridSpacing10Atom : 3336 case PPT_PST_CommentIndex10 : 3337 case PPT_PST_DocToolbarStates10Atom : 3338 break; 3339 #endif 3340 } 3341 if (!aHd.SeekToEndOfRecord(rSt)) 3342 break; 3343 } 3344 } 3345 3346 if ( pHd && SdrPowerPointImport::SeekToContentOfProgTag( 9, rSt, *pHd, aContentDataHd ) ) 3347 { // get the extended paragraph styles on mainmaster ( graphical bullets, num ruling ... ) 3348 auto nEndRecPos = DffPropSet::SanitizeEndPos(rSt, aContentDataHd.GetRecEndFilePos()); 3349 while ( ( rSt.GetError() == ERRCODE_NONE ) && ( rSt.Tell() < nEndRecPos ) ) 3350 { 3351 ReadDffRecordHeader( rSt, aHd ); 3352 switch ( aHd.nRecType ) 3353 { 3354 case PPT_PST_ExtendedParagraphMasterAtom : 3355 { 3356 if ( aHd.nRecInstance < PPT_STYLESHEETENTRIES ) 3357 { 3358 sal_uInt16 nDepth = 0, i = 0; 3359 rSt.ReadUInt16(nDepth); 3360 nDepth = std::min<sal_uInt16>(nDepth, nMaxPPTLevels); 3361 auto nHdEndRecPos = DffPropSet::SanitizeEndPos(rSt, aHd.GetRecEndFilePos()); 3362 while ( ( rSt.GetError() == ERRCODE_NONE ) && ( rSt.Tell() < nHdEndRecPos ) && ( i < nDepth ) ) 3363 { 3364 bStyles = true; 3365 ReadPPTExtParaLevel( rSt, aExtParaSheet[ static_cast<TSS_Type>(aHd.nRecInstance) ].aExtParaLevel[ i++ ] ); 3366 } 3367 #ifdef DBG_UTIL 3368 if ( rSt.Tell() != aHd.GetRecEndFilePos() ) 3369 OSL_FAIL( "PPTExParaProv::PPTExParaProv - error reading PPT_PST_ExtendedParagraphMasterAtom (SJ)" ); 3370 #endif 3371 } 3372 #ifdef DBG_UTIL 3373 else OSL_FAIL( "PPTExParaProv::PPTExParaProv - instance out of range (SJ)" ); 3374 #endif 3375 } 3376 break; 3377 default : 3378 OSL_FAIL( "PPTExParaProv::PPTExParaProv - unknown atom, assuming PPT_PST_ExtendedParagraphMasterAtom (SJ)" ); 3379 break; 3380 case PPT_PST_HashCodeAtom : 3381 case PPT_PST_BuildList : 3382 case PPT_PST_SlideFlags10Atom : 3383 case PPT_PST_SlideTime10Atom : 3384 case 0xf144 : 3385 break; 3386 } 3387 if (!aHd.SeekToEndOfRecord(rSt)) 3388 break; 3389 } 3390 } 3391 rSt.Seek( nOldPos ); 3392 } 3393 3394 PPTExtParaProv::~PPTExtParaProv() 3395 { 3396 } 3397 3398 PPTNumberFormatCreator::PPTNumberFormatCreator( std::unique_ptr<PPTExtParaProv> pParaProv ) 3399 : nIsBullet(0) 3400 , nBulletChar(0) 3401 , nBulletFont(0) 3402 , nBulletHeight(0) 3403 , nBulletColor(0) 3404 , nTextOfs(0) 3405 , nBulletOfs(0) 3406 , pExtParaProv(std::move(pParaProv)) 3407 { 3408 } 3409 3410 PPTNumberFormatCreator::~PPTNumberFormatCreator() 3411 { 3412 } 3413 3414 bool PPTNumberFormatCreator::ImplGetExtNumberFormat( SdrPowerPointImport const & rManager, 3415 SvxNumberFormat& rNumberFormat, sal_uInt32 nLevel, TSS_Type nInstance, TSS_Type nDestinationInstance, 3416 std::optional< sal_Int16 >& rStartNumbering, sal_uInt32 nFontHeight, PPTParagraphObj const * pPara ) 3417 { 3418 bool bHardAttribute = ( nDestinationInstance == TSS_Type::Unknown ); 3419 3420 sal_uInt32 nBuFlags = 0; 3421 sal_uInt16 nHasAnm = 0; 3422 sal_uInt32 nAnmScheme = 0xFFFF0003; 3423 sal_uInt16 nBuBlip = 0xffff; 3424 3425 const PPTExtParaProv* pParaProv = pExtParaProv.get(); 3426 if ( !pExtParaProv ) 3427 pParaProv = pPara ? pPara->mrStyleSheet.pExtParaProv.get() 3428 : rManager.m_pPPTStyleSheet->pExtParaProv.get(); 3429 if ( pPara ) 3430 { 3431 nBuFlags = pPara->mxParaSet->mnExtParagraphMask; 3432 if ( nBuFlags ) 3433 { 3434 if ( nBuFlags & 0x00800000 ) 3435 nBuBlip = pPara->mxParaSet->mnBuBlip; 3436 if ( nBuFlags & 0x01000000 ) 3437 nAnmScheme = pPara->mxParaSet->mnAnmScheme; 3438 if ( nBuFlags & 0x02000000 ) 3439 nHasAnm = pPara->mxParaSet->mnHasAnm; 3440 bHardAttribute = true; 3441 } 3442 } 3443 3444 if ( ( nBuFlags & 0x03800000 ) != 0x03800000 ) // merge style sheet 3445 { 3446 // we have to read the master attributes 3447 if (pParaProv && nLevel < nMaxPPTLevels) 3448 { 3449 if ( pParaProv->bStyles ) 3450 { 3451 const PPTExtParaLevel& rLev = pParaProv->aExtParaSheet[ nInstance ].aExtParaLevel[ nLevel ]; 3452 if ( rLev.mbSet ) 3453 { 3454 sal_uInt32 nMaBuFlags = rLev.mnExtParagraphMask; 3455 3456 if ( (!( nBuFlags & 0x00800000)) && ( nMaBuFlags & 0x00800000 ) ) 3457 { 3458 if (!( nBuFlags & 0x02000000)) // if there is a BuStart without BuInstance, 3459 nBuBlip = rLev.mnBuBlip; // then there is no graphical Bullet possible 3460 } 3461 if ( (!( nBuFlags & 0x01000000)) && ( nMaBuFlags & 0x01000000 ) ) 3462 nAnmScheme = rLev.mnAnmScheme; 3463 if ( (!( nBuFlags & 0x02000000)) && ( nMaBuFlags & 0x02000000 ) ) 3464 nHasAnm = rLev.mnHasAnm; 3465 nBuFlags |= nMaBuFlags; 3466 } 3467 } 3468 } 3469 } 3470 if ( nBuBlip != 0xffff ) // set graphical bullet 3471 { 3472 Graphic aGraphic; 3473 if ( pParaProv && pParaProv->GetGraphic( nBuBlip, aGraphic ) ) 3474 { 3475 SvxBrushItem aBrush( aGraphic, GPOS_MM, SID_ATTR_BRUSH ); 3476 rNumberFormat.SetGraphicBrush( &aBrush ); 3477 sal_uInt32 nHeight = static_cast<sal_uInt32>( static_cast<double>(nFontHeight) * 0.2540 * nBulletHeight + 0.5 ); 3478 Size aPrefSize( aGraphic.GetPrefSize() ); 3479 sal_uInt32 nWidth; 3480 if (aPrefSize.Height()) 3481 nWidth = ( nHeight * aPrefSize.Width() ) / aPrefSize.Height(); 3482 else 3483 nWidth = 0; 3484 rNumberFormat.SetGraphicSize( Size( nWidth, nHeight ) ); 3485 rNumberFormat.SetNumberingType ( SVX_NUM_BITMAP ); 3486 } 3487 } 3488 else if ( nHasAnm ) 3489 { 3490 switch( static_cast< sal_uInt16 >( nAnmScheme ) ) 3491 { 3492 default : 3493 case 0 : 3494 { 3495 rNumberFormat.SetNumberingType( SVX_NUM_CHARS_LOWER_LETTER ); 3496 rNumberFormat.SetListFormat("", ".", nLevel); 3497 } 3498 break; 3499 case 1 : 3500 { 3501 rNumberFormat.SetNumberingType( SVX_NUM_CHARS_UPPER_LETTER ); 3502 rNumberFormat.SetListFormat("", ".", nLevel); 3503 } 3504 break; 3505 case 2 : 3506 { 3507 rNumberFormat.SetNumberingType( SVX_NUM_ARABIC ); 3508 rNumberFormat.SetListFormat("", ")", nLevel); 3509 } 3510 break; 3511 case 3 : 3512 { 3513 rNumberFormat.SetNumberingType( SVX_NUM_ARABIC ); 3514 rNumberFormat.SetListFormat("", ".", nLevel); 3515 } 3516 break; 3517 case 4 : 3518 { 3519 rNumberFormat.SetNumberingType( SVX_NUM_ROMAN_LOWER ); 3520 rNumberFormat.SetListFormat("(", ")", nLevel); 3521 } 3522 break; 3523 case 5 : 3524 { 3525 rNumberFormat.SetNumberingType( SVX_NUM_ROMAN_LOWER ); 3526 rNumberFormat.SetListFormat("", ")", nLevel); 3527 } 3528 break; 3529 case 6 : 3530 { 3531 rNumberFormat.SetNumberingType( SVX_NUM_ROMAN_LOWER ); 3532 rNumberFormat.SetListFormat("", ".", nLevel); 3533 } 3534 break; 3535 case 7 : 3536 { 3537 rNumberFormat.SetNumberingType( SVX_NUM_ROMAN_UPPER ); 3538 rNumberFormat.SetListFormat("", ".", nLevel); 3539 } 3540 break; 3541 case 8 : 3542 { 3543 rNumberFormat.SetNumberingType( SVX_NUM_CHARS_LOWER_LETTER ); 3544 rNumberFormat.SetListFormat("(", ")", nLevel); 3545 } 3546 break; 3547 case 9 : 3548 { 3549 rNumberFormat.SetNumberingType( SVX_NUM_CHARS_LOWER_LETTER ); 3550 rNumberFormat.SetListFormat("", ")", nLevel); 3551 } 3552 break; 3553 case 10 : 3554 { 3555 rNumberFormat.SetNumberingType( SVX_NUM_CHARS_UPPER_LETTER ); 3556 rNumberFormat.SetListFormat("(", ")", nLevel); 3557 } 3558 break; 3559 case 11 : 3560 { 3561 rNumberFormat.SetNumberingType( SVX_NUM_CHARS_UPPER_LETTER ); 3562 rNumberFormat.SetListFormat("", ")", nLevel); 3563 } 3564 break; 3565 case 12 : 3566 { 3567 rNumberFormat.SetNumberingType( SVX_NUM_ARABIC ); 3568 rNumberFormat.SetListFormat("(", ")", nLevel); 3569 } 3570 break; 3571 case 13 : 3572 { 3573 rNumberFormat.SetNumberingType( SVX_NUM_ARABIC ); 3574 } 3575 break; 3576 case 14 : 3577 { 3578 rNumberFormat.SetNumberingType( SVX_NUM_ROMAN_UPPER ); 3579 rNumberFormat.SetListFormat("(", ")", nLevel); 3580 } 3581 break; 3582 case 15 : 3583 { 3584 rNumberFormat.SetNumberingType( SVX_NUM_ROMAN_UPPER ); 3585 rNumberFormat.SetListFormat("", ")", nLevel); 3586 } 3587 break; 3588 case 16: // Simplified Chinese. 3589 { 3590 rNumberFormat.SetNumberingType( SVX_NUM_NUMBER_UPPER_ZH ); 3591 } 3592 break; 3593 case 17: // Simplified Chinese with single-byte period. 3594 { 3595 rNumberFormat.SetNumberingType( SVX_NUM_NUMBER_UPPER_ZH ); 3596 rNumberFormat.SetListFormat("", ".", nLevel); 3597 } 3598 break; 3599 case 18: // Double byte circle numbers. 3600 case 19: // Wingdings white circle numbers. 3601 case 20: // Wingdings black circle numbers. 3602 { 3603 rNumberFormat.SetNumberingType( SVX_NUM_CIRCLE_NUMBER ); 3604 } 3605 break; 3606 case 21: // Traditional Chinese. 3607 { 3608 rNumberFormat.SetNumberingType( SVX_NUM_NUMBER_UPPER_ZH_TW ); 3609 } 3610 break; 3611 case 22: // Traditional Chinese with single-byte period. 3612 { 3613 rNumberFormat.SetNumberingType( SVX_NUM_NUMBER_UPPER_ZH_TW ); 3614 rNumberFormat.SetListFormat("", ".", nLevel); 3615 } 3616 break; 3617 case 25: // Bidi Hebrew 2 with ANSI minus symbol. 3618 { 3619 rNumberFormat.SetNumberingType( SVX_NUM_NUMBER_HEBREW ); 3620 rNumberFormat.SetListFormat("", "-", nLevel); 3621 } 3622 break; 3623 case 26: // Japanese/Korean. 3624 { 3625 rNumberFormat.SetNumberingType( SVX_NUM_NUMBER_LOWER_ZH ); 3626 } 3627 break; 3628 case 27: // Japanese/Korean with single-byte period. 3629 { 3630 rNumberFormat.SetNumberingType( SVX_NUM_NUMBER_LOWER_ZH ); 3631 rNumberFormat.SetListFormat("", ".", nLevel); 3632 } 3633 break; 3634 case 28: // Double-byte Arabic numbers. 3635 { 3636 rNumberFormat.SetNumberingType( SVX_NUM_FULL_WIDTH_ARABIC ); 3637 } 3638 break; 3639 case 29: // Double-byte Arabic numbers with double-byte period. 3640 { 3641 rNumberFormat.SetNumberingType( SVX_NUM_FULL_WIDTH_ARABIC ); 3642 rNumberFormat.SetListFormat("", OUString(u'\xff0e'), nLevel); 3643 } 3644 break; 3645 case 38: // Japanese with double-byte period. 3646 { 3647 rNumberFormat.SetNumberingType( SVX_NUM_NUMBER_LOWER_ZH ); // No such type. Instead with Lower Chinese Number 3648 rNumberFormat.SetListFormat("", OUString(u'\xff0e'), nLevel); 3649 } 3650 break; 3651 } 3652 rStartNumbering = std::optional< sal_Int16 >( nAnmScheme >> 16 ); 3653 sal_Int16 nBuStart = *rStartNumbering; 3654 //The Seventh bit of nBuFlags that specifies whether fBulletHasAutoNumber exists, 3655 //and fBulletHasAutoNumber that specifies whether this paragraph has an automatic numbering scheme. 3656 if ( ( nBuFlags & 0x02000000 ) && ( nBuStart != -1 )) 3657 { 3658 rNumberFormat.SetStart( static_cast<sal_uInt16>(nBuStart) ); 3659 } 3660 } 3661 return bHardAttribute; 3662 } 3663 3664 void PPTNumberFormatCreator::GetNumberFormat( SdrPowerPointImport const & rManager, SvxNumberFormat& rNumberFormat, sal_uInt32 nLevel, const PPTParaLevel& rParaLevel, const PPTCharLevel& rCharLevel, TSS_Type nInstance ) 3665 { 3666 nIsBullet = ( rParaLevel.mnBuFlags & ( 1 << PPT_ParaAttr_BulletOn ) ) != 0 ? 1 : 0; 3667 nBulletChar = rParaLevel.mnBulletChar; 3668 3669 bool bBuHardFont; 3670 bBuHardFont = ( rParaLevel.mnBuFlags & ( 1 << PPT_ParaAttr_BuHardFont ) ) != 0; 3671 if ( bBuHardFont ) 3672 nBulletFont = rParaLevel.mnBulletFont; 3673 else 3674 nBulletFont = rCharLevel.mnFont; 3675 nBulletHeight = rParaLevel.mnBulletHeight; 3676 nBulletColor = rParaLevel.mnBulletColor; 3677 nTextOfs = rParaLevel.mnTextOfs; 3678 nBulletOfs = rParaLevel.mnBulletOfs; 3679 3680 std::optional< sal_Int16 > oStartNumbering; 3681 ImplGetExtNumberFormat( rManager, rNumberFormat, nLevel, nInstance, TSS_Type::Unknown, oStartNumbering, rCharLevel.mnFontHeight, nullptr ); 3682 if ( ( rNumberFormat.GetNumberingType() != SVX_NUM_BITMAP ) && ( nBulletHeight > 0x7fff ) ) 3683 nBulletHeight = rCharLevel.mnFontHeight ? ((- static_cast<sal_Int16>(nBulletHeight)) * 100 ) / rCharLevel.mnFontHeight : 100; 3684 ImplGetNumberFormat( rManager, rNumberFormat ); 3685 switch ( rNumberFormat.GetNumberingType() ) 3686 { 3687 case SVX_NUM_CHARS_UPPER_LETTER : 3688 case SVX_NUM_CHARS_LOWER_LETTER : 3689 case SVX_NUM_ROMAN_UPPER : 3690 case SVX_NUM_ROMAN_LOWER : 3691 case SVX_NUM_ARABIC : 3692 case SVX_NUM_CHARS_UPPER_LETTER_N : 3693 case SVX_NUM_CHARS_LOWER_LETTER_N : 3694 { 3695 sal_uInt32 nFont = rCharLevel.mnFont; 3696 const PptFontEntityAtom* pFontEnityAtom = rManager.GetFontEnityAtom( nFont ); 3697 if ( pFontEnityAtom ) 3698 { 3699 vcl::Font aFont; 3700 aFont.SetCharSet( pFontEnityAtom->eCharSet ); 3701 aFont.SetFamilyName( pFontEnityAtom->aName ); 3702 aFont.SetFamily( pFontEnityAtom->eFamily ); 3703 aFont.SetPitch( pFontEnityAtom->ePitch ); 3704 rNumberFormat.SetBulletFont( &aFont ); 3705 } 3706 } 3707 break; 3708 default: break; 3709 } 3710 } 3711 3712 bool PPTNumberFormatCreator::GetNumberFormat( SdrPowerPointImport const & rManager, SvxNumberFormat& rNumberFormat, PPTParagraphObj* pParaObj, 3713 TSS_Type nDestinationInstance, std::optional< sal_Int16 >& rStartNumbering ) 3714 { 3715 sal_uInt32 nHardCount = 0; 3716 nHardCount += pParaObj->GetAttrib( PPT_ParaAttr_BulletOn, nIsBullet, nDestinationInstance ) ? 1 : 0; 3717 nHardCount += pParaObj->GetAttrib( PPT_ParaAttr_BulletChar, nBulletChar, nDestinationInstance ) ? 1 : 0; 3718 nHardCount += pParaObj->GetAttrib( PPT_ParaAttr_BulletFont, nBulletFont, nDestinationInstance ) ? 1 : 0; 3719 nHardCount += pParaObj->GetAttrib( PPT_ParaAttr_BulletHeight, nBulletHeight, nDestinationInstance ) ? 1 : 0; 3720 nHardCount += pParaObj->GetAttrib( PPT_ParaAttr_BulletColor, nBulletColor, nDestinationInstance ) ? 1 : 0; 3721 nHardCount += pParaObj->GetAttrib( PPT_ParaAttr_TextOfs, nTextOfs, nDestinationInstance ) ? 1 : 0; 3722 nHardCount += pParaObj->GetAttrib( PPT_ParaAttr_BulletOfs, nBulletOfs, nDestinationInstance ) ? 1 : 0; 3723 3724 if ( nIsBullet ) 3725 rNumberFormat.SetNumberingType( SVX_NUM_CHAR_SPECIAL ); 3726 3727 sal_uInt32 nFontHeight = 24; 3728 PPTPortionObj* pPtr = pParaObj->First(); 3729 if ( pPtr ) 3730 pPtr->GetAttrib( PPT_CharAttr_FontHeight, nFontHeight, nDestinationInstance ); 3731 if ( nIsBullet ) 3732 nHardCount += ImplGetExtNumberFormat( rManager, rNumberFormat, pParaObj->mxParaSet->mnDepth, 3733 pParaObj->mnInstance, nDestinationInstance, rStartNumbering, nFontHeight, pParaObj ) ? 1 : 0; 3734 3735 if ( rNumberFormat.GetNumberingType() != SVX_NUM_BITMAP ) 3736 pParaObj->UpdateBulletRelSize( nBulletHeight ); 3737 if ( nHardCount ) 3738 { 3739 ImplGetNumberFormat( rManager, rNumberFormat ); 3740 switch ( rNumberFormat.GetNumberingType() ) 3741 { 3742 case SVX_NUM_CHARS_UPPER_LETTER : 3743 case SVX_NUM_CHARS_LOWER_LETTER : 3744 case SVX_NUM_ROMAN_UPPER : 3745 case SVX_NUM_ROMAN_LOWER : 3746 case SVX_NUM_ARABIC : 3747 case SVX_NUM_CHARS_UPPER_LETTER_N : 3748 case SVX_NUM_CHARS_LOWER_LETTER_N : 3749 { 3750 if ( pPtr ) 3751 { 3752 sal_uInt32 nFont; 3753 pPtr->GetAttrib( PPT_CharAttr_Font, nFont, nDestinationInstance ); 3754 const PptFontEntityAtom* pFontEnityAtom = rManager.GetFontEnityAtom( nFont ); 3755 if ( pFontEnityAtom ) 3756 { 3757 vcl::Font aFont; 3758 aFont.SetCharSet( pFontEnityAtom->eCharSet ); 3759 aFont.SetFamilyName( pFontEnityAtom->aName ); 3760 aFont.SetFamily( pFontEnityAtom->eFamily ); 3761 aFont.SetPitch( pFontEnityAtom->ePitch ); 3762 rNumberFormat.SetBulletFont( &aFont ); 3763 } 3764 } 3765 } 3766 break; 3767 default: break; 3768 } 3769 } 3770 return nHardCount != 0; 3771 } 3772 3773 void PPTNumberFormatCreator::ImplGetNumberFormat( SdrPowerPointImport const & rManager, SvxNumberFormat& rNumberFormat ) 3774 { 3775 vcl::Font aFont; 3776 const PptFontEntityAtom* pAtom = rManager.GetFontEnityAtom( nBulletFont ); 3777 if ( pAtom ) 3778 { 3779 rtl_TextEncoding eCharSet( pAtom->eCharSet ); 3780 aFont.SetFamilyName( pAtom->aName ); 3781 aFont.SetCharSet( eCharSet ); 3782 aFont.SetFamily( pAtom->eFamily ); 3783 aFont.SetPitch( pAtom->ePitch ); 3784 } 3785 Color aCol( rManager.MSO_TEXT_CLR_ToColor( nBulletColor ) ); 3786 aFont.SetColor( aCol ); 3787 3788 sal_uInt16 nBuChar = static_cast<sal_uInt16>(nBulletChar); 3789 if ( aFont.GetCharSet() == RTL_TEXTENCODING_SYMBOL ) 3790 { 3791 nBuChar &= 0x00ff; 3792 nBuChar |= 0xf000; 3793 } 3794 rNumberFormat.SetBulletFont( &aFont ); 3795 rNumberFormat.SetBulletChar( nBuChar ); 3796 rNumberFormat.SetBulletRelSize( static_cast<sal_uInt16>(nBulletHeight) ); 3797 rNumberFormat.SetBulletColor( aCol ); 3798 sal_uInt32 nAbsLSpace = convertMasterUnitToMm100(nTextOfs); 3799 sal_uInt32 nFirstLineOffset = nAbsLSpace - convertMasterUnitToMm100(nBulletOfs); 3800 rNumberFormat.SetAbsLSpace( nAbsLSpace ); 3801 rNumberFormat.SetFirstLineOffset( -static_cast<sal_Int32>(nFirstLineOffset) ); 3802 } 3803 3804 PPTCharSheet::PPTCharSheet( TSS_Type nInstance ) 3805 { 3806 sal_uInt32 nColor = PPT_COLSCHEME_TEXT_UND_ZEILEN; 3807 sal_uInt16 nFontHeight(0); 3808 switch ( nInstance ) 3809 { 3810 case TSS_Type::PageTitle : 3811 case TSS_Type::Title : 3812 { 3813 nColor = PPT_COLSCHEME_TITELTEXT; 3814 nFontHeight = 44; 3815 } 3816 break; 3817 case TSS_Type::Body : 3818 case TSS_Type::Subtitle : 3819 case TSS_Type::HalfBody : 3820 case TSS_Type::QuarterBody : 3821 nFontHeight = 32; 3822 break; 3823 case TSS_Type::Notes : 3824 nFontHeight = 12; 3825 break; 3826 case TSS_Type::Unused : 3827 case TSS_Type::TextInShape : 3828 nFontHeight = 24; 3829 break; 3830 default: break; 3831 } 3832 for (PPTCharLevel & nDepth : maCharLevel) 3833 { 3834 nDepth.mnFlags = 0; 3835 nDepth.mnFont = 0; 3836 nDepth.mnAsianOrComplexFont = 0xffff; 3837 nDepth.mnFontHeight = nFontHeight; 3838 nDepth.mnFontColor = nColor; 3839 nDepth.mnFontColorInStyleSheet = Color( static_cast<sal_uInt8>(nColor), static_cast<sal_uInt8>( nColor >> 8 ), static_cast<sal_uInt8>( nColor >> 16 ) ); 3840 nDepth.mnEscapement = 0; 3841 } 3842 } 3843 3844 void PPTCharSheet::Read( SvStream& rIn, sal_uInt32 nLevel) 3845 { 3846 // character attributes 3847 sal_uInt32 nCMask(0); 3848 sal_uInt16 nVal16; 3849 rIn.ReadUInt32(nCMask); 3850 3851 if ( nCMask & 0x0000FFFF ) 3852 { 3853 sal_uInt16 nBitAttr(0); 3854 maCharLevel[ nLevel ].mnFlags &= ~static_cast<sal_uInt16>(nCMask); 3855 rIn.ReadUInt16( nBitAttr ); // Bit attributes (bold, underlined, ...) 3856 maCharLevel[ nLevel ].mnFlags |= nBitAttr; 3857 } 3858 if ( nCMask & ( 1 << PPT_CharAttr_Font ) ) // 0x00010000 3859 rIn.ReadUInt16( maCharLevel[ nLevel ].mnFont ); 3860 if ( nCMask & ( 1 << PPT_CharAttr_AsianOrComplexFont ) ) // 0x00200000 3861 rIn.ReadUInt16( maCharLevel[ nLevel ].mnAsianOrComplexFont ); 3862 if ( nCMask & ( 1 << PPT_CharAttr_ANSITypeface ) ) // 0x00400000 3863 rIn.ReadUInt16( nVal16 ); 3864 if ( nCMask & ( 1 << PPT_CharAttr_Symbol ) ) // 0x00800000 3865 rIn.ReadUInt16( nVal16 ); 3866 if ( nCMask & ( 1 << PPT_CharAttr_FontHeight ) ) // 0x00020000 3867 rIn.ReadUInt16( maCharLevel[ nLevel ].mnFontHeight ); 3868 if ( nCMask & ( 1 << PPT_CharAttr_FontColor ) ) // 0x00040000 3869 { 3870 rIn.ReadUInt32( maCharLevel[ nLevel ].mnFontColor ); 3871 if( ! (maCharLevel[ nLevel ].mnFontColor & 0xff000000 ) ) 3872 maCharLevel[ nLevel ].mnFontColor = PPT_COLSCHEME_HINTERGRUND; 3873 } 3874 if ( nCMask & ( 1 << PPT_CharAttr_Escapement ) ) // 0x00080000 3875 rIn.ReadUInt16( maCharLevel[ nLevel ].mnEscapement ); 3876 if ( nCMask & 0x00100000 ) // 0x00100000 3877 rIn.ReadUInt16( nVal16 ); 3878 3879 nCMask >>= 24; 3880 while( nCMask ) 3881 { 3882 if ( nCMask & 1 ) 3883 { 3884 OSL_FAIL( "PPTCharSheet::Read - unknown attribute, send me this document (SJ)" ); 3885 rIn.ReadUInt16( nVal16 ); 3886 } 3887 nCMask >>= 1; 3888 } 3889 } 3890 3891 PPTParaSheet::PPTParaSheet( TSS_Type nInstance ) 3892 { 3893 sal_uInt16 nBuFlags = 0; 3894 sal_uInt32 nBulletColor = 0x8000000; 3895 sal_uInt16 nUpperDist = 0; 3896 3897 switch ( nInstance ) 3898 { 3899 case TSS_Type::PageTitle : 3900 case TSS_Type::Title : 3901 nBulletColor = PPT_COLSCHEME_TITELTEXT; 3902 break; 3903 case TSS_Type::Body : 3904 case TSS_Type::Subtitle : 3905 case TSS_Type::HalfBody : 3906 case TSS_Type::QuarterBody : 3907 { 3908 nBuFlags = 1; 3909 nUpperDist = 0x14; 3910 } 3911 break; 3912 case TSS_Type::Notes : 3913 nUpperDist = 0x1e; 3914 break; 3915 default: break; 3916 } 3917 for (PPTParaLevel & i : maParaLevel) 3918 { 3919 i.mnBuFlags = nBuFlags; 3920 i.mnBulletChar = 0x2022; 3921 i.mnBulletFont = 0; 3922 i.mnBulletHeight = 100; 3923 i.mnBulletColor = nBulletColor; 3924 i.mnAdjust = 0; 3925 i.mnLineFeed = 100; 3926 i.mnLowerDist = 0; 3927 i.mnUpperDist = nUpperDist; 3928 i.mnTextOfs = 0; 3929 i.mnBulletOfs = 0; 3930 i.mnDefaultTab = 0x240; 3931 i.mnAsianLineBreak = 0; 3932 i.mnBiDi = 0; 3933 } 3934 } 3935 3936 void PPTParaSheet::Read( SdrPowerPointImport const & 3937 #ifdef DBG_UTIL 3938 rManager 3939 #endif 3940 , SvStream& rIn 3941 , sal_uInt32 nLevel, bool bFirst ) 3942 { 3943 // paragraph attributes 3944 sal_uInt32 nPMask(0); 3945 rIn.ReadUInt32(nPMask); 3946 3947 sal_uInt16 nMask16 = static_cast<sal_uInt16>(nPMask) & 0xf; 3948 if ( nMask16 ) 3949 { 3950 sal_uInt16 nVal16(0); 3951 rIn.ReadUInt16( nVal16 ); 3952 maParaLevel[ nLevel ].mnBuFlags &=~ nMask16; 3953 nVal16 &= nMask16; 3954 maParaLevel[ nLevel ].mnBuFlags |= nVal16; 3955 } 3956 if ( nPMask & 0x0080 ) 3957 rIn.ReadUInt16( maParaLevel[ nLevel ].mnBulletChar ); 3958 if ( nPMask & 0x0010 ) 3959 rIn.ReadUInt16( maParaLevel[ nLevel ].mnBulletFont ); 3960 if ( nPMask & 0x0040 ) 3961 { 3962 sal_uInt16 nVal16(0); 3963 rIn.ReadUInt16( nVal16 ); 3964 maParaLevel[ nLevel ].mnBulletHeight = nVal16; 3965 } 3966 if ( nPMask & 0x0020 ) 3967 { 3968 sal_uInt32 nVal32(0); 3969 rIn.ReadUInt32(nVal32); 3970 maParaLevel[ nLevel ].mnBulletColor = nVal32; 3971 } 3972 if ( bFirst ) 3973 { 3974 if ( nPMask & 0xF00 ) 3975 { 3976 // AbsJust! 3977 sal_uInt16 nVal16(0); 3978 rIn.ReadUInt16( nVal16 ); 3979 maParaLevel[ nLevel ].mnAdjust = nVal16 & 3; 3980 } 3981 if ( nPMask & 0x1000 ) 3982 rIn.ReadUInt16( maParaLevel[ nLevel ].mnLineFeed ); 3983 if ( nPMask & 0x2000 ) 3984 rIn.ReadUInt16( maParaLevel[ nLevel ].mnUpperDist ); 3985 if ( nPMask & 0x4000 ) 3986 rIn.ReadUInt16( maParaLevel[ nLevel ].mnLowerDist ); 3987 if ( nPMask & 0x8000 ) 3988 rIn.ReadUInt16( maParaLevel[ nLevel ].mnTextOfs ); 3989 if ( nPMask & 0x10000 ) 3990 rIn.ReadUInt16( maParaLevel[ nLevel ].mnBulletOfs ); 3991 if ( nPMask & 0x20000 ) 3992 rIn.ReadUInt16( maParaLevel[ nLevel ].mnDefaultTab ); 3993 if ( nPMask & 0x200000 ) 3994 { 3995 sal_uInt16 nVal16; 3996 sal_uInt32 nVal32; 3997 // number of tabulators 3998 rIn.ReadUInt16( nVal16 ); 3999 if (!rIn.good() || rIn.remainingSize() / sizeof(nVal32) < nVal16) 4000 return; 4001 for (sal_uInt16 i = 0; i < nVal16; ++i) 4002 rIn.ReadUInt32( nVal32 ); // reading the tabulators 4003 } 4004 if ( nPMask & 0x40000 ) 4005 { 4006 sal_uInt16 nVal16; 4007 rIn.ReadUInt16( nVal16 ); 4008 } 4009 if ( nPMask & 0x80000 ) 4010 rIn.ReadUInt16( maParaLevel[ nLevel ].mnAsianLineBreak ); 4011 if ( nPMask & 0x100000 ) 4012 rIn.ReadUInt16( maParaLevel[ nLevel ].mnBiDi ); 4013 } 4014 else 4015 { 4016 if ( nPMask & 0x800 ) 4017 { 4018 sal_uInt16 nVal16(0); 4019 rIn.ReadUInt16( nVal16 ); 4020 maParaLevel[ nLevel ].mnAdjust = nVal16 & 3; 4021 } 4022 if ( nPMask & 0x1000 ) 4023 rIn.ReadUInt16( maParaLevel[ nLevel ].mnLineFeed ); 4024 if ( nPMask & 0x2000 ) 4025 rIn.ReadUInt16( maParaLevel[ nLevel ].mnUpperDist ); 4026 if ( nPMask & 0x4000 ) 4027 rIn.ReadUInt16( maParaLevel[ nLevel ].mnLowerDist ); 4028 if ( nPMask & 0x8000 ) 4029 { 4030 sal_uInt16 nVal16; 4031 rIn.ReadUInt16( nVal16 ); 4032 } 4033 if ( nPMask & 0x100 ) 4034 rIn.ReadUInt16( maParaLevel[ nLevel ].mnTextOfs ); 4035 if ( nPMask & 0x200 ) 4036 { 4037 sal_uInt16 nVal16; 4038 rIn.ReadUInt16( nVal16 ); 4039 } 4040 if ( nPMask & 0x400 ) 4041 rIn.ReadUInt16( maParaLevel[ nLevel ].mnBulletOfs ); 4042 if ( nPMask & 0x10000 ) 4043 { 4044 sal_uInt16 nVal16; 4045 rIn.ReadUInt16( nVal16 ); 4046 } 4047 if ( nPMask & 0xe0000 ) 4048 { 4049 sal_uInt16 nFlagsToModifyMask = static_cast<sal_uInt16>( ( nPMask >> 17 ) & 7 ); 4050 sal_uInt16 nVal16(0); 4051 rIn.ReadUInt16( nVal16 ); 4052 // bits that are not involved to zero 4053 nVal16 &= nFlagsToModifyMask; 4054 // bits that are to change to zero 4055 maParaLevel[ nLevel ].mnAsianLineBreak &=~nFlagsToModifyMask; 4056 // now set the corresponding bits 4057 maParaLevel[ nLevel ].mnAsianLineBreak |= nVal16; 4058 } 4059 if ( nPMask & 0x100000 ) 4060 { 4061 sal_uInt16 nVal16; 4062 sal_uInt32 nVal32; 4063 // number of tabulators 4064 rIn.ReadUInt16( nVal16 ); 4065 if (!rIn.good() || rIn.remainingSize() / sizeof(nVal32) < nVal16) 4066 return; 4067 for (sal_uInt16 i = 0; i < nVal16; ++i) 4068 rIn.ReadUInt32( nVal32 ); // reading the tabulators 4069 } 4070 if ( nPMask & 0x200000 ) 4071 rIn.ReadUInt16( maParaLevel[ nLevel ].mnBiDi ); 4072 } 4073 4074 nPMask >>= 22; 4075 while( nPMask ) 4076 { 4077 if ( nPMask & 1 ) 4078 { 4079 #ifdef DBG_UTIL 4080 if (!(rManager.rImportParam.nImportFlags & PPT_IMPORTFLAGS_NO_TEXT_ASSERT)) 4081 { 4082 OSL_FAIL( "PPTParaSheet::Read - unknown attribute, send me this document (SJ)" ); 4083 } 4084 #endif 4085 sal_uInt16 nVal16; 4086 rIn.ReadUInt16( nVal16 ); 4087 } 4088 nPMask >>= 1; 4089 } 4090 } 4091 4092 void PPTParaSheet::UpdateBulletRelSize( sal_uInt32 nLevel, sal_uInt16 nFontHeight ) 4093 { 4094 if ( maParaLevel[ nLevel ].mnBulletHeight > 0x7fff ) // a negative value is the absolute bullet height 4095 { 4096 sal_Int16 nBulletRelSize = static_cast<sal_Int16>(maParaLevel[ nLevel ].mnBulletHeight); 4097 nBulletRelSize = nFontHeight ? ((-nBulletRelSize) * 100 ) / nFontHeight : 100; 4098 if ( nBulletRelSize < 0 ) //bullet size over flow 4099 nBulletRelSize = 100; 4100 maParaLevel[ nLevel ].mnBulletHeight = nBulletRelSize; 4101 } 4102 } 4103 4104 PPTStyleSheet::PPTStyleSheet( const DffRecordHeader& rSlideHd, SvStream& rIn, SdrPowerPointImport& rManager, 4105 const PPTTextParagraphStyleAtomInterpreter& rTxPFStyle, 4106 const PPTTextSpecInfo& rTextSpecInfo ) : 4107 4108 PPTNumberFormatCreator ( std::make_unique<PPTExtParaProv>( rManager, rIn, &rSlideHd ) ), 4109 maTxSI ( rTextSpecInfo ) 4110 { 4111 sal_uInt32 nOldFilePos = rIn.Tell(); 4112 4113 // default stylesheets 4114 mpCharSheet[ TSS_Type::PageTitle ] = std::make_unique<PPTCharSheet>( TSS_Type::PageTitle ); 4115 mpCharSheet[ TSS_Type::Body ] = std::make_unique<PPTCharSheet>( TSS_Type::Body ); 4116 mpCharSheet[ TSS_Type::Notes ] = std::make_unique<PPTCharSheet>( TSS_Type::Notes ); 4117 mpCharSheet[ TSS_Type::Unused ] = std::make_unique<PPTCharSheet>( TSS_Type::Unused ); // this entry is not used by ppt 4118 mpCharSheet[ TSS_Type::TextInShape ] = std::make_unique<PPTCharSheet>( TSS_Type::TextInShape ); 4119 mpParaSheet[ TSS_Type::PageTitle ] = std::make_unique<PPTParaSheet>( TSS_Type::PageTitle ); 4120 mpParaSheet[ TSS_Type::Body ] = std::make_unique<PPTParaSheet>( TSS_Type::Body ); 4121 mpParaSheet[ TSS_Type::Notes ] = std::make_unique<PPTParaSheet>( TSS_Type::Notes ); 4122 mpParaSheet[ TSS_Type::Unused ] = std::make_unique<PPTParaSheet>( TSS_Type::Unused ); 4123 mpParaSheet[ TSS_Type::TextInShape ] = std::make_unique<PPTParaSheet>( TSS_Type::TextInShape ); 4124 // mpCharSheet[ TSS_Type::QuarterBody ], mpCharSheet[ TSS_Type::HalfBody ], mpCharSheet[ TSS_Type::Title ], mpCharSheet[ TSS_Type::Subtitle ] intentionally null 4125 // mpParaSheet[ TSS_Type::QuarterBody ], mpParaSheet[ TSS_Type::HalfBody ], mpParaSheet[ TSS_Type::Title ], mpParaSheet[ TSS_Type::Subtitle ] intentionally null 4126 4127 /* SJ: try to locate the txMasterStyleAtom in the Environment 4128 4129 it seems that the environment TextStyle is having a higher priority 4130 than the TextStyle that can be found within the master page 4131 */ 4132 bool bFoundTxMasterStyleAtom04 = false; 4133 DffRecordHeader* pEnvHeader = rManager.aDocRecManager.GetRecordHeader( PPT_PST_Environment ); 4134 if ( pEnvHeader ) 4135 { 4136 pEnvHeader->SeekToContent( rIn ); 4137 DffRecordHeader aTxMasterStyleHd; 4138 auto nEndRecPos = DffPropSet::SanitizeEndPos(rIn, pEnvHeader->GetRecEndFilePos()); 4139 while (rIn.Tell() < nEndRecPos) 4140 { 4141 ReadDffRecordHeader( rIn, aTxMasterStyleHd ); 4142 if ( aTxMasterStyleHd.nRecType == PPT_PST_TxMasterStyleAtom ) 4143 { 4144 sal_uInt16 nLevelCnt(0); 4145 rIn.ReadUInt16(nLevelCnt); 4146 4147 sal_uInt16 nLev = 0; 4148 bool bFirst = true; 4149 bFoundTxMasterStyleAtom04 = true; 4150 auto nTxEndRecPos = DffPropSet::SanitizeEndPos(rIn, aTxMasterStyleHd.GetRecEndFilePos()); 4151 while (rIn.GetError() == ERRCODE_NONE && rIn.Tell() < nTxEndRecPos && nLev < nLevelCnt && nLev < nMaxPPTLevels) 4152 { 4153 if ( nLev ) 4154 { 4155 mpParaSheet[ TSS_Type::TextInShape ]->maParaLevel[ nLev ] = mpParaSheet[ TSS_Type::TextInShape ]->maParaLevel[ nLev - 1 ]; 4156 mpCharSheet[ TSS_Type::TextInShape ]->maCharLevel[ nLev ] = mpCharSheet[ TSS_Type::TextInShape ]->maCharLevel[ nLev - 1 ]; 4157 } 4158 mpParaSheet[ TSS_Type::TextInShape ]->Read( rManager, rIn, nLev, bFirst ); 4159 if ( !nLev ) 4160 { 4161 // set paragraph defaults for instance 4 (TSS_Type::TextInShape) 4162 if ( rTxPFStyle.bValid ) 4163 { 4164 PPTParaLevel& rParaLevel = mpParaSheet[ TSS_Type::TextInShape ]->maParaLevel[ 0 ]; 4165 rParaLevel.mnAsianLineBreak = 0; 4166 if ( rTxPFStyle.bForbiddenRules ) 4167 rParaLevel.mnAsianLineBreak |= 1; 4168 if ( !rTxPFStyle.bLatinTextWrap ) 4169 rParaLevel.mnAsianLineBreak |= 2; 4170 if ( rTxPFStyle.bHangingPunctuation ) 4171 rParaLevel.mnAsianLineBreak |= 4; 4172 } 4173 } 4174 mpCharSheet[ TSS_Type::TextInShape ]->Read( rIn, nLev ); 4175 mpParaSheet[ TSS_Type::TextInShape ]->UpdateBulletRelSize( nLev, mpCharSheet[ TSS_Type::TextInShape ]->maCharLevel[ nLev ].mnFontHeight ); 4176 bFirst = false; 4177 nLev++; 4178 } 4179 break; 4180 } 4181 else 4182 { 4183 if (!aTxMasterStyleHd.SeekToEndOfRecord(rIn)) 4184 break; 4185 } 4186 } 4187 } 4188 4189 rSlideHd.SeekToContent( rIn ); 4190 4191 DffRecordHeader aTxMasterStyleHd; 4192 auto nEndRecPos = DffPropSet::SanitizeEndPos(rIn, rSlideHd.GetRecEndFilePos()); 4193 while (rIn.Tell() < nEndRecPos) 4194 { 4195 ReadDffRecordHeader( rIn, aTxMasterStyleHd ); 4196 if ( aTxMasterStyleHd.nRecType == PPT_PST_TxMasterStyleAtom ) 4197 break; 4198 else 4199 { 4200 if (!aTxMasterStyleHd.SeekToEndOfRecord(rIn)) 4201 break; 4202 } 4203 } 4204 while ( ( aTxMasterStyleHd.nRecType == PPT_PST_TxMasterStyleAtom ) && ( rIn.Tell() < nEndRecPos ) ) //TODO: aTxMasterStyleHd may be used without having been properly initialized 4205 { 4206 TSS_Type nInstance = static_cast<TSS_Type>(aTxMasterStyleHd.nRecInstance); 4207 if ( ( nInstance <= TSS_Type::LAST ) && 4208 ( ( nInstance != TSS_Type::TextInShape ) || !bFoundTxMasterStyleAtom04 ) ) 4209 { 4210 if ( nInstance > TSS_Type::TextInShape ) 4211 { 4212 mpCharSheet[ nInstance ].reset(); // be sure to delete the old one if this instance comes twice 4213 mpParaSheet[ nInstance ].reset(); 4214 4215 switch ( nInstance ) 4216 { 4217 case TSS_Type::Subtitle : 4218 { 4219 mpCharSheet[ TSS_Type::Subtitle ] = std::make_unique<PPTCharSheet>( *( mpCharSheet[ TSS_Type::Body ] ) ); 4220 mpParaSheet[ TSS_Type::Subtitle ] = std::make_unique<PPTParaSheet>( *( mpParaSheet[ TSS_Type::Body ] ) ); 4221 } 4222 break; 4223 case TSS_Type::Title : 4224 { 4225 mpCharSheet[ TSS_Type::Title ] = std::make_unique<PPTCharSheet>( *( mpCharSheet[ TSS_Type::PageTitle ] ) ); 4226 mpParaSheet[ TSS_Type::Title ] = std::make_unique<PPTParaSheet>( *( mpParaSheet[ TSS_Type::PageTitle ] ) ); 4227 } 4228 break; 4229 case TSS_Type::HalfBody : 4230 { 4231 mpCharSheet[ TSS_Type::HalfBody ] = std::make_unique<PPTCharSheet>( *( mpCharSheet[ TSS_Type::Body ] ) ); 4232 mpParaSheet[ TSS_Type::HalfBody ] = std::make_unique<PPTParaSheet>( *( mpParaSheet[ TSS_Type::Body ] ) ); 4233 } 4234 break; 4235 4236 case TSS_Type::QuarterBody : 4237 { 4238 mpCharSheet[ TSS_Type::QuarterBody ] = std::make_unique<PPTCharSheet>( *( mpCharSheet[ TSS_Type::Body ] ) ); 4239 mpParaSheet[ TSS_Type::QuarterBody ] = std::make_unique<PPTParaSheet>( *( mpParaSheet[ TSS_Type::Body ] ) ); 4240 } 4241 break; 4242 default: break; 4243 } 4244 } 4245 sal_uInt16 nLevelCnt(0); 4246 rIn.ReadUInt16(nLevelCnt); 4247 if (nLevelCnt > nMaxPPTLevels) 4248 { 4249 OSL_FAIL( "PPTStyleSheet::Ppt-TextStylesheet has more than 5 levels! (SJ)" ); 4250 nLevelCnt = nMaxPPTLevels; 4251 } 4252 sal_uInt16 nLev = 0; 4253 bool bFirst = true; 4254 4255 auto nTxEndRecPos = DffPropSet::SanitizeEndPos(rIn, aTxMasterStyleHd.GetRecEndFilePos()); 4256 while ( rIn.GetError() == ERRCODE_NONE && rIn.Tell() < nTxEndRecPos && nLev < nLevelCnt ) 4257 { 4258 if ( nLev && ( nInstance < TSS_Type::Subtitle ) ) 4259 { 4260 mpParaSheet[ nInstance ]->maParaLevel[ nLev ] = mpParaSheet[ nInstance ]->maParaLevel[ nLev - 1 ]; 4261 mpCharSheet[ nInstance ]->maCharLevel[ nLev ] = mpCharSheet[ nInstance ]->maCharLevel[ nLev - 1 ]; 4262 } 4263 4264 // Exception: Template 5, 6 (MasterTitle Title and SubTitle) 4265 if ( nInstance >= TSS_Type::Subtitle ) 4266 { 4267 bFirst = false; 4268 4269 sal_uInt16 nDontKnow; 4270 rIn.ReadUInt16( nDontKnow ); 4271 } 4272 mpParaSheet[ nInstance ]->Read( rManager, rIn, nLev, bFirst ); 4273 mpCharSheet[ nInstance ]->Read( rIn, nLev ); 4274 mpParaSheet[ nInstance ]->UpdateBulletRelSize( nLev, mpCharSheet[ nInstance ]->maCharLevel[ nLev ].mnFontHeight ); 4275 bFirst = false; 4276 nLev++; 4277 } 4278 #ifdef DBG_UTIL 4279 if (!(rManager.rImportParam.nImportFlags & PPT_IMPORTFLAGS_NO_TEXT_ASSERT)) 4280 { 4281 if ( rIn.GetError() == ERRCODE_NONE ) 4282 { 4283 OStringBuffer aMsg; 4284 if ( rIn.Tell() > aTxMasterStyleHd.GetRecEndFilePos() ) 4285 { 4286 aMsg.append("\n reading too many bytes:" + 4287 OString::number(rIn.Tell() - aTxMasterStyleHd.GetRecEndFilePos())); 4288 } 4289 if ( rIn.Tell() < aTxMasterStyleHd.GetRecEndFilePos() ) 4290 { 4291 aMsg.append("\n reading too few bytes:" + 4292 OString::number(aTxMasterStyleHd.GetRecEndFilePos() - rIn.Tell())); 4293 } 4294 if (aMsg.getLength()) 4295 { 4296 aMsg.insert(0, "PptStyleSheet::operator>>[]"); 4297 OSL_FAIL(aMsg.getStr()); 4298 } 4299 } 4300 if ( rIn.Tell() != aTxMasterStyleHd.GetRecEndFilePos() ) 4301 SAL_WARN( "filter.ms", "SJ: Wrong number of bytes read during import of PPT style"); 4302 } 4303 #endif 4304 } 4305 if (!aTxMasterStyleHd.SeekToEndOfRecord(rIn)) 4306 break; 4307 ReadDffRecordHeader( rIn, aTxMasterStyleHd ); 4308 } 4309 if ( !mpCharSheet[ TSS_Type::Subtitle ] ) 4310 { 4311 mpCharSheet[ TSS_Type::Subtitle ] = std::make_unique<PPTCharSheet>( *( mpCharSheet[ TSS_Type::Body ] ) ); 4312 mpParaSheet[ TSS_Type::Subtitle ] = std::make_unique<PPTParaSheet>( *( mpParaSheet[ TSS_Type::Body ] ) ); 4313 } 4314 if ( !mpCharSheet[ TSS_Type::Title ] ) 4315 { 4316 mpCharSheet[ TSS_Type::Title ] = std::make_unique<PPTCharSheet>( *( mpCharSheet[ TSS_Type::PageTitle ] ) ); 4317 mpParaSheet[ TSS_Type::Title ] = std::make_unique<PPTParaSheet>( *( mpParaSheet[ TSS_Type::PageTitle ] ) ); 4318 } 4319 if ( !mpCharSheet[ TSS_Type::HalfBody ] ) 4320 { 4321 mpCharSheet[ TSS_Type::HalfBody ] = std::make_unique<PPTCharSheet>( *( mpCharSheet[ TSS_Type::Body ] ) ); 4322 mpParaSheet[ TSS_Type::HalfBody ] = std::make_unique<PPTParaSheet>( *( mpParaSheet[ TSS_Type::Body ] ) ); 4323 } 4324 if ( !mpCharSheet[ TSS_Type::QuarterBody ] ) 4325 { 4326 mpCharSheet[ TSS_Type::QuarterBody ] = std::make_unique<PPTCharSheet>( *( mpCharSheet[ TSS_Type::Body ] ) ); 4327 mpParaSheet[ TSS_Type::QuarterBody ] = std::make_unique<PPTParaSheet>( *( mpParaSheet[ TSS_Type::Body ] ) ); 4328 } 4329 if ( !bFoundTxMasterStyleAtom04 ) 4330 { // try to locate the txMasterStyleAtom in the Environment 4331 DffRecordHeader* pEnvHeader2 = rManager.aDocRecManager.GetRecordHeader( PPT_PST_Environment ); 4332 if ( pEnvHeader2 ) 4333 { 4334 pEnvHeader2->SeekToContent( rIn ); 4335 DffRecordHeader aTxMasterStyleHd2; 4336 auto nEnvEndRecPos = DffPropSet::SanitizeEndPos(rIn, pEnvHeader2->GetRecEndFilePos()); 4337 while (rIn.Tell() < nEnvEndRecPos) 4338 { 4339 ReadDffRecordHeader( rIn, aTxMasterStyleHd2 ); 4340 if ( aTxMasterStyleHd2.nRecType == PPT_PST_TxMasterStyleAtom ) 4341 { 4342 sal_uInt16 nLevelCnt; 4343 rIn.ReadUInt16( nLevelCnt ); 4344 4345 sal_uInt16 nLev = 0; 4346 bool bFirst = true; 4347 auto nTxEndRecPos = DffPropSet::SanitizeEndPos(rIn, aTxMasterStyleHd2.GetRecEndFilePos()); 4348 while ( rIn.GetError() == ERRCODE_NONE && rIn.Tell() < nTxEndRecPos && nLev < nLevelCnt ) 4349 { 4350 if ( nLev ) 4351 { 4352 mpParaSheet[ TSS_Type::TextInShape ]->maParaLevel[ nLev ] = mpParaSheet[ TSS_Type::TextInShape ]->maParaLevel[ nLev - 1 ]; 4353 mpCharSheet[ TSS_Type::TextInShape ]->maCharLevel[ nLev ] = mpCharSheet[ TSS_Type::TextInShape ]->maCharLevel[ nLev - 1 ]; 4354 } 4355 mpParaSheet[ TSS_Type::TextInShape ]->Read( rManager, rIn, nLev, bFirst ); 4356 if ( !nLev ) 4357 { 4358 // set paragraph defaults for instance 4 (TSS_Type::TextInShape) 4359 if ( rTxPFStyle.bValid ) 4360 { 4361 PPTParaLevel& rParaLevel = mpParaSheet[ TSS_Type::TextInShape ]->maParaLevel[ 0 ]; 4362 rParaLevel.mnAsianLineBreak = 0; 4363 if ( rTxPFStyle.bForbiddenRules ) 4364 rParaLevel.mnAsianLineBreak |= 1; 4365 if ( !rTxPFStyle.bLatinTextWrap ) 4366 rParaLevel.mnAsianLineBreak |= 2; 4367 if ( rTxPFStyle.bHangingPunctuation ) 4368 rParaLevel.mnAsianLineBreak |= 4; 4369 } 4370 } 4371 mpCharSheet[ TSS_Type::TextInShape ]->Read( rIn, nLev ); 4372 mpParaSheet[ TSS_Type::TextInShape ]->UpdateBulletRelSize( nLev, mpCharSheet[ TSS_Type::TextInShape ]->maCharLevel[ nLev ].mnFontHeight ); 4373 bFirst = false; 4374 nLev++; 4375 } 4376 break; 4377 } 4378 else 4379 { 4380 if (!aTxMasterStyleHd2.SeekToEndOfRecord(rIn)) 4381 break; 4382 } 4383 } 4384 } 4385 } 4386 rIn.Seek( nOldFilePos ); 4387 4388 // will create the default numbulletitem for each instance 4389 for ( auto i : o3tl::enumrange<TSS_Type>() ) 4390 { 4391 sal_uInt16 nLevels, nDepth = 0; 4392 SvxNumRuleType eNumRuleType; 4393 4394 switch ( i ) 4395 { 4396 case TSS_Type::PageTitle : 4397 case TSS_Type::Title : 4398 nLevels = 1; 4399 eNumRuleType = SvxNumRuleType::NUMBERING; 4400 break; 4401 case TSS_Type::Subtitle : 4402 nLevels = SVX_MAX_NUM; 4403 eNumRuleType = SvxNumRuleType::NUMBERING; 4404 break; 4405 case TSS_Type::Body : 4406 case TSS_Type::HalfBody : 4407 case TSS_Type::QuarterBody : 4408 nLevels = SVX_MAX_NUM; 4409 eNumRuleType = SvxNumRuleType::PRESENTATION_NUMBERING; 4410 break; 4411 default : 4412 case TSS_Type::Notes : 4413 case TSS_Type::Unused : 4414 case TSS_Type::TextInShape : 4415 nLevels = SVX_MAX_NUM; 4416 eNumRuleType = SvxNumRuleType::NUMBERING; 4417 break; 4418 } 4419 SvxNumRule aRule( SvxNumRuleFlags::BULLET_REL_SIZE | SvxNumRuleFlags::BULLET_COLOR, 4420 nLevels, false, eNumRuleType ); 4421 for ( sal_uInt16 nCount = 0; nDepth < nLevels; nCount++ ) 4422 { 4423 const PPTParaLevel& rParaLevel = mpParaSheet[ i ]->maParaLevel[ nCount ]; 4424 const PPTCharLevel& rCharLevel = mpCharSheet[ i ]->maCharLevel[ nCount ]; 4425 SvxNumberFormat aNumberFormat( SVX_NUM_CHAR_SPECIAL ); 4426 aNumberFormat.SetBulletChar( ' ' ); 4427 GetNumberFormat( rManager, aNumberFormat, nCount, rParaLevel, rCharLevel, i ); 4428 aRule.SetLevel( nDepth++, aNumberFormat ); 4429 if ( nCount >= 4 ) 4430 { 4431 for ( ;nDepth < nLevels; nDepth++ ) 4432 aRule.SetLevel( nDepth, aNumberFormat ); 4433 } 4434 } 4435 mpNumBulletItem[ i ] = std::make_unique<SvxNumBulletItem>( std::move(aRule), EE_PARA_NUMBULLET ); 4436 } 4437 } 4438 4439 PPTStyleSheet::~PPTStyleSheet() 4440 { 4441 for ( auto i : o3tl::enumrange<TSS_Type>() ) 4442 { 4443 mpCharSheet[i].reset(); 4444 mpParaSheet[i].reset(); 4445 mpNumBulletItem[i].reset(); 4446 } 4447 } 4448 4449 PPTParaPropSet::PPTParaPropSet() 4450 : mnOriginalTextPos(0) 4451 , mxParaSet( new ImplPPTParaPropSet ) 4452 { 4453 mxParaSet->mnHasAnm = 1; 4454 } 4455 4456 PPTParaPropSet::PPTParaPropSet( PPTParaPropSet const & rParaPropSet ) 4457 { 4458 mxParaSet = rParaPropSet.mxParaSet; 4459 mnOriginalTextPos = rParaPropSet.mnOriginalTextPos; 4460 } 4461 4462 PPTParaPropSet::~PPTParaPropSet() 4463 { 4464 } 4465 4466 PPTParaPropSet& PPTParaPropSet::operator=( const PPTParaPropSet& rParaPropSet ) 4467 { 4468 if ( this != &rParaPropSet ) 4469 { 4470 mxParaSet = rParaPropSet.mxParaSet; 4471 mnOriginalTextPos = rParaPropSet.mnOriginalTextPos; 4472 } 4473 return *this; 4474 } 4475 4476 PPTCharPropSet::PPTCharPropSet(sal_uInt32 nParagraph) 4477 : mnOriginalTextPos(0) 4478 , mnParagraph(nParagraph) 4479 { 4480 mnHylinkOrigColor = 0; 4481 mbIsHyperlink = false; 4482 mbHardHylinkOrigColor = false; 4483 mnLanguage[ 0 ] = mnLanguage[ 1 ] = mnLanguage[ 2 ] = LANGUAGE_SYSTEM; 4484 } 4485 4486 PPTCharPropSet::PPTCharPropSet( const PPTCharPropSet& rCharPropSet ) 4487 : mpImplPPTCharPropSet( rCharPropSet.mpImplPPTCharPropSet ) 4488 { 4489 mnHylinkOrigColor = rCharPropSet.mnHylinkOrigColor; 4490 mbIsHyperlink = rCharPropSet.mbIsHyperlink; 4491 mbHardHylinkOrigColor = rCharPropSet.mbHardHylinkOrigColor; 4492 4493 mnParagraph = rCharPropSet.mnParagraph; 4494 mnOriginalTextPos = rCharPropSet.mnOriginalTextPos; 4495 maString = rCharPropSet.maString; 4496 mpFieldItem.reset( rCharPropSet.mpFieldItem ? new SvxFieldItem( *rCharPropSet.mpFieldItem ) : nullptr ); 4497 mnLanguage[ 0 ] = rCharPropSet.mnLanguage[ 0 ]; 4498 mnLanguage[ 1 ] = rCharPropSet.mnLanguage[ 1 ]; 4499 mnLanguage[ 2 ] = rCharPropSet.mnLanguage[ 2 ]; 4500 } 4501 4502 PPTCharPropSet::PPTCharPropSet( const PPTCharPropSet& rCharPropSet, sal_uInt32 nParagraph ) 4503 : mpImplPPTCharPropSet(rCharPropSet.mpImplPPTCharPropSet) 4504 { 4505 mnHylinkOrigColor = rCharPropSet.mnHylinkOrigColor; 4506 mbIsHyperlink = rCharPropSet.mbIsHyperlink; 4507 mbHardHylinkOrigColor = rCharPropSet.mbHardHylinkOrigColor; 4508 4509 mnParagraph = nParagraph; 4510 mnOriginalTextPos = rCharPropSet.mnOriginalTextPos; 4511 maString = rCharPropSet.maString; 4512 mpFieldItem.reset( rCharPropSet.mpFieldItem ? new SvxFieldItem( *rCharPropSet.mpFieldItem ) : nullptr ); 4513 mnLanguage[ 0 ] = mnLanguage[ 1 ] = mnLanguage[ 2 ] = LANGUAGE_SYSTEM; 4514 } 4515 4516 PPTCharPropSet::~PPTCharPropSet() 4517 { 4518 } 4519 4520 PPTCharPropSet& PPTCharPropSet::operator=( const PPTCharPropSet& rCharPropSet ) 4521 { 4522 if ( this != &rCharPropSet ) 4523 { 4524 mpImplPPTCharPropSet = rCharPropSet.mpImplPPTCharPropSet; 4525 mnOriginalTextPos = rCharPropSet.mnOriginalTextPos; 4526 mnParagraph = rCharPropSet.mnParagraph; 4527 maString = rCharPropSet.maString; 4528 mpFieldItem.reset( rCharPropSet.mpFieldItem ? new SvxFieldItem( *rCharPropSet.mpFieldItem ) : nullptr ); 4529 } 4530 return *this; 4531 } 4532 4533 void PPTCharPropSet::SetFont( sal_uInt16 nFont ) 4534 { 4535 sal_uInt32 nMask = 1 << PPT_CharAttr_Font; 4536 bool bDoNotMake = (mpImplPPTCharPropSet->mnAttrSet & nMask) != 0; 4537 4538 if ( bDoNotMake ) 4539 bDoNotMake = nFont == mpImplPPTCharPropSet->mnFont; 4540 4541 if ( !bDoNotMake ) 4542 { 4543 mpImplPPTCharPropSet->mnFont = nFont; 4544 mpImplPPTCharPropSet->mnAttrSet |= nMask; 4545 } 4546 } 4547 4548 void PPTCharPropSet::SetColor( sal_uInt32 nColor ) 4549 { 4550 mpImplPPTCharPropSet->mnColor = nColor; 4551 mpImplPPTCharPropSet->mnAttrSet |= 1 << PPT_CharAttr_FontColor; 4552 } 4553 4554 PPTRuler::PPTRuler() 4555 : nFlags(0) 4556 , nDefaultTab(0x240) 4557 , nTabCount(0) 4558 { 4559 } 4560 4561 PPTRuler::~PPTRuler() 4562 { 4563 }; 4564 4565 4566 PPTTextRulerInterpreter::PPTTextRulerInterpreter() : 4567 mxImplRuler ( new PPTRuler() ) 4568 { 4569 } 4570 4571 PPTTextRulerInterpreter::PPTTextRulerInterpreter( PPTTextRulerInterpreter const & rRuler ) 4572 { 4573 mxImplRuler = rRuler.mxImplRuler; 4574 } 4575 4576 PPTTextRulerInterpreter::PPTTextRulerInterpreter( sal_uInt32 nFileOfs, DffRecordHeader const & rHeader, SvStream& rIn ) : 4577 mxImplRuler ( new PPTRuler() ) 4578 { 4579 if ( nFileOfs == 0xffffffff ) 4580 return; 4581 4582 sal_uInt32 nOldPos = rIn.Tell(); 4583 DffRecordHeader rHd; 4584 if ( nFileOfs ) 4585 { 4586 rIn.Seek( nFileOfs ); 4587 ReadDffRecordHeader( rIn, rHd ); 4588 } 4589 else 4590 { 4591 rHeader.SeekToContent( rIn ); 4592 if ( SvxMSDffManager::SeekToRec( rIn, PPT_PST_TextRulerAtom, rHeader.GetRecEndFilePos(), &rHd ) ) 4593 nFileOfs++; 4594 } 4595 if ( nFileOfs ) 4596 { 4597 bool bRecordOk = true; 4598 4599 sal_Int16 nTCount(0); 4600 sal_Int32 i; 4601 rIn.ReadInt32( mxImplRuler->nFlags ); 4602 4603 // number of indent levels, unused now 4604 if ( mxImplRuler->nFlags & 2 ) 4605 rIn.ReadInt16( nTCount ); 4606 if ( mxImplRuler->nFlags & 1 ) 4607 rIn.ReadUInt16( mxImplRuler->nDefaultTab ); 4608 if ( mxImplRuler->nFlags & 4 ) 4609 { 4610 rIn.ReadInt16(nTCount); 4611 4612 const size_t nMaxPossibleRecords = rIn.remainingSize() / (2*sizeof(sal_uInt16)); 4613 const sal_uInt16 nTabCount(nTCount); 4614 4615 bRecordOk = nTabCount <= nMaxPossibleRecords; 4616 4617 if (nTCount && bRecordOk) 4618 { 4619 mxImplRuler->nTabCount = nTabCount; 4620 mxImplRuler->pTab.reset( new PPTTabEntry[ mxImplRuler->nTabCount ] ); 4621 for ( i = 0; i < nTCount; i++ ) 4622 { 4623 rIn.ReadUInt16( mxImplRuler->pTab[ i ].nOffset ) 4624 .ReadUInt16( mxImplRuler->pTab[ i ].nStyle ); 4625 } 4626 } 4627 } 4628 4629 if (bRecordOk) 4630 { 4631 for ( i = 0; i < 5; i++ ) 4632 { 4633 if ( mxImplRuler->nFlags & ( 8 << i ) ) 4634 rIn.ReadUInt16( mxImplRuler->nTextOfs[ i ] ); 4635 if ( mxImplRuler->nFlags & ( 256 << i ) ) 4636 rIn.ReadUInt16( mxImplRuler->nBulletOfs[ i ] ); 4637 if( mxImplRuler->nBulletOfs[ i ] > 0x7fff) 4638 { 4639 // workaround 4640 // when bullet offset is > 0x7fff, the paragraph should look like 4641 // * first line text 4642 // second line text 4643 4644 // we add to bullet para indent 0xffff - bullet offset. It looks like 4645 // best we can do for now 4646 mxImplRuler->nTextOfs[ i ] += 0xffff - mxImplRuler->nBulletOfs[ i ]; 4647 mxImplRuler->nBulletOfs[ i ] = 0; 4648 } 4649 } 4650 } 4651 } 4652 rIn.Seek( nOldPos ); 4653 } 4654 4655 bool PPTTextRulerInterpreter::GetDefaultTab( sal_uInt16& nValue ) const 4656 { 4657 if ( ! ( mxImplRuler->nFlags & 1 ) ) 4658 return false; 4659 nValue = mxImplRuler->nDefaultTab; 4660 return true; 4661 } 4662 4663 bool PPTTextRulerInterpreter::GetTextOfs( sal_uInt32 nLevel, sal_uInt16& nValue ) const 4664 { 4665 if ( ! ( ( nLevel < 5 ) && ( mxImplRuler->nFlags & ( 8 << nLevel ) ) ) ) 4666 return false; 4667 nValue = mxImplRuler->nTextOfs[ nLevel ]; 4668 return true; 4669 } 4670 4671 bool PPTTextRulerInterpreter::GetBulletOfs( sal_uInt32 nLevel, sal_uInt16& nValue ) const 4672 { 4673 if ( ! ( ( nLevel < 5 ) && ( mxImplRuler->nFlags & ( 256 << nLevel ) ) ) ) 4674 return false; 4675 nValue = mxImplRuler->nBulletOfs[ nLevel ]; 4676 return true; 4677 } 4678 4679 PPTTextRulerInterpreter& PPTTextRulerInterpreter::operator=( const PPTTextRulerInterpreter& rRuler ) 4680 { 4681 if ( this != &rRuler ) 4682 { 4683 mxImplRuler = rRuler.mxImplRuler; 4684 } 4685 return *this; 4686 } 4687 4688 PPTTextRulerInterpreter::~PPTTextRulerInterpreter() 4689 { 4690 } 4691 4692 PPTTextParagraphStyleAtomInterpreter::PPTTextParagraphStyleAtomInterpreter() : 4693 bValid ( false ), 4694 bForbiddenRules ( false ), 4695 bHangingPunctuation ( false ), 4696 bLatinTextWrap ( false ) 4697 { 4698 } 4699 4700 bool PPTTextParagraphStyleAtomInterpreter::Read( SvStream& rIn, const DffRecordHeader& rRecHd ) 4701 { 4702 bValid = false; 4703 rRecHd.SeekToContent( rIn ); 4704 sal_uInt32 nDummy32, nFlags, nRecEndPos = rRecHd.GetRecEndFilePos(); 4705 sal_uInt16 nDummy16; 4706 4707 rIn.ReadUInt16( nDummy16 ) 4708 .ReadUInt32( nFlags ); 4709 4710 if ( nFlags & 0xf && ( rIn.Tell() < nRecEndPos ) ) 4711 rIn.ReadUInt16( nDummy16 ); // BuFlags 4712 if ( nFlags & 0x80 && ( rIn.Tell() < nRecEndPos ) ) 4713 rIn.ReadUInt16( nDummy16 ); // BuChar 4714 if ( nFlags & 0x10 && ( rIn.Tell() < nRecEndPos ) ) 4715 rIn.ReadUInt16( nDummy16 ); // nBuFont; 4716 if ( nFlags & 0x40 && ( rIn.Tell() < nRecEndPos ) ) 4717 rIn.ReadUInt16( nDummy16 ); // nBuHeight; 4718 if ( nFlags & 0x0020 && ( rIn.Tell() < nRecEndPos ) ) 4719 rIn.ReadUInt32( nDummy32 ); // nBuColor; 4720 if ( nFlags & 0x800 && ( rIn.Tell() < nRecEndPos ) ) 4721 rIn.ReadUInt16( nDummy16 ); // AbsJust! 4722 if ( nFlags & 0x400 && ( rIn.Tell() < nRecEndPos ) ) 4723 rIn.ReadUInt16( nDummy16 ); 4724 if ( nFlags & 0x200 && ( rIn.Tell() < nRecEndPos ) ) 4725 rIn.ReadUInt16( nDummy16 ); 4726 if ( nFlags & 0x100 && ( rIn.Tell() < nRecEndPos ) ) 4727 rIn.ReadUInt16( nDummy16 ); 4728 if ( nFlags & 0x1000 && ( rIn.Tell() < nRecEndPos ) ) 4729 rIn.ReadUInt16( nDummy16 ); // LineFeed 4730 if ( nFlags & 0x2000 && ( rIn.Tell() < nRecEndPos ) ) 4731 rIn.ReadUInt16( nDummy16 ); // nUpperDist 4732 if ( nFlags & 0x4000 && ( rIn.Tell() < nRecEndPos ) ) 4733 rIn.ReadUInt16( nDummy16 ); // nLowerDist 4734 if ( nFlags & 0x8000 && ( rIn.Tell() < nRecEndPos ) ) 4735 rIn.ReadUInt16( nDummy16 ); 4736 if ( nFlags & 0x10000 && ( rIn.Tell() < nRecEndPos ) ) 4737 rIn.ReadUInt16( nDummy16 ); 4738 if ( nFlags & 0xe0000 && ( rIn.Tell() < nRecEndPos ) ) 4739 { 4740 rIn.ReadUInt16( nDummy16 ); 4741 if ( nFlags & 0x20000 ) 4742 bForbiddenRules = ( nDummy16 & 1 ) == 1; 4743 if ( nFlags & 0x40000 ) 4744 bLatinTextWrap = ( nDummy16 & 2 ) == 0; 4745 if ( nFlags & 0x80000 ) 4746 bHangingPunctuation = ( nDummy16 & 4 ) == 4; 4747 } 4748 nFlags &=~ 0xfffff; 4749 sal_uInt32 nMask = 0x100000; 4750 while ( nFlags && nMask && ( rIn.Tell() < nRecEndPos ) ) 4751 { 4752 if ( nFlags & nMask ) 4753 { 4754 rIn.ReadUInt16( nDummy16 ); 4755 nFlags ^= nMask; 4756 } 4757 nMask <<= 1; 4758 } 4759 bValid = rIn.Tell() == nRecEndPos; 4760 return bValid; 4761 } 4762 4763 PPTTextSpecInfo::PPTTextSpecInfo( sal_uInt32 _nCharIdx ) : 4764 nCharIdx ( _nCharIdx ), 4765 nDontKnow ( 1 ) 4766 { 4767 nLanguage[ 0 ] = LANGUAGE_PROCESS_OR_USER_DEFAULT; 4768 nLanguage[ 1 ] = LANGUAGE_SYSTEM; 4769 nLanguage[ 2 ] = LANGUAGE_SYSTEM; 4770 } 4771 4772 PPTTextSpecInfoAtomInterpreter::PPTTextSpecInfoAtomInterpreter() : 4773 bValid ( false ) 4774 { 4775 } 4776 4777 bool PPTTextSpecInfoAtomInterpreter::Read( SvStream& rIn, const DffRecordHeader& rRecHd, 4778 sal_uInt16 nRecordType, const PPTTextSpecInfo* pTextSpecDefault ) 4779 { 4780 bValid = false; 4781 sal_uInt32 nCharIdx = 0; 4782 rRecHd.SeekToContent( rIn ); 4783 4784 auto nEndRecPos = DffPropSet::SanitizeEndPos(rIn, rRecHd.GetRecEndFilePos()); 4785 while (rIn.Tell() < nEndRecPos && rIn.good()) 4786 { 4787 if ( nRecordType == PPT_PST_TextSpecInfoAtom ) 4788 { 4789 sal_uInt32 nCharCount(0); 4790 rIn.ReadUInt32( nCharCount ); 4791 nCharIdx += nCharCount; 4792 } 4793 4794 sal_uInt32 nFlags(0); 4795 rIn.ReadUInt32(nFlags); 4796 4797 PPTTextSpecInfo aEntry( nCharIdx ); 4798 if ( pTextSpecDefault ) 4799 { 4800 aEntry.nDontKnow = pTextSpecDefault->nDontKnow; 4801 aEntry.nLanguage[ 0 ] = pTextSpecDefault->nLanguage[ 0 ]; 4802 aEntry.nLanguage[ 1 ] = pTextSpecDefault->nLanguage[ 1 ]; 4803 aEntry.nLanguage[ 2 ] = pTextSpecDefault->nLanguage[ 2 ]; 4804 } 4805 for (sal_uInt32 i = 1; nFlags && i ; i <<= 1) 4806 { 4807 sal_uInt16 nLang = 0; 4808 switch( nFlags & i ) 4809 { 4810 case 0 : break; 4811 case 1 : rIn.ReadUInt16( aEntry.nDontKnow ); break; 4812 case 2 : rIn.ReadUInt16( nLang ); break; 4813 case 4 : rIn.ReadUInt16( nLang ); break; 4814 default : 4815 { 4816 rIn.SeekRel( 2 ); 4817 } 4818 } 4819 if ( nLang ) 4820 { 4821 // #i119985#, we could probably handle this better if we have a 4822 // place to override the final language for weak 4823 // characters/fields to fallback to, rather than the current 4824 // application locale. Assuming that we can determine what the 4825 // default fallback language for a given .ppt, etc is during 4826 // load time. 4827 if (i == 2) 4828 { 4829 aEntry.nLanguage[ 0 ] = aEntry.nLanguage[ 1 ] = aEntry.nLanguage[ 2 ] = LanguageType(nLang); 4830 } 4831 } 4832 nFlags &= ~i; 4833 } 4834 aList.push_back( aEntry ); 4835 } 4836 bValid = rIn.Tell() == rRecHd.GetRecEndFilePos(); 4837 return bValid; 4838 } 4839 4840 PPTTextSpecInfoAtomInterpreter::~PPTTextSpecInfoAtomInterpreter() 4841 { 4842 } 4843 4844 void StyleTextProp9::Read( SvStream& rIn ) 4845 { 4846 rIn.ReadUInt32( mnExtParagraphMask ); 4847 if ( mnExtParagraphMask & 0x800000 ) 4848 rIn.ReadUInt16( mnBuBlip ); 4849 if ( mnExtParagraphMask & 0x2000000 ) 4850 rIn.ReadUInt16( mnHasAnm ); 4851 if ( mnExtParagraphMask & 0x1000000 ) 4852 rIn.ReadUInt32( mnAnmScheme ); 4853 if ( mnExtParagraphMask & 0x4000000 ) 4854 rIn.ReadUInt32( mpfPP10Ext ); 4855 rIn.ReadUInt32( mnExtCharacterMask ); 4856 if ( mnExtCharacterMask & 0x100000 ) 4857 rIn.ReadUInt32( mncfPP10Ext ); 4858 rIn.ReadUInt32( mnSpecialInfoMask ); 4859 if ( mnSpecialInfoMask & 0x20 ) 4860 rIn.ReadUInt32( mnPP10Ext ); 4861 if ( mnSpecialInfoMask & 0x40 ) 4862 rIn.ReadUInt16( mfBidi ); 4863 } 4864 4865 PPTStyleTextPropReader::PPTStyleTextPropReader( SvStream& rIn, const DffRecordHeader& rTextHeader, 4866 PPTTextRulerInterpreter const & rRuler, const DffRecordHeader& rExtParaHd, TSS_Type nInstance ) 4867 { 4868 Init(rIn, rTextHeader, rRuler, rExtParaHd, nInstance); 4869 } 4870 4871 void PPTStyleTextPropReader::ReadParaProps( SvStream& rIn, const DffRecordHeader& rTextHeader, 4872 const OUString& aString, PPTTextRulerInterpreter const & rRuler, 4873 sal_uInt32& nCharCount, bool& bTextPropAtom ) 4874 { 4875 sal_uInt32 nMask = 0; //TODO: nMask initialized here to suppress warning for now, see corresponding TODO below 4876 sal_uInt32 nCharReadCnt = 0; 4877 sal_uInt16 nDummy16; 4878 4879 sal_uInt16 nStringLen = aString.getLength(); 4880 4881 DffRecordHeader aTextHd2; 4882 rTextHeader.SeekToContent( rIn ); 4883 if ( SvxMSDffManager::SeekToRec( rIn, PPT_PST_StyleTextPropAtom, rTextHeader.GetRecEndFilePos(), &aTextHd2 ) ) 4884 bTextPropAtom = true; 4885 while ( nCharReadCnt <= nStringLen ) 4886 { 4887 PPTParaPropSet aParaPropSet; 4888 ImplPPTParaPropSet& aSet = *aParaPropSet.mxParaSet; 4889 if ( bTextPropAtom ) 4890 { 4891 rIn.ReadUInt32( nCharCount ) 4892 .ReadUInt16( aParaPropSet.mxParaSet->mnDepth ); // indent depth 4893 4894 aParaPropSet.mxParaSet->mnDepth = // taking care of about using not more than 9 outliner levels 4895 std::min(sal_uInt16(8), 4896 aParaPropSet.mxParaSet->mnDepth); 4897 4898 nCharCount--; 4899 4900 rIn.ReadUInt32( nMask ); 4901 aSet.mnAttrSet = nMask & 0x207df7; 4902 sal_uInt16 nBulFlg = 0; 4903 if ( nMask & 0xF ) 4904 rIn.ReadUInt16( nBulFlg ); // Bullet-HardAttr-Flags 4905 aSet.mpArry[ PPT_ParaAttr_BulletOn ] = ( nBulFlg & 1 ) ? 1 : 0; 4906 aSet.mpArry[ PPT_ParaAttr_BuHardFont ] = ( nBulFlg & 2 ) ? 1 : 0; 4907 aSet.mpArry[ PPT_ParaAttr_BuHardColor ] = ( nBulFlg & 4 ) ? 1 : 0; 4908 4909 // NOTE: one might think that the hard-coded numbers here are the 4910 // same as the PPT_ParaAttr_* constants, but it's NOT always true! 4911 if ( nMask & 0x0080 ) // buChar 4912 { 4913 rIn.ReadUInt16( aSet.mpArry[ PPT_ParaAttr_BulletChar ] ); 4914 if (!rIn.good()) 4915 { 4916 aSet.mnAttrSet &= ~(1 << PPT_ParaAttr_BulletChar); 4917 } 4918 } 4919 if ( nMask & 0x0010 ) // buTypeface 4920 { 4921 rIn.ReadUInt16( aSet.mpArry[ PPT_ParaAttr_BulletFont ] ); 4922 if (!rIn.good()) 4923 { 4924 aSet.mnAttrSet &= ~(1 << PPT_ParaAttr_BulletFont); 4925 } 4926 } 4927 if ( nMask & 0x0040 ) // buSize 4928 { 4929 rIn.ReadUInt16( aSet.mpArry[ PPT_ParaAttr_BulletHeight ] ); 4930 if (!rIn.good() 4931 || !((nMask & (1 << PPT_ParaAttr_BuHardHeight)) 4932 && (nBulFlg & (1 << PPT_ParaAttr_BuHardHeight)))) 4933 { 4934 aSet.mnAttrSet &= ~(1 << PPT_ParaAttr_BulletHeight); 4935 } 4936 } 4937 if ( nMask & 0x0020 ) // buColor 4938 { 4939 sal_uInt32 nVal32; 4940 rIn.ReadUInt32( nVal32 ); 4941 if (!rIn.good()) 4942 { 4943 aSet.mnBulletColor = 0; // no flag for this? default it 4944 } 4945 else 4946 { 4947 sal_uInt32 nHiByte; 4948 nHiByte = nVal32 >> 24; 4949 if ( nHiByte <= 8 ) 4950 nVal32 = nHiByte | PPT_COLSCHEME; 4951 aSet.mnBulletColor = nVal32; 4952 } 4953 } 4954 if ( nMask & 0x0800 ) // pfAlignment 4955 { 4956 rIn.ReadUInt16( nDummy16 ); 4957 if (!rIn.good()) 4958 { 4959 aSet.mnAttrSet &= ~(1 << PPT_ParaAttr_Adjust); 4960 } 4961 else 4962 { 4963 aSet.mpArry[ PPT_ParaAttr_Adjust ] = nDummy16 & 3; 4964 } 4965 } 4966 if ( nMask & 0x1000 ) // pfLineSpacing 4967 { 4968 rIn.ReadUInt16( aSet.mpArry[ PPT_ParaAttr_LineFeed ] ); 4969 if (!rIn.good()) 4970 { 4971 aSet.mnAttrSet &= ~(1 << PPT_ParaAttr_LineFeed); 4972 } 4973 } 4974 if ( nMask & 0x2000 ) // pfSpaceBefore 4975 { 4976 rIn.ReadUInt16( aSet.mpArry[ PPT_ParaAttr_UpperDist ] ); 4977 if (!rIn.good()) 4978 { 4979 aSet.mnAttrSet &= ~(1 << PPT_ParaAttr_UpperDist); 4980 } 4981 } 4982 if ( nMask & 0x4000 ) // pfSpaceAfter 4983 { 4984 rIn.ReadUInt16( aSet.mpArry[ PPT_ParaAttr_LowerDist ] ); 4985 if (!rIn.good()) 4986 { 4987 aSet.mnAttrSet &= ~(1 << PPT_ParaAttr_LowerDist); 4988 } 4989 } 4990 if ( nMask & 0x100 ) // pfLeftMargin 4991 { 4992 rIn.ReadUInt16( aSet.mpArry[ PPT_ParaAttr_TextOfs ] ); 4993 if (!rIn.good()) 4994 { 4995 aSet.mnAttrSet &= ~(1 << PPT_ParaAttr_TextOfs); 4996 } 4997 else 4998 { 4999 aSet.mnAttrSet |= 1 << PPT_ParaAttr_TextOfs; 5000 } 5001 } 5002 if ( nMask & 0x400 ) // pfIndent 5003 { 5004 rIn.ReadUInt16( aSet.mpArry[ PPT_ParaAttr_BulletOfs ] ); 5005 if (!rIn.good()) 5006 { 5007 aSet.mnAttrSet &= ~(1 << PPT_ParaAttr_BulletOfs); 5008 } 5009 else 5010 { 5011 aSet.mnAttrSet |= 1 << PPT_ParaAttr_BulletOfs; 5012 } 5013 } 5014 if ( nMask & 0x8000 ) // pfDefaultTabSize 5015 { 5016 rIn.ReadUInt16( nDummy16 ); 5017 if (!rIn.good()) 5018 { 5019 // TODO? 5020 } 5021 } 5022 if ( nMask & 0x100000 ) // pfTabStops 5023 { 5024 sal_uInt16 i, nDistance, nAlignment, nNumberOfTabStops = 0; 5025 rIn.ReadUInt16( nNumberOfTabStops ); 5026 if (!rIn.good()) 5027 { 5028 // TODO? 5029 } 5030 else 5031 { 5032 const size_t nMinRecordSize = 4; 5033 const size_t nMaxRecords = rIn.remainingSize() / nMinRecordSize; 5034 if (nNumberOfTabStops > nMaxRecords) 5035 { 5036 SAL_WARN("filter.ms", "Parsing error: " << nMaxRecords << 5037 " max possible entries, but " << nNumberOfTabStops << " claimed, truncating"); 5038 nNumberOfTabStops = nMaxRecords; 5039 } 5040 for (i = 0; i < nNumberOfTabStops; ++i) 5041 { 5042 rIn.ReadUInt16( nDistance ) 5043 .ReadUInt16( nAlignment ); 5044 } 5045 } 5046 } 5047 if ( nMask & 0x10000 ) // pfBaseLine 5048 { 5049 rIn.ReadUInt16( nDummy16 ); 5050 if (!rIn.good()) 5051 { 5052 // TODO? 5053 } 5054 } 5055 if ( nMask & 0xe0000 ) // pfCharWrap, pfWordWrap, pfOverflow 5056 { 5057 rIn.ReadUInt16( nDummy16 ); 5058 if (!rIn.good()) 5059 { // clear flag to avoid invalid access 5060 aSet.mnAttrSet &= ~((1 << PPT_ParaAttr_AsianLB_1) 5061 | (1 << PPT_ParaAttr_AsianLB_2) 5062 | (1 << PPT_ParaAttr_AsianLB_3)); 5063 } 5064 else 5065 { 5066 if (nMask & 0x20000) 5067 aSet.mpArry[PPT_ParaAttr_AsianLB_1] = nDummy16 & 1; 5068 if (nMask & 0x40000) 5069 aSet.mpArry[PPT_ParaAttr_AsianLB_2] = (nDummy16 >> 1) & 1; 5070 if (nMask & 0x80000) 5071 aSet.mpArry[PPT_ParaAttr_AsianLB_3] = (nDummy16 >> 2) & 1; 5072 aSet.mnAttrSet |= ((nMask >> 17) & 7) << PPT_ParaAttr_AsianLB_1; 5073 } 5074 } 5075 if ( nMask & 0x200000 ) // pfTextDirection 5076 { 5077 rIn.ReadUInt16( aSet.mpArry[ PPT_ParaAttr_BiDi ] ); 5078 if (!rIn.good()) 5079 { // clear flag to avoid invalid access 5080 aSet.mnAttrSet &= ~(1 << PPT_ParaAttr_BiDi); 5081 } 5082 } 5083 } 5084 else 5085 nCharCount = nStringLen; 5086 5087 //if the textofs attr has been read at above, need not to reset. 5088 if ( ( !( aSet.mnAttrSet & 1 << PPT_ParaAttr_TextOfs ) ) && rRuler.GetTextOfs( aParaPropSet.mxParaSet->mnDepth, aSet.mpArry[ PPT_ParaAttr_TextOfs ] ) ) 5089 aSet.mnAttrSet |= 1 << PPT_ParaAttr_TextOfs; 5090 if ( ( !( aSet.mnAttrSet & 1 << PPT_ParaAttr_BulletOfs ) ) && rRuler.GetBulletOfs( aParaPropSet.mxParaSet->mnDepth, aSet.mpArry[ PPT_ParaAttr_BulletOfs ] ) ) 5091 aSet.mnAttrSet |= 1 << PPT_ParaAttr_BulletOfs; 5092 if ( rRuler.GetDefaultTab( aSet.mpArry[ PPT_ParaAttr_DefaultTab ] ) ) 5093 aSet.mnAttrSet |= 1 << PPT_ParaAttr_DefaultTab; 5094 5095 if ( ( nCharCount > nStringLen ) || ( nStringLen < nCharReadCnt + nCharCount ) ) 5096 { 5097 bTextPropAtom = false; 5098 nCharCount = nStringLen - nCharReadCnt; 5099 // please fix the right hand side of 5100 // PPTParaPropSet& PPTParaPropSet::operator=(PPTParaPropSet&), 5101 // it should be a const reference 5102 PPTParaPropSet aTmpPPTParaPropSet; 5103 aParaPropSet = aTmpPPTParaPropSet; 5104 OSL_FAIL( "SJ:PPTStyleTextPropReader::could not get this PPT_PST_StyleTextPropAtom by reading the paragraph attributes" ); 5105 } 5106 PPTParaPropSet* pPara = new PPTParaPropSet( aParaPropSet ); 5107 pPara->mnOriginalTextPos = nCharReadCnt; 5108 aParaPropList.emplace_back( pPara ); 5109 if ( nCharCount ) 5110 { 5111 sal_uInt32 nCount; 5112 const sal_Unicode* pDat = aString.getStr() + nCharReadCnt; 5113 for ( nCount = 0; nCount < nCharCount; nCount++ ) 5114 { 5115 if ( pDat[ nCount ] == 0xd ) 5116 { 5117 pPara = new PPTParaPropSet( aParaPropSet ); 5118 pPara->mnOriginalTextPos = nCharReadCnt + nCount + 1; 5119 aParaPropList.emplace_back( pPara ); 5120 } 5121 } 5122 } 5123 nCharReadCnt += nCharCount + 1; 5124 } 5125 } 5126 5127 void PPTStyleTextPropReader::ReadCharProps( SvStream& rIn, PPTCharPropSet& aCharPropSet, const OUString& aString, 5128 sal_uInt32& nCharCount, sal_uInt32 nCharReadCnt, 5129 bool& bTextPropAtom, sal_uInt32 nExtParaPos, 5130 const std::vector< StyleTextProp9 >& aStyleTextProp9, 5131 sal_uInt32& nExtParaFlags, sal_uInt16& nBuBlip, 5132 sal_uInt16& nHasAnm, sal_uInt32& nAnmScheme ) 5133 { 5134 sal_uInt16 nStringLen = aString.getLength(); 5135 5136 sal_uInt16 nDummy16; 5137 rIn.ReadUInt16( nDummy16 ); 5138 nCharCount = (rIn.good()) ? nDummy16 : 0; 5139 rIn.ReadUInt16( nDummy16 ); 5140 5141 sal_Int32 nCharsToRead = nStringLen - ( nCharReadCnt + nCharCount ); 5142 if ( nCharsToRead < 0 ) 5143 { 5144 nCharCount = nStringLen - nCharReadCnt; 5145 if ( nCharsToRead < -1 ) 5146 { 5147 bTextPropAtom = false; 5148 OSL_FAIL( "SJ:PPTStyleTextPropReader::could not get this PPT_PST_StyleTextPropAtom by reading the character attributes" ); 5149 } 5150 } 5151 ImplPPTCharPropSet& aSet = *aCharPropSet.mpImplPPTCharPropSet; 5152 5153 // character attributes 5154 sal_uInt32 nMask(0); 5155 rIn.ReadUInt32( nMask ); 5156 if ( static_cast<sal_uInt16>(nMask) ) 5157 { 5158 aSet.mnAttrSet |= static_cast<sal_uInt16>(nMask); 5159 rIn.ReadUInt16( aSet.mnFlags ); 5160 } 5161 if ( nMask & 0x10000 ) // cfTypeface 5162 { 5163 rIn.ReadUInt16( aSet.mnFont ); 5164 aSet.mnAttrSet |= 1 << PPT_CharAttr_Font; 5165 } 5166 if ( nMask & 0x200000 ) // cfFEOldTypeface 5167 { 5168 rIn.ReadUInt16( aSet.mnAsianOrComplexFont ); 5169 aSet.mnAttrSet |= 1 << PPT_CharAttr_AsianOrComplexFont; 5170 } 5171 if ( nMask & 0x400000 ) // cfANSITypeface 5172 { 5173 rIn.ReadUInt16( aSet.mnANSITypeface ); 5174 aSet.mnAttrSet |= 1 << PPT_CharAttr_ANSITypeface; 5175 } 5176 if ( nMask & 0x800000 ) // cfSymbolTypeface 5177 { 5178 rIn.ReadUInt16( aSet.mnSymbolFont ); 5179 aSet.mnAttrSet |= 1 << PPT_CharAttr_Symbol; 5180 } 5181 if ( nMask & 0x20000 ) // cfSize 5182 { 5183 rIn.ReadUInt16( aSet.mnFontHeight ); 5184 aSet.mnAttrSet |= 1 << PPT_CharAttr_FontHeight; 5185 } 5186 if ( nMask & 0x40000 ) // cfColor 5187 { 5188 sal_uInt32 nVal(0); 5189 rIn.ReadUInt32( nVal ); 5190 if ( !( nVal & 0xff000000 ) ) 5191 nVal = PPT_COLSCHEME_HINTERGRUND; 5192 aSet.mnColor = nVal; 5193 aSet.mnAttrSet |= 1 << PPT_CharAttr_FontColor; 5194 } 5195 if ( nMask & 0x80000 ) // cfPosition 5196 { 5197 rIn.ReadUInt16( aSet.mnEscapement ); 5198 aSet.mnAttrSet |= 1 << PPT_CharAttr_Escapement; 5199 } 5200 if ( !nExtParaPos ) 5201 return; 5202 5203 sal_uInt32 nExtBuInd = nMask & 0x3c00; 5204 if ( nExtBuInd ) 5205 nExtBuInd = ( aSet.mnFlags & 0x3c00 ) >> 10; 5206 if ( nExtBuInd < aStyleTextProp9.size() ) 5207 { 5208 nExtParaFlags = aStyleTextProp9[ nExtBuInd ].mnExtParagraphMask; 5209 nBuBlip = aStyleTextProp9[ nExtBuInd ].mnBuBlip; 5210 nHasAnm = aStyleTextProp9[ nExtBuInd ].mnHasAnm; 5211 nAnmScheme = aStyleTextProp9[ nExtBuInd ].mnAnmScheme; 5212 } 5213 } 5214 5215 void PPTStyleTextPropReader::Init( SvStream& rIn, const DffRecordHeader& rTextHeader, 5216 PPTTextRulerInterpreter const & rRuler, const DffRecordHeader& rExtParaHd, TSS_Type nInstance ) 5217 { 5218 sal_uInt32 nOldPos = rIn.Tell(); 5219 sal_uInt32 nExtParaPos = ( rExtParaHd.nRecType == PPT_PST_ExtendedParagraphAtom ) ? rExtParaHd.nFilePos + 8 : 0; 5220 5221 std::vector< StyleTextProp9 > aStyleTextProp9; 5222 if ( rExtParaHd.nRecType == PPT_PST_ExtendedParagraphAtom ) 5223 { 5224 rIn.Seek( rExtParaHd.nFilePos + 8 ); 5225 5226 auto nEndRecPos = DffPropSet::SanitizeEndPos(rIn, rExtParaHd.GetRecEndFilePos()); 5227 while( ( rIn.GetError() == ERRCODE_NONE ) && ( rIn.Tell() < nEndRecPos ) ) 5228 { 5229 aStyleTextProp9.emplace_back(); 5230 aStyleTextProp9.back().Read( rIn ); 5231 } 5232 rIn.Seek( nOldPos ); 5233 } 5234 5235 OUString aString; 5236 DffRecordHeader aTextHd; 5237 ReadDffRecordHeader( rIn, aTextHd ); 5238 sal_uInt32 nMaxLen = aTextHd.nRecLen; 5239 if ( nMaxLen >= 0xFFFF ) 5240 nMaxLen = 0xFFFE; 5241 5242 if( aTextHd.nRecType == PPT_PST_TextCharsAtom ) 5243 { 5244 std::vector<sal_Unicode> aBuf(( nMaxLen >> 1 ) + 1); 5245 void* pDest = aBuf.data(); 5246 auto nRead = rIn.ReadBytes(pDest, nMaxLen); 5247 if (nRead != nMaxLen) 5248 memset(static_cast<char*>(pDest) + nRead, 0, nMaxLen - nRead); 5249 nMaxLen >>= 1; 5250 aBuf[nMaxLen] = 0; 5251 5252 sal_uInt32 i; 5253 sal_Unicode* pPtr = aBuf.data(); 5254 5255 #ifdef OSL_BIGENDIAN 5256 sal_Unicode nTemp; 5257 for ( i = 0; i < nMaxLen; i++ ) 5258 { 5259 nTemp = *pPtr; 5260 *pPtr++ = ( nTemp << 8 ) | ( nTemp >> 8 ); 5261 } 5262 pPtr = aBuf.data(); 5263 #endif 5264 5265 for ( i = 0; i < nMaxLen; pPtr++, i++ ) 5266 { 5267 sal_Unicode nChar = *pPtr; 5268 if ( !nChar ) 5269 break; 5270 if ( ( nChar & 0xff00 ) == 0xf000 ) // in this special case we got a symbol 5271 aSpecMarkerList.push_back( static_cast<sal_uInt32>( i | PPT_SPEC_SYMBOL ) ); 5272 else if ( nChar == 0xd ) 5273 { 5274 if ( nInstance == TSS_Type::PageTitle ) 5275 *pPtr = 0xb; 5276 else 5277 aSpecMarkerList.push_back( static_cast<sal_uInt32>( i | PPT_SPEC_NEWLINE ) ); 5278 } 5279 } 5280 if ( i ) 5281 aString = OUString(aBuf.data(), i); 5282 } 5283 else if( aTextHd.nRecType == PPT_PST_TextBytesAtom ) 5284 { 5285 std::unique_ptr<char[]> pBuf(new char[ nMaxLen + 1 ]); 5286 nMaxLen = rIn.ReadBytes(pBuf.get(), nMaxLen); 5287 pBuf[ nMaxLen ] = 0; 5288 char* pPtr = pBuf.get(); 5289 for (;;) 5290 { 5291 char cLo = *pPtr; 5292 if ( cLo == 0 ) 5293 break; 5294 if ( cLo == 0xd ) 5295 { 5296 if ( nInstance == TSS_Type::PageTitle ) 5297 *pPtr = 0xb; 5298 else 5299 aSpecMarkerList.push_back( static_cast<sal_uInt32>( (pPtr - pBuf.get()) | PPT_SPEC_NEWLINE ) ); 5300 } 5301 pPtr++; 5302 } 5303 sal_Int32 nLen = pPtr - pBuf.get(); 5304 if ( nLen ) 5305 aString = OUString( pBuf.get(), nLen, RTL_TEXTENCODING_MS_1252 ); 5306 } 5307 else 5308 { 5309 // no chars, but potentially char/para props? 5310 sal_uInt32 nCharCount; 5311 bool bTextPropAtom = false; 5312 ReadParaProps( rIn, rTextHeader, aString, rRuler, nCharCount, bTextPropAtom ); 5313 5314 if ( bTextPropAtom ) 5315 { 5316 // yeah, StyleTextProp is there, read it all & push to 5317 // aParaPropList 5318 PPTCharPropSet aCharPropSet(0); 5319 aCharPropSet.mnOriginalTextPos = 0; 5320 5321 sal_uInt32 nExtParaFlags = 0, nAnmScheme = 0; 5322 sal_uInt16 nBuBlip = 0xffff, nHasAnm = 0; 5323 ReadCharProps( rIn, aCharPropSet, aString, nCharCount, 0/*nCharReadCnt*/, 5324 bTextPropAtom, nExtParaPos, aStyleTextProp9, nExtParaFlags, 5325 nBuBlip, nHasAnm, nAnmScheme ); 5326 5327 aCharPropList.push_back(std::make_unique<PPTCharPropSet>(aCharPropSet, 0)); 5328 } 5329 } 5330 5331 if ( !aString.isEmpty() ) 5332 { 5333 sal_uInt32 nCharCount; 5334 bool bTextPropAtom = false; 5335 5336 ReadParaProps( rIn, rTextHeader, aString, rRuler, nCharCount, bTextPropAtom ); 5337 5338 bool bEmptyParaPossible = true; 5339 sal_uInt32 nCharReadCnt = 0; 5340 sal_uInt32 nCurrentPara = 0; 5341 size_t i = 1; // points to the next element to process 5342 sal_uInt32 nCurrentSpecMarker = aSpecMarkerList.empty() ? 0 : aSpecMarkerList[0]; 5343 sal_uInt32 nStringLen = aString.getLength(); 5344 5345 while ( nCharReadCnt < nStringLen ) 5346 { 5347 sal_uInt32 nExtParaFlags = 0, nLatestParaUpdate = 0xffffffff, nAnmScheme = 0; 5348 sal_uInt16 nBuBlip = 0xffff, nHasAnm = 0; 5349 5350 PPTCharPropSet aCharPropSet( nCurrentPara ); 5351 if ( bTextPropAtom ) 5352 { 5353 ReadCharProps( rIn, aCharPropSet, aString, nCharCount, nCharReadCnt, 5354 bTextPropAtom, nExtParaPos, aStyleTextProp9, nExtParaFlags, 5355 nBuBlip, nHasAnm, nAnmScheme ); 5356 if (!rIn.good()) 5357 break; 5358 } 5359 else 5360 nCharCount = nStringLen; 5361 5362 sal_uInt32 nLen; 5363 while( nCharCount ) 5364 { 5365 if ( nExtParaPos && ( nLatestParaUpdate != nCurrentPara ) && ( nCurrentPara < aParaPropList.size() ) ) 5366 { 5367 PPTParaPropSet* pPropSet = aParaPropList[ nCurrentPara ].get(); 5368 pPropSet->mxParaSet->mnExtParagraphMask = nExtParaFlags; 5369 if ( nExtParaFlags & 0x800000 ) 5370 pPropSet->mxParaSet->mnBuBlip = nBuBlip; 5371 if ( nExtParaFlags & 0x01000000 ) 5372 pPropSet->mxParaSet->mnAnmScheme = nAnmScheme; 5373 if ( nExtParaFlags & 0x02000000 ) 5374 pPropSet->mxParaSet->mnHasAnm = nHasAnm; 5375 nLatestParaUpdate = nCurrentPara; 5376 } 5377 aCharPropSet.mnOriginalTextPos = nCharReadCnt; 5378 if ( nCurrentSpecMarker && ( ( nCurrentSpecMarker & 0xffff ) < ( nCharReadCnt + nCharCount ) ) ) 5379 { 5380 if ( nCurrentSpecMarker & PPT_SPEC_NEWLINE ) 5381 { 5382 nLen = ( nCurrentSpecMarker & 0xffff ) - nCharReadCnt; 5383 if ( nLen ) 5384 aCharPropSet.maString = aString.copy( nCharReadCnt, nLen ); 5385 else if ( bEmptyParaPossible ) 5386 aCharPropSet.maString.clear(); 5387 if ( nLen || bEmptyParaPossible ) 5388 aCharPropList.push_back( 5389 std::make_unique<PPTCharPropSet>(aCharPropSet, nCurrentPara)); 5390 nCurrentPara++; 5391 nLen++; 5392 nCharReadCnt += nLen; 5393 nCharCount -= nLen; 5394 bEmptyParaPossible = true; 5395 } 5396 else if ( nCurrentSpecMarker & PPT_SPEC_SYMBOL ) 5397 { 5398 if ( ( nCurrentSpecMarker & 0xffff ) != nCharReadCnt ) 5399 { 5400 nLen = ( nCurrentSpecMarker & 0xffff ) - nCharReadCnt; 5401 aCharPropSet.maString = aString.copy(nCharReadCnt, nLen); 5402 aCharPropList.push_back( 5403 std::make_unique<PPTCharPropSet>(aCharPropSet, nCurrentPara)); 5404 nCharCount -= nLen; 5405 nCharReadCnt += nLen; 5406 } 5407 PPTCharPropSet* pCPropSet = new PPTCharPropSet( aCharPropSet, nCurrentPara ); 5408 pCPropSet->maString = aString.copy(nCharReadCnt, 1); 5409 if ( aCharPropSet.mpImplPPTCharPropSet->mnAttrSet & ( 1 << PPT_CharAttr_Symbol ) ) 5410 pCPropSet->SetFont( aCharPropSet.mpImplPPTCharPropSet->mnSymbolFont ); 5411 aCharPropList.emplace_back( pCPropSet ); 5412 nCharCount--; 5413 nCharReadCnt++; 5414 bEmptyParaPossible = false; 5415 } 5416 nCurrentSpecMarker = ( i < aSpecMarkerList.size() ) ? aSpecMarkerList[ i++ ] : 0; 5417 } 5418 else 5419 { 5420 if (nCharReadCnt > o3tl::make_unsigned(aString.getLength())) 5421 aCharPropSet.maString = OUString(); 5422 else 5423 { 5424 sal_Int32 nStrLen = nCharCount; 5425 sal_Int32 nMaxStrLen = aString.getLength() - nCharReadCnt; 5426 if (nStrLen > nMaxStrLen) 5427 nStrLen = nMaxStrLen; 5428 aCharPropSet.maString = aString.copy(nCharReadCnt, nStrLen); 5429 } 5430 aCharPropList.push_back( 5431 std::make_unique<PPTCharPropSet>(aCharPropSet, nCurrentPara)); 5432 nCharReadCnt += nCharCount; 5433 bEmptyParaPossible = false; 5434 break; 5435 } 5436 } 5437 } 5438 if ( !aCharPropList.empty() && ( aCharPropList.back()->mnParagraph != nCurrentPara ) ) 5439 { 5440 PPTCharPropSet* pCharPropSet = new PPTCharPropSet( *aCharPropList.back(), nCurrentPara ); 5441 pCharPropSet->maString.clear(); 5442 pCharPropSet->mnOriginalTextPos = nStringLen - 1; 5443 aCharPropList.emplace_back( pCharPropSet ); 5444 } 5445 } 5446 rIn.Seek( nOldPos ); 5447 } 5448 5449 PPTStyleTextPropReader::~PPTStyleTextPropReader() 5450 { 5451 } 5452 5453 PPTPortionObj::PPTPortionObj( const PPTStyleSheet& rStyleSheet, TSS_Type nInstance, sal_uInt32 nDepth ) : 5454 PPTCharPropSet ( 0 ), 5455 mrStyleSheet ( rStyleSheet ), 5456 mnInstance ( nInstance ), 5457 mnDepth ( std::min<sal_uInt32>( nDepth, 4 ) ) 5458 { 5459 } 5460 5461 PPTPortionObj::PPTPortionObj( const PPTCharPropSet& rCharPropSet, const PPTStyleSheet& rStyleSheet, TSS_Type nInstance, sal_uInt32 nDepth ) : 5462 PPTCharPropSet ( rCharPropSet ), 5463 mrStyleSheet ( rStyleSheet ), 5464 mnInstance ( nInstance ), 5465 mnDepth ( std::min<sal_uInt32>( nDepth, 4 ) ) 5466 { 5467 } 5468 5469 PPTPortionObj::PPTPortionObj( const PPTPortionObj& rPortionObj ) : 5470 PPTCharPropSet ( rPortionObj ), 5471 mrStyleSheet ( rPortionObj.mrStyleSheet ), 5472 mnInstance ( rPortionObj.mnInstance ), 5473 mnDepth ( rPortionObj.mnDepth ) 5474 { 5475 } 5476 5477 PPTPortionObj::~PPTPortionObj() 5478 { 5479 } 5480 5481 bool PPTPortionObj::GetAttrib( sal_uInt32 nAttr, sal_uInt32& rRetValue, TSS_Type nDestinationInstance ) const 5482 { 5483 sal_uInt32 nMask = 1 << nAttr; 5484 rRetValue = 0; 5485 5486 bool bIsHardAttribute = ( ( mpImplPPTCharPropSet->mnAttrSet & nMask ) != 0 ); 5487 5488 if ( bIsHardAttribute ) 5489 { 5490 switch ( nAttr ) 5491 { 5492 case PPT_CharAttr_Bold : 5493 case PPT_CharAttr_Italic : 5494 case PPT_CharAttr_Underline : 5495 case PPT_CharAttr_Shadow : 5496 case PPT_CharAttr_Strikeout : 5497 case PPT_CharAttr_Embossed : 5498 rRetValue = ( mpImplPPTCharPropSet->mnFlags & nMask ) ? 1 : 0; 5499 break; 5500 case PPT_CharAttr_Font : 5501 rRetValue = mpImplPPTCharPropSet->mnFont; 5502 break; 5503 case PPT_CharAttr_AsianOrComplexFont : 5504 rRetValue = mpImplPPTCharPropSet->mnAsianOrComplexFont; 5505 break; 5506 case PPT_CharAttr_FontHeight : 5507 rRetValue = mpImplPPTCharPropSet->mnFontHeight; 5508 break; 5509 case PPT_CharAttr_FontColor : 5510 rRetValue = mpImplPPTCharPropSet->mnColor; 5511 break; 5512 case PPT_CharAttr_Escapement : 5513 rRetValue = mpImplPPTCharPropSet->mnEscapement; 5514 break; 5515 default : 5516 OSL_FAIL( "SJ:PPTPortionObj::GetAttrib ( hard attribute does not exist )" ); 5517 } 5518 } 5519 else 5520 { 5521 const PPTCharLevel& rCharLevel = mrStyleSheet.mpCharSheet[ mnInstance ]->maCharLevel[ mnDepth ]; 5522 PPTCharLevel* pCharLevel = nullptr; 5523 if ( ( nDestinationInstance == TSS_Type::Unknown ) 5524 || ( mnDepth && ( ( mnInstance == TSS_Type::Subtitle ) || ( mnInstance == TSS_Type::TextInShape ) ) ) ) 5525 bIsHardAttribute = true; 5526 else if ( nDestinationInstance != mnInstance ) 5527 pCharLevel = &mrStyleSheet.mpCharSheet[ nDestinationInstance ]->maCharLevel[ mnDepth ]; 5528 switch( nAttr ) 5529 { 5530 case PPT_CharAttr_Bold : 5531 case PPT_CharAttr_Italic : 5532 case PPT_CharAttr_Underline : 5533 case PPT_CharAttr_Shadow : 5534 case PPT_CharAttr_Strikeout : 5535 case PPT_CharAttr_Embossed : 5536 { 5537 rRetValue = ( rCharLevel.mnFlags & nMask ) ? 1 : 0; 5538 if ( pCharLevel ) 5539 { 5540 sal_uInt32 nTmp = ( pCharLevel->mnFlags & nMask ) ? 1 : 0; 5541 if ( rRetValue != nTmp ) 5542 bIsHardAttribute = true; 5543 } 5544 } 5545 break; 5546 case PPT_CharAttr_Font : 5547 { 5548 rRetValue = rCharLevel.mnFont; 5549 if ( pCharLevel && ( rRetValue != pCharLevel->mnFont ) ) 5550 bIsHardAttribute = true; 5551 } 5552 break; 5553 case PPT_CharAttr_AsianOrComplexFont : 5554 { 5555 rRetValue = rCharLevel.mnAsianOrComplexFont; 5556 if ( pCharLevel && ( rRetValue != pCharLevel->mnAsianOrComplexFont ) ) 5557 bIsHardAttribute = true; 5558 } 5559 break; 5560 case PPT_CharAttr_FontHeight : 5561 { 5562 rRetValue = rCharLevel.mnFontHeight; 5563 if ( pCharLevel && ( rRetValue != pCharLevel->mnFontHeight ) ) 5564 bIsHardAttribute = true; 5565 } 5566 break; 5567 case PPT_CharAttr_FontColor : 5568 { 5569 rRetValue = rCharLevel.mnFontColor; 5570 if ( pCharLevel && ( rRetValue != pCharLevel->mnFontColor ) ) 5571 bIsHardAttribute = true; 5572 } 5573 break; 5574 case PPT_CharAttr_Escapement : 5575 { 5576 rRetValue = rCharLevel.mnEscapement; 5577 if ( pCharLevel && ( rRetValue != pCharLevel->mnEscapement ) ) 5578 bIsHardAttribute = true; 5579 } 5580 break; 5581 default : 5582 OSL_FAIL( "SJ:PPTPortionObj::GetAttrib ( attribute does not exist )" ); 5583 } 5584 } 5585 return bIsHardAttribute; 5586 } 5587 5588 void PPTPortionObj::ApplyTo( SfxItemSet& rSet, SdrPowerPointImport& rManager, TSS_Type nDestinationInstance ) 5589 { 5590 ApplyTo( rSet, rManager, nDestinationInstance, nullptr ); 5591 } 5592 5593 void PPTPortionObj::ApplyTo( SfxItemSet& rSet, SdrPowerPointImport& rManager, TSS_Type nDestinationInstance, const PPTTextObj* pTextObj ) 5594 { 5595 sal_uInt32 nVal; 5596 if ( GetAttrib( PPT_CharAttr_Bold, nVal, nDestinationInstance ) ) 5597 { 5598 rSet.Put( SvxWeightItem( nVal != 0 ? WEIGHT_BOLD : WEIGHT_NORMAL, EE_CHAR_WEIGHT ) ); 5599 rSet.Put( SvxWeightItem( nVal != 0 ? WEIGHT_BOLD : WEIGHT_NORMAL, EE_CHAR_WEIGHT_CJK ) ); 5600 rSet.Put( SvxWeightItem( nVal != 0 ? WEIGHT_BOLD : WEIGHT_NORMAL, EE_CHAR_WEIGHT_CTL ) ); 5601 } 5602 if ( GetAttrib( PPT_CharAttr_Italic, nVal, nDestinationInstance ) ) 5603 { 5604 rSet.Put( SvxPostureItem( nVal != 0 ? ITALIC_NORMAL : ITALIC_NONE, EE_CHAR_ITALIC ) ); 5605 rSet.Put( SvxPostureItem( nVal != 0 ? ITALIC_NORMAL : ITALIC_NONE, EE_CHAR_ITALIC_CJK ) ); 5606 rSet.Put( SvxPostureItem( nVal != 0 ? ITALIC_NORMAL : ITALIC_NONE, EE_CHAR_ITALIC_CTL ) ); 5607 } 5608 if ( GetAttrib( PPT_CharAttr_Underline, nVal, nDestinationInstance ) ) 5609 rSet.Put( SvxUnderlineItem( nVal != 0 ? LINESTYLE_SINGLE : LINESTYLE_NONE, EE_CHAR_UNDERLINE ) ); 5610 5611 if ( GetAttrib( PPT_CharAttr_Shadow, nVal, nDestinationInstance ) ) 5612 rSet.Put( SvxShadowedItem( nVal != 0, EE_CHAR_SHADOW ) ); 5613 5614 if ( GetAttrib( PPT_CharAttr_Strikeout, nVal, nDestinationInstance ) ) 5615 rSet.Put( SvxCrossedOutItem( nVal != 0 ? STRIKEOUT_SINGLE : STRIKEOUT_NONE, EE_CHAR_STRIKEOUT ) ); 5616 5617 sal_uInt32 nAsianFontId = 0xffff; 5618 if ( GetAttrib( PPT_CharAttr_AsianOrComplexFont, nAsianFontId, nDestinationInstance ) ) 5619 { 5620 if ( nAsianFontId != 0xffff ) 5621 { 5622 const PptFontEntityAtom* pFontEnityAtom = rManager.GetFontEnityAtom( nAsianFontId ); 5623 if ( pFontEnityAtom ) 5624 { 5625 rSet.Put( SvxFontItem( pFontEnityAtom->eFamily, pFontEnityAtom->aName, 5626 OUString(), pFontEnityAtom->ePitch, pFontEnityAtom->eCharSet, EE_CHAR_FONTINFO_CJK ) ); 5627 rSet.Put( SvxFontItem( pFontEnityAtom->eFamily, pFontEnityAtom->aName, 5628 OUString(), pFontEnityAtom->ePitch, pFontEnityAtom->eCharSet, EE_CHAR_FONTINFO_CTL ) ); 5629 } 5630 } 5631 } 5632 if ( GetAttrib( PPT_CharAttr_Font, nVal, nDestinationInstance ) ) 5633 { 5634 const PptFontEntityAtom* pFontEnityAtom = rManager.GetFontEnityAtom( nVal ); 5635 if ( pFontEnityAtom ) 5636 { 5637 rSet.Put( SvxFontItem( pFontEnityAtom->eFamily, pFontEnityAtom->aName, OUString(), pFontEnityAtom->ePitch, pFontEnityAtom->eCharSet, EE_CHAR_FONTINFO ) ); 5638 5639 // #i119475# bullet font info for CJK and CTL 5640 if ( RTL_TEXTENCODING_SYMBOL == pFontEnityAtom->eCharSet ) 5641 { 5642 rSet.Put( SvxFontItem( pFontEnityAtom->eFamily, pFontEnityAtom->aName, OUString(), pFontEnityAtom->ePitch, pFontEnityAtom->eCharSet, EE_CHAR_FONTINFO_CJK ) ); 5643 rSet.Put( SvxFontItem( pFontEnityAtom->eFamily, pFontEnityAtom->aName, OUString(), pFontEnityAtom->ePitch, pFontEnityAtom->eCharSet, EE_CHAR_FONTINFO_CTL ) ); 5644 } 5645 } 5646 } 5647 if ( GetAttrib( PPT_CharAttr_FontHeight, nVal, nDestinationInstance ) ) // Schriftgrad in Point 5648 { 5649 sal_uInt32 nHeight = rManager.ScalePoint( nVal ); 5650 rSet.Put( SvxFontHeightItem( nHeight, 100, EE_CHAR_FONTHEIGHT ) ); 5651 rSet.Put( SvxFontHeightItem( nHeight, 100, EE_CHAR_FONTHEIGHT_CJK ) ); 5652 rSet.Put( SvxFontHeightItem( nHeight, 100, EE_CHAR_FONTHEIGHT_CTL ) ); 5653 } 5654 5655 if ( GetAttrib( PPT_CharAttr_Embossed, nVal, nDestinationInstance ) ) 5656 rSet.Put( SvxCharReliefItem( nVal != 0 ? FontRelief::Embossed : FontRelief::NONE, EE_CHAR_RELIEF ) ); 5657 if ( nVal ) /* if Embossed is set, the font color depends to the fillstyle/color of the object, 5658 if the object has no fillstyle, the font color depends to fillstyle of the background */ 5659 { 5660 Color aDefColor( COL_BLACK ); 5661 sal_uInt32 eFillType = mso_fillSolid; 5662 if ( rManager.GetPropertyValue( DFF_Prop_fNoFillHitTest, 0 ) & 0x10 ) 5663 eFillType = rManager.GetPropertyValue(DFF_Prop_fillType, mso_fillSolid); 5664 else 5665 eFillType = mso_fillBackground; 5666 switch( eFillType ) 5667 { 5668 case mso_fillShade : 5669 case mso_fillShadeCenter : 5670 case mso_fillShadeShape : 5671 case mso_fillShadeScale : 5672 case mso_fillShadeTitle : 5673 case mso_fillSolid : 5674 aDefColor = rManager.MSO_CLR_ToColor( rManager.GetPropertyValue( DFF_Prop_fillColor, 0 ) ); 5675 break; 5676 case mso_fillPattern : 5677 aDefColor = rManager.MSO_CLR_ToColor( rManager.GetPropertyValue( DFF_Prop_fillBackColor, 0 ) ); 5678 break; 5679 case mso_fillTexture : 5680 { 5681 Graphic aGraf; 5682 if ( rManager.GetBLIP( rManager.GetPropertyValue( DFF_Prop_fillBlip, 0 ), aGraf ) ) 5683 { 5684 Bitmap aBmp( aGraf.GetBitmapEx().GetBitmap() ); 5685 Size aSize( aBmp.GetSizePixel() ); 5686 if ( aSize.Width() && aSize.Height() ) 5687 { 5688 if ( aSize.Width () > 64 ) 5689 aSize.setWidth( 64 ); 5690 if ( aSize.Height() > 64 ) 5691 aSize.setHeight( 64 ); 5692 5693 Bitmap::ScopedReadAccess pAcc(aBmp); 5694 if( pAcc ) 5695 { 5696 sal_uLong nRt = 0, nGn = 0, nBl = 0; 5697 const tools::Long nWidth = aSize.Width(); 5698 const tools::Long nHeight = aSize.Height(); 5699 5700 if( pAcc->HasPalette() ) 5701 { 5702 for( tools::Long nY = 0; nY < nHeight; nY++ ) 5703 { 5704 Scanline pScanline = pAcc->GetScanline( nY ); 5705 for( tools::Long nX = 0; nX < nWidth; nX++ ) 5706 { 5707 const BitmapColor& rCol = pAcc->GetPaletteColor( pAcc->GetIndexFromData( pScanline, nX ) ); 5708 nRt+=rCol.GetRed(); nGn+=rCol.GetGreen(); nBl+=rCol.GetBlue(); 5709 } 5710 } 5711 } 5712 else 5713 { 5714 for( tools::Long nY = 0; nY < nHeight; nY++ ) 5715 { 5716 Scanline pScanline = pAcc->GetScanline( nY ); 5717 for( tools::Long nX = 0; nX < nWidth; nX++ ) 5718 { 5719 const BitmapColor aCol( pAcc->GetPixelFromData( pScanline, nX ) ); 5720 nRt+=aCol.GetRed(); nGn+=aCol.GetGreen(); nBl+=aCol.GetBlue(); 5721 } 5722 } 5723 } 5724 pAcc.reset(); 5725 sal_uInt32 nC = aSize.Width() * aSize.Height(); 5726 nRt /= nC; 5727 nGn /= nC; 5728 nBl /= nC; 5729 aDefColor = Color(sal_uInt8( nRt ), sal_uInt8( nGn ),sal_uInt8( nBl ) ); 5730 } 5731 } 5732 } 5733 } 5734 break; 5735 case mso_fillBackground : 5736 { 5737 if ( pTextObj ) // the textobject is needed 5738 { 5739 const SfxItemSet* pItemSet = pTextObj->GetBackground(); 5740 if ( pItemSet ) 5741 { 5742 const XFillStyleItem* pFillStyleItem = pItemSet->GetItemIfSet( XATTR_FILLSTYLE, false ); 5743 if ( pFillStyleItem ) 5744 { 5745 drawing::FillStyle eFillStyle = pFillStyleItem->GetValue(); 5746 switch( eFillStyle ) 5747 { 5748 case drawing::FillStyle_SOLID : 5749 { 5750 const XColorItem* pFillColorItem = pItemSet->GetItemIfSet( XATTR_FILLCOLOR, false ); 5751 if ( pFillColorItem ) 5752 aDefColor = pFillColorItem->GetColorValue(); 5753 } 5754 break; 5755 case drawing::FillStyle_GRADIENT : 5756 { 5757 const XFillGradientItem* pGradientItem = pItemSet->GetItemIfSet( XATTR_FILLGRADIENT, false ); 5758 if ( pGradientItem ) 5759 aDefColor = pGradientItem->GetGradientValue().GetStartColor(); 5760 } 5761 break; 5762 case drawing::FillStyle_HATCH : 5763 case drawing::FillStyle_BITMAP : 5764 aDefColor = COL_WHITE; 5765 break; 5766 default: break; 5767 } 5768 } 5769 } 5770 } 5771 } 5772 break; 5773 default: break; 5774 } 5775 rSet.Put( SvxColorItem( aDefColor, EE_CHAR_COLOR ) ); 5776 } 5777 else 5778 { 5779 if ( GetAttrib( PPT_CharAttr_FontColor, nVal, nDestinationInstance ) ) // text color (4Byte-Arg) 5780 { 5781 Color aCol( rManager.MSO_TEXT_CLR_ToColor( nVal ) ); 5782 rSet.Put( SvxColorItem( aCol, EE_CHAR_COLOR ) ); 5783 if ( nDestinationInstance == TSS_Type::Unknown ) 5784 mrStyleSheet.mpCharSheet[ mnInstance ]->maCharLevel[ mnDepth ].mnFontColorInStyleSheet = aCol; 5785 } 5786 else if ( nVal & 0x0f000000 ) // this is not a hard attribute, but maybe the page has a different colorscheme, 5787 { // so that in this case we must use a hard color attribute 5788 Color aCol( rManager.MSO_TEXT_CLR_ToColor( nVal ) ); 5789 Color& aColorInSheet = mrStyleSheet.mpCharSheet[ mnInstance ]->maCharLevel[ mnDepth ].mnFontColorInStyleSheet; 5790 if ( aColorInSheet != aCol ) 5791 rSet.Put( SvxColorItem( aCol, EE_CHAR_COLOR ) ); 5792 } 5793 } 5794 5795 if ( GetAttrib( PPT_CharAttr_Escapement, nVal, nDestinationInstance ) ) // super-/subscript in % 5796 { 5797 sal_uInt16 nEsc = 0; 5798 sal_uInt8 nProp = 100; 5799 5800 if ( nVal ) 5801 { 5802 nEsc = static_cast<sal_Int16>(nVal); 5803 nProp = DFLT_ESC_PROP; 5804 } 5805 SvxEscapementItem aItem( nEsc, nProp, EE_CHAR_ESCAPEMENT ); 5806 rSet.Put( aItem ); 5807 } 5808 if ( mnLanguage[ 0 ] ) 5809 rSet.Put( SvxLanguageItem( mnLanguage[ 0 ], EE_CHAR_LANGUAGE ) ); 5810 if ( mnLanguage[ 1 ] ) 5811 rSet.Put( SvxLanguageItem( mnLanguage[ 1 ], EE_CHAR_LANGUAGE_CJK ) ); 5812 if ( mnLanguage[ 2 ] ) 5813 rSet.Put( SvxLanguageItem( mnLanguage[ 2 ], EE_CHAR_LANGUAGE_CTL ) ); 5814 } 5815 5816 SvxFieldItem* PPTPortionObj::GetTextField() 5817 { 5818 if ( mpFieldItem ) 5819 return new SvxFieldItem( *mpFieldItem ); 5820 return nullptr; 5821 } 5822 5823 namespace 5824 { 5825 sal_uInt16 sanitizeForMaxPPTLevels(sal_uInt16 nDepth) 5826 { 5827 if (nDepth >= nMaxPPTLevels) 5828 { 5829 SAL_WARN("filter.ms", "Para Style Sheet depth " << nDepth << " but " << nMaxPPTLevels - 1 << " is max possible"); 5830 nDepth = nMaxPPTLevels - 1; 5831 } 5832 return nDepth; 5833 } 5834 } 5835 5836 PPTParagraphObj::PPTParagraphObj( const PPTStyleSheet& rStyleSheet, TSS_Type nInstance, sal_uInt16 nDepth ) : 5837 PPTNumberFormatCreator ( nullptr ), 5838 mrStyleSheet ( rStyleSheet ), 5839 mnInstance ( nInstance ), 5840 mnCurrentObject ( 0 ) 5841 { 5842 mxParaSet->mnDepth = sanitizeForMaxPPTLevels(nDepth); 5843 } 5844 5845 PPTParagraphObj::PPTParagraphObj( PPTStyleTextPropReader& rPropReader, 5846 size_t const nCurParaPos, size_t& rnCurCharPos, 5847 const PPTStyleSheet& rStyleSheet, 5848 TSS_Type nInstance, PPTTextRulerInterpreter const & rRuler ) : 5849 PPTParaPropSet ( *rPropReader.aParaPropList[nCurParaPos] ), 5850 PPTNumberFormatCreator ( nullptr ), 5851 PPTTextRulerInterpreter ( rRuler ), 5852 mrStyleSheet ( rStyleSheet ), 5853 mnInstance ( nInstance ), 5854 mnCurrentObject ( 0 ) 5855 { 5856 if (rnCurCharPos >= rPropReader.aCharPropList.size()) 5857 return; 5858 5859 sal_uInt32 const nCurrentParagraph = 5860 rPropReader.aCharPropList[rnCurCharPos]->mnParagraph; 5861 for (; rnCurCharPos < rPropReader.aCharPropList.size() && 5862 rPropReader.aCharPropList[rnCurCharPos]->mnParagraph == nCurrentParagraph; 5863 ++rnCurCharPos) 5864 { 5865 PPTCharPropSet *const pCharPropSet = 5866 rPropReader.aCharPropList[rnCurCharPos].get(); 5867 std::unique_ptr<PPTPortionObj> pPPTPortion(new PPTPortionObj( 5868 *pCharPropSet, rStyleSheet, nInstance, mxParaSet->mnDepth)); 5869 m_PortionList.push_back(std::move(pPPTPortion)); 5870 } 5871 } 5872 5873 PPTParagraphObj::~PPTParagraphObj() 5874 { 5875 } 5876 5877 void PPTParagraphObj::AppendPortion( PPTPortionObj& rPPTPortion ) 5878 { 5879 m_PortionList.push_back( 5880 std::make_unique<PPTPortionObj>(rPPTPortion)); 5881 } 5882 5883 void PPTParagraphObj::UpdateBulletRelSize( sal_uInt32& nBulletRelSize ) const 5884 { 5885 if ( nBulletRelSize <= 0x7fff ) // a negative value is the absolute bullet height 5886 return; 5887 5888 sal_uInt16 nFontHeight = 0; 5889 if (!m_PortionList.empty()) 5890 { 5891 PPTPortionObj const& rPortion = *m_PortionList.front(); 5892 if (rPortion.mpImplPPTCharPropSet->mnAttrSet & (1 << PPT_CharAttr_FontHeight)) 5893 { 5894 nFontHeight = rPortion.mpImplPPTCharPropSet->mnFontHeight; 5895 } 5896 } 5897 // if we do not have a hard attributed fontheight, the fontheight is taken from the style 5898 if ( !nFontHeight ) 5899 { 5900 nFontHeight = mrStyleSheet.mpCharSheet[ mnInstance ]->maCharLevel[sanitizeForMaxPPTLevels(mxParaSet->mnDepth)].mnFontHeight; 5901 } 5902 nBulletRelSize = nFontHeight ? ((- static_cast<sal_Int16>(nBulletRelSize)) * 100 ) / nFontHeight : 100; 5903 } 5904 5905 bool PPTParagraphObj::GetAttrib( sal_uInt32 nAttr, sal_uInt32& rRetValue, TSS_Type nDestinationInstance ) 5906 { 5907 sal_uInt32 nMask = 1 << nAttr; 5908 rRetValue = 0; 5909 5910 if ( nAttr > 21 ) 5911 { 5912 OSL_FAIL( "SJ:PPTParagraphObj::GetAttrib - attribute does not exist" ); 5913 return false; 5914 } 5915 5916 bool bIsHardAttribute = ( ( mxParaSet->mnAttrSet & nMask ) != 0 ); 5917 5918 sal_uInt16 nDepth = sanitizeForMaxPPTLevels(mxParaSet->mnDepth); 5919 5920 if ( bIsHardAttribute ) 5921 { 5922 if ( nAttr == PPT_ParaAttr_BulletColor ) 5923 { 5924 bool bHardBulletColor; 5925 if ( mxParaSet->mnAttrSet & ( 1 << PPT_ParaAttr_BuHardColor ) ) 5926 bHardBulletColor = mxParaSet->mpArry[ PPT_ParaAttr_BuHardColor ] != 0; 5927 else 5928 bHardBulletColor = ( mrStyleSheet.mpParaSheet[ mnInstance ]->maParaLevel[nDepth].mnBuFlags 5929 & ( 1 << PPT_ParaAttr_BuHardColor ) ) != 0; 5930 if ( bHardBulletColor ) 5931 rRetValue = mxParaSet->mnBulletColor; 5932 else 5933 { 5934 rRetValue = PPT_COLSCHEME_TEXT_UND_ZEILEN; 5935 if ((nDestinationInstance != TSS_Type::Unknown) && !m_PortionList.empty()) 5936 { 5937 PPTPortionObj const& rPortion = *m_PortionList.front(); 5938 if (rPortion.mpImplPPTCharPropSet->mnAttrSet & (1 << PPT_CharAttr_FontColor)) 5939 { 5940 rRetValue = rPortion.mpImplPPTCharPropSet->mnColor; 5941 } 5942 else 5943 { 5944 rRetValue = mrStyleSheet.mpCharSheet[ nDestinationInstance ]->maCharLevel[nDepth].mnFontColor; 5945 } 5946 } 5947 } 5948 } 5949 else if ( nAttr == PPT_ParaAttr_BulletFont ) 5950 { 5951 bool bHardBuFont; 5952 if ( mxParaSet->mnAttrSet & ( 1 << PPT_ParaAttr_BuHardFont ) ) 5953 bHardBuFont = mxParaSet->mpArry[ PPT_ParaAttr_BuHardFont ] != 0; 5954 else 5955 bHardBuFont = ( mrStyleSheet.mpParaSheet[ mnInstance ]->maParaLevel[nDepth].mnBuFlags 5956 & ( 1 << PPT_ParaAttr_BuHardFont ) ) != 0; 5957 if ( bHardBuFont ) 5958 rRetValue = mxParaSet->mpArry[ PPT_ParaAttr_BulletFont ]; 5959 else 5960 { 5961 // it is the font used which assigned to the first character of the following text 5962 rRetValue = 0; 5963 if ((nDestinationInstance != TSS_Type::Unknown) && !m_PortionList.empty()) 5964 { 5965 PPTPortionObj const& rPortion = *m_PortionList.front(); 5966 if (rPortion.mpImplPPTCharPropSet->mnAttrSet & ( 1 << PPT_CharAttr_Font ) ) 5967 { 5968 rRetValue = rPortion.mpImplPPTCharPropSet->mnFont; 5969 } 5970 else 5971 { 5972 rRetValue = mrStyleSheet.mpCharSheet[ nDestinationInstance ]->maCharLevel[nDepth].mnFont; 5973 } 5974 } 5975 } 5976 } 5977 else 5978 rRetValue = mxParaSet->mpArry[ nAttr ]; 5979 } 5980 else 5981 { 5982 const PPTParaLevel& rParaLevel = mrStyleSheet.mpParaSheet[ mnInstance ]->maParaLevel[nDepth]; 5983 5984 PPTParaLevel* pParaLevel = nullptr; 5985 if ( ( nDestinationInstance == TSS_Type::Unknown ) 5986 || ( nDepth && ( ( mnInstance == TSS_Type::Subtitle ) || ( mnInstance == TSS_Type::TextInShape ) ) ) ) 5987 bIsHardAttribute = true; 5988 else if ( nDestinationInstance != mnInstance ) 5989 pParaLevel = &mrStyleSheet.mpParaSheet[ nDestinationInstance ]->maParaLevel[nDepth]; 5990 switch ( nAttr ) 5991 { 5992 case PPT_ParaAttr_BulletOn : 5993 { 5994 rRetValue = rParaLevel.mnBuFlags & ( 1 << PPT_ParaAttr_BulletOn ); 5995 if ( pParaLevel ) 5996 { 5997 if ( rRetValue != ( static_cast<sal_uInt32>(pParaLevel->mnBuFlags) & ( 1 << PPT_ParaAttr_BulletOn ) ) ) 5998 bIsHardAttribute = true; 5999 } 6000 } 6001 break; 6002 case PPT_ParaAttr_BuHardFont : 6003 case PPT_ParaAttr_BuHardColor : 6004 case PPT_ParaAttr_BuHardHeight : 6005 OSL_FAIL( "SJ:PPTParagraphObj::GetAttrib - this attribute does not make sense" ); 6006 break; 6007 case PPT_ParaAttr_BulletChar : 6008 { 6009 rRetValue = rParaLevel.mnBulletChar; 6010 if ( pParaLevel && ( rRetValue != pParaLevel->mnBulletChar ) ) 6011 bIsHardAttribute = true; 6012 } 6013 break; 6014 case PPT_ParaAttr_BulletFont : 6015 { 6016 bool bHardBuFont; 6017 if ( mxParaSet->mnAttrSet & ( 1 << PPT_ParaAttr_BuHardFont ) ) 6018 bHardBuFont = mxParaSet->mpArry[ PPT_ParaAttr_BuHardFont ] != 0; 6019 else 6020 bHardBuFont = ( rParaLevel.mnBuFlags & ( 1 << PPT_ParaAttr_BuHardFont ) ) != 0; 6021 if ( bHardBuFont ) 6022 { 6023 rRetValue = rParaLevel.mnBulletFont; 6024 if ( pParaLevel && ( rRetValue != pParaLevel->mnBulletFont ) ) 6025 bIsHardAttribute = true; 6026 } 6027 else 6028 { 6029 if (!m_PortionList.empty()) 6030 { 6031 PPTPortionObj const& rPortion = *m_PortionList.front(); 6032 bIsHardAttribute = rPortion.GetAttrib( 6033 PPT_CharAttr_Font, rRetValue, nDestinationInstance); 6034 } 6035 else 6036 { 6037 rRetValue = mrStyleSheet.mpCharSheet[ mnInstance ]->maCharLevel[nDepth].mnFont; 6038 bIsHardAttribute = true; 6039 } 6040 } 6041 } 6042 break; 6043 case PPT_ParaAttr_BulletHeight : 6044 { 6045 rRetValue = rParaLevel.mnBulletHeight; 6046 if ( pParaLevel && ( rRetValue != pParaLevel->mnBulletHeight ) ) 6047 bIsHardAttribute = true; 6048 } 6049 break; 6050 case PPT_ParaAttr_BulletColor : 6051 { 6052 bool bHardBulletColor; 6053 if ( mxParaSet->mnAttrSet & ( 1 << PPT_ParaAttr_BuHardColor ) ) 6054 bHardBulletColor = mxParaSet->mpArry[ PPT_ParaAttr_BuHardColor ] != 0; 6055 else 6056 bHardBulletColor = ( rParaLevel.mnBuFlags & ( 1 << PPT_ParaAttr_BuHardColor ) ) != 0; 6057 if ( bHardBulletColor ) 6058 { 6059 rRetValue = rParaLevel.mnBulletColor; 6060 if ( pParaLevel && ( rRetValue != pParaLevel->mnBulletColor ) ) 6061 bIsHardAttribute = true; 6062 } 6063 else 6064 { 6065 if (!m_PortionList.empty()) 6066 { 6067 PPTPortionObj const& rPortion = *m_PortionList.front(); 6068 if (rPortion.mbIsHyperlink ) 6069 { 6070 if( rPortion.mbHardHylinkOrigColor ) 6071 rRetValue = rPortion.mnHylinkOrigColor; 6072 else 6073 rRetValue = mrStyleSheet.mpCharSheet[ mnInstance ]->maCharLevel[nDepth].mnFontColor; 6074 bIsHardAttribute = true; 6075 } 6076 else 6077 { 6078 bIsHardAttribute = rPortion.GetAttrib( PPT_CharAttr_FontColor, rRetValue, nDestinationInstance ); 6079 } 6080 } 6081 else 6082 { 6083 rRetValue = mrStyleSheet.mpCharSheet[ mnInstance ]->maCharLevel[nDepth].mnFontColor; 6084 bIsHardAttribute = true; 6085 } 6086 } 6087 } 6088 break; 6089 case PPT_ParaAttr_Adjust : 6090 { 6091 rRetValue = rParaLevel.mnAdjust; 6092 if ( pParaLevel && ( rRetValue != pParaLevel->mnAdjust ) ) 6093 bIsHardAttribute = true; 6094 } 6095 break; 6096 case PPT_ParaAttr_LineFeed : 6097 { 6098 rRetValue = rParaLevel.mnLineFeed; 6099 if ( pParaLevel && ( rRetValue != pParaLevel->mnLineFeed ) ) 6100 bIsHardAttribute = true; 6101 } 6102 break; 6103 case PPT_ParaAttr_UpperDist : 6104 { 6105 rRetValue = rParaLevel.mnUpperDist; 6106 if ( pParaLevel && ( rRetValue != pParaLevel->mnUpperDist ) ) 6107 bIsHardAttribute = true; 6108 } 6109 break; 6110 case PPT_ParaAttr_LowerDist : 6111 { 6112 rRetValue = rParaLevel.mnLowerDist; 6113 if ( pParaLevel && ( rRetValue != pParaLevel->mnLowerDist ) ) 6114 bIsHardAttribute = true; 6115 } 6116 break; 6117 case PPT_ParaAttr_TextOfs : 6118 { 6119 rRetValue = rParaLevel.mnTextOfs; 6120 if ( pParaLevel && ( rRetValue != pParaLevel->mnTextOfs ) ) 6121 bIsHardAttribute = true; 6122 } 6123 break; 6124 case PPT_ParaAttr_BulletOfs : 6125 { 6126 rRetValue = rParaLevel.mnBulletOfs; 6127 if ( pParaLevel && ( rRetValue != pParaLevel->mnBulletOfs ) ) 6128 bIsHardAttribute = true; 6129 } 6130 break; 6131 case PPT_ParaAttr_DefaultTab : 6132 { 6133 rRetValue = rParaLevel.mnDefaultTab; 6134 if ( pParaLevel && ( rRetValue != pParaLevel->mnDefaultTab ) ) 6135 bIsHardAttribute = true; 6136 } 6137 break; 6138 case PPT_ParaAttr_AsianLB_1 : 6139 { 6140 rRetValue = rParaLevel.mnAsianLineBreak & 1; 6141 if ( pParaLevel && ( rRetValue != ( static_cast<sal_uInt32>(pParaLevel->mnAsianLineBreak) & 1 ) ) ) 6142 bIsHardAttribute = true; 6143 } 6144 break; 6145 case PPT_ParaAttr_AsianLB_2 : 6146 { 6147 rRetValue = ( rParaLevel.mnAsianLineBreak >> 1 ) & 1; 6148 if ( pParaLevel && ( rRetValue != ( ( static_cast<sal_uInt32>(pParaLevel->mnAsianLineBreak) >> 1 ) & 1 ) ) ) 6149 bIsHardAttribute = true; 6150 } 6151 break; 6152 case PPT_ParaAttr_AsianLB_3 : 6153 { 6154 rRetValue = ( rParaLevel.mnAsianLineBreak >> 2 ) & 1; 6155 if ( pParaLevel && ( rRetValue != ( ( static_cast<sal_uInt32>(pParaLevel->mnAsianLineBreak) >> 2 ) & 1 ) ) ) 6156 bIsHardAttribute = true; 6157 } 6158 break; 6159 case PPT_ParaAttr_BiDi : 6160 { 6161 rRetValue = rParaLevel.mnBiDi; 6162 if ( pParaLevel && ( rRetValue != pParaLevel->mnBiDi ) ) 6163 bIsHardAttribute = true; 6164 } 6165 break; 6166 } 6167 } 6168 return bIsHardAttribute; 6169 } 6170 6171 void PPTParagraphObj::ApplyTo( SfxItemSet& rSet, std::optional< sal_Int16 >& rStartNumbering, SdrPowerPointImport const & rManager, TSS_Type nDestinationInstance ) 6172 { 6173 sal_Int16 nVal2; 6174 sal_uInt32 nVal, nUpperDist, nLowerDist; 6175 TSS_Type nInstance = nDestinationInstance != TSS_Type::Unknown ? nDestinationInstance : mnInstance; 6176 6177 if ( ( nDestinationInstance != TSS_Type::Unknown ) || ( mxParaSet->mnDepth <= 1 ) ) 6178 { 6179 SvxNumBulletItem* pNumBulletItem = mrStyleSheet.mpNumBulletItem[ nInstance ].get(); 6180 if ( pNumBulletItem ) 6181 { 6182 SvxNumberFormat aNumberFormat( SVX_NUM_NUMBER_NONE ); 6183 if ( GetNumberFormat( rManager, aNumberFormat, this, nDestinationInstance, rStartNumbering ) ) 6184 { 6185 if ( aNumberFormat.GetNumberingType() == SVX_NUM_NUMBER_NONE ) 6186 { 6187 aNumberFormat.SetAbsLSpace( 0 ); 6188 aNumberFormat.SetFirstLineOffset( 0 ); 6189 aNumberFormat.SetCharTextDistance( 0 ); 6190 aNumberFormat.SetFirstLineIndent( 0 ); 6191 aNumberFormat.SetIndentAt( 0 ); 6192 } 6193 SvxNumBulletItem aNewNumBulletItem( *pNumBulletItem ); 6194 SvxNumRule& rRule = aNewNumBulletItem.GetNumRule(); 6195 rRule.SetLevel( mxParaSet->mnDepth, aNumberFormat ); 6196 for (sal_uInt16 i = 0; i < rRule.GetLevelCount(); ++i) 6197 { 6198 if ( i != mxParaSet->mnDepth ) 6199 { 6200 sal_uInt16 n = sanitizeForMaxPPTLevels(i); 6201 6202 SvxNumberFormat aNumberFormat2( rRule.GetLevel( i ) ); 6203 const PPTParaLevel& rParaLevel = mrStyleSheet.mpParaSheet[ nInstance ]->maParaLevel[ n ]; 6204 const PPTCharLevel& rCharLevel = mrStyleSheet.mpCharSheet[ nInstance ]->maCharLevel[ n ]; 6205 sal_uInt32 nColor; 6206 if ( rParaLevel.mnBuFlags & ( 1 << PPT_ParaAttr_BuHardColor ) ) 6207 nColor = rParaLevel.mnBulletColor; 6208 else 6209 nColor = rCharLevel.mnFontColor; 6210 aNumberFormat2.SetBulletColor( rManager.MSO_TEXT_CLR_ToColor( nColor ) ); 6211 rRule.SetLevel( i, aNumberFormat2 ); 6212 } 6213 } 6214 rSet.Put( aNewNumBulletItem ); 6215 } 6216 } 6217 } 6218 6219 sal_uInt32 nIsBullet2, _nTextOfs, _nBulletOfs; 6220 GetAttrib(PPT_ParaAttr_BulletOn, nIsBullet2, nDestinationInstance); 6221 GetAttrib(PPT_ParaAttr_TextOfs, _nTextOfs, nDestinationInstance); 6222 GetAttrib(PPT_ParaAttr_BulletOfs, _nBulletOfs, nDestinationInstance); 6223 if ( !nIsBullet2 ) 6224 { 6225 SvxLRSpaceItem aLRSpaceItem( EE_PARA_LRSPACE ); 6226 auto const nAbsLSpace = convertMasterUnitToMm100(_nTextOfs); 6227 auto const nFirstLineOffset = nAbsLSpace - convertMasterUnitToMm100(_nBulletOfs); 6228 aLRSpaceItem.SetLeft( nAbsLSpace ); 6229 aLRSpaceItem.SetTextFirstLineOffsetValue( -nFirstLineOffset ); 6230 rSet.Put( aLRSpaceItem ); 6231 } 6232 else 6233 { 6234 SvxLRSpaceItem aLRSpaceItem( EE_PARA_LRSPACE ); 6235 aLRSpaceItem.SetLeft( 0 ); 6236 aLRSpaceItem.SetTextFirstLineOffsetValue( 0 ); 6237 rSet.Put( aLRSpaceItem ); 6238 } 6239 if ( GetAttrib( PPT_ParaAttr_Adjust, nVal, nDestinationInstance ) ) 6240 { 6241 if ( nVal <= 3 ) 6242 { // paragraph adjustment 6243 static SvxAdjust const aAdj[ 4 ] = { SvxAdjust::Left, SvxAdjust::Center, SvxAdjust::Right, SvxAdjust::Block }; 6244 rSet.Put( SvxAdjustItem( aAdj[ nVal ], EE_PARA_JUST ) ); 6245 } 6246 } 6247 6248 if ( GetAttrib( PPT_ParaAttr_AsianLB_1, nVal, nDestinationInstance ) ) 6249 rSet.Put(SvxForbiddenRuleItem(nVal != 0, EE_PARA_FORBIDDENRULES)); 6250 if ( GetAttrib( PPT_ParaAttr_AsianLB_3, nVal, nDestinationInstance ) ) 6251 rSet.Put(SvxHangingPunctuationItem(nVal != 0, EE_PARA_HANGINGPUNCTUATION)); 6252 6253 if ( GetAttrib( PPT_ParaAttr_BiDi, nVal, nDestinationInstance ) ) 6254 rSet.Put( SvxFrameDirectionItem( nVal == 1 ? SvxFrameDirection::Horizontal_RL_TB : SvxFrameDirection::Horizontal_LR_TB, EE_PARA_WRITINGDIR ) ); 6255 6256 // LineSpacing 6257 PPTPortionObj* pPortion = First(); 6258 bool bIsHardAttribute = GetAttrib( PPT_ParaAttr_LineFeed, nVal, nDestinationInstance ); 6259 nVal2 = static_cast<sal_Int16>(nVal); 6260 sal_uInt32 nFont = sal_uInt32(); 6261 if ( pPortion && pPortion->GetAttrib( PPT_CharAttr_Font, nFont, nDestinationInstance ) ) 6262 bIsHardAttribute = true; 6263 6264 if ( bIsHardAttribute ) 6265 { 6266 SdrTextFixedCellHeightItem aHeightItem(true); 6267 aHeightItem.SetWhich(SDRATTR_TEXT_USEFIXEDCELLHEIGHT); 6268 rSet.Put( aHeightItem ); 6269 SvxLineSpacingItem aItem( 200, EE_PARA_SBL ); 6270 if ( nVal2 <= 0 ) { 6271 aItem.SetLineHeight( static_cast<sal_uInt16>( rManager.ScalePoint( -nVal2 ) / 8 ) ); 6272 aItem.SetLineSpaceRule( SvxLineSpaceRule::Fix ); 6273 aItem.SetInterLineSpaceRule(SvxInterLineSpaceRule::Off); 6274 } else 6275 { 6276 sal_uInt16 nPropLineSpace = static_cast<sal_uInt16>(nVal2); 6277 aItem.SetPropLineSpace( nPropLineSpace ); 6278 aItem.SetLineSpaceRule( SvxLineSpaceRule::Auto ); 6279 } 6280 rSet.Put( aItem ); 6281 } 6282 6283 // Paragraph Spacing 6284 bIsHardAttribute = ( static_cast<sal_uInt32>(GetAttrib( PPT_ParaAttr_UpperDist, nUpperDist, nDestinationInstance )) + 6285 static_cast<sal_uInt32>(GetAttrib( PPT_ParaAttr_LowerDist, nLowerDist, nDestinationInstance )) ) != 0; 6286 if ( ( nUpperDist > 0 ) || ( nLowerDist > 0 ) ) 6287 { 6288 if (!m_PortionList.empty()) 6289 { 6290 sal_uInt32 nFontHeight = 0; 6291 m_PortionList.back()->GetAttrib( 6292 PPT_CharAttr_FontHeight, nFontHeight, nDestinationInstance); 6293 if ( static_cast<sal_Int16>(nUpperDist) > 0 ) 6294 nUpperDist = - static_cast<sal_Int16>( ( nFontHeight * nUpperDist * 100 ) / 1000 ); 6295 if ( static_cast<sal_Int16>(nLowerDist) > 0 ) 6296 nLowerDist = - static_cast<sal_Int16>( ( nFontHeight * nLowerDist * 100 ) / 1000 ); 6297 } 6298 bIsHardAttribute = true; 6299 } 6300 if ( bIsHardAttribute ) 6301 { 6302 SvxULSpaceItem aULSpaceItem( EE_PARA_ULSPACE ); 6303 nVal2 = static_cast<sal_Int16>(nUpperDist); 6304 if ( nVal2 <= 0 ) 6305 aULSpaceItem.SetUpper(static_cast<sal_uInt16>(convertMasterUnitToMm100(-nVal2))); 6306 else 6307 { 6308 aULSpaceItem.SetUpperValue( 0 ); 6309 aULSpaceItem.SetPropUpper( static_cast<sal_uInt16>(nUpperDist) == 100 ? 101 : static_cast<sal_uInt16>(nUpperDist) ); 6310 } 6311 nVal2 = static_cast<sal_Int16>(nLowerDist); 6312 if ( nVal2 <= 0 ) 6313 aULSpaceItem.SetLower(static_cast<sal_uInt16>(convertMasterUnitToMm100(-nVal2))); 6314 else 6315 { 6316 aULSpaceItem.SetLowerValue( 0 ); 6317 aULSpaceItem.SetPropLower( static_cast<sal_uInt16>(nLowerDist) == 100 ? 101 : static_cast<sal_uInt16>(nLowerDist) ); 6318 } 6319 rSet.Put( aULSpaceItem ); 6320 } 6321 6322 sal_uInt32 i, nDefaultTab, nTab, nTextOfs2 = 0; 6323 sal_uInt32 nLatestManTab = 0; 6324 GetAttrib( PPT_ParaAttr_TextOfs, nTextOfs2, nDestinationInstance ); 6325 GetAttrib( PPT_ParaAttr_BulletOfs, nTab, nDestinationInstance ); 6326 GetAttrib( PPT_ParaAttr_DefaultTab, nDefaultTab, nDestinationInstance ); 6327 6328 SvxTabStopItem aTabItem( 0, 0, SvxTabAdjust::Default, EE_PARA_TABS ); 6329 if ( GetTabCount() ) 6330 { 6331 for ( i = 0; i < GetTabCount(); i++ ) 6332 { 6333 SvxTabAdjust eTabAdjust; 6334 nTab = GetTabOffsetByIndex( static_cast<sal_uInt16>(i) ); 6335 switch( GetTabStyleByIndex( static_cast<sal_uInt16>(i) ) ) 6336 { 6337 case 1 : eTabAdjust = SvxTabAdjust::Center; break; 6338 case 2 : eTabAdjust = SvxTabAdjust::Right; break; 6339 case 3 : eTabAdjust = SvxTabAdjust::Decimal; break; 6340 default : eTabAdjust = SvxTabAdjust::Left; 6341 } 6342 aTabItem.Insert(SvxTabStop(convertMasterUnitToMm100(nTab), eTabAdjust)); 6343 } 6344 nLatestManTab = nTab; 6345 } 6346 if ( nIsBullet2 == 0 ) 6347 aTabItem.Insert( SvxTabStop( sal_uInt16(0) ) ); 6348 if ( nDefaultTab ) 6349 { 6350 nTab = std::max( nTextOfs2, nLatestManTab ); 6351 nTab /= nDefaultTab; 6352 nTab = nDefaultTab * ( 1 + nTab ); 6353 for ( i = 0; ( i < 20 ) && ( nTab < 0x1b00 ); i++ ) 6354 { 6355 aTabItem.Insert( SvxTabStop( convertMasterUnitToMm100(nTab))); 6356 nTab += nDefaultTab; 6357 } 6358 } 6359 rSet.Put( aTabItem ); 6360 } 6361 6362 sal_uInt32 PPTParagraphObj::GetTextSize() 6363 { 6364 sal_uInt32 nCount, nRetValue = 0; 6365 for (const std::unique_ptr<PPTPortionObj> & i : m_PortionList) 6366 { 6367 PPTPortionObj const& rPortionObj = *i; 6368 nCount = rPortionObj.Count(); 6369 if ((!nCount) && rPortionObj.mpFieldItem) 6370 nCount++; 6371 nRetValue += nCount; 6372 } 6373 return nRetValue; 6374 } 6375 6376 PPTPortionObj* PPTParagraphObj::First() 6377 { 6378 mnCurrentObject = 0; 6379 if (m_PortionList.empty()) 6380 return nullptr; 6381 return m_PortionList.front().get(); 6382 } 6383 6384 PPTPortionObj* PPTParagraphObj::Next() 6385 { 6386 sal_uInt32 i = mnCurrentObject + 1; 6387 if (i >= m_PortionList.size()) 6388 return nullptr; 6389 mnCurrentObject++; 6390 return m_PortionList[i].get(); 6391 } 6392 6393 PPTFieldEntry::~PPTFieldEntry() 6394 { 6395 } 6396 6397 void PPTFieldEntry::GetDateTime( const sal_uInt32 nVal, SvxDateFormat& eDateFormat, SvxTimeFormat& eTimeFormat ) 6398 { 6399 eDateFormat = SvxDateFormat::AppDefault; 6400 eTimeFormat = SvxTimeFormat::AppDefault; 6401 // evaluate ID 6402 switch( nVal ) 6403 { 6404 case 0: 6405 case 6: 6406 eDateFormat = SvxDateFormat::A; 6407 break; 6408 case 1: 6409 eDateFormat = SvxDateFormat::F; 6410 break; 6411 case 2: 6412 case 3: 6413 eDateFormat = SvxDateFormat::D; 6414 break; 6415 case 4: 6416 case 5: 6417 eDateFormat = SvxDateFormat::C; 6418 break; 6419 case 7: 6420 eDateFormat = SvxDateFormat::A; 6421 [[fallthrough]]; 6422 case 9: 6423 eTimeFormat = SvxTimeFormat::HH24_MM; 6424 break; 6425 case 8: 6426 eDateFormat = SvxDateFormat::A; 6427 [[fallthrough]]; 6428 case 11: 6429 eTimeFormat = SvxTimeFormat::HH12_MM; 6430 break; 6431 case 10: 6432 eTimeFormat = SvxTimeFormat::HH24_MM_SS; 6433 break; 6434 case 12: 6435 eTimeFormat = SvxTimeFormat::HH12_MM_SS; 6436 break; 6437 } 6438 } 6439 6440 void PPTFieldEntry::SetDateTime( sal_uInt32 nVal ) 6441 { 6442 SvxDateFormat eDateFormat; 6443 SvxTimeFormat eTimeFormat; 6444 GetDateTime( nVal, eDateFormat, eTimeFormat ); 6445 if ( eDateFormat != SvxDateFormat::AppDefault ) 6446 xField1.reset(new SvxFieldItem(SvxDateField( Date( Date::SYSTEM ), SvxDateType::Var, eDateFormat ), EE_FEATURE_FIELD)); 6447 if ( eTimeFormat != SvxTimeFormat::AppDefault ) 6448 { 6449 std::unique_ptr<SvxFieldItem> xFieldItem(new SvxFieldItem(SvxExtTimeField( tools::Time( tools::Time::SYSTEM ), SvxTimeType::Var, eTimeFormat ), EE_FEATURE_FIELD)); 6450 if (xField1) 6451 xField2 = std::move(xFieldItem); 6452 else 6453 xField1 = std::move(xFieldItem); 6454 } 6455 } 6456 6457 PPTTextObj::PPTTextObj( SvStream& rIn, SdrPowerPointImport& rSdrPowerPointImport, PptSlidePersistEntry& rPersistEntry, DffObjData const * pObjData ) : 6458 mxImplTextObj ( new ImplPPTTextObj( rPersistEntry ) ) 6459 { 6460 mxImplTextObj->mnShapeId = 0; 6461 mxImplTextObj->mnShapeMaster = 0; 6462 mxImplTextObj->mnDestinationInstance = mxImplTextObj->mnInstance = TSS_Type::TextInShape; 6463 mxImplTextObj->mnCurrentObject = 0; 6464 mxImplTextObj->mnParagraphCount = 0; 6465 mxImplTextObj->mnTextFlags = 0; 6466 mxImplTextObj->meShapeType = ( pObjData && pObjData->bShapeType ) ? pObjData->eShapeType : mso_sptMin; 6467 6468 DffRecordHeader aExtParaHd; 6469 aExtParaHd.nRecType = 0; // set empty 6470 6471 6472 DffRecordHeader aShapeContainerHd; 6473 ReadDffRecordHeader( rIn, aShapeContainerHd ); 6474 6475 if ( !(( pObjData == nullptr ) || ( pObjData->bShapeType )) ) 6476 return; 6477 6478 PPTExtParaProv* pExtParaProv = rSdrPowerPointImport.m_pPPTStyleSheet->pExtParaProv.get(); 6479 if ( pObjData ) 6480 { 6481 mxImplTextObj->mnShapeId = pObjData->nShapeId; 6482 if ( pObjData->nSpFlags & ShapeFlag::HaveMaster ) 6483 mxImplTextObj->mnShapeMaster = rSdrPowerPointImport.GetPropertyValue( DFF_Prop_hspMaster, 0 ); 6484 } 6485 // ClientData 6486 if ( rSdrPowerPointImport.maShapeRecords.SeekToContent( rIn, DFF_msofbtClientData, SEEK_FROM_CURRENT_AND_RESTART ) ) 6487 { 6488 sal_uInt32 nOldPos = rIn.Tell(); 6489 DffRecordHeader& aClientDataContainerHd = *rSdrPowerPointImport.maShapeRecords.Current(); 6490 DffRecordHeader aPlaceHolderAtomHd; 6491 if ( SvxMSDffManager::SeekToRec( rIn, PPT_PST_OEPlaceholderAtom, aClientDataContainerHd.GetRecEndFilePos(), &aPlaceHolderAtomHd ) ) 6492 { 6493 mxImplTextObj->mpPlaceHolderAtom.reset( new PptOEPlaceholderAtom ); 6494 ReadPptOEPlaceholderAtom( rIn, *( mxImplTextObj->mpPlaceHolderAtom ) ); 6495 } 6496 rIn.Seek( nOldPos ); 6497 DffRecordHeader aProgTagHd; 6498 if ( SdrPowerPointImport::SeekToContentOfProgTag( 9, rIn, aClientDataContainerHd, aProgTagHd ) ) 6499 { 6500 ReadDffRecordHeader( rIn, aExtParaHd ); 6501 } 6502 } 6503 6504 // ClientTextBox 6505 if ( !rSdrPowerPointImport.maShapeRecords.SeekToContent( rIn, DFF_msofbtClientTextbox, SEEK_FROM_CURRENT_AND_RESTART ) ) 6506 return; 6507 6508 bool bStatus = true; 6509 6510 6511 DffRecordHeader aClientTextBoxHd( *rSdrPowerPointImport.maShapeRecords.Current() ); 6512 sal_uInt32 nTextRulerAtomOfs = 0; // case of zero -> this atom may be found in aClientDataContainerHd; 6513 // case of -1 -> there is no atom of this kind 6514 // else -> this is the fileofs where we can get it 6515 6516 // checkout if this is a referenced 6517 // textobj, if so the we will patch 6518 // the ClientTextBoxHd for a 6519 // equivalent one 6520 DffRecordHeader aTextHd; 6521 if ( SvxMSDffManager::SeekToRec( rIn, PPT_PST_OutlineTextRefAtom, aClientTextBoxHd.GetRecEndFilePos(), &aTextHd ) ) 6522 { 6523 sal_uInt32 nRefNum; 6524 rIn.ReadUInt32( nRefNum ); 6525 6526 if ( SvxMSDffManager::SeekToRec( rIn, PPT_PST_TextRulerAtom, aClientTextBoxHd.GetRecEndFilePos() ) ) 6527 nTextRulerAtomOfs = rIn.Tell(); 6528 else 6529 nTextRulerAtomOfs = 0xffffffff; 6530 6531 switch( rSdrPowerPointImport.m_eCurrentPageKind ) 6532 { 6533 case PPT_NOTEPAGE : 6534 case PPT_MASTERPAGE : 6535 case PPT_SLIDEPAGE : 6536 break; 6537 default : 6538 bStatus = false; 6539 } 6540 if ( bStatus ) 6541 { 6542 sal_uInt32 nSlideId = rSdrPowerPointImport.GetCurrentPageId(); 6543 if ( !nSlideId ) 6544 bStatus = false; 6545 else 6546 { 6547 if ( !aExtParaHd.nRecType ) 6548 { 6549 sal_uInt32 nOldPos = rIn.Tell(); 6550 // try to locate the referenced ExtendedParaHd 6551 DffRecordHeader* pHd = pExtParaProv-> 6552 aExtendedPresRules.GetRecordHeader( PPT_PST_ExtendedParagraphHeaderAtom, 6553 SEEK_FROM_CURRENT_AND_RESTART ); 6554 DffRecordHeader aPresRuleHd; 6555 DffRecordHeader* pFirst = pHd; 6556 6557 while ( pHd ) 6558 { 6559 pHd->SeekToContent( rIn ); 6560 sal_uInt32 nTmpSlideId(0), nTmpRef; 6561 rIn.ReadUInt32( nTmpSlideId ) 6562 .ReadUInt32( nTmpRef ); // this seems to be the instance 6563 6564 if ( ( nTmpSlideId == nSlideId ) && ( pHd->nRecInstance == nRefNum ) ) 6565 { 6566 if (!pHd->SeekToEndOfRecord(rIn)) 6567 break; 6568 ReadDffRecordHeader( rIn, aPresRuleHd ); 6569 if ( aPresRuleHd.nRecType == PPT_PST_ExtendedParagraphAtom ) 6570 { 6571 aExtParaHd = aPresRuleHd; 6572 break; 6573 } 6574 } 6575 pHd = pExtParaProv-> 6576 aExtendedPresRules.GetRecordHeader( PPT_PST_ExtendedParagraphHeaderAtom, 6577 SEEK_FROM_CURRENT_AND_RESTART ); 6578 if ( pHd == pFirst ) 6579 break; 6580 } 6581 rIn.Seek( nOldPos ); 6582 } 6583 // now pHd points to the right SlideListWithText Container 6584 PptSlidePersistList* pPageList = rSdrPowerPointImport.GetPageList( rSdrPowerPointImport.m_eCurrentPageKind ); 6585 PptSlidePersistEntry* pE = nullptr; 6586 if ( pPageList && ( rSdrPowerPointImport.m_nCurrentPageNum < pPageList->size() ) ) 6587 pE = &(*pPageList)[ rSdrPowerPointImport.m_nCurrentPageNum ]; 6588 if ( (!pE) || (!pE->nSlidePersistStartOffset) || ( pE->aPersistAtom.nSlideId != nSlideId ) ) 6589 bStatus = false; 6590 else 6591 { 6592 auto nOffset(pE->nSlidePersistStartOffset); 6593 bStatus = (nOffset == rIn.Seek(nOffset)); 6594 // now we got the right page and are searching for the right 6595 // TextHeaderAtom 6596 auto nEndRecPos = DffPropSet::SanitizeEndPos(rIn, pE->nSlidePersistEndOffset); 6597 while (bStatus && rIn.Tell() < nEndRecPos) 6598 { 6599 ReadDffRecordHeader( rIn, aClientTextBoxHd ); 6600 if ( aClientTextBoxHd.nRecType == PPT_PST_TextHeaderAtom ) 6601 { 6602 if ( aClientTextBoxHd.nRecInstance == nRefNum ) 6603 { 6604 aClientTextBoxHd.SeekToEndOfRecord( rIn ); 6605 break; 6606 } 6607 } 6608 if (!aClientTextBoxHd.SeekToEndOfRecord(rIn)) 6609 break; 6610 } 6611 if ( rIn.Tell() > pE->nSlidePersistEndOffset ) 6612 bStatus = false; 6613 else 6614 { // patching the RecordHeader 6615 aClientTextBoxHd.nFilePos -= DFF_COMMON_RECORD_HEADER_SIZE; 6616 aClientTextBoxHd.nRecLen += DFF_COMMON_RECORD_HEADER_SIZE; 6617 aClientTextBoxHd.nRecType = DFF_msofbtClientTextbox; 6618 aClientTextBoxHd.nRecVer = DFF_PSFLAG_CONTAINER; 6619 6620 // we have to calculate the correct record len 6621 DffRecordHeader aTmpHd; 6622 nEndRecPos = DffPropSet::SanitizeEndPos(rIn, pE->nSlidePersistEndOffset); 6623 while (rIn.Tell() < nEndRecPos) 6624 { 6625 ReadDffRecordHeader( rIn, aTmpHd ); 6626 if ( ( aTmpHd.nRecType == PPT_PST_SlidePersistAtom ) || ( aTmpHd.nRecType == PPT_PST_TextHeaderAtom ) ) 6627 break; 6628 if (!aTmpHd.SeekToEndOfRecord(rIn)) 6629 break; 6630 aClientTextBoxHd.nRecLen += aTmpHd.nRecLen + DFF_COMMON_RECORD_HEADER_SIZE; 6631 } 6632 aClientTextBoxHd.SeekToContent( rIn ); 6633 } 6634 } 6635 } 6636 } 6637 } 6638 6639 if ( !bStatus ) 6640 return; 6641 6642 if ( !SvxMSDffManager::SeekToRec( rIn, PPT_PST_TextHeaderAtom, aClientTextBoxHd.GetRecEndFilePos(), &aTextHd ) ) 6643 return; 6644 6645 // TextHeaderAtom is always the first Atom 6646 sal_uInt16 nTmp(0); 6647 rIn.ReadUInt16(nTmp); // this number tells us the TxMasterStyleAtom Instance 6648 if (nTmp > 8) 6649 nTmp = 4; 6650 TSS_Type nInstance = static_cast<TSS_Type>(nTmp); 6651 aTextHd.SeekToEndOfRecord( rIn ); 6652 mxImplTextObj->mnInstance = nInstance; 6653 6654 sal_uInt32 nFilePos = rIn.Tell(); 6655 if ( !(rSdrPowerPointImport.SeekToRec2( PPT_PST_TextBytesAtom, 6656 PPT_PST_TextCharsAtom, 6657 aClientTextBoxHd.GetRecEndFilePos() ) 6658 || SvxMSDffManager::SeekToRec( rIn, 6659 PPT_PST_StyleTextPropAtom, 6660 aClientTextBoxHd.GetRecEndFilePos() )) ) 6661 return; 6662 6663 PPTTextRulerInterpreter aTextRulerInterpreter( nTextRulerAtomOfs, aClientTextBoxHd, rIn ); 6664 6665 PPTStyleTextPropReader aStyleTextPropReader( rIn, aClientTextBoxHd, 6666 aTextRulerInterpreter, aExtParaHd, nInstance ); 6667 sal_uInt32 nParagraphs = mxImplTextObj->mnParagraphCount = aStyleTextPropReader.aParaPropList.size(); 6668 if ( !nParagraphs ) 6669 return; 6670 6671 // the language settings will be merged into the list of PPTCharPropSet 6672 DffRecordHeader aTextSpecInfoHd; 6673 PPTTextSpecInfoAtomInterpreter aTextSpecInfoAtomInterpreter; 6674 if ( SvxMSDffManager::SeekToRec( rIn, PPT_PST_TextSpecInfoAtom, 6675 aClientTextBoxHd.GetRecEndFilePos(), &aTextSpecInfoHd ) ) 6676 { 6677 if ( aTextSpecInfoAtomInterpreter.Read( rIn, aTextSpecInfoHd, PPT_PST_TextSpecInfoAtom, 6678 &(rSdrPowerPointImport.m_pPPTStyleSheet->maTxSI) ) ) 6679 { 6680 size_t nI = 0; 6681 for (const PPTTextSpecInfo& rSpecInfo : aTextSpecInfoAtomInterpreter.aList) 6682 { 6683 sal_uInt32 nCharIdx = rSpecInfo.nCharIdx; 6684 6685 // portions and text have to been split in some cases 6686 for ( ; nI < aStyleTextPropReader.aCharPropList.size(); ++nI) 6687 { 6688 PPTCharPropSet* pSet = aStyleTextPropReader.aCharPropList[nI].get(); 6689 if (pSet->mnOriginalTextPos >= nCharIdx) 6690 break; 6691 pSet->mnLanguage[0] = rSpecInfo.nLanguage[0]; 6692 pSet->mnLanguage[1] = rSpecInfo.nLanguage[1]; 6693 pSet->mnLanguage[2] = rSpecInfo.nLanguage[2]; 6694 // test if the current portion needs to be split 6695 if (pSet->maString.getLength() <= 1) 6696 continue; 6697 sal_Int32 nIndexOfNextPortion = pSet->maString.getLength() + pSet->mnOriginalTextPos; 6698 sal_Int32 nNewLen = nIndexOfNextPortion - nCharIdx; 6699 if (nNewLen <= 0) 6700 continue; 6701 sal_Int32 nOldLen = pSet->maString.getLength() - nNewLen; 6702 if (nOldLen <= 0) 6703 continue; 6704 OUString aString(pSet->maString); 6705 PPTCharPropSet* pNew = new PPTCharPropSet(*pSet); 6706 pSet->maString = aString.copy(0, nOldLen); 6707 pNew->maString = aString.copy(nOldLen, nNewLen); 6708 pNew->mnOriginalTextPos += nOldLen; 6709 aStyleTextPropReader.aCharPropList.emplace(aStyleTextPropReader.aCharPropList.begin() + nI + 1, pNew); 6710 } 6711 } 6712 } 6713 #ifdef DBG_UTIL 6714 else 6715 { 6716 if (!(rSdrPowerPointImport.rImportParam.nImportFlags & PPT_IMPORTFLAGS_NO_TEXT_ASSERT)) 6717 { 6718 OSL_FAIL( "SdrTextSpecInfoAtomInterpreter::Ctor(): parsing error, this document needs to be analysed (SJ)" ); 6719 } 6720 } 6721 #endif 6722 } 6723 // now will search for possible textextensions such as date/time fields 6724 // or ParaTabStops and append them on this textobj 6725 rIn.Seek( nFilePos ); 6726 ::std::vector< std::unique_ptr<PPTFieldEntry> > FieldList; 6727 auto nEndRecPos = DffPropSet::SanitizeEndPos(rIn, aClientTextBoxHd.GetRecEndFilePos()); 6728 while (rIn.Tell() < nEndRecPos) 6729 { 6730 ReadDffRecordHeader( rIn, aTextHd ); 6731 sal_uInt16 nVal = 0; 6732 std::unique_ptr<PPTFieldEntry> xEntry; 6733 switch ( aTextHd.nRecType ) 6734 { 6735 case PPT_PST_DateTimeMCAtom : 6736 { 6737 xEntry.reset(new PPTFieldEntry); 6738 rIn.ReadUInt16(xEntry->nPos) 6739 .ReadUInt16( nVal ) 6740 .ReadUInt16( nVal ); 6741 xEntry->SetDateTime( nVal & 0xff ); 6742 } 6743 break; 6744 6745 case PPT_PST_FooterMCAtom : 6746 { 6747 xEntry.reset(new PPTFieldEntry); 6748 rIn.ReadUInt16(xEntry->nPos); 6749 xEntry->xField1.reset(new SvxFieldItem(SvxFooterField(), EE_FEATURE_FIELD)); 6750 } 6751 break; 6752 6753 case PPT_PST_HeaderMCAtom : 6754 { 6755 xEntry.reset(new PPTFieldEntry); 6756 rIn.ReadUInt16(xEntry->nPos); 6757 xEntry->xField1.reset(new SvxFieldItem(SvxHeaderField(), EE_FEATURE_FIELD)); 6758 } 6759 break; 6760 6761 case PPT_PST_GenericDateMCAtom : 6762 { 6763 xEntry.reset(new PPTFieldEntry); 6764 rIn.ReadUInt16(xEntry->nPos); 6765 xEntry->xField1.reset(new SvxFieldItem(SvxDateTimeField(), EE_FEATURE_FIELD)); 6766 if (rPersistEntry.xHeaderFooterEntry) // sj: #i34111# on master pages it is possible 6767 { // that there is no HeaderFooterEntry available 6768 if (rPersistEntry.xHeaderFooterEntry->nAtom & 0x20000) // auto date time 6769 xEntry->SetDateTime(rPersistEntry.xHeaderFooterEntry->nAtom & 0xff); 6770 else 6771 xEntry->xString = rPersistEntry.xHeaderFooterEntry->pPlaceholder[nVal]; 6772 } 6773 } 6774 break; 6775 6776 case PPT_PST_SlideNumberMCAtom : 6777 case PPT_PST_RTFDateTimeMCAtom : 6778 { 6779 xEntry.reset(new PPTFieldEntry); 6780 if ( aTextHd.nRecLen >= 4 ) 6781 { 6782 rIn.ReadUInt16(xEntry->nPos) 6783 .ReadUInt16( nVal ); 6784 6785 // evaluate ID 6786 //SvxFieldItem* pFieldItem = NULL; 6787 switch( aTextHd.nRecType ) 6788 { 6789 case PPT_PST_SlideNumberMCAtom: 6790 xEntry->xField1.reset(new SvxFieldItem(SvxPageField(), EE_FEATURE_FIELD)); 6791 break; 6792 6793 case PPT_PST_RTFDateTimeMCAtom: 6794 { 6795 // Rude workaround for one special case reported 6796 // by a customer. (#i75203#) 6797 6798 // Don't even attempt to handle the general use 6799 // case for PPT_PST_RTFDateTimeMCAtom (a generic 6800 // MS style date/time format string). Just handle 6801 // the special case where the format string 6802 // contains only one or several possibly empty 6803 // quoted strings. I.e. something that doesn't 6804 // expand to any date or time at all, but to a 6805 // fixed string. How on earth somebody manages to 6806 // produce such things in PPT slides I have no 6807 // idea. 6808 if (nVal == 0) 6809 { 6810 OUStringBuffer aStr; 6811 bool inquote = false; 6812 for (int nLen = 0; nLen < 64; ++nLen) 6813 { 6814 sal_Unicode n(0); 6815 rIn.ReadUtf16( n ); 6816 6817 // Collect quoted characters into aStr 6818 if ( n == '\'') 6819 inquote = !inquote; 6820 else if (!n) 6821 { 6822 // End of format string 6823 xEntry->xString = aStr.makeStringAndClear(); 6824 break; 6825 } 6826 else if (!inquote) 6827 { 6828 // Non-quoted character, i.e. a real 6829 // format specifier. We don't handle 6830 // those. Sorry. 6831 break; 6832 } 6833 else 6834 { 6835 aStr.append(OUStringChar(n)); 6836 } 6837 } 6838 } 6839 if (!xEntry->xString) 6840 { 6841 // Handle as previously 6842 xEntry->xField1.reset(new SvxFieldItem( SvxDateField( Date( Date::SYSTEM ), SvxDateType::Fix ), EE_FEATURE_FIELD )); 6843 } 6844 } 6845 } 6846 } 6847 } 6848 break; 6849 6850 case PPT_PST_InteractiveInfo : 6851 { 6852 DffRecordHeader aHdInteractiveInfoAtom; 6853 if ( SvxMSDffManager::SeekToRec( rIn, PPT_PST_InteractiveInfoAtom, aTextHd.GetRecEndFilePos(), &aHdInteractiveInfoAtom ) ) 6854 { 6855 PptInteractiveInfoAtom aInteractiveInfoAtom; 6856 ReadPptInteractiveInfoAtom( rIn, aInteractiveInfoAtom ); 6857 for (const SdHyperlinkEntry& rHyperlink : rSdrPowerPointImport.m_aHyperList) 6858 { 6859 if ( rHyperlink.nIndex == aInteractiveInfoAtom.nExHyperlinkId ) 6860 { 6861 if (!aTextHd.SeekToEndOfRecord(rIn)) 6862 { 6863 break; 6864 } 6865 ReadDffRecordHeader( rIn, aTextHd ); 6866 if ( aTextHd.nRecType != PPT_PST_TxInteractiveInfoAtom ) 6867 { 6868 aTextHd.SeekToBegOfRecord( rIn ); 6869 continue; 6870 } 6871 else 6872 { 6873 sal_uInt32 nStartPos, nEndPos; 6874 rIn.ReadUInt32( nStartPos ) 6875 .ReadUInt32( nEndPos ); 6876 if ( nEndPos ) 6877 { 6878 xEntry.reset(new PPTFieldEntry); 6879 xEntry->nPos = static_cast<sal_uInt16>(nStartPos); 6880 xEntry->nTextRangeEnd = static_cast<sal_uInt16>(nEndPos); 6881 OUString aTarget( rHyperlink.aTarget ); 6882 if ( !rHyperlink.aConvSubString.isEmpty() ) 6883 { 6884 aTarget += "#" + rHyperlink.aConvSubString; 6885 } 6886 xEntry->xField1.reset(new SvxFieldItem( SvxURLField( aTarget, OUString(), SvxURLFormat::Repr ), EE_FEATURE_FIELD )); 6887 } 6888 } 6889 break; 6890 } 6891 } 6892 } 6893 } 6894 break; 6895 } 6896 if (!aTextHd.SeekToEndOfRecord(rIn)) 6897 break; 6898 if (xEntry) 6899 { 6900 // sorting fields ( hi >> lo ) 6901 auto it = std::find_if(FieldList.begin(), FieldList.end(), 6902 [&xEntry](const std::unique_ptr<PPTFieldEntry>& rxField) { 6903 return rxField->nPos < xEntry->nPos; }); 6904 if ( it != FieldList.end() ) { 6905 FieldList.insert(it, std::move(xEntry)); 6906 } else { 6907 FieldList.push_back( std::move(xEntry)); 6908 } 6909 } 6910 } 6911 if ( !FieldList.empty() ) 6912 { 6913 auto FE = FieldList.begin(); 6914 auto& aCharPropList = aStyleTextPropReader.aCharPropList; 6915 6916 sal_Int32 i = nParagraphs - 1; 6917 sal_Int32 n = aCharPropList.size() - 1; 6918 6919 // at this point we just have a list of textportions(aCharPropList) 6920 // the next while loop tries to resolve the list of fields(pFieldList) 6921 while( ( FE < FieldList.end() ) && ( n >= 0 ) && ( i >= 0 ) ) 6922 { 6923 PPTCharPropSet* pSet = aCharPropList[n].get(); 6924 OUString aString( pSet->maString ); 6925 sal_uInt32 nCount = aString.getLength(); 6926 sal_uInt32 nPos = pSet->mnOriginalTextPos + nCount; 6927 while ( ( FE < FieldList.end() ) && nCount-- ) 6928 { 6929 nPos--; 6930 FE = std::find_if(FE, FieldList.end(), 6931 [&nPos](const std::unique_ptr<PPTFieldEntry>& rxField) {return rxField->nPos <= nPos;}); 6932 if (FE == FieldList.end()) 6933 break; 6934 6935 if ( (*FE)->nPos == nPos ) 6936 { 6937 if ( aString[nCount] == 0x2a ) 6938 { 6939 sal_uInt32 nBehind = aString.getLength() - ( nCount + 1 ); 6940 pSet->maString.clear(); 6941 if ( nBehind ) 6942 { 6943 PPTCharPropSet* pNewCPS = new PPTCharPropSet( *pSet ); 6944 pNewCPS->maString = aString.copy( nCount + 1, nBehind ); 6945 aCharPropList.emplace( aCharPropList.begin() + n + 1, pNewCPS ); 6946 } 6947 if ( (*FE)->xField2 ) 6948 { 6949 PPTCharPropSet* pNewCPS = new PPTCharPropSet( *pSet ); 6950 pNewCPS->mpFieldItem = std::move((*FE)->xField2); 6951 aCharPropList.emplace( aCharPropList.begin() + n + 1, pNewCPS ); 6952 6953 pNewCPS = new PPTCharPropSet( *pSet ); 6954 pNewCPS->maString = " "; 6955 aCharPropList.emplace( aCharPropList.begin() + n + 1, pNewCPS ); 6956 } 6957 if ( nCount ) 6958 { 6959 PPTCharPropSet* pNewCPS = new PPTCharPropSet( *pSet ); 6960 pNewCPS->maString = aString.copy( 0, nCount ); 6961 aCharPropList.emplace( aCharPropList.begin() + n++, pNewCPS ); 6962 } 6963 if ( (*FE)->xField1 ) 6964 { 6965 pSet->mpFieldItem = std::move((*FE)->xField1); 6966 } 6967 else if ( (*FE)->xString ) 6968 pSet->maString = *(*FE)->xString; 6969 } 6970 else 6971 { 6972 if ( (*FE)->nTextRangeEnd ) // text range hyperlink 6973 { 6974 sal_uInt32 nHyperLen = (*FE)->nTextRangeEnd - nPos; 6975 if ( nHyperLen ) 6976 { 6977 PPTCharPropSet* pBefCPS = nullptr; 6978 if ( nCount ) 6979 { 6980 pBefCPS = new PPTCharPropSet( *pSet ); 6981 pSet->maString = pSet->maString.copy(nCount); 6982 } 6983 sal_uInt32 nIdx = n; 6984 sal_Int32 nHyperLenLeft = nHyperLen; 6985 6986 while ( ( aCharPropList.size() > nIdx ) && nHyperLenLeft ) 6987 { 6988 // the textrange hyperlink can take more than 1 paragraph 6989 // the solution here is to clone the hyperlink... 6990 6991 PPTCharPropSet* pCurrent = aCharPropList[ nIdx ].get(); 6992 sal_Int32 nNextStringLen = pCurrent->maString.getLength(); 6993 6994 DBG_ASSERT( (*FE)->xField1, "missing field!" ); 6995 if (!(*FE)->xField1) 6996 break; 6997 6998 const SvxURLField* pField = static_cast<const SvxURLField*>((*FE)->xField1->GetField()); 6999 7000 pCurrent->mbIsHyperlink = true; 7001 pCurrent->mnHylinkOrigColor = pCurrent->mpImplPPTCharPropSet->mnColor; 7002 pCurrent->mbHardHylinkOrigColor = ( ( pCurrent->mpImplPPTCharPropSet->mnAttrSet >>PPT_CharAttr_FontColor ) & 1)>0; 7003 7004 // add missing attribute to show underline property 7005 pCurrent->mpImplPPTCharPropSet->mnAttrSet |= 1 << PPT_CharAttr_Underline; 7006 pCurrent->mpImplPPTCharPropSet->mnFlags = 1 << PPT_CharAttr_Underline; 7007 7008 if ( pCurrent->mpFieldItem ) 7009 { 7010 pCurrent->SetColor( PPT_COLSCHEME_A_UND_HYPERLINK ); 7011 if ( dynamic_cast< const SvxURLField* >(pCurrent->mpFieldItem->GetField()) != nullptr) 7012 break; 7013 nHyperLenLeft--; 7014 } 7015 else if ( nNextStringLen ) 7016 { 7017 if ( nNextStringLen <= nHyperLenLeft ) 7018 { 7019 pCurrent->mpFieldItem.reset( new SvxFieldItem( SvxURLField( pField->GetURL(), pCurrent->maString, SvxURLFormat::Repr ), EE_FEATURE_FIELD ) ); 7020 nHyperLenLeft -= nNextStringLen; 7021 7022 if ( nHyperLenLeft ) 7023 { 7024 // if the next portion is in a higher paragraph, 7025 // the textrange is to decrease (because of the LineBreak character) 7026 if ( aCharPropList.size() > ( nIdx + 1 ) ) 7027 { 7028 PPTCharPropSet* pNext = aCharPropList[ nIdx + 1 ].get(); 7029 if ( pNext->mnParagraph > pCurrent->mnParagraph ) 7030 nHyperLenLeft--; 7031 } 7032 } 7033 } 7034 else 7035 { 7036 PPTCharPropSet* pNewCPS = new PPTCharPropSet( *pCurrent ); 7037 pNewCPS->maString = pCurrent->maString.copy( nHyperLenLeft,( nNextStringLen - nHyperLenLeft ) ); 7038 aCharPropList.emplace( aCharPropList.begin() + nIdx + 1, pNewCPS ); 7039 OUString aRepresentation = pCurrent->maString.copy( 0, nHyperLenLeft ); 7040 pCurrent->mpFieldItem.reset( new SvxFieldItem( SvxURLField( pField->GetURL(), aRepresentation, SvxURLFormat::Repr ), EE_FEATURE_FIELD ) ); 7041 nHyperLenLeft = 0; 7042 } 7043 pCurrent->maString.clear(); 7044 pCurrent->SetColor( PPT_COLSCHEME_A_UND_HYPERLINK ); 7045 } 7046 nIdx++; 7047 } 7048 (*FE)->xField1.reset(); 7049 7050 if ( pBefCPS ) 7051 { 7052 pBefCPS->maString = aString.copy( 0, nCount ); 7053 aCharPropList.emplace( aCharPropList.begin() + n, pBefCPS ); 7054 n++; 7055 } 7056 } 7057 } 7058 } 7059 break; 7060 } 7061 } 7062 n--; 7063 } 7064 } 7065 mxImplTextObj->maParagraphList.resize( nParagraphs ); 7066 for (size_t nCurCharPos = 0, nCurPos = 0; 7067 nCurPos < aStyleTextPropReader.aParaPropList.size(); 7068 ++nCurPos) 7069 { 7070 mxImplTextObj->maParagraphList[ nCurPos ].reset( 7071 new PPTParagraphObj( 7072 aStyleTextPropReader, nCurPos, nCurCharPos, 7073 *rSdrPowerPointImport.m_pPPTStyleSheet, 7074 nInstance, aTextRulerInterpreter ) ); 7075 7076 sal_uInt32 nParaAdjust, nFlags = 0; 7077 mxImplTextObj->maParagraphList[ nCurPos ]->GetAttrib( PPT_ParaAttr_Adjust, nParaAdjust, GetInstance() ); 7078 7079 switch ( nParaAdjust ) 7080 { 7081 case 0 : nFlags = PPT_TEXTOBJ_FLAGS_PARA_ALIGNMENT_USED_LEFT; break; 7082 case 1 : nFlags = PPT_TEXTOBJ_FLAGS_PARA_ALIGNMENT_USED_CENTER; break; 7083 case 2 : nFlags = PPT_TEXTOBJ_FLAGS_PARA_ALIGNMENT_USED_RIGHT; break; 7084 case 3 : nFlags = PPT_TEXTOBJ_FLAGS_PARA_ALIGNMENT_USED_BLOCK; break; 7085 } 7086 mxImplTextObj->mnTextFlags |= nFlags; 7087 } 7088 } 7089 7090 PPTTextObj::PPTTextObj( PPTTextObj const & rTextObj ) 7091 { 7092 mxImplTextObj = rTextObj.mxImplTextObj; 7093 } 7094 7095 PPTTextObj::~PPTTextObj() 7096 { 7097 } 7098 7099 PPTParagraphObj* PPTTextObj::First() 7100 { 7101 mxImplTextObj->mnCurrentObject = 0; 7102 if ( !mxImplTextObj->mnParagraphCount ) 7103 return nullptr; 7104 return mxImplTextObj->maParagraphList[ 0 ].get(); 7105 } 7106 7107 PPTParagraphObj* PPTTextObj::Next() 7108 { 7109 sal_uInt32 i = mxImplTextObj->mnCurrentObject + 1; 7110 if ( i >= mxImplTextObj->mnParagraphCount ) 7111 return nullptr; 7112 mxImplTextObj->mnCurrentObject++; 7113 return mxImplTextObj->maParagraphList[ i ].get(); 7114 } 7115 7116 const SfxItemSet* PPTTextObj::GetBackground() const 7117 { 7118 if ( mxImplTextObj->mrPersistEntry.pBObj ) 7119 return &mxImplTextObj->mrPersistEntry.pBObj->GetMergedItemSet(); 7120 else 7121 return nullptr; 7122 } 7123 7124 PPTTextObj& PPTTextObj::operator=( const PPTTextObj& rTextObj ) 7125 { 7126 if ( this != &rTextObj ) 7127 { 7128 mxImplTextObj = rTextObj.mxImplTextObj; 7129 } 7130 return *this; 7131 } 7132 7133 static bool IsLine( const SdrObject* pObj ) 7134 { 7135 auto pSdrPathObj = dynamic_cast< const SdrPathObj* >(pObj); 7136 return pSdrPathObj && pSdrPathObj->IsLine() && pSdrPathObj->GetPointCount() == 2; 7137 } 7138 7139 static bool GetCellPosition( const SdrObject* pObj, const o3tl::sorted_vector< sal_Int32 >& rRows, const o3tl::sorted_vector< sal_Int32 >& rColumns, 7140 sal_Int32& nTableIndex, sal_Int32& nRow, sal_Int32& nRowCount, sal_Int32& nColumn, sal_Int32& nColumnCount ) 7141 { 7142 tools::Rectangle aSnapRect( pObj->GetSnapRect() ); 7143 bool bCellObject = ( aSnapRect.GetWidth() > 1 ) && ( aSnapRect.GetHeight() > 1 ); 7144 if ( bCellObject ) 7145 { 7146 auto aRowIter = rRows.find( aSnapRect.Top() ); 7147 auto aColumnIter = rColumns.find( aSnapRect.Left() ); 7148 if ( ( aRowIter == rRows.end() ) || ( aColumnIter == rColumns.end() ) ) 7149 bCellObject = false; 7150 else 7151 { 7152 nRowCount = 1; 7153 nRow = std::distance( rRows.begin(), aRowIter ); 7154 while( ++aRowIter != rRows.end() ) 7155 { 7156 if ( *aRowIter >= aSnapRect.Bottom() ) 7157 break; 7158 nRowCount++; 7159 } 7160 nColumnCount = 1; 7161 nColumn = std::distance( rColumns.begin(), aColumnIter ); 7162 while( ++aColumnIter != rColumns.end() ) 7163 { 7164 if ( *aColumnIter >= aSnapRect.Right() ) 7165 break; 7166 nColumnCount++; 7167 } 7168 nTableIndex = nRow * rColumns.size() + nColumn; 7169 } 7170 } 7171 return bCellObject; 7172 } 7173 7174 #define LinePositionLeft 0x01000000 7175 #define LinePositionTop 0x02000000 7176 #define LinePositionRight 0x04000000 7177 #define LinePositionBottom 0x08000000 7178 #define LinePositionTLBR 0x10000000 7179 #define LinePositionBLTR 0x20000000 7180 7181 7182 static void GetRowPositions( const tools::Rectangle& rSnapRect, const o3tl::sorted_vector< sal_Int32 >& rRows, 7183 const o3tl::sorted_vector< sal_Int32 >& rColumns, std::vector< sal_Int32 >& rPositions, sal_Int32 nColumn, sal_Int32 nFlags ) 7184 { 7185 auto aRow = rRows.find( rSnapRect.Top() ); 7186 if ( aRow == rRows.end() ) 7187 return; 7188 7189 sal_Int32 nRow = std::distance( rRows.begin(), aRow ); 7190 while( ( aRow != rRows.end() ) && ((*aRow) < rSnapRect.Bottom() ) ) 7191 { 7192 if ( nFlags & LinePositionLeft ) 7193 rPositions.push_back( ( ( nRow * rColumns.size() ) + nColumn ) | LinePositionLeft ); 7194 if ( nFlags & LinePositionRight ) 7195 rPositions.push_back( ( ( nRow * rColumns.size() ) + ( nColumn - 1 ) ) | LinePositionRight ); 7196 7197 ++nRow; 7198 ++aRow; 7199 } 7200 } 7201 7202 7203 static void GetColumnPositions( const tools::Rectangle& rSnapRect, 7204 const o3tl::sorted_vector< sal_Int32 >& rColumns, std::vector< sal_Int32 >& rPositions, sal_Int32 nRow, sal_Int32 nFlags ) 7205 { 7206 auto aColumn = rColumns.find( rSnapRect.Left() ); 7207 if ( aColumn == rColumns.end() ) 7208 return; 7209 7210 sal_Int32 nColumn = std::distance( rColumns.begin(), aColumn ); 7211 while( ( aColumn != rColumns.end() ) && ((*aColumn) < rSnapRect.Right() ) ) 7212 { 7213 if ( nFlags & LinePositionTop ) 7214 rPositions.push_back( ( ( nRow * rColumns.size() ) + nColumn ) | LinePositionTop ); 7215 if ( nFlags & LinePositionBottom ) 7216 rPositions.push_back( ( ( ( nRow - 1 ) * rColumns.size() ) + nColumn ) | LinePositionBottom ); 7217 7218 ++nColumn; 7219 ++aColumn; 7220 } 7221 } 7222 7223 static void GetLinePositions( const SdrObject* pObj, const o3tl::sorted_vector< sal_Int32 >& rRows, const o3tl::sorted_vector< sal_Int32 >& rColumns, 7224 std::vector< sal_Int32 >& rPositions, const tools::Rectangle& rGroupSnap ) 7225 { 7226 tools::Rectangle aSnapRect( pObj->GetSnapRect() ); 7227 if ( aSnapRect.Left() == aSnapRect.Right() ) 7228 { 7229 auto aColumn = rColumns.find( aSnapRect.Left() ); 7230 if ( ( aColumn != rColumns.end() ) || ( aSnapRect.Left() == rGroupSnap.Right() ) ) 7231 { 7232 sal_Int32 nColumn, nFlags; 7233 if ( aColumn != rColumns.end() ) 7234 { 7235 nColumn = std::distance( rColumns.begin(), aColumn ); 7236 nFlags = LinePositionLeft; 7237 if ( aColumn != rColumns.begin() ) 7238 nFlags |= LinePositionRight; 7239 } 7240 else 7241 { 7242 nColumn = rColumns.size(); 7243 nFlags = LinePositionRight; 7244 } 7245 GetRowPositions( aSnapRect, rRows, rColumns, rPositions, nColumn, nFlags ); 7246 } 7247 } 7248 else if ( aSnapRect.Top() == aSnapRect.Bottom() ) 7249 { 7250 auto aRow = rRows.find( aSnapRect.Top() ); 7251 if ( ( aRow != rRows.end() ) || ( aSnapRect.Top() == rGroupSnap.Bottom() ) ) 7252 { 7253 sal_Int32 nRow, nFlags; 7254 if ( aRow != rRows.end() ) 7255 { 7256 nRow = std::distance( rRows.begin(), aRow ); 7257 nFlags = LinePositionTop; 7258 if ( aRow != rRows.begin() ) 7259 nFlags |= LinePositionBottom; 7260 } 7261 else 7262 { 7263 nRow = rRows.size(); 7264 nFlags = LinePositionBottom; 7265 } 7266 GetColumnPositions( aSnapRect, rColumns, rPositions, nRow, nFlags ); 7267 } 7268 } 7269 else 7270 { 7271 sal_uInt32 nPosition = 0; 7272 Point aPt1( static_cast<const SdrPathObj*>(pObj)->GetPoint( 0 ) ); 7273 Point aPt2( static_cast<const SdrPathObj*>(pObj)->GetPoint( 1 ) ); 7274 if ( aPt1.X() < aPt2.X() ) 7275 nPosition |= aPt1.Y() < aPt2.Y() ? LinePositionTLBR : LinePositionBLTR; 7276 else 7277 nPosition |= aPt1.Y() < aPt2.Y() ? LinePositionBLTR : LinePositionTLBR; 7278 7279 auto aRow = rRows.find( std::min(aPt1.Y(), aPt2.Y() ) ); 7280 auto aColumn = rColumns.find( std::min(aPt1.X(), aPt2.X() ) ); 7281 if ( ( aRow != rRows.end() ) && ( aColumn != rColumns.end() ) ) 7282 { 7283 nPosition |= ( std::distance( rRows.begin(), aRow ) * rColumns.size() ) + std::distance( rColumns.begin(), aColumn ); 7284 rPositions.push_back( nPosition ); 7285 } 7286 } 7287 } 7288 7289 static void CreateTableRows( const Reference< XTableRows >& xTableRows, const o3tl::sorted_vector< sal_Int32 >& rRows, sal_Int32 nTableBottom ) 7290 { 7291 if ( rRows.size() > 1 ) 7292 xTableRows->insertByIndex( 0, rRows.size() - 1 ); 7293 7294 auto aIter = rRows.begin(); 7295 sal_Int32 nLastPosition( *aIter ); 7296 for ( sal_Int32 n = 0; n < xTableRows->getCount(); n++ ) 7297 { 7298 sal_Int32 nHeight; 7299 if ( ++aIter != rRows.end() ) 7300 { 7301 if (o3tl::checked_sub<sal_Int32>(*aIter, nLastPosition, nHeight)) 7302 throw lang::IllegalArgumentException(); 7303 nLastPosition = *aIter; 7304 } 7305 else 7306 { 7307 if (o3tl::checked_sub<sal_Int32>(nTableBottom, nLastPosition, nHeight)) 7308 throw lang::IllegalArgumentException(); 7309 } 7310 7311 Reference< XPropertySet > xPropSet( xTableRows->getByIndex( n ), UNO_QUERY_THROW ); 7312 xPropSet->setPropertyValue( "Height", Any( nHeight ) ); 7313 } 7314 } 7315 7316 static void CreateTableColumns( const Reference< XTableColumns >& xTableColumns, const o3tl::sorted_vector< sal_Int32 >& rColumns, sal_Int32 nTableRight ) 7317 { 7318 if ( rColumns.size() > 1 ) 7319 xTableColumns->insertByIndex( 0, rColumns.size() - 1 ); 7320 7321 auto aIter = rColumns.begin(); 7322 sal_Int32 nLastPosition( *aIter ); 7323 for ( sal_Int32 n = 0; n < xTableColumns->getCount(); n++ ) 7324 { 7325 sal_Int32 nWidth; 7326 if ( ++aIter != rColumns.end() ) 7327 { 7328 if (o3tl::checked_sub<sal_Int32>(*aIter, nLastPosition, nWidth)) 7329 throw lang::IllegalArgumentException(); 7330 nLastPosition = *aIter; 7331 } 7332 else 7333 { 7334 if (o3tl::checked_sub<sal_Int32>(nTableRight, nLastPosition, nWidth)) 7335 throw lang::IllegalArgumentException(); 7336 } 7337 7338 Reference< XPropertySet > xPropSet( xTableColumns->getByIndex( n ), UNO_QUERY_THROW ); 7339 xPropSet->setPropertyValue( "Width", Any( nWidth ) ); 7340 } 7341 } 7342 7343 static void MergeCells( const Reference< XTable >& xTable, sal_Int32 nCol, sal_Int32 nRow, sal_Int32 nColSpan, sal_Int32 nRowSpan ) 7344 { 7345 DBG_ASSERT( (nColSpan > 1) || (nRowSpan > 1), "nonsense parameter!!" ); 7346 DBG_ASSERT( (nCol >= 0) && (nCol < xTable->getColumnCount()) && (nRow >= 0) && (nRow < xTable->getRowCount()), "the cell does not exists!!" ); 7347 DBG_ASSERT( (nColSpan >= 1) && ((nCol + nColSpan - 1) < xTable->getColumnCount()), "nColSpan botch!" ); 7348 DBG_ASSERT( (nRowSpan >= 1) && ((nRow + nRowSpan - 1) < xTable->getRowCount()), "nRowSpan botch!" ); 7349 7350 if( xTable.is() ) try 7351 { 7352 Reference< XMergeableCellRange > xRange( xTable->createCursorByRange( xTable->getCellRangeByPosition( nCol, nRow,nCol + nColSpan - 1, nRow + nRowSpan - 1 ) ), UNO_QUERY_THROW ); 7353 if( xRange->isMergeable() ) 7354 xRange->merge(); 7355 } 7356 catch( const Exception& ) 7357 { 7358 DBG_UNHANDLED_EXCEPTION("filter.ms"); 7359 } 7360 } 7361 7362 static void ApplyCellAttributes( const SdrObject* pObj, Reference< XCell > const & xCell ) 7363 { 7364 try 7365 { 7366 Reference< XPropertySet > xPropSet( xCell, UNO_QUERY_THROW ); 7367 7368 const sal_Int32 nLeftDist(pObj->GetMergedItem(SDRATTR_TEXT_LEFTDIST).GetValue()); 7369 const sal_Int32 nRightDist(pObj->GetMergedItem(SDRATTR_TEXT_RIGHTDIST).GetValue()); 7370 const sal_Int32 nUpperDist(pObj->GetMergedItem(SDRATTR_TEXT_UPPERDIST).GetValue()); 7371 const sal_Int32 nLowerDist(pObj->GetMergedItem(SDRATTR_TEXT_LOWERDIST).GetValue()); 7372 xPropSet->setPropertyValue( "TextUpperDistance", Any( nUpperDist ) ); 7373 xPropSet->setPropertyValue( "TextRightDistance", Any( nRightDist ) ); 7374 xPropSet->setPropertyValue( "TextLeftDistance", Any( nLeftDist ) ); 7375 xPropSet->setPropertyValue( "TextLowerDistance", Any( nLowerDist ) ); 7376 7377 const SdrTextVertAdjust eTextVertAdjust(pObj->GetMergedItem(SDRATTR_TEXT_VERTADJUST).GetValue()); 7378 drawing::TextVerticalAdjust eVA( drawing::TextVerticalAdjust_TOP ); 7379 if ( eTextVertAdjust == SDRTEXTVERTADJUST_CENTER ) 7380 eVA = drawing::TextVerticalAdjust_CENTER; 7381 else if ( eTextVertAdjust == SDRTEXTVERTADJUST_BOTTOM ) 7382 eVA = drawing::TextVerticalAdjust_BOTTOM; 7383 xPropSet->setPropertyValue( "TextVerticalAdjust", Any( eVA ) ); 7384 7385 //set textHorizontalAdjust and TextWritingMode attr 7386 const sal_Int32 eHA(pObj->GetMergedItem(SDRATTR_TEXT_HORZADJUST).GetValue()); 7387 const SvxFrameDirection eDirection = pObj->GetMergedItem(EE_PARA_WRITINGDIR).GetValue(); 7388 xPropSet->setPropertyValue( "TextHorizontalAdjust" , Any( eHA ) ); 7389 if ( eDirection == SvxFrameDirection::Vertical_RL_TB ) 7390 {//vertical writing 7391 xPropSet->setPropertyValue( "TextWritingMode" , Any( css::text::WritingMode_TB_RL ) ); 7392 } 7393 drawing::FillStyle eFillStyle(pObj->GetMergedItem( XATTR_FILLSTYLE ).GetValue()); 7394 css::drawing::FillStyle eFS( css::drawing::FillStyle_NONE ); 7395 switch( eFillStyle ) 7396 { 7397 case drawing::FillStyle_SOLID : 7398 { 7399 eFS = css::drawing::FillStyle_SOLID; 7400 Color aFillColor( pObj->GetMergedItem( XATTR_FILLCOLOR ).GetColorValue() ); 7401 xPropSet->setPropertyValue( "FillColor", Any( aFillColor ) ); 7402 } 7403 break; 7404 case drawing::FillStyle_GRADIENT : 7405 { 7406 eFS = css::drawing::FillStyle_GRADIENT; 7407 XGradient aXGradient(pObj->GetMergedItem(XATTR_FILLGRADIENT).GetGradientValue()); 7408 7409 css::awt::Gradient aGradient; 7410 aGradient.Style = aXGradient.GetGradientStyle(); 7411 aGradient.StartColor = static_cast<sal_Int32>(aXGradient.GetStartColor()); 7412 aGradient.EndColor = static_cast<sal_Int32>(aXGradient.GetEndColor()); 7413 aGradient.Angle = static_cast<short>(aXGradient.GetAngle()); 7414 aGradient.Border = aXGradient.GetBorder(); 7415 aGradient.XOffset = aXGradient.GetXOffset(); 7416 aGradient.YOffset = aXGradient.GetYOffset(); 7417 aGradient.StartIntensity = aXGradient.GetStartIntens(); 7418 aGradient.EndIntensity = aXGradient.GetEndIntens(); 7419 aGradient.StepCount = aXGradient.GetSteps(); 7420 7421 xPropSet->setPropertyValue( "FillGradient", Any( aGradient ) ); 7422 } 7423 break; 7424 case drawing::FillStyle_HATCH : 7425 eFS = css::drawing::FillStyle_HATCH; 7426 break; 7427 case drawing::FillStyle_BITMAP : 7428 { 7429 eFS = css::drawing::FillStyle_BITMAP; 7430 7431 const XFillBitmapItem & rXFillBitmapItem(pObj->GetMergedItem( XATTR_FILLBITMAP )); 7432 uno::Reference<graphic::XGraphic> xGraphic = rXFillBitmapItem.GetGraphicObject().GetGraphic().GetXGraphic(); 7433 uno::Reference<awt::XBitmap> xBitmap(xGraphic, uno::UNO_QUERY); 7434 xPropSet->setPropertyValue("FillBitmap", uno::Any(xBitmap)); 7435 7436 const XFillBmpStretchItem & rStretchItem(pObj->GetMergedItem( XATTR_FILLBMP_STRETCH )); 7437 const XFillBmpTileItem & rTileItem(pObj->GetMergedItem( XATTR_FILLBMP_TILE )); 7438 if( rTileItem.GetValue() ) 7439 xPropSet->setPropertyValue("FillBitmapMode", uno::Any(drawing::BitmapMode_REPEAT)); 7440 else if( rStretchItem.GetValue() ) 7441 xPropSet->setPropertyValue("FillBitmapMode", uno::Any(drawing::BitmapMode_STRETCH)); 7442 else 7443 xPropSet->setPropertyValue("FillBitmapMode", uno::Any(drawing::BitmapMode_NO_REPEAT)); 7444 } 7445 break; 7446 default: 7447 case drawing::FillStyle_NONE : 7448 eFS = css::drawing::FillStyle_NONE; 7449 break; 7450 7451 } 7452 xPropSet->setPropertyValue( "FillStyle", Any( eFS ) ); 7453 if ( eFillStyle != drawing::FillStyle_NONE ) 7454 { 7455 sal_Int16 nFillTransparence( pObj->GetMergedItem( XATTR_FILLTRANSPARENCE ).GetValue() ); 7456 xPropSet->setPropertyValue( "FillTransparence", Any( nFillTransparence ) ); 7457 } 7458 } 7459 catch( const Exception& ) 7460 { 7461 } 7462 } 7463 7464 static void ApplyCellLineAttributes( const SdrObject* pLine, Reference< XTable > const & xTable, const std::vector< sal_Int32 >& vPositions, sal_Int32 nColumns ) 7465 { 7466 try 7467 { 7468 drawing::LineStyle eLineStyle(pLine->GetMergedItem( XATTR_LINESTYLE ).GetValue()); 7469 css::table::BorderLine2 aBorderLine; 7470 switch( eLineStyle ) 7471 { 7472 case drawing::LineStyle_DASH : 7473 case drawing::LineStyle_SOLID : 7474 { 7475 Color aLineColor( pLine->GetMergedItem( XATTR_LINECOLOR ).GetColorValue() ); 7476 aBorderLine.Color = sal_Int32(aLineColor); 7477 // Avoid width = 0, the min value should be 1. 7478 sal_Int32 nLineWidth = std::max(sal_Int32(1), pLine->GetMergedItem(XATTR_LINEWIDTH) .GetValue() / 4); 7479 aBorderLine.LineWidth = static_cast< sal_Int16 >( nLineWidth ); 7480 aBorderLine.LineStyle = eLineStyle == drawing::LineStyle_SOLID ? table::BorderLineStyle::SOLID : table::BorderLineStyle::DASHED; 7481 } 7482 break; 7483 default: 7484 case drawing::LineStyle_NONE : 7485 { 7486 aBorderLine.LineWidth = 0; 7487 aBorderLine.LineStyle = table::BorderLineStyle::NONE; 7488 } 7489 break; 7490 } 7491 for (auto const& vPos : vPositions) 7492 { 7493 sal_Int32 nPosition = vPos & 0xffffff; 7494 sal_Int32 nFlags = vPos &~0xffffff; 7495 sal_Int32 nRow = nPosition / nColumns; 7496 sal_Int32 nColumn = nPosition - ( nRow * nColumns ); 7497 Reference< XCell > xCell( xTable->getCellByPosition( nColumn, nRow ) ); 7498 Reference< XPropertySet > xPropSet( xCell, UNO_QUERY_THROW ); 7499 7500 if ( nFlags & LinePositionLeft ) 7501 xPropSet->setPropertyValue( "LeftBorder", Any( aBorderLine ) ); 7502 if ( nFlags & LinePositionTop ) 7503 xPropSet->setPropertyValue( "TopBorder", Any( aBorderLine ) ); 7504 if ( nFlags & LinePositionRight ) 7505 xPropSet->setPropertyValue( "RightBorder", Any( aBorderLine ) ); 7506 if ( nFlags & LinePositionBottom ) 7507 xPropSet->setPropertyValue( "BottomBorder", Any( aBorderLine ) ); 7508 if ( nFlags & LinePositionTLBR ) 7509 xPropSet->setPropertyValue( "DiagonalTLBR", Any( true ) ); 7510 if ( nFlags & LinePositionBLTR ) 7511 xPropSet->setPropertyValue( "DiagonalBLTR", Any( true ) ); 7512 } 7513 } 7514 catch( const Exception& ) 7515 { 7516 } 7517 } 7518 7519 rtl::Reference<SdrObject> SdrPowerPointImport::CreateTable( 7520 SdrObject* pGroup, const sal_uInt32* pTableArry, 7521 SvxMSDffSolverContainer* pSolverContainer, 7522 std::vector<rtl::Reference<SdrObject>>& rBackgroundColoredObjects) 7523 { 7524 rtl::Reference<SdrObject> pRet = pGroup; 7525 7526 sal_uInt32 nRows = pTableArry[ 1 ]; 7527 if (!nRows) 7528 return pRet; 7529 7530 const SdrObjGroup* pObjGroup = dynamic_cast<const SdrObjGroup*>(pGroup); 7531 if (!pObjGroup) 7532 return pRet; 7533 7534 SdrObjList* pSubList(pObjGroup->GetSubList()); 7535 if (!pSubList) 7536 return pRet; 7537 7538 o3tl::sorted_vector< sal_Int32 > aRows; 7539 o3tl::sorted_vector< sal_Int32 > aColumns; 7540 7541 SdrObjListIter aGroupIter( pSubList, SdrIterMode::DeepNoGroups, false ); 7542 while( aGroupIter.IsMore() ) 7543 { 7544 const SdrObject* pObj( aGroupIter.Next() ); 7545 if ( !IsLine( pObj ) ) 7546 { 7547 tools::Rectangle aSnapRect( pObj->GetSnapRect() ); 7548 aRows.insert( aSnapRect.Top() ); 7549 aColumns.insert( aSnapRect.Left() ); 7550 } 7551 } 7552 7553 if (aRows.empty()) 7554 return pRet; 7555 7556 rtl::Reference<sdr::table::SdrTableObj> pTable = new sdr::table::SdrTableObj(*pSdrModel); 7557 pTable->uno_lock(); 7558 Reference< XTable > xTable( pTable->getTable() ); 7559 7560 try 7561 { 7562 CreateTableRows( xTable->getRows(), aRows, pGroup->GetSnapRect().Bottom() ); 7563 CreateTableColumns( xTable->getColumns(), aColumns, pGroup->GetSnapRect().Right() ); 7564 7565 sal_Int32 nCellCount = aRows.size() * aColumns.size(); 7566 std::unique_ptr<sal_Int32[]> pMergedCellIndexTable(new sal_Int32[ nCellCount ]); 7567 for ( sal_Int32 i = 0; i < nCellCount; i++ ) 7568 pMergedCellIndexTable[ i ] = i; 7569 7570 aGroupIter.Reset(); 7571 while( aGroupIter.IsMore() ) 7572 { 7573 SdrObject* pObj( aGroupIter.Next() ); 7574 if ( !IsLine( pObj ) ) 7575 { 7576 sal_Int32 nTableIndex = 0; 7577 sal_Int32 nRow = 0; 7578 sal_Int32 nRowCount = 0; 7579 sal_Int32 nColumn = 0; 7580 sal_Int32 nColumnCount = 0; 7581 if ( GetCellPosition( pObj, aRows, aColumns, nTableIndex, nRow, nRowCount, nColumn, nColumnCount ) ) 7582 { 7583 Reference< XCell > xCell( xTable->getCellByPosition( nColumn, nRow ) ); 7584 7585 ApplyCellAttributes( pObj, xCell ); 7586 7587 if ( ( nRowCount > 1 ) || ( nColumnCount > 1 ) ) // cell merging 7588 { 7589 MergeCells( xTable, nColumn, nRow, nColumnCount, nRowCount ); 7590 for ( sal_Int32 nRowIter = 0; nRowIter < nRowCount; nRowIter++ ) 7591 { 7592 for ( sal_Int32 nColumnIter = 0; nColumnIter < nColumnCount; nColumnIter++ ) 7593 { // now set the correct index for the merged cell 7594 pMergedCellIndexTable[ ( ( nRow + nRowIter ) * aColumns.size() ) + nColumn + nColumnIter ] = nTableIndex; 7595 } 7596 } 7597 } 7598 7599 // applying text 7600 OutlinerParaObject* pParaObject = pObj->GetOutlinerParaObject(); 7601 if ( pParaObject ) 7602 { 7603 SdrText* pSdrText = pTable->getText( nTableIndex ); 7604 if ( pSdrText ) 7605 pSdrText->SetOutlinerParaObject(*pParaObject); 7606 } 7607 } 7608 } 7609 } 7610 aGroupIter.Reset(); 7611 while( aGroupIter.IsMore() ) 7612 { 7613 SdrObject* pObj( aGroupIter.Next() ); 7614 if ( IsLine( pObj ) ) 7615 { 7616 std::vector< sal_Int32 > vPositions; // containing cell indexes + cell position 7617 GetLinePositions( pObj, aRows, aColumns, vPositions, pGroup->GetSnapRect() ); 7618 7619 // correcting merged cell position 7620 for (auto & vPos : vPositions) 7621 { 7622 sal_Int32 nOldPosition = vPos & 0xffff; 7623 sal_Int32 nOldFlags = vPos & 0xffff0000; 7624 sal_Int32 nNewPosition = pMergedCellIndexTable[ nOldPosition ] | nOldFlags; 7625 vPos = nNewPosition; 7626 } 7627 ApplyCellLineAttributes( pObj, xTable, vPositions, aColumns.size() ); 7628 } 7629 } 7630 pMergedCellIndexTable.reset(); 7631 7632 // we are replacing the whole group object by a single table object, so 7633 // possibly connections to the group object have to be removed. 7634 if ( pSolverContainer ) 7635 { 7636 for (auto & pPtr : pSolverContainer->aCList) 7637 { 7638 // check connections to the group object 7639 if ( pPtr->pAObj == pGroup ) 7640 pPtr->pAObj = nullptr; 7641 if ( pPtr->pBObj == pGroup ) 7642 pPtr->pBObj = nullptr; 7643 7644 // check connections to all its subobjects 7645 SdrObjListIter aIter( *pGroup, SdrIterMode::DeepWithGroups ); 7646 while( aIter.IsMore() ) 7647 { 7648 SdrObject* pPartObj = aIter.Next(); 7649 if ( pPtr->pAObj == pPartObj ) 7650 pPtr->pAObj = nullptr; 7651 if ( pPtr->pBObj == pPartObj ) 7652 pPtr->pBObj = nullptr; 7653 } 7654 //In MS, the one_row_one_col table is made up of five 7655 //shape,the connector is connected to some part of a 7656 //table. But for us, the connector is connected to the 7657 //whole group table,so the connector obj is a group 7658 //table when export by us. We should process this 7659 //situation when importing. 7660 if ( pPtr->pAObj == pGroup ) 7661 pPtr->pAObj = pTable.get(); 7662 if ( pPtr->pBObj == pGroup ) 7663 pPtr->pBObj = pTable.get(); 7664 } 7665 } 7666 pTable->uno_unlock(); 7667 pTable->SetSnapRect( pGroup->GetSnapRect() ); 7668 pRet = pTable; 7669 7670 //Remove Objects from shape map 7671 SdrObjListIter aIter( *pGroup, SdrIterMode::DeepWithGroups ); 7672 while( aIter.IsMore() ) 7673 { 7674 SdrObject* pPartObj = aIter.Next(); 7675 removeShapeId(pPartObj); 7676 // ofz#41510 make sure rBackgroundColoredObjects doesn't contain deleted objects 7677 std::replace(rBackgroundColoredObjects.begin(), rBackgroundColoredObjects.end(), pPartObj, pRet.get()); 7678 } 7679 } 7680 catch( const Exception& ) 7681 { 7682 pTable->uno_unlock(); 7683 pTable = nullptr; 7684 } 7685 7686 return pRet; 7687 } 7688 7689 bool SdrPowerPointImport::IsVerticalText() const 7690 { 7691 bool bVerticalText = false; 7692 if ( IsProperty( DFF_Prop_txflTextFlow ) ) 7693 { 7694 auto eTextFlow = GetPropertyValue(DFF_Prop_txflTextFlow, 0) & 0xFFFF; 7695 switch( eTextFlow ) 7696 { 7697 case mso_txflTtoBA : // Top to Bottom @-font, above -> below 7698 case mso_txflTtoBN : // Top to Bottom non-@, above -> below 7699 case mso_txflVertN : // Vertical, non-@, above -> below 7700 bVerticalText = !bVerticalText; 7701 break; 7702 default: break; 7703 } 7704 } 7705 7706 return bVerticalText; 7707 } 7708 7709 void SdrPowerPointImport::ApplyTextAnchorAttributes( PPTTextObj const & rTextObj, SfxItemSet& rSet ) const 7710 { 7711 SdrTextVertAdjust eTVA; 7712 SdrTextHorzAdjust eTHA; 7713 7714 sal_uInt32 nTextFlags = rTextObj.GetTextFlags(); 7715 7716 nTextFlags &= PPT_TEXTOBJ_FLAGS_PARA_ALIGNMENT_USED_LEFT | PPT_TEXTOBJ_FLAGS_PARA_ALIGNMENT_USED_RIGHT 7717 | PPT_TEXTOBJ_FLAGS_PARA_ALIGNMENT_USED_CENTER | PPT_TEXTOBJ_FLAGS_PARA_ALIGNMENT_USED_BLOCK; 7718 7719 if ( IsVerticalText() ) 7720 { 7721 eTVA = SDRTEXTVERTADJUST_BLOCK; 7722 eTHA = SDRTEXTHORZADJUST_CENTER; 7723 7724 // read text anchor 7725 auto eTextAnchor = GetPropertyValue(DFF_Prop_anchorText, mso_anchorTop); 7726 7727 switch( eTextAnchor ) 7728 { 7729 case mso_anchorTop: 7730 case mso_anchorTopCentered: 7731 eTHA = SDRTEXTHORZADJUST_RIGHT; 7732 break; 7733 7734 case mso_anchorMiddle : 7735 case mso_anchorMiddleCentered: 7736 eTHA = SDRTEXTHORZADJUST_CENTER; 7737 break; 7738 7739 case mso_anchorBottom: 7740 case mso_anchorBottomCentered: 7741 eTHA = SDRTEXTHORZADJUST_LEFT; 7742 break; 7743 7744 default: 7745 break; 7746 } 7747 // if there is a 100% use of following attributes, the textbox can been aligned also in vertical direction 7748 switch ( eTextAnchor ) 7749 { 7750 case mso_anchorTopCentered : 7751 case mso_anchorMiddleCentered : 7752 case mso_anchorBottomCentered : 7753 { 7754 // check if it is sensible to use the centered alignment 7755 sal_uInt32 nMask = PPT_TEXTOBJ_FLAGS_PARA_ALIGNMENT_USED_LEFT | PPT_TEXTOBJ_FLAGS_PARA_ALIGNMENT_USED_RIGHT; 7756 if ( ( nTextFlags & nMask ) != nMask ) // if the textobject has left or also right aligned paragraphs 7757 eTVA = SDRTEXTVERTADJUST_CENTER; // the text has to be displayed using the full width; 7758 } 7759 break; 7760 7761 default : 7762 { 7763 if ( nTextFlags == PPT_TEXTOBJ_FLAGS_PARA_ALIGNMENT_USED_LEFT ) 7764 eTVA = SDRTEXTVERTADJUST_TOP; 7765 else if ( nTextFlags == PPT_TEXTOBJ_FLAGS_PARA_ALIGNMENT_USED_RIGHT ) 7766 eTVA = SDRTEXTVERTADJUST_BOTTOM; 7767 } 7768 break; 7769 } 7770 } 7771 else 7772 { 7773 eTVA = SDRTEXTVERTADJUST_CENTER; 7774 eTHA = SDRTEXTHORZADJUST_BLOCK; 7775 7776 // read text anchor 7777 auto eTextAnchor = GetPropertyValue(DFF_Prop_anchorText, mso_anchorTop); 7778 7779 switch( eTextAnchor ) 7780 { 7781 case mso_anchorTop: 7782 case mso_anchorTopCentered: 7783 eTVA = SDRTEXTVERTADJUST_TOP; 7784 break; 7785 7786 case mso_anchorMiddle : 7787 case mso_anchorMiddleCentered: 7788 eTVA = SDRTEXTVERTADJUST_CENTER; 7789 break; 7790 7791 case mso_anchorBottom: 7792 case mso_anchorBottomCentered: 7793 eTVA = SDRTEXTVERTADJUST_BOTTOM; 7794 break; 7795 7796 default: 7797 break; 7798 } 7799 7800 // if there is a 100% usage of following attributes, the textbox can be aligned also in horizontal direction 7801 switch ( eTextAnchor ) 7802 { 7803 case mso_anchorTopCentered : 7804 case mso_anchorMiddleCentered : 7805 case mso_anchorBottomCentered : 7806 { 7807 // check if it is sensible to use the centered alignment 7808 sal_uInt32 nMask = PPT_TEXTOBJ_FLAGS_PARA_ALIGNMENT_USED_LEFT | PPT_TEXTOBJ_FLAGS_PARA_ALIGNMENT_USED_RIGHT; 7809 if ( ( nTextFlags & nMask ) != nMask ) // if the textobject has left or also right aligned paragraphs 7810 eTHA = SDRTEXTHORZADJUST_CENTER; // the text has to be displayed using the full width; 7811 } 7812 break; 7813 7814 default : 7815 { 7816 if ( nTextFlags == PPT_TEXTOBJ_FLAGS_PARA_ALIGNMENT_USED_LEFT ) 7817 eTHA = SDRTEXTHORZADJUST_LEFT; 7818 else if ( nTextFlags == PPT_TEXTOBJ_FLAGS_PARA_ALIGNMENT_USED_RIGHT ) 7819 eTHA = SDRTEXTHORZADJUST_RIGHT; 7820 } 7821 break; 7822 } 7823 } 7824 rSet.Put( SdrTextVertAdjustItem( eTVA ) ); 7825 rSet.Put( SdrTextHorzAdjustItem( eTHA ) ); 7826 } 7827 7828 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ 7829
