Bug Summary

File:home/maarten/src/libreoffice/core/filter/source/msfilter/svdfppt.cxx
Warning:line 931, column 21
Value stored to 'eTVA' is never read

Annotated Source Code

Press '?' to see keyboard shortcuts

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