Coverage Report

Created: 2026-07-10 11:04

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libreoffice/oox/source/drawingml/textparagraphproperties.cxx
Line
Count
Source
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 <drawingml/textparagraphproperties.hxx>
21
#include <drawingml/textliststyle.hxx>
22
23
#include <algorithm>
24
25
#include <com/sun/star/text/XNumberingRulesSupplier.hpp>
26
#include <com/sun/star/container/XIndexReplace.hpp>
27
#include <com/sun/star/text/HoriOrientation.hpp>
28
#include <com/sun/star/awt/FontDescriptor.hpp>
29
#include <com/sun/star/awt/FontWeight.hpp>
30
#include <com/sun/star/awt/XBitmap.hpp>
31
#include <com/sun/star/graphic/XGraphic.hpp>
32
#include <com/sun/star/beans/PropertyValue.hpp>
33
#include <com/sun/star/style/NumberingType.hpp>
34
#include <com/sun/star/style/TabStop.hpp>
35
#include <com/sun/star/style/ParagraphAdjust.hpp>
36
#include <com/sun/star/drawing/XDrawPage.hpp>
37
38
#include <osl/diagnose.h>
39
40
#include <oox/helper/propertyset.hxx>
41
#include <oox/core/xmlfilterbase.hxx>
42
#include <oox/token/properties.hxx>
43
#include <oox/token/tokens.hxx>
44
45
#if OSL_DEBUG_LEVEL > 0
46
#include <com/sun/star/lang/XMultiServiceFactory.hpp>
47
#include <com/sun/star/text/XText.hpp>
48
#include <com/sun/star/drawing/XShape.hpp>
49
#include <oox/ppt/pptimport.hxx>
50
#include <oox/ppt/slidepersist.hxx>
51
#endif
52
53
using namespace ::oox::core;
54
using namespace ::com::sun::star::uno;
55
using namespace ::com::sun::star::beans;
56
using namespace ::com::sun::star::style;
57
using namespace ::com::sun::star::text;
58
using namespace ::com::sun::star::container;
59
using ::com::sun::star::awt::FontDescriptor;
60
61
namespace oox::drawingml {
62
63
BulletList::BulletList( )
64
11.4M
: maBulletColorPtr( std::make_shared<Color>() ),
65
11.4M
  mbBulletColorFollowText ( false ),
66
11.4M
  mbBulletFontFollowText ( false ),
67
11.4M
  mbBulletSizeFollowText ( false )
68
11.4M
{
69
11.4M
}
70
71
bool BulletList::is() const
72
253k
{
73
253k
    return mnNumberingType.hasValue();
74
253k
}
75
76
void BulletList::setBulletChar( const OUString & sChar )
77
71.3k
{
78
71.3k
    mnNumberingType <<= NumberingType::CHAR_SPECIAL;
79
71.3k
    msBulletChar <<= sChar;
80
71.3k
}
81
82
void BulletList::setGraphic( css::uno::Reference< css::graphic::XGraphic > const & rXGraphic )
83
0
{
84
0
    mnNumberingType <<= NumberingType::BITMAP;
85
0
    maGraphic <<= rXGraphic;
86
0
}
87
88
void BulletList::setNone( )
89
29.2k
{
90
29.2k
    mnNumberingType <<= NumberingType::NUMBER_NONE;
91
29.2k
}
92
93
void BulletList::setSuffixParenBoth()
94
0
{
95
0
    msNumberingSuffix <<= u")"_ustr;
96
0
    msNumberingPrefix <<= u"("_ustr;
97
0
}
98
99
void BulletList::setSuffixParenRight()
100
10
{
101
10
    msNumberingSuffix <<= u")"_ustr;
102
10
    msNumberingPrefix <<= OUString();
103
10
}
104
105
void BulletList::setSuffixPeriod()
106
40
{
107
40
    msNumberingSuffix <<= u"."_ustr;
108
40
    msNumberingPrefix <<= OUString();
109
40
}
110
111
void BulletList::setSuffixNone()
112
71.3k
{
113
71.3k
    msNumberingSuffix <<= OUString();
114
71.3k
    msNumberingPrefix <<= OUString();
115
71.3k
}
116
117
void BulletList::setSuffixMinusRight()
118
0
{
119
0
    msNumberingSuffix <<= u"-"_ustr;
120
0
    msNumberingPrefix <<= OUString();
121
0
}
122
123
void BulletList::setType( sal_Int32 nType )
124
50
{
125
50
    OSL_ASSERT((nType & sal_Int32(0xFFFF0000))==0);
126
50
    switch( nType )
127
50
    {
128
0
    case XML_alphaLcParenBoth:
129
0
        mnNumberingType <<= NumberingType::CHARS_LOWER_LETTER;
130
0
        setSuffixParenBoth();
131
0
        break;
132
10
    case XML_alphaLcParenR:
133
10
        mnNumberingType <<= NumberingType::CHARS_LOWER_LETTER;
134
10
        setSuffixParenRight();
135
10
        break;
136
0
    case XML_alphaLcPeriod:
137
0
        mnNumberingType <<= NumberingType::CHARS_LOWER_LETTER;
138
0
        setSuffixPeriod();
139
0
        break;
140
0
    case XML_alphaUcParenBoth:
141
0
        mnNumberingType <<= NumberingType::CHARS_UPPER_LETTER;
142
0
        setSuffixParenBoth();
143
0
        break;
144
0
    case XML_alphaUcParenR:
145
0
        mnNumberingType <<= NumberingType::CHARS_UPPER_LETTER;
146
0
        setSuffixParenRight();
147
0
        break;
148
10
    case XML_alphaUcPeriod:
149
10
        mnNumberingType <<= NumberingType::CHARS_UPPER_LETTER;
150
10
        setSuffixPeriod();
151
10
        break;
152
0
    case XML_arabic1Minus:
153
0
    case XML_arabic2Minus:
154
0
    case XML_arabicDbPeriod:
155
0
    case XML_arabicDbPlain:
156
        // TODO
157
0
        break;
158
0
    case XML_arabicParenBoth:
159
0
         mnNumberingType <<= NumberingType::ARABIC;
160
0
        setSuffixParenBoth();
161
0
        break;
162
0
    case XML_arabicParenR:
163
0
         mnNumberingType <<= NumberingType::ARABIC;
164
0
        setSuffixParenRight();
165
0
        break;
166
10
    case XML_arabicPeriod:
167
10
         mnNumberingType <<= NumberingType::ARABIC;
168
10
        setSuffixPeriod();
169
10
        break;
170
0
    case XML_arabicPlain:
171
0
         mnNumberingType <<= NumberingType::ARABIC;
172
0
        setSuffixNone();
173
0
        break;
174
0
    case XML_circleNumDbPlain:
175
0
    case XML_circleNumWdBlackPlain:
176
0
    case XML_circleNumWdWhitePlain:
177
0
        mnNumberingType <<= NumberingType::CIRCLE_NUMBER;
178
0
        break;
179
0
    case XML_ea1ChsPeriod:
180
0
        mnNumberingType <<= NumberingType::NUMBER_UPPER_ZH;
181
0
         setSuffixPeriod();
182
0
        break;
183
0
    case XML_ea1ChsPlain:
184
0
        mnNumberingType <<= NumberingType::NUMBER_UPPER_ZH;
185
0
        setSuffixNone();
186
0
        break;
187
0
    case XML_ea1ChtPeriod:
188
0
        mnNumberingType <<= NumberingType::NUMBER_UPPER_ZH_TW;
189
0
         setSuffixPeriod();
190
0
        break;
191
0
    case XML_ea1ChtPlain:
192
0
        mnNumberingType <<= NumberingType::NUMBER_UPPER_ZH_TW;
193
0
        setSuffixNone();
194
0
        break;
195
0
    case XML_ea1JpnChsDbPeriod:
196
0
    case XML_ea1JpnKorPeriod:
197
0
    case XML_ea1JpnKorPlain:
198
0
        break;
199
0
    case XML_hebrew2Minus:
200
0
        mnNumberingType <<= NumberingType::CHARS_HEBREW;
201
0
        setSuffixMinusRight();
202
0
        break;
203
0
    case XML_hindiAlpha1Period:
204
0
    case XML_hindiAlphaPeriod:
205
0
    case XML_hindiNumParenR:
206
0
    case XML_hindiNumPeriod:
207
        // TODO
208
0
        break;
209
0
    case XML_romanLcParenBoth:
210
0
        mnNumberingType <<= NumberingType::ROMAN_LOWER;
211
0
        setSuffixParenBoth();
212
0
        break;
213
0
    case XML_romanLcParenR:
214
0
        mnNumberingType <<= NumberingType::ROMAN_LOWER;
215
0
        setSuffixParenRight();
216
0
        break;
217
10
    case XML_romanLcPeriod:
218
10
        mnNumberingType <<= NumberingType::ROMAN_LOWER;
219
10
         setSuffixPeriod();
220
10
        break;
221
0
    case XML_romanUcParenBoth:
222
0
        mnNumberingType <<= NumberingType::ROMAN_UPPER;
223
0
        setSuffixParenBoth();
224
0
        break;
225
0
    case XML_romanUcParenR:
226
0
        mnNumberingType <<= NumberingType::ROMAN_UPPER;
227
0
        setSuffixParenRight();
228
0
        break;
229
10
    case XML_romanUcPeriod:
230
10
        mnNumberingType <<= NumberingType::ROMAN_UPPER;
231
10
         setSuffixPeriod();
232
10
        break;
233
0
    case XML_thaiAlphaParenBoth:
234
0
    case XML_thaiNumParenBoth:
235
0
        mnNumberingType <<= NumberingType::CHARS_THAI;
236
0
        setSuffixParenBoth();
237
0
        break;
238
0
    case XML_thaiAlphaParenR:
239
0
    case XML_thaiNumParenR:
240
0
        mnNumberingType <<= NumberingType::CHARS_THAI;
241
0
        setSuffixParenRight();
242
0
        break;
243
0
    case XML_thaiAlphaPeriod:
244
0
    case XML_thaiNumPeriod:
245
0
        mnNumberingType <<= NumberingType::CHARS_THAI;
246
0
         setSuffixPeriod();
247
0
        break;
248
50
    }
249
50
}
250
251
void BulletList::setBulletSize(sal_Int16 nSize)
252
29.1k
{
253
29.1k
    mnSize <<= nSize;
254
29.1k
}
255
256
void BulletList::setBulletAspectRatio(double nAspectRatio)
257
0
{
258
0
    mnAspectRatio <<= nAspectRatio;
259
0
}
260
261
void BulletList::setFontSize(sal_Int16 nSize)
262
0
{
263
0
    mnFontSize <<= nSize;
264
0
}
265
266
void BulletList::apply( const BulletList& rSource )
267
8.57M
{
268
8.57M
    if ( rSource.maBulletColorPtr->isUsed() )
269
11.5k
        maBulletColorPtr = rSource.maBulletColorPtr;
270
8.57M
    if ( rSource.mbBulletColorFollowText.hasValue() )
271
8.57M
        mbBulletColorFollowText = rSource.mbBulletColorFollowText;
272
8.57M
    if ( rSource.mbBulletFontFollowText.hasValue() )
273
8.57M
        mbBulletFontFollowText = rSource.mbBulletFontFollowText;
274
8.57M
    if ( rSource.mbBulletSizeFollowText.hasValue() )
275
8.57M
        mbBulletSizeFollowText = rSource.mbBulletSizeFollowText;
276
8.57M
    maBulletFont.assignIfUsed( rSource.maBulletFont );
277
8.57M
    if ( rSource.msBulletChar.hasValue() )
278
473k
        msBulletChar = rSource.msBulletChar;
279
8.57M
    if ( rSource.mnStartAt.hasValue() )
280
50
        mnStartAt = rSource.mnStartAt;
281
8.57M
    if ( rSource.mnNumberingType.hasValue() )
282
587k
        mnNumberingType = rSource.mnNumberingType;
283
8.57M
    if ( rSource.msNumberingPrefix.hasValue() )
284
473k
        msNumberingPrefix = rSource.msNumberingPrefix;
285
8.57M
    if ( rSource.msNumberingSuffix.hasValue() )
286
473k
        msNumberingSuffix = rSource.msNumberingSuffix;
287
8.57M
    if ( rSource.mnSize.hasValue() )
288
1.87k
        mnSize = rSource.mnSize;
289
8.57M
    if ( rSource.mnAspectRatio.hasValue() )
290
0
        mnAspectRatio = rSource.mnAspectRatio;
291
8.57M
    if ( rSource.mnFontSize.hasValue() )
292
0
        mnFontSize = rSource.mnFontSize;
293
8.57M
    if ( rSource.maStyleName.hasValue() )
294
1.17M
        maStyleName = rSource.maStyleName;
295
8.57M
    if ( rSource.maGraphic.hasValue() )
296
0
        maGraphic = rSource.maGraphic;
297
8.57M
}
298
299
void BulletList::pushToPropMap( const ::oox::core::XmlFilterBase* pFilterBase, PropertyMap& rPropMap ) const
300
148k
{
301
148k
    if( msNumberingPrefix.hasValue() )
302
44.4k
        rPropMap.setAnyProperty( PROP_Prefix, msNumberingPrefix);
303
148k
    if( msNumberingSuffix.hasValue() )
304
44.4k
        rPropMap.setAnyProperty( PROP_Suffix, msNumberingSuffix);
305
148k
    if( mnStartAt.hasValue() )
306
50
        rPropMap.setAnyProperty( PROP_StartWith, mnStartAt);
307
148k
    rPropMap.setProperty( PROP_Adjust, HoriOrientation::LEFT);
308
309
148k
    if( mnNumberingType.hasValue() )
310
56.2k
        rPropMap.setAnyProperty( PROP_NumberingType, mnNumberingType);
311
312
148k
    OUString aBulletFontName;
313
148k
    sal_Int16 nBulletFontPitch = 0;
314
148k
    sal_Int16 nBulletFontFamily = 0;
315
148k
    float nBulletFontWeight = css::awt::FontWeight::NORMAL;
316
148k
    bool bSymbolFont = false;
317
148k
    if( pFilterBase) {
318
148k
        bool bFollowTextFont = false;
319
148k
        mbBulletFontFollowText >>= bFollowTextFont;
320
148k
        if (!bFollowTextFont && maBulletFont.getFontData( aBulletFontName, nBulletFontPitch, nBulletFontFamily, &bSymbolFont, *pFilterBase ) )
321
43.8k
        {
322
43.8k
            FontDescriptor aFontDesc;
323
43.8k
            sal_Int16 nFontSize = 0;
324
43.8k
            if( mnFontSize >>= nFontSize )
325
0
                aFontDesc.Height = nFontSize;
326
327
            // TODO It is likely that bSymbolFont from getFontData is sufficient to check here
328
            // and looking at the font name is not necessary, if it is necessary then moving
329
            // the name lookup into getFontData is likely the best fix
330
43.8k
            aFontDesc.Name = aBulletFontName;
331
43.8k
            aFontDesc.Pitch = nBulletFontPitch;
332
43.8k
            aFontDesc.Family = nBulletFontFamily;
333
43.8k
            aFontDesc.Weight = nBulletFontWeight;
334
43.8k
            if ( bSymbolFont ||
335
43.2k
                 aBulletFontName.equalsIgnoreAsciiCase("Wingdings") ||
336
43.2k
                 aBulletFontName.equalsIgnoreAsciiCase("Wingdings 2") ||
337
43.2k
                 aBulletFontName.equalsIgnoreAsciiCase("Wingdings 3") ||
338
43.2k
                 aBulletFontName.equalsIgnoreAsciiCase("Monotype Sorts") ||
339
43.2k
                 aBulletFontName.equalsIgnoreAsciiCase("Monotype Sorts 2") ||
340
43.2k
                 aBulletFontName.equalsIgnoreAsciiCase("Webdings") ||
341
43.2k
                 aBulletFontName.equalsIgnoreAsciiCase("StarBats") ||
342
43.2k
                 aBulletFontName.equalsIgnoreAsciiCase("StarMath") ||
343
43.2k
                 aBulletFontName.equalsIgnoreAsciiCase("ZapfDingbats") ) {
344
560
                aFontDesc.CharSet = RTL_TEXTENCODING_SYMBOL;
345
560
                bSymbolFont = true;
346
560
            }
347
43.8k
            rPropMap.setProperty( PROP_BulletFont, aFontDesc);
348
43.8k
            rPropMap.setProperty( PROP_BulletFontName, aBulletFontName);
349
43.8k
        }
350
148k
    }
351
148k
    if ( msBulletChar.hasValue() ) {
352
44.3k
        OUString sBuChar;
353
354
44.3k
        msBulletChar >>= sBuChar;
355
356
44.3k
        if( pFilterBase && sBuChar.getLength() == 1 && maBulletFont.getFontData( aBulletFontName, nBulletFontPitch, nBulletFontFamily, nullptr, *pFilterBase ) && bSymbolFont )
357
553
        {
358
553
            sal_Unicode nBuChar = sBuChar.toChar();
359
553
            nBuChar &= 0x00ff;
360
553
            nBuChar |= 0xf000;
361
553
            sBuChar = OUString( &nBuChar, 1 );
362
553
        }
363
364
44.3k
        rPropMap.setProperty( PROP_BulletChar, sBuChar);
365
44.3k
    }
366
148k
    if ( maGraphic.hasValue() )
367
0
    {
368
0
        Reference<css::awt::XBitmap> xBitmap(maGraphic, UNO_QUERY);
369
0
        if (xBitmap.is())
370
0
            rPropMap.setProperty(PROP_GraphicBitmap, xBitmap);
371
0
    }
372
148k
    bool bFollowTextSize = false;
373
148k
    mbBulletSizeFollowText >>= bFollowTextSize;
374
148k
    if( !bFollowTextSize && mnSize.hasValue() )
375
1.21k
        rPropMap.setAnyProperty( PROP_BulletRelSize, mnSize);
376
148k
    if ( maStyleName.hasValue() )
377
88.7k
        rPropMap.setAnyProperty( PROP_CharStyleName, maStyleName);
378
148k
    if (pFilterBase ) {
379
148k
        bool bFollowTextColor = false;
380
148k
        mbBulletColorFollowText >>= bFollowTextColor;
381
148k
        if ( maBulletColorPtr->isUsed() && !bFollowTextColor )
382
1.09k
            rPropMap.setProperty( PROP_BulletColor, maBulletColorPtr->getColor( pFilterBase->getGraphicHelper() ));
383
148k
    }
384
148k
}
385
386
TextParagraphProperties::TextParagraphProperties()
387
11.4M
: mnLevel( 0 ), mbRestartNumbering( false )
388
11.4M
{
389
11.4M
}
390
391
void TextParagraphProperties::apply( const TextParagraphProperties& rSourceProps )
392
8.57M
{
393
8.57M
    maTextParagraphPropertyMap.assignAll( rSourceProps.maTextParagraphPropertyMap );
394
8.57M
    maBulletList.apply( rSourceProps.maBulletList );
395
8.57M
    maTextCharacterProperties.assignUsed( rSourceProps.maTextCharacterProperties );
396
8.57M
    if ( rSourceProps.maParaTopMargin.bHasValue )
397
562k
        maParaTopMargin = rSourceProps.maParaTopMargin;
398
8.57M
    if ( rSourceProps.maParaBottomMargin.bHasValue )
399
670k
        maParaBottomMargin = rSourceProps.maParaBottomMargin;
400
8.57M
    if ( rSourceProps.moParaLeftMargin )
401
954k
        moParaLeftMargin = rSourceProps.moParaLeftMargin;
402
8.57M
    if ( rSourceProps.moFirstLineIndentation )
403
587k
        moFirstLineIndentation = rSourceProps.moFirstLineIndentation;
404
8.57M
    if ( rSourceProps.moDefaultTabSize )
405
841k
        moDefaultTabSize = rSourceProps.moDefaultTabSize;
406
8.57M
    if( rSourceProps.mnLevel )
407
13.0k
        mnLevel = rSourceProps.mnLevel;
408
8.57M
    if( rSourceProps.moParaAdjust )
409
968k
        moParaAdjust = rSourceProps.moParaAdjust;
410
8.57M
    if( rSourceProps.maLineSpacing.bHasValue )
411
369k
        maLineSpacing = rSourceProps.maLineSpacing;
412
8.57M
    if( rSourceProps.mbRestartNumbering )
413
50
        mbRestartNumbering = rSourceProps.mbRestartNumbering;
414
8.57M
}
415
416
void TextParagraphProperties::pushToPropSet( const ::oox::core::XmlFilterBase* pFilterBase,
417
    const Reference < XPropertySet >& xPropSet, PropertyMap& rioBulletMap, const BulletList* pMasterBuList, bool bApplyBulletMap, float fCharacterSize,
418
    bool bPushDefaultValues, TextListStyle* pTextListStyle ) const
419
148k
{
420
148k
    PropertySet aPropSet( xPropSet );
421
148k
    aPropSet.setProperties( maTextParagraphPropertyMap );
422
423
148k
    sal_Int32 nNumberingType = NumberingType::NUMBER_NONE;
424
148k
    if ( maBulletList.mnNumberingType.hasValue() )
425
56.2k
    {
426
56.2k
        maBulletList.mnNumberingType >>= nNumberingType;
427
56.2k
        if (aPropSet.hasProperty(PROP_NumberingLevel))
428
19.6k
            aPropSet.setProperty< sal_Int16 >( PROP_NumberingLevel, getLevel() );
429
56.2k
    }
430
92.5k
    else if ( pMasterBuList && pMasterBuList->mnNumberingType.hasValue() )
431
0
        pMasterBuList->mnNumberingType >>= nNumberingType;
432
148k
    if ( nNumberingType == NumberingType::NUMBER_NONE
433
107k
        && aPropSet.hasProperty(PROP_NumberingLevel) )
434
53.5k
        aPropSet.setProperty< sal_Int16 >( PROP_NumberingLevel, -1 );
435
436
148k
    maBulletList.pushToPropMap( pFilterBase, rioBulletMap );
437
438
148k
    if ( maParaTopMargin.bHasValue || bPushDefaultValues )
439
138k
        aPropSet.setProperty( PROP_ParaTopMargin, maParaTopMargin.toMargin( fCharacterSize != 0.0 ? fCharacterSize : getCharHeightPoints ( 12.0 ) ) );
440
148k
    if ( maParaBottomMargin.bHasValue || bPushDefaultValues )
441
138k
        aPropSet.setProperty( PROP_ParaBottomMargin, maParaBottomMargin.toMargin( fCharacterSize != 0.0 ? fCharacterSize : getCharHeightPoints ( 12.0 ) ) );
442
443
148k
    std::optional< sal_Int32 > noParaLeftMargin( moParaLeftMargin );
444
148k
    std::optional< sal_Int32 > noFirstLineIndentation( moFirstLineIndentation );
445
446
148k
    if ( nNumberingType != NumberingType::NUMBER_NONE )
447
41.6k
    {
448
41.6k
        if ( noFirstLineIndentation )
449
37.6k
        {
450
            // DrawingML 'indent' is signed (< 0 hanging, > 0 first-line) and relative to 'marL'.
451
            // editeng's numbering can only represent a bullet that hangs to the left
452
            // (FirstLineOffset <= 0) and never sits at a negative position. Map (marL, indent) the
453
            // way PowerPoint lays it out: clamp the bullet to >= 0 and place the text |indent| to its
454
            // right, so the bullet->text gap survives even when marL < |indent| (e.g. marL == 0).
455
            // This is identical to the previous naive mapping whenever marL >= |indent| (the normal
456
            // hanging bullet); it only corrects the marL < |indent| and positive-indent cases that
457
            // used to collapse the gap (and which feed editeng an out-of-contract numbering rule).
458
37.6k
            const sal_Int32 nMarL = noParaLeftMargin.value_or(0);
459
37.6k
            const sal_Int32 nIndent = *noFirstLineIndentation;
460
37.6k
            const sal_Int32 nAbsIndent = nIndent < 0 ? -nIndent : nIndent;
461
37.6k
            const sal_Int32 nBulletX = std::max<sal_Int32>(0, std::min(nMarL, nMarL + nIndent));
462
463
            // Force Paragraph property as zero - impress seems to use the value from previous
464
            // (non) bullet line if not set to zero explicitly :(
465
37.6k
            aPropSet.setProperty<sal_Int32>( PROP_ParaLeftMargin, 0);
466
37.6k
            aPropSet.setProperty<sal_Int32>( PROP_ParaFirstLineIndent, 0);
467
37.6k
            rioBulletMap.setProperty( PROP_LeftMargin, nBulletX + nAbsIndent);
468
37.6k
            rioBulletMap.setProperty( PROP_FirstLineOffset, -nAbsIndent);
469
37.6k
            noParaLeftMargin.reset();
470
37.6k
            noFirstLineIndentation.reset();
471
37.6k
        }
472
4.05k
        else if ( noParaLeftMargin )
473
0
        {
474
0
            aPropSet.setProperty<sal_Int32>( PROP_ParaLeftMargin, 0);
475
0
            rioBulletMap.setProperty( PROP_LeftMargin, *noParaLeftMargin);
476
0
            noParaLeftMargin.reset();
477
0
        }
478
41.6k
        if ( nNumberingType != NumberingType::BITMAP && !rioBulletMap.hasProperty( PROP_BulletColor ) && pFilterBase )
479
31.4k
            rioBulletMap.setProperty( PROP_BulletColor, maTextCharacterProperties.maFillProperties.getBestSolidColor().getColor( pFilterBase->getGraphicHelper()));
480
41.6k
    }
481
482
148k
    if ( bApplyBulletMap )
483
148k
    {
484
148k
        Reference< XIndexReplace > xNumRule;
485
148k
        aPropSet.getProperty( xNumRule, PROP_NumberingRules );
486
148k
        OSL_ENSURE( xNumRule.is(), "can't get Numbering rules");
487
488
148k
        try
489
148k
        {
490
148k
            if( xNumRule.is() )
491
148k
            {
492
148k
                if( !rioBulletMap.empty() )
493
148k
                {
494
                    // fix default bullet size to be 100%
495
148k
                    if( !rioBulletMap.hasProperty( PROP_BulletRelSize ) )
496
147k
                        rioBulletMap.setProperty<sal_Int16>( PROP_BulletRelSize, 100);
497
148k
                    Sequence< PropertyValue > aBulletPropSeq = rioBulletMap.makePropertyValueSequence();
498
148k
                    xNumRule->replaceByIndex( getLevel(), Any( aBulletPropSeq ) );
499
500
148k
                    if (pTextListStyle)
501
53.1k
                    {
502
                        // We got the list style of this shape, then set the other levels of the
503
                        // numbering rules, too.
504
53.1k
                        pTextListStyle->pushToNumberingRules(xNumRule, getLevel());
505
53.1k
                    }
506
148k
                }
507
508
148k
                aPropSet.setProperty( PROP_NumberingRules, xNumRule );
509
148k
            }
510
148k
        }
511
148k
        catch (const Exception &)
512
148k
        {
513
            // Don't warn for now, expected to fail for Writer.
514
3.76k
        }
515
148k
    }
516
148k
    if ( noParaLeftMargin )
517
19.1k
        aPropSet.setProperty( PROP_ParaLeftMargin, *noParaLeftMargin);
518
129k
    else // Use 0 as default left margin
519
129k
        aPropSet.setProperty<sal_Int32>(PROP_ParaLeftMargin, 0);
520
521
148k
    if ( noFirstLineIndentation )
522
8.73k
    {
523
8.73k
        aPropSet.setProperty( PROP_ParaFirstLineIndent, *noFirstLineIndentation );
524
8.73k
        if( bPushDefaultValues )
525
8.73k
        {
526
            // Reset TabStops - these would be auto calculated by Impress
527
8.73k
            TabStop aTabStop;
528
8.73k
            aTabStop.Position = 0;
529
8.73k
            Sequence< TabStop > aSeq { aTabStop };
530
8.73k
            aPropSet.setProperty( PROP_ParaTabStops, aSeq );
531
8.73k
        }
532
8.73k
    }
533
140k
    else
534
140k
        aPropSet.setProperty<sal_Int32>( PROP_ParaFirstLineIndent, 0);
535
536
148k
    if ( moDefaultTabSize )
537
60.3k
    {
538
60.3k
        aPropSet.setProperty( PROP_ParaTabStopDefaultDistance, *moDefaultTabSize );
539
60.3k
    }
540
541
148k
    if ( moParaAdjust )
542
74.6k
    {
543
74.6k
        aPropSet.setProperty( PROP_ParaAdjust, *moParaAdjust);
544
74.6k
    }
545
74.1k
    else
546
74.1k
    {
547
74.1k
        aPropSet.setProperty( PROP_ParaAdjust, css::style::ParagraphAdjust_LEFT);
548
74.1k
    }
549
550
148k
    if ( maLineSpacing.bHasValue )
551
41.9k
    {
552
41.9k
        aPropSet.setProperty( PROP_ParaLineSpacing, maLineSpacing.toLineSpacing());
553
41.9k
    }
554
106k
    else
555
106k
    {
556
106k
        aPropSet.setProperty( PROP_ParaLineSpacing, css::style::LineSpacing( css::style::LineSpacingMode::PROP, 100 ));
557
106k
    }
558
559
148k
    if ( mbRestartNumbering )
560
50
    {
561
50
        aPropSet.setProperty( PROP_ParaIsNumberingRestart, true);
562
50
    }
563
148k
}
564
565
float TextParagraphProperties::getCharHeightPoints( float fDefault ) const
566
15.7k
{
567
15.7k
    return maTextCharacterProperties.getCharHeightPoints( fDefault );
568
15.7k
}
569
570
#ifdef DBG_UTIL
571
// Note: Please don't remove this function. This is required for
572
// debugging pptx import problems.
573
void TextParagraphProperties::dump() const
574
{
575
    Reference< css::drawing::XShape > xShape( oox::ppt::PowerPointImport::mpDebugFilterBase->getModelFactory()->createInstance( u"com.sun.star.presentation.TitleTextShape"_ustr ), UNO_QUERY );
576
    Reference< css::text::XText > xText( xShape, UNO_QUERY );
577
578
    Reference< css::drawing::XDrawPage > xDebugPage(ppt::SlidePersist::mxDebugPage.get(), UNO_QUERY);
579
    if (xDebugPage.is())
580
        xDebugPage->add( xShape );
581
582
    PropertyMap emptyMap;
583
584
    xText->setString( u"debug"_ustr );
585
    Reference< css::text::XTextCursor > xStart = xText->createTextCursor();
586
    xStart->gotoEnd( true );
587
    Reference< XPropertySet > xPropSet( xStart, UNO_QUERY );
588
    pushToPropSet( nullptr, xPropSet, emptyMap, nullptr, false, 0 );
589
    PropertySet aPropSet( xPropSet );
590
    aPropSet.dump();
591
}
592
#endif
593
}
594
595
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */