LibreOffice Module sd (master) 1
pptx-text.cxx
Go to the documentation of this file.
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 <memory>
21#include "text.hxx"
22
23#include <com/sun/star/awt/CharSet.hpp>
24#include <com/sun/star/awt/FontWeight.hpp>
25#include <com/sun/star/awt/FontUnderline.hpp>
26#include <com/sun/star/awt/XBitmap.hpp>
27#include <com/sun/star/beans/XPropertyState.hpp>
28#include <com/sun/star/beans/XPropertySet.hpp>
29#include <com/sun/star/container/XEnumerationAccess.hpp>
30#include <com/sun/star/container/XIndexReplace.hpp>
31#include <com/sun/star/i18n/BreakIterator.hpp>
32#include <com/sun/star/i18n/ScriptDirection.hpp>
33#include <com/sun/star/i18n/ScriptType.hpp>
34#include <com/sun/star/text/FontRelief.hpp>
35#include <com/sun/star/text/XTextField.hpp>
36#include <com/sun/star/text/XTextRange.hpp>
37#include <com/sun/star/style/LineSpacing.hpp>
38#include <com/sun/star/style/LineSpacingMode.hpp>
39#include <com/sun/star/style/ParagraphAdjust.hpp>
40#include <com/sun/star/style/TabStop.hpp>
41#include <com/sun/star/graphic/XGraphic.hpp>
42
44#include <editeng/svxenum.hxx>
45#include <editeng/frmdir.hxx>
48#include <o3tl/any.hxx>
50#include <osl/diagnose.h>
53
54#include <vcl/settings.hxx>
55#include <vcl/metric.hxx>
56#include <vcl/virdev.hxx>
57#include <vcl/svapp.hxx>
58
59using namespace css;
60
61static css::uno::Reference< css::i18n::XBreakIterator > xPPTBreakIter;
62
63PortionObj::PortionObj(const css::uno::Reference< css::beans::XPropertySet > & rXPropSet,
64 FontCollection& rFontCollection)
65 : meCharColor(css::beans::PropertyState_AMBIGUOUS_VALUE)
66 , meCharHeight(css::beans::PropertyState_AMBIGUOUS_VALUE)
67 , meFontName(css::beans::PropertyState_AMBIGUOUS_VALUE)
68 , meAsianOrComplexFont(css::beans::PropertyState_AMBIGUOUS_VALUE)
69 , meCharEscapement(css::beans::PropertyState_AMBIGUOUS_VALUE)
70 , mnCharAttrHard(0)
71 , mnCharColor(0)
72 , mnCharAttr(0)
73 , mnFont(0)
74 , mnAsianOrComplexFont(0xffff)
75 , mnTextSize(0)
76 , mbLastPortion(true)
77{
78 mXPropSet = rXPropSet;
79
80 ImplGetPortionValues( rFontCollection, false );
81}
82
83PortionObj::PortionObj(css::uno::Reference< css::text::XTextRange > & rXTextRange,
84 bool bLast, FontCollection& rFontCollection)
85 : meCharColor(css::beans::PropertyState_AMBIGUOUS_VALUE)
86 , meCharHeight(css::beans::PropertyState_AMBIGUOUS_VALUE)
87 , meFontName(css::beans::PropertyState_AMBIGUOUS_VALUE)
88 , meAsianOrComplexFont(css::beans::PropertyState_AMBIGUOUS_VALUE)
89 , meCharEscapement(css::beans::PropertyState_AMBIGUOUS_VALUE)
90 , mnCharAttrHard(0)
91 , mnCharColor(0)
92 , mnCharAttr(0)
93 , mnCharHeight(0)
94 , mnFont(0)
95 , mnAsianOrComplexFont(0xffff)
96 , mnCharEscapement(0)
97 , mbLastPortion(bLast)
98{
99 OUString aString( rXTextRange->getString() );
100 OUString aURL;
101
102 mnTextSize = aString.getLength();
103 if ( bLast )
104 mnTextSize++;
105
106 if ( !mnTextSize )
107 return;
108
109 bool bRTL_endingParen = false;
110 mpFieldEntry = nullptr;
111 sal_uInt32 nFieldType = 0;
112
113 mXPropSet.set( rXTextRange, css::uno::UNO_QUERY );
114 mXPropState.set( rXTextRange, css::uno::UNO_QUERY );
115
116 bool bPropSetsValid = ( mXPropSet.is() && mXPropState.is() );
117 if ( bPropSetsValid )
118 nFieldType = ImplGetTextField( rXTextRange, mXPropSet, aURL );
119 if ( nFieldType )
120 {
121 mpFieldEntry.reset( new FieldEntry( nFieldType, 0, mnTextSize ) );
122 if ( nFieldType >> 28 == 4 )
123 {
124 mpFieldEntry->aRepresentation = aString;
125 mpFieldEntry->aFieldUrl = aURL;
126 }
127 }
128 bool bSymbol = false;
129
130 if ( bPropSetsValid && ImplGetPropertyValue( "CharFontCharSet", false ) )
131 {
132 sal_Int16 nCharset = 0;
133 mAny >>= nCharset;
134 if ( nCharset == css::awt::CharSet::SYMBOL )
135 bSymbol = true;
136 }
137 if ( mpFieldEntry && ( nFieldType & 0x800000 ) ) // placeholder ?
138 {
139 mnTextSize = 1;
140 if ( bLast )
141 mnTextSize++;
142 mpText.reset( new sal_uInt16[ mnTextSize ] );
143 mpText[ 0 ] = 0x2a;
144 }
145 else
146 {
147 // For i39516 - a closing parenthesis that ends an RTL string is displayed backwards by PPT
148 // Solution: add a Unicode Right-to-Left Mark, following the method described in i18024
149 if (bLast && !aString.isEmpty()
150 && aString[aString.getLength() - 1] == ')'
151 && FontCollection::GetScriptDirection(aString) == css::i18n::ScriptDirection::RIGHT_TO_LEFT)
152 {
153 mnTextSize++;
154 bRTL_endingParen = true;
155 }
156 mpText.reset( new sal_uInt16[ mnTextSize ] );
157 sal_uInt16 nChar;
158 for ( sal_Int32 i = 0; i < aString.getLength(); i++ )
159 {
160 nChar = static_cast<sal_uInt16>(aString[ i ]);
161 if ( nChar == 0xa )
162 nChar++;
163 else if ( !bSymbol )
164 {
165 switch ( nChar )
166 {
167 // Currency
168 case 128: nChar = 0x20AC; break;
169 // Punctuation and other
170 case 130: nChar = 0x201A; break;// SINGLE LOW-9 QUOTATION MARK
171 case 131: nChar = 0x0192; break;// LATIN SMALL LETTER F WITH HOOK
172 case 132: nChar = 0x201E; break;// DOUBLE LOW-9 QUOTATION MARK
173 // LOW DOUBLE PRIME QUOTATION MARK
174 case 133: nChar = 0x2026; break;// HORIZONTAL ELLIPSES
175 case 134: nChar = 0x2020; break;// DAGGER
176 case 135: nChar = 0x2021; break;// DOUBLE DAGGER
177 case 136: nChar = 0x02C6; break;// MODIFIER LETTER CIRCUMFLEX ACCENT
178 case 137: nChar = 0x2030; break;// PER MILLE SIGN
179 case 138: nChar = 0x0160; break;// LATIN CAPITAL LETTER S WITH CARON
180 case 139: nChar = 0x2039; break;// SINGLE LEFT-POINTING ANGLE QUOTATION MARK
181 case 140: nChar = 0x0152; break;// LATIN CAPITAL LIGATURE OE
182 case 142: nChar = 0x017D; break;// LATIN CAPITAL LETTER Z WITH CARON
183 case 145: nChar = 0x2018; break;// LEFT SINGLE QUOTATION MARK
184 // MODIFIER LETTER TURNED COMMA
185 case 146: nChar = 0x2019; break;// RIGHT SINGLE QUOTATION MARK
186 // MODIFIER LETTER APOSTROPHE
187 case 147: nChar = 0x201C; break;// LEFT DOUBLE QUOTATION MARK
188 // REVERSED DOUBLE PRIME QUOTATION MARK
189 case 148: nChar = 0x201D; break;// RIGHT DOUBLE QUOTATION MARK
190 // REVERSED DOUBLE PRIME QUOTATION MARK
191 case 149: nChar = 0x2022; break;// BULLET
192 case 150: nChar = 0x2013; break;// EN DASH
193 case 151: nChar = 0x2014; break;// EM DASH
194 case 152: nChar = 0x02DC; break;// SMALL TILDE
195 case 153: nChar = 0x2122; break;// TRADE MARK SIGN
196 case 154: nChar = 0x0161; break;// LATIN SMALL LETTER S WITH CARON
197 case 155: nChar = 0x203A; break;// SINGLE RIGHT-POINTING ANGLE QUOTATION MARK
198 case 156: nChar = 0x0153; break;// LATIN SMALL LIGATURE OE
199 case 158: nChar = 0x017E; break;// LATIN SMALL LETTER Z WITH CARON
200 case 159: nChar = 0x0178; break;// LATIN CAPITAL LETTER Y WITH DIAERESIS
201 }
202 }
203 mpText[ i ] = nChar;
204 }
205 }
206 if ( bRTL_endingParen )
207 mpText[ mnTextSize - 2 ] = 0x200F; // Unicode Right-to-Left mark
208
209 if ( bLast )
210 mpText[ mnTextSize - 1 ] = 0xd;
211
212 if ( bPropSetsValid )
213 ImplGetPortionValues( rFontCollection, true );
214}
215
217: PropStateValue( rPortionObj )
218{
219 ImplConstruct( rPortionObj );
220}
221
223{
224 ImplClear();
225}
226
227void PortionObj::Write( SvStream* pStrm, bool bLast )
228{
229 sal_uInt32 nCount = mnTextSize;
230 if ( bLast && mbLastPortion )
231 nCount--;
232 for ( sal_uInt32 i = 0; i < nCount; i++ )
233 pStrm->WriteUInt16( mpText[ i ] );
234}
235
236void PortionObj::ImplGetPortionValues( FontCollection& rFontCollection, bool bGetPropStateValue )
237{
238
239 bool bOk = ImplGetPropertyValue( "CharFontName", bGetPropStateValue );
241 if ( bOk )
242 {
243 FontCollectionEntry aFontDesc( *o3tl::doAccess<OUString>(mAny) );
244 sal_uInt32 nCount = rFontCollection.GetCount();
245 mnFont = static_cast<sal_uInt16>(rFontCollection.GetId( aFontDesc ));
246 if ( mnFont == nCount )
247 {
248 FontCollectionEntry& rFontDesc = rFontCollection.GetLast();
249 if ( ImplGetPropertyValue( "CharFontCharSet", false ) )
250 mAny >>= rFontDesc.CharSet;
251 if ( ImplGetPropertyValue( "CharFontFamily", false ) )
252 mAny >>= rFontDesc.Family;
253 if ( ImplGetPropertyValue( "CharFontPitch", false ) )
254 mAny >>= rFontDesc.Pitch;
255 }
256 }
257
258 sal_Int16 nScriptType = SvtLanguageOptions::FromSvtScriptTypeToI18N( SvtLanguageOptions::GetScriptTypeOfLanguage( Application::GetSettings().GetLanguageTag().getLanguageType() ) );
259 if ( mpText && mnTextSize && xPPTBreakIter.is() )
260 {
261 OUString sT( reinterpret_cast<sal_Unicode *>(mpText.get()), mnTextSize );
262 nScriptType = xPPTBreakIter->getScriptType( sT, 0 );
263 }
264 if ( nScriptType != css::i18n::ScriptType::COMPLEX )
265 {
266 bOk = ImplGetPropertyValue( "CharFontNameAsian", bGetPropStateValue );
268 if ( bOk )
269 {
270 FontCollectionEntry aFontDesc( *o3tl::doAccess<OUString>(mAny) );
271 sal_uInt32 nCount = rFontCollection.GetCount();
272 mnAsianOrComplexFont = static_cast<sal_uInt16>(rFontCollection.GetId( aFontDesc ));
274 {
275 FontCollectionEntry& rFontDesc = rFontCollection.GetLast();
276 if ( ImplGetPropertyValue( "CharFontCharSetAsian", false ) )
277 mAny >>= rFontDesc.CharSet;
278 if ( ImplGetPropertyValue( "CharFontFamilyAsian", false ) )
279 mAny >>= rFontDesc.Family;
280 if ( ImplGetPropertyValue( "CharFontPitchAsian", false ) )
281 mAny >>= rFontDesc.Pitch;
282 }
283 }
284 }
285 else
286 {
287 bOk = ImplGetPropertyValue( "CharFontNameComplex", bGetPropStateValue );
289 if ( bOk )
290 {
291 FontCollectionEntry aFontDesc( *o3tl::doAccess<OUString>(mAny) );
292 sal_uInt32 nCount = rFontCollection.GetCount();
293 mnAsianOrComplexFont = static_cast<sal_uInt16>(rFontCollection.GetId( aFontDesc ));
295 {
296 FontCollectionEntry& rFontDesc = rFontCollection.GetLast();
297 if ( ImplGetPropertyValue( "CharFontCharSetComplex", false ) )
298 mAny >>= rFontDesc.CharSet;
299 if ( ImplGetPropertyValue( "CharFontFamilyComplex", false ) )
300 mAny >>= rFontDesc.Family;
301 if ( ImplGetPropertyValue( "CharFontPitchComplex", false ) )
302 mAny >>= rFontDesc.Pitch;
303 }
304 }
305 }
306
307 OUString aCharHeightName, aCharWeightName, aCharLocaleName, aCharPostureName;
308 switch( nScriptType )
309 {
310 case css::i18n::ScriptType::ASIAN :
311 {
312 aCharHeightName = "CharHeightAsian";
313 aCharWeightName = "CharWeightAsian";
314 aCharLocaleName = "CharLocaleAsian";
315 aCharPostureName = "CharPostureAsian";
316 break;
317 }
318 case css::i18n::ScriptType::COMPLEX :
319 {
320 aCharHeightName = "CharHeightComplex";
321 aCharWeightName = "CharWeightComplex";
322 aCharLocaleName = "CharLocaleComplex";
323 aCharPostureName = "CharPostureComplex";
324 break;
325 }
326 default:
327 {
328 aCharHeightName = "CharHeight";
329 aCharWeightName = "CharWeight";
330 aCharLocaleName = "CharLocale";
331 aCharPostureName = "CharPosture";
332 break;
333 }
334 }
335
336 mnCharHeight = 24;
337 if ( GetPropertyValue( mAny, mXPropSet, aCharHeightName ) )
338 {
339 float fVal(0.0);
340 if ( mAny >>= fVal )
341 {
342 mnCharHeight = static_cast<sal_uInt16>( fVal + 0.5 );
343 meCharHeight = GetPropertyState( mXPropSet, aCharHeightName );
344 }
345 }
346 if ( GetPropertyValue( mAny, mXPropSet, aCharWeightName ) )
347 {
348 float fFloat(0.0);
349 if ( mAny >>= fFloat )
350 {
351 if ( fFloat >= css::awt::FontWeight::SEMIBOLD )
352 mnCharAttr |= 1;
353 if ( GetPropertyState( mXPropSet, aCharWeightName ) == css::beans::PropertyState_DIRECT_VALUE )
354 mnCharAttrHard |= 1;
355 }
356 }
357 if ( GetPropertyValue( mAny, mXPropSet, aCharLocaleName ) )
358 {
359 css::lang::Locale eLocale;
360 if ( mAny >>= eLocale )
361 meCharLocale = eLocale;
362 }
363 if ( GetPropertyValue( mAny, mXPropSet, aCharPostureName ) )
364 {
365 css::awt::FontSlant aFS;
366 if ( mAny >>= aFS )
367 {
368 switch( aFS )
369 {
370 case css::awt::FontSlant_OBLIQUE :
371 case css::awt::FontSlant_ITALIC :
372 mnCharAttr |= 2;
373 break;
374 default:
375 break;
376 }
377 if ( GetPropertyState( mXPropSet, aCharPostureName ) == css::beans::PropertyState_DIRECT_VALUE )
378 mnCharAttrHard |= 2;
379 }
380 }
381
382 if ( ImplGetPropertyValue( "CharUnderline", bGetPropStateValue ) )
383 {
384 sal_Int16 nVal(0);
385 mAny >>= nVal;
386 switch ( nVal )
387 {
388 case css::awt::FontUnderline::SINGLE :
389 case css::awt::FontUnderline::DOUBLE :
390 case css::awt::FontUnderline::DOTTED :
391 mnCharAttr |= 4;
392 }
393 }
394 if ( ePropState == css::beans::PropertyState_DIRECT_VALUE )
395 mnCharAttrHard |= 4;
396
397 if ( ImplGetPropertyValue( "CharShadowed", bGetPropStateValue ) )
398 {
399 bool bBool(false);
400 mAny >>= bBool;
401 if ( bBool )
402 mnCharAttr |= 0x10;
403 }
404 if ( ePropState == css::beans::PropertyState_DIRECT_VALUE )
405 mnCharAttrHard |= 16;
406
407 if ( ImplGetPropertyValue( "CharRelief", bGetPropStateValue ) )
408 {
409 sal_Int16 nVal(0);
410 mAny >>= nVal;
411 if ( nVal != css::text::FontRelief::NONE )
412 mnCharAttr |= 512;
413 }
414 if ( ePropState == css::beans::PropertyState_DIRECT_VALUE )
415 mnCharAttrHard |= 512;
416
417 if ( ImplGetPropertyValue( "CharColor", bGetPropStateValue ) )
418 {
419 sal_uInt32 nSOColor = *( o3tl::doAccess<sal_uInt32>(mAny) );
420 mnCharColor = nSOColor & 0xff00ff00; // green and hibyte
421 mnCharColor |= static_cast<sal_uInt8>(nSOColor) << 16; // red and blue is switched
422 mnCharColor |= static_cast<sal_uInt8>( nSOColor >> 16 );
423 }
425
427 if ( ImplGetPropertyValue( "CharEscapement", bGetPropStateValue ) )
428 {
430 if ( mnCharEscapement > 100 )
431 mnCharEscapement = 33;
432 else if ( mnCharEscapement < -100 )
433 mnCharEscapement = -33;
434 }
436}
437
439{
440 mpFieldEntry.reset();
441 mpText.reset();
442}
443
444void PortionObj::ImplConstruct( const PortionObj& rPortionObj )
445{
446 meCharColor = rPortionObj.meCharColor;
447 meCharHeight = rPortionObj.meCharHeight;
448 meFontName = rPortionObj.meFontName;
451 meCharLocale = rPortionObj.meCharLocale;
452 mnCharAttrHard = rPortionObj.mnCharAttrHard;
453
454 mbLastPortion = rPortionObj.mbLastPortion;
455 mnTextSize = rPortionObj.mnTextSize;
456 mnCharColor = rPortionObj.mnCharColor;
458 mnCharAttr = rPortionObj.mnCharAttr;
459 mnCharHeight = rPortionObj.mnCharHeight;
460 mnFont = rPortionObj.mnFont;
462
463 if ( rPortionObj.mpText )
464 {
465 mpText.reset( new sal_uInt16[ mnTextSize ] );
466 memcpy( mpText.get(), rPortionObj.mpText.get(), mnTextSize << 1 );
467 }
468
469 if ( rPortionObj.mpFieldEntry )
470 mpFieldEntry.reset( new FieldEntry( *( rPortionObj.mpFieldEntry ) ) );
471}
472
473sal_uInt32 PortionObj::ImplCalculateTextPositions( sal_uInt32 nCurrentTextPosition )
474{
475 if ( mpFieldEntry && ( !mpFieldEntry->nFieldStartPos ) )
476 {
477 mpFieldEntry->nFieldStartPos += nCurrentTextPosition;
478 mpFieldEntry->nFieldEndPos += nCurrentTextPosition;
479 }
480 return mnTextSize;
481}
482
483// Return: 0 = no TextField
484// bit28->31 text field type :
485// 1 = Date
486// 2 = Time
487// 3 = SlideNumber
488// 4 = Url
489// 5 = DateTime
490// 6 = header
491// 7 = footer
492// bit24->27 text field sub type (optional)
493// 23-> PPT Textfield needs a placeholder
494
495sal_uInt32 PortionObj::ImplGetTextField( css::uno::Reference< css::text::XTextRange > & ,
496 const css::uno::Reference< css::beans::XPropertySet > & rXPropSet, OUString& rURL )
497{
498 sal_uInt32 nRetValue = 0;
499 sal_Int32 nFormat;
500 css::uno::Any aAny;
501 if ( GetPropertyValue( aAny, rXPropSet, "TextPortionType", true ) )
502 {
503 auto aTextFieldType = o3tl::doAccess<OUString>(aAny);
504 if ( *aTextFieldType == "TextField" )
505 {
506 if ( GetPropertyValue( aAny, rXPropSet, *aTextFieldType, true ) )
507 {
508 css::uno::Reference< css::text::XTextField > aXTextField;
509 if ( aAny >>= aXTextField )
510 {
511 if ( aXTextField.is() )
512 {
513 css::uno::Reference< css::beans::XPropertySet > xFieldPropSet( aXTextField, css::uno::UNO_QUERY );
514 if ( xFieldPropSet.is() )
515 {
516 OUString aFieldKind( aXTextField->getPresentation( true ) );
517 if ( aFieldKind == "Date" )
518 {
519 if ( GetPropertyValue( aAny, xFieldPropSet, "IsFix", true ) )
520 {
521 bool bBool = false;
522 aAny >>= bBool;
523 if ( !bBool ) // Fixed DateFields does not exist in PPT
524 {
525 if ( GetPropertyValue( aAny, xFieldPropSet, "Format", true ) )
526 {
527 nFormat = *o3tl::doAccess<sal_Int32>(aAny);
528 switch ( nFormat )
529 {
530 default:
531 case 5 :
532 case 4 :
533 case 2 : nFormat = 0; break;
534 case 8 :
535 case 9 :
536 case 3 : nFormat = 1; break;
537 case 7 :
538 case 6 : nFormat = 2; break;
539 }
540 nRetValue |= ( ( ( 1 << 4 ) | nFormat ) << 24 ) | 0x800000;
541 }
542 }
543 }
544 }
545 else if ( aFieldKind == "URL" )
546 {
547 if ( GetPropertyValue( aAny, xFieldPropSet, "URL", true ) )
548 rURL = *o3tl::doAccess<OUString>(aAny);
549 nRetValue = 4 << 28;
550 }
551 else if ( aFieldKind == "Page" )
552 {
553 nRetValue = 3 << 28 | 0x800000;
554 }
555 else if ( aFieldKind == "Pages" )
556 {
557
558 }
559 else if ( aFieldKind == "Time" )
560 {
561 if ( GetPropertyValue( aAny, xFieldPropSet, "IsFix", true ) )
562 {
563 bool bBool = false;
564 aAny >>= bBool;
565 if ( !bBool )
566 {
567 if ( GetPropertyValue( aAny, xFieldPropSet, "IsFix", true ) )
568 {
569 nFormat = *o3tl::doAccess<sal_Int32>(aAny);
570 nRetValue |= ( ( ( 2 << 4 ) | nFormat ) << 24 ) | 0x800000;
571 }
572 }
573 }
574 }
575 else if ( aFieldKind == "File" )
576 {
577
578 }
579 else if ( aFieldKind == "Table" )
580 {
581
582 }
583 else if ( aFieldKind == "ExtTime" )
584 {
585 if ( GetPropertyValue( aAny, xFieldPropSet, "IsFix", true ) )
586 {
587 bool bBool = false;
588 aAny >>= bBool;
589 if ( !bBool )
590 {
591 if ( GetPropertyValue( aAny, xFieldPropSet, "Format", true ) )
592 {
593 nFormat = *o3tl::doAccess<sal_Int32>(aAny);
594 switch ( nFormat )
595 {
596 default:
597 case 6 :
598 case 7 :
599 case 8 :
600 case 2 : nFormat = 12; break;
601 case 3 : nFormat = 9; break;
602 case 5 :
603 case 4 : nFormat = 10; break;
604
605 }
606 nRetValue |= ( ( ( 2 << 4 ) | nFormat ) << 24 ) | 0x800000;
607 }
608 }
609 }
610 }
611 else if ( aFieldKind == "ExtFile" )
612 {
613
614 }
615 else if ( aFieldKind == "Author" )
616 {
617
618 }
619 else if ( aFieldKind == "DateTime" )
620 {
621 nRetValue = 5 << 28 | 0x800000;
622 }
623 else if ( aFieldKind == "Header" )
624 {
625 nRetValue = 6 << 28 | 0x800000;
626 }
627 else if ( aFieldKind == "Footer" )
628 {
629 nRetValue = 7 << 28 | 0x800000;
630 }
631 }
632 }
633 }
634 }
635 }
636 }
637 return nRetValue;
638}
639
641{
642 if ( this != &rPortionObj )
643 {
644 ImplClear();
645 ImplConstruct( rPortionObj );
646 }
647 return *this;
648}
649
650ParagraphObj::ParagraphObj(const css::uno::Reference< css::beans::XPropertySet > & rXPropSet,
651 PPTExBulletProvider* pProv)
652 : mnTextSize(0)
653 , mbFirstParagraph(false)
654 , mbLastParagraph(false)
655 , meBullet(css::beans::PropertyState_AMBIGUOUS_VALUE)
656 , mnTextAdjust(0)
657 , mnLineSpacing(0)
658 , mbFixedLineSpacing(false)
659 , mnLineSpacingTop(0)
660 , mnLineSpacingBottom(0)
661 , mbForbiddenRules(false)
662 , mbParagraphPunctation(false)
663 , mnBiDi(0)
664{
665 mXPropSet = rXPropSet;
666
667 bExtendedParameters = false;
668
669 nDepth = 0;
670 nBulletFlags = 0;
671 nParaFlags = 0;
672
673 ImplGetParagraphValues( pProv, false );
674}
675
676ParagraphObj::ParagraphObj(css::uno::Reference< css::text::XTextContent > const & rXTextContent,
677 ParaFlags aParaFlags, FontCollection& rFontCollection, PPTExBulletProvider& rProv )
678 : mnTextSize(0)
679 , mbIsBullet(false)
680 , mbFirstParagraph( aParaFlags.bFirstParagraph )
681 , mbLastParagraph( aParaFlags.bLastParagraph )
682 , meBullet(css::beans::PropertyState_AMBIGUOUS_VALUE)
683 , meTextAdjust(css::beans::PropertyState_AMBIGUOUS_VALUE)
684 , meLineSpacing(css::beans::PropertyState_AMBIGUOUS_VALUE)
685 , meLineSpacingTop(css::beans::PropertyState_AMBIGUOUS_VALUE)
686 , meLineSpacingBottom(css::beans::PropertyState_AMBIGUOUS_VALUE)
687 , meForbiddenRules(css::beans::PropertyState_AMBIGUOUS_VALUE)
688 , meParagraphPunctation(css::beans::PropertyState_AMBIGUOUS_VALUE)
689 , meBiDi(css::beans::PropertyState_AMBIGUOUS_VALUE)
690 , mnTextAdjust(0)
691 , mnLineSpacing(0)
692 , mbFixedLineSpacing(false)
693 , mnLineSpacingTop(0)
694 , mnLineSpacingBottom(0)
695 , mbForbiddenRules(false)
696 , mbParagraphPunctation(false)
697 , mnBiDi(0)
698{
699 bExtendedParameters = false;
700
701 nDepth = 0;
702 nBulletFlags = 0;
703 nParaFlags = 0;
704
705 mXPropSet.set( rXTextContent, css::uno::UNO_QUERY );
706
707 mXPropState.set( rXTextContent, css::uno::UNO_QUERY );
708
709 if ( !(mXPropSet.is() && mXPropState.is()) )
710 return;
711
712 css::uno::Reference< css::container::XEnumerationAccess > aXTextPortionEA( rXTextContent, css::uno::UNO_QUERY );
713 if ( aXTextPortionEA.is() )
714 {
715 css::uno::Reference< css::container::XEnumeration > aXTextPortionE( aXTextPortionEA->createEnumeration() );
716 if ( aXTextPortionE.is() )
717 {
718 while ( aXTextPortionE->hasMoreElements() )
719 {
720 css::uno::Reference< css::text::XTextRange > aXCursorText;
721 css::uno::Any aAny( aXTextPortionE->nextElement() );
722 if ( aAny >>= aXCursorText )
723 {
724 std::unique_ptr<PortionObj> pPortionObj(new PortionObj( aXCursorText, !aXTextPortionE->hasMoreElements(), rFontCollection ));
725 if ( pPortionObj->Count() )
726 mvPortions.push_back( std::move(pPortionObj) );
727 }
728 }
729 }
730 }
731 ImplGetParagraphValues( &rProv, true );
732}
733
735{
736 ImplClear();
737}
738
740{
741 for ( std::vector<std::unique_ptr<PortionObj> >::iterator it = mvPortions.begin(); it != mvPortions.end(); ++it )
742 (*it)->Write( pStrm, mbLastParagraph );
743}
744
746{
747 mvPortions.clear();
748}
749
750void ParagraphObj::CalculateGraphicBulletSize( sal_uInt16 nFontHeight )
751{
752 if ( ( nNumberingType != SVX_NUM_BITMAP ) || ( nBulletId == 0xffff ) )
753 return;
754
755 // calculate the bullet real size for this graphic
756 if ( aBuGraSize.Width() && aBuGraSize.Height() )
757 {
758 double fCharHeight = nFontHeight;
759 double fLen = aBuGraSize.Height();
760 fCharHeight = fCharHeight * 0.2540;
761 double fQuo = fLen / fCharHeight;
762 nBulletRealSize = static_cast<sal_Int16>( fQuo + 0.5 );
763 if ( static_cast<sal_uInt16>(nBulletRealSize) > 400 )
764 nBulletRealSize = 400;
765 }
766}
767
768void ParagraphObj::ImplGetNumberingLevel( PPTExBulletProvider* pBuProv, sal_Int16 nNumberingDepth, bool bIsBullet, bool bGetPropStateValue )
769{
770 css::uno::Any aAny;
771 if ( GetPropertyValue( aAny, mXPropSet, "ParaLeftMargin" ) )
772 {
773 sal_Int32 nVal(0);
774 if ( aAny >>= nVal )
776 }
777 if ( GetPropertyValue( aAny, mXPropSet, "ParaFirstLineIndent" ) )
778 {
779 if ( aAny >>= nBulletOfs )
781 }
782 if ( GetPropertyValue( aAny, mXPropSet, "NumberingIsNumber" ) )
783 aAny >>= bNumberingIsNumber;
784
785 css::uno::Reference< css::container::XIndexReplace > aXIndexReplace;
786
787 if ( bIsBullet && ImplGetPropertyValue( "NumberingRules", bGetPropStateValue ) )
788 {
789 if ( ( mAny >>= aXIndexReplace ) && nNumberingDepth < aXIndexReplace->getCount() )
790 {
791 mAny = aXIndexReplace->getByIndex( nNumberingDepth );
792 auto aPropertySequence = o3tl::doAccess<css::uno::Sequence<css::beans::PropertyValue>>(mAny);
793
794 if ( aPropertySequence->hasElements() )
795 {
796 bExtendedParameters = true;
797 nBulletRealSize = 100;
798 nMappedNumType = 0;
799
800 uno::Reference<graphic::XGraphic> xGraphic;
801 for ( const css::beans::PropertyValue& rPropValue : *aPropertySequence )
802 {
803 OUString aPropName( rPropValue.Name );
804 if ( aPropName == "NumberingType" )
805 nNumberingType = static_cast<SvxNumType>(*o3tl::doAccess<sal_Int16>(rPropValue.Value));
806 else if ( aPropName == "Adjust" )
807 nHorzAdjust = *o3tl::doAccess<sal_Int16>(rPropValue.Value);
808 else if ( aPropName == "BulletChar" )
809 {
810 OUString aString( *o3tl::doAccess<OUString>(rPropValue.Value) );
811 if ( !aString.isEmpty() )
812 cBulletId = aString[ 0 ];
813 }
814 else if ( aPropName == "BulletFont" )
815 {
816 aFontDesc = *o3tl::doAccess<css::awt::FontDescriptor>(rPropValue.Value);
817
818 // Our numbullet dialog has set the wrong textencoding for our "StarSymbol" font,
819 // instead of a Unicode encoding the encoding RTL_TEXTENCODING_SYMBOL was used.
820 // Because there might exist a lot of damaged documents I added this two lines
821 // which fixes the bullet problem for the export.
822 if ( aFontDesc.Name.equalsIgnoreAsciiCase("StarSymbol") )
823 aFontDesc.CharSet = RTL_TEXTENCODING_MS_1252;
824
825 }
826 else if ( aPropName == "GraphicBitmap" )
827 {
828 auto xBitmap = rPropValue.Value.get<uno::Reference<awt::XBitmap>>();
829 xGraphic.set(xBitmap, uno::UNO_QUERY);
830 }
831 else if ( aPropName == "GraphicSize" )
832 {
833 if (auto aSize = o3tl::tryAccess<css::awt::Size>(rPropValue.Value))
834 {
835 // don't cast awt::Size to Size as on 64-bits they are not the same.
836 aBuGraSize.setWidth( aSize->Width );
837 aBuGraSize.setHeight( aSize->Height );
838 }
839 }
840 else if ( aPropName == "StartWith" )
841 nStartWith = *o3tl::doAccess<sal_Int16>(rPropValue.Value);
842 else if ( aPropName == "LeftMargin" )
843 nTextOfs += convertMm100ToMasterUnit(*o3tl::doAccess<sal_Int32>(rPropValue.Value));
844 else if ( aPropName == "FirstLineOffset" )
845 nBulletOfs += convertMm100ToMasterUnit(*o3tl::doAccess<sal_Int32>(rPropValue.Value));
846 else if ( aPropName == "BulletColor" )
847 {
848 sal_uInt32 nSOColor = *o3tl::doAccess<sal_uInt32>(rPropValue.Value);
849 nBulletColor = nSOColor & 0xff00ff00; // green and hibyte
850 nBulletColor |= static_cast<sal_uInt8>(nSOColor) << 16; // red
851 nBulletColor |= static_cast<sal_uInt8>( nSOColor >> 16 ) | 0xfe000000; // blue
852 }
853 else if ( aPropName == "BulletRelSize" )
854 {
855 nBulletRealSize = *o3tl::doAccess<sal_Int16>(rPropValue.Value);
856 nParaFlags |= 0x40;
857 nBulletFlags |= 8;
858 }
859 else if ( aPropName == "Prefix" )
860 sPrefix = *o3tl::doAccess<OUString>(rPropValue.Value);
861 else if ( aPropName == "Suffix" )
862 sSuffix = *o3tl::doAccess<OUString>(rPropValue.Value);
863#ifdef DBG_UTIL
864 else if ( aPropName != "SymbolTextDistance" && aPropName != "GraphicBitmap" )
865 {
866 OSL_FAIL( "Unknown Property" );
867 }
868#endif
869 }
870
871 if (xGraphic.is())
872 {
873 if ( aBuGraSize.Width() && aBuGraSize.Height() )
874 {
875 nBulletId = pBuProv->GetId(xGraphic, aBuGraSize );
876 if ( nBulletId != 0xffff )
878 }
879 else
880 {
882 }
883 }
884
885 CalculateGraphicBulletSize( ( mvPortions.empty() ) ? 24 : mvPortions.front()->mnCharHeight );
886
887 switch( nNumberingType )
888 {
889 case SVX_NUM_NUMBER_NONE : nParaFlags |= 0xf; break;
890
891 case SVX_NUM_CHAR_SPECIAL : // Bullet
892 {
893 if ( IsOpenSymbol(aFontDesc.Name) )
894 {
895 rtl_TextEncoding eChrSet = aFontDesc.CharSet;
897 aFontDesc.CharSet = eChrSet;
898 }
899
900 if ( !aFontDesc.Name.isEmpty() )
901 {
902 nParaFlags |= 0x90; // we define the font and charset
903 }
904
905 [[fallthrough]];
906 }
907 case SVX_NUM_CHARS_UPPER_LETTER : // count from a-z, aa - az, ba - bz, ...
911 case SVX_NUM_ARABIC :
912 case SVX_NUM_PAGEDESC : // numbering from the page template
913 case SVX_NUM_BITMAP :
914 case SVX_NUM_CHARS_UPPER_LETTER_N : // count from a-z, aa-zz, aaa-zzz
921 {
923 {
925 if ( nNumberingDepth & 1 )
926 cBulletId = 0x2013; // defaulting bullet characters for ppt97
927 else if ( nNumberingDepth == 4 )
928 cBulletId = 0xbb;
929 else
930 cBulletId = 0x2022;
931
932 switch( nNumberingType )
933 {
936 {
937 if ( sSuffix == ")" )
938 {
939 if ( sPrefix == "(" )
940 nMappedNumType = 0xa0001; // (A)
941 else
942 nMappedNumType = 0xb0001; // A)
943 }
944 else
945 nMappedNumType = 0x10001; // A.
946 }
947 break;
950 {
951 if ( sSuffix == ")" )
952 {
953 if ( sPrefix == "(" )
954 nMappedNumType = 0x80001; // (a)
955 else
956 nMappedNumType = 0x90001; // a)
957 }
958 else
959 nMappedNumType = 0x00001; // a.
960 }
961 break;
963 {
964 if ( sSuffix == ")" )
965 {
966 if ( sPrefix == "(" )
967 nMappedNumType = 0xe0001; // (I)
968 else
969 nMappedNumType = 0xf0001; // I)
970 }
971 else
972 nMappedNumType = 0x70001; // I.
973 }
974 break;
976 {
977 if ( sSuffix == ")" )
978 {
979 if ( sPrefix == "(" )
980 nMappedNumType = 0x40001; // (i)
981 else
982 nMappedNumType = 0x50001; // i)
983 }
984 else
985 nMappedNumType = 0x60001; // i.
986 }
987 break;
988 case SVX_NUM_ARABIC :
989 {
990 if ( sSuffix == ")" )
991 {
992 if ( sPrefix == "(" )
993 nMappedNumType = 0xc0001; // (1)
994 else
995 nMappedNumType = 0x20001; // 1)
996 }
997 else
998 {
999 if ( sSuffix.isEmpty() && sPrefix.isEmpty() )
1000 nMappedNumType = 0xd0001; // 1
1001 else
1002 nMappedNumType = 0x30001; // 1.
1003 }
1004 }
1005 break;
1007 {
1008 if ( !sSuffix.isEmpty() )
1009 nMappedNumType = 0x110001; // Simplified Chinese with single-byte period.
1010 else
1011 nMappedNumType = 0x100001; // Simplified Chinese.
1012 }
1013 break;
1015 {
1016 nMappedNumType = 0x120001; // Double byte circle numbers.
1017 }
1018 break;
1020 {
1021 if ( !sSuffix.isEmpty() )
1022 nMappedNumType = 0x160001; // Traditional Chinese with single-byte period.
1023 else
1024 nMappedNumType = 0x150001; // Traditional Chinese.
1025 }
1026 break;
1028 {
1029 if ( sSuffix == u"\uff0e" )
1030 nMappedNumType = 0x260001; // Japanese with double-byte period.
1031 else if ( !sSuffix.isEmpty() )
1032 nMappedNumType = 0x1B0001; // Japanese/Korean with single-byte period.
1033 else
1034 nMappedNumType = 0x1A0001; // Japanese/Korean.
1035 }
1036 break;
1038 {
1039 if ( !sSuffix.isEmpty() )
1040 nMappedNumType = 0x1D0001; // Double-byte Arabic numbers with double-byte period.
1041 else
1042 nMappedNumType = 0x1C0001; // Double-byte Arabic numbers.
1043 }
1044 break;
1045 default:
1046 break;
1047 }
1048 }
1049 nParaFlags |= 0x2f;
1050 nBulletFlags |= 6;
1052 nBulletFlags |= 1;
1053 break;
1054 }
1055 default:
1056 break;
1057 }
1058 }
1059 }
1060 }
1062 if ( nBulletOfs < 0 )
1063 nBulletOfs = 0;
1064}
1065
1066void ParagraphObj::ImplGetParagraphValues( PPTExBulletProvider* pBuProv, bool bGetPropStateValue )
1067{
1068 css::uno::Any aAny;
1069 if ( GetPropertyValue( aAny, mXPropSet, "NumberingLevel", true ) )
1070 {
1071 if ( bGetPropStateValue )
1072 meBullet = GetPropertyState( mXPropSet, "NumberingLevel" );
1073 nDepth = *o3tl::doAccess<sal_Int16>(aAny);
1074
1075 if ( nDepth < 0 )
1076 {
1077 mbIsBullet = false;
1078 nDepth = 0;
1079 }
1080 else
1081 {
1082 if ( nDepth > 4 )
1083 nDepth = 4;
1084 mbIsBullet = true;
1085 }
1086 }
1087 else
1088 {
1089 nDepth = 0;
1090 mbIsBullet = false;
1091 }
1092 ImplGetNumberingLevel( pBuProv, nDepth, mbIsBullet, bGetPropStateValue );
1093
1094 if ( ImplGetPropertyValue( "ParaTabStops", bGetPropStateValue ) )
1095 maTabStop = *o3tl::doAccess<css::uno::Sequence<css::style::TabStop>>(mAny);
1096 sal_Int16 eTextAdjust = sal_Int16(css::style::ParagraphAdjust_LEFT);
1097 if ( GetPropertyValue( aAny, mXPropSet, "ParaAdjust", bGetPropStateValue ) )
1098 aAny >>= eTextAdjust;
1099 switch ( static_cast<css::style::ParagraphAdjust>(eTextAdjust) )
1100 {
1101 case css::style::ParagraphAdjust_CENTER :
1102 mnTextAdjust = 1;
1103 break;
1104 case css::style::ParagraphAdjust_RIGHT :
1105 mnTextAdjust = 2;
1106 break;
1107 case css::style::ParagraphAdjust_BLOCK :
1108 mnTextAdjust = 3;
1109 break;
1110 default :
1111 case css::style::ParagraphAdjust_LEFT :
1112 mnTextAdjust = 0;
1113 break;
1114 }
1116
1117 if ( ImplGetPropertyValue( "ParaLineSpacing", bGetPropStateValue ) )
1118 {
1119 css::style::LineSpacing aLineSpacing
1120 = *o3tl::doAccess<css::style::LineSpacing>(mAny);
1121 switch ( aLineSpacing.Mode )
1122 {
1123 case css::style::LineSpacingMode::FIX :
1124 mnLineSpacing = static_cast<sal_Int16>(-( aLineSpacing.Height ) );
1125 mbFixedLineSpacing = true;
1126 break;
1127 case css::style::LineSpacingMode::MINIMUM :
1128 case css::style::LineSpacingMode::LEADING :
1129 mnLineSpacing = static_cast<sal_Int16>(-( aLineSpacing.Height ) );
1130 mbFixedLineSpacing = false;
1131 break;
1132
1133 case css::style::LineSpacingMode::PROP :
1134 default:
1135 mnLineSpacing = aLineSpacing.Height;
1136 break;
1137 }
1138 }
1140
1141 if ( ImplGetPropertyValue( "ParaBottomMargin", bGetPropStateValue ) )
1142 {
1143 double fSpacing = *o3tl::doAccess<sal_uInt32>(mAny) + convertMasterUnitToMm100(1.0) - 1;
1144 mnLineSpacingBottom = std::round(-convertMm100ToMasterUnit(fSpacing));
1145 }
1147
1148 if ( ImplGetPropertyValue( "ParaTopMargin", bGetPropStateValue ) )
1149 {
1150 double fSpacing = *o3tl::doAccess<sal_uInt32>(mAny) + convertMasterUnitToMm100(1.0) - 1;
1151 mnLineSpacingTop = std::round(-convertMm100ToMasterUnit(fSpacing));
1152 }
1154
1155 if ( ImplGetPropertyValue( "ParaIsForbiddenRules", bGetPropStateValue ) )
1158
1159 if ( ImplGetPropertyValue( "ParaIsHangingPunctuation", bGetPropStateValue ) )
1162
1163 mnBiDi = 0;
1164 if ( ImplGetPropertyValue( "WritingMode", bGetPropStateValue ) )
1165 {
1166 sal_Int16 nWritingMode = 0;
1167 mAny >>= nWritingMode;
1168
1169 SvxFrameDirection eWritingMode = static_cast<SvxFrameDirection>(nWritingMode);
1170 if ( ( eWritingMode == SvxFrameDirection::Horizontal_RL_TB )
1171 || ( eWritingMode == SvxFrameDirection::Vertical_RL_TB ) )
1172 {
1173 mnBiDi = 1;
1174 }
1175 }
1177}
1178
1179void ParagraphObj::ImplConstruct( const ParagraphObj& rParagraphObj )
1180{
1181 mbIsBullet = rParagraphObj.mbIsBullet;
1182 meBullet = rParagraphObj.meBullet;
1183 meTextAdjust = rParagraphObj.meTextAdjust;
1184 meLineSpacing = rParagraphObj.meLineSpacing;
1185 meLineSpacingTop = rParagraphObj.meLineSpacingTop;
1187 meForbiddenRules = rParagraphObj.meForbiddenRules;
1189 meBiDi =rParagraphObj.meBiDi;
1190 mbFixedLineSpacing = rParagraphObj.mbFixedLineSpacing;
1191 mnTextSize = rParagraphObj.mnTextSize;
1192 mnTextAdjust = rParagraphObj.mnTextAdjust;
1193 mnLineSpacing = rParagraphObj.mnLineSpacing;
1194 mnLineSpacingTop = rParagraphObj.mnLineSpacingTop;
1196 mbFirstParagraph = rParagraphObj.mbFirstParagraph;
1197 mbLastParagraph = rParagraphObj.mbLastParagraph;
1199 mbForbiddenRules = rParagraphObj.mbForbiddenRules;
1200 mnBiDi = rParagraphObj.mnBiDi;
1201
1202 for ( std::vector<std::unique_ptr<PortionObj> >::const_iterator it = rParagraphObj.begin(); it != rParagraphObj.end(); ++it )
1203 mvPortions.push_back( std::make_unique<PortionObj>( **it ) );
1204
1205 maTabStop = rParagraphObj.maTabStop;
1207 nParaFlags = rParagraphObj.nParaFlags;
1208 nBulletFlags = rParagraphObj.nBulletFlags;
1209 sPrefix = rParagraphObj.sPrefix;
1210 sSuffix = rParagraphObj.sSuffix;
1211 sGraphicUrl = rParagraphObj.sGraphicUrl; // String to a graphic
1212 aBuGraSize = rParagraphObj.aBuGraSize;
1213 nNumberingType = rParagraphObj.nNumberingType; // this is actually a SvxEnum
1214 nHorzAdjust = rParagraphObj.nHorzAdjust;
1215 nBulletColor = rParagraphObj.nBulletColor;
1216 nBulletOfs = rParagraphObj.nBulletOfs;
1217 nStartWith = rParagraphObj.nStartWith; // start of numbering
1218 nTextOfs = rParagraphObj.nTextOfs;
1219 nBulletRealSize = rParagraphObj.nBulletRealSize; // scale in percent
1220 nDepth = rParagraphObj.nDepth; // actual depth
1221 cBulletId = rParagraphObj.cBulletId; // if Numbering Type == CharSpecial
1222 aFontDesc = rParagraphObj.aFontDesc;
1223
1225 nBulletId = rParagraphObj.nBulletId;
1226}
1227
1228sal_uInt32 ParagraphObj::ImplCalculateTextPositions( sal_uInt32 nCurrentTextPosition )
1229{
1230 mnTextSize = 0;
1231 for ( std::vector<std::unique_ptr<PortionObj> >::iterator it = mvPortions.begin(); it != mvPortions.end(); ++it )
1232 mnTextSize += (*it)->ImplCalculateTextPositions( nCurrentTextPosition + mnTextSize );
1233 return mnTextSize;
1234}
1235
1237{
1238 if ( this != &rParagraphObj )
1239 {
1240 ImplClear();
1241 ImplConstruct( rParagraphObj );
1242 }
1243 return *this;
1244}
1245
1247{
1248 sal_uInt32 mnTextSize;
1250 std::vector<std::unique_ptr<ParagraphObj>> maList;
1252
1253 explicit ImplTextObj( int nInstance );
1254};
1255
1257 : mnTextSize(0),
1258 mnInstance(nInstance),
1259 mbHasExtendedBullets(false)
1260{
1261}
1262
1263TextObj::TextObj( css::uno::Reference< css::text::XSimpleText > const & rXTextRef,
1264 int nInstance, FontCollection& rFontCollection, PPTExBulletProvider& rProv ):
1265 mpImplTextObj(std::make_shared<ImplTextObj>(nInstance))
1266{
1267 css::uno::Reference< css::container::XEnumerationAccess > aXTextParagraphEA( rXTextRef, css::uno::UNO_QUERY );
1268
1269 if ( aXTextParagraphEA.is() )
1270 {
1271 css::uno::Reference< css::container::XEnumeration > aXTextParagraphE( aXTextParagraphEA->createEnumeration() );
1272 if ( aXTextParagraphE.is() )
1273 {
1274 ParaFlags aParaFlags;
1275 while ( aXTextParagraphE->hasMoreElements() )
1276 {
1277 css::uno::Reference< css::text::XTextContent > aXParagraph;
1278 css::uno::Any aAny( aXTextParagraphE->nextElement() );
1279 if ( aAny >>= aXParagraph )
1280 {
1281 if ( !aXTextParagraphE->hasMoreElements() )
1282 aParaFlags.bLastParagraph = true;
1283 std::unique_ptr<ParagraphObj> pPara(new ParagraphObj( aXParagraph, aParaFlags, rFontCollection, rProv ));
1284 mpImplTextObj->mbHasExtendedBullets |= pPara->bExtendedBulletsUsed;
1285 mpImplTextObj->maList.push_back( std::move(pPara) );
1286 aParaFlags.bFirstParagraph = false;
1287 }
1288 }
1289 }
1290 }
1292}
1293
1295{
1296 mpImplTextObj->mnTextSize = 0;
1297 for ( sal_uInt32 i = 0; i < ParagraphCount(); ++i )
1299}
1300
1302{
1303 return mpImplTextObj->maList[idx].get();
1304}
1305
1306sal_uInt32 TextObj::ParagraphCount() const
1307{
1308 return mpImplTextObj->maList.size();
1309}
1310
1311sal_uInt32 TextObj::Count() const
1312{
1313 return mpImplTextObj->mnTextSize;
1314}
1315
1317{
1318 return mpImplTextObj->mnInstance;
1319}
1320
1322{
1323 return mpImplTextObj->mbHasExtendedBullets;
1324}
1325
1326void FontCollectionEntry::ImplInit( const OUString& rName )
1327{
1328 OUString aSubstName( GetSubsFontName( rName, SubsFontFlags::ONLYONE | SubsFontFlags::MS ) );
1329 if ( !aSubstName.isEmpty() )
1330 {
1331 Name = aSubstName;
1332 }
1333 else
1334 {
1335 Name = rName;
1336 }
1337}
1338
1340{
1342 xPPTBreakIter = nullptr;
1343}
1344
1346 pVDev ( nullptr )
1347{
1348 xPPTBreakIter = css::i18n::BreakIterator::create( ::comphelper::getProcessComponentContext() );
1349}
1350
1351short FontCollection::GetScriptDirection( std::u16string_view rString )
1352{
1353 short nRet = ScriptTypeDetector::getScriptDirection( rString, 0, css::i18n::ScriptDirection::NEUTRAL );
1354 return nRet;
1355}
1356
1358{
1359 if( !rEntry.Name.isEmpty() )
1360 {
1361 const sal_uInt32 nFonts = maFonts.size();
1362
1363 for( sal_uInt32 i = 0; i < nFonts; i++ )
1364 {
1365 const FontCollectionEntry* pEntry = GetById( i );
1366 if( pEntry->Name == rEntry.Name )
1367 return i;
1368 }
1369 vcl::Font aFont;
1370 aFont.SetCharSet( rEntry.CharSet );
1371 aFont.SetFamilyName( rEntry.Original );
1372 aFont.SetFontHeight( 100 );
1373
1374 if ( !pVDev )
1376
1377 pVDev->SetFont( aFont );
1378 FontMetric aMetric( pVDev->GetFontMetric() );
1379
1380 sal_uInt16 nTxtHeight = static_cast<sal_uInt16>(aMetric.GetAscent()) + static_cast<sal_uInt16>(aMetric.GetDescent());
1381
1382 if ( nTxtHeight )
1383 {
1384 double fScaling = static_cast<double>(nTxtHeight) / 120.0;
1385 if ( ( fScaling > 0.50 ) && ( fScaling < 1.5 ) )
1386 rEntry.Scaling = fScaling;
1387 }
1388
1389 maFonts.push_back(rEntry);
1390 return nFonts;
1391 }
1392 return 0;
1393}
1394
1396{
1397 return nId < maFonts.size() ? &maFonts[nId] : nullptr;
1398}
1399
1400/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
constexpr auto convertMasterUnitToMm100(N n)
constexpr auto convertMm100ToMasterUnit(N n)
static const AllSettings & GetSettings()
FontCollectionEntry & GetLast()
Definition: epptbase.hxx:193
std::vector< FontCollectionEntry > maFonts
Definition: epptbase.hxx:198
const FontCollectionEntry * GetById(sal_uInt32 nId)
Definition: pptx-text.cxx:1395
VclPtr< VirtualDevice > pVDev
Definition: epptbase.hxx:193
sal_uInt32 GetId(FontCollectionEntry &rFontDescriptor)
Definition: pptx-text.cxx:1357
sal_uInt32 GetCount() const
Definition: epptbase.hxx:189
static short GetScriptDirection(std::u16string_view rText)
Definition: pptx-text.cxx:1351
tools::Long GetDescent() const
tools::Long GetAscent() const
css::beans::PropertyState meLineSpacingBottom
Definition: text.hxx:199
void ImplConstruct(const ParagraphObj &rParagraphObj)
Definition: pptx-text.cxx:1179
sal_Int16 mnLineSpacingBottom
Definition: text.hxx:208
std::vector< std::unique_ptr< PortionObj > >::const_iterator begin() const
Definition: text.hxx:224
bool mbParagraphPunctation
Definition: text.hxx:210
sal_uInt32 mnTextSize
Definition: text.hxx:189
std::vector< std::unique_ptr< PortionObj > > mvPortions
Definition: text.hxx:175
css::beans::PropertyState meBiDi
Definition: text.hxx:202
void ImplGetNumberingLevel(PPTExBulletProvider *pBuProv, sal_Int16 nDepth, bool bIsBullet, bool bGetPropStateValue)
Definition: pptx-text.cxx:768
bool mbFirstParagraph
Definition: text.hxx:192
css::beans::PropertyState meBullet
Definition: text.hxx:195
ParagraphObj & operator=(const ParagraphObj &rParagraphObj)
Definition: pptx-text.cxx:1236
css::beans::PropertyState meLineSpacingTop
Definition: text.hxx:198
bool mbIsBullet
Definition: text.hxx:191
ParagraphObj(css::uno::Reference< css::text::XTextContent > const &rXTextContentRef, ParaFlags, FontCollection &rFontCollection, PPTExBulletProvider &rBuProv)
Definition: pptx-text.cxx:676
bool mbFixedLineSpacing
Definition: text.hxx:206
css::uno::Sequence< css::style::TabStop > maTabStop
Definition: text.hxx:187
void ImplGetParagraphValues(PPTExBulletProvider *pBuProv, bool bGetPropStateValue)
Definition: pptx-text.cxx:1066
css::beans::PropertyState meForbiddenRules
Definition: text.hxx:200
sal_Int16 mnLineSpacingTop
Definition: text.hxx:207
sal_uInt32 ImplCalculateTextPositions(sal_uInt32 nCurrentTextPosition)
Definition: pptx-text.cxx:1228
sal_uInt16 mnTextAdjust
Definition: text.hxx:204
bool mbForbiddenRules
Definition: text.hxx:209
sal_Int16 mnLineSpacing
Definition: text.hxx:205
sal_uInt16 mnBiDi
Definition: text.hxx:211
void Write(SvStream *pStrm)
Definition: pptx-text.cxx:739
void ImplClear()
Definition: pptx-text.cxx:745
void CalculateGraphicBulletSize(sal_uInt16 nFontHeight)
Definition: pptx-text.cxx:750
bool mbLastParagraph
Definition: text.hxx:193
css::beans::PropertyState meParagraphPunctation
Definition: text.hxx:201
std::vector< std::unique_ptr< PortionObj > >::const_iterator end() const
Definition: text.hxx:225
css::beans::PropertyState meTextAdjust
Definition: text.hxx:196
css::beans::PropertyState meLineSpacing
Definition: text.hxx:197
sal_uInt16 mnCharHeight
Definition: text.hxx:138
std::unique_ptr< FieldEntry > mpFieldEntry
Definition: text.hxx:147
sal_uInt32 mnTextSize
Definition: text.hxx:143
css::beans::PropertyState meCharColor
Definition: text.hxx:128
static sal_uInt32 ImplGetTextField(css::uno::Reference< css::text::XTextRange > &rXTextRangeRef, const css::uno::Reference< css::beans::XPropertySet > &rXPropSetRef, OUString &rURL)
Definition: pptx-text.cxx:495
sal_uInt16 mnCharAttr
Definition: text.hxx:137
css::beans::PropertyState meCharEscapement
Definition: text.hxx:132
PortionObj(css::uno::Reference< css::text::XTextRange > &rXTextRangeRef, bool bLast, FontCollection &rFontCollection)
Definition: pptx-text.cxx:83
css::beans::PropertyState meAsianOrComplexFont
Definition: text.hxx:131
css::lang::Locale meCharLocale
Definition: text.hxx:133
void ImplGetPortionValues(FontCollection &rFontCollection, bool bGetPropStateValue)
Definition: pptx-text.cxx:236
sal_uInt16 mnCharAttrHard
Definition: text.hxx:134
bool mbLastPortion
Definition: text.hxx:144
sal_uInt16 mnFont
Definition: text.hxx:139
sal_uInt32 mnCharColor
Definition: text.hxx:136
std::unique_ptr< sal_uInt16[]> mpText
Definition: text.hxx:146
PortionObj & operator=(const PortionObj &rPortionObj)
Definition: pptx-text.cxx:640
css::beans::PropertyState meCharHeight
Definition: text.hxx:129
void ImplConstruct(const PortionObj &rPortionObj)
Definition: pptx-text.cxx:444
void ImplClear()
Definition: pptx-text.cxx:438
sal_uInt32 ImplCalculateTextPositions(sal_uInt32 nCurrentTextPosition)
Definition: pptx-text.cxx:473
css::beans::PropertyState meFontName
Definition: text.hxx:130
void Write(SvStream *pStrm, bool bLast)
Definition: pptx-text.cxx:227
sal_Int16 mnCharEscapement
Definition: text.hxx:141
sal_uInt16 mnAsianOrComplexFont
Definition: text.hxx:140
bool ImplGetPropertyValue(const OUString &rString, bool bGetPropertyState)
Definition: epptso.cxx:597
css::beans::PropertyState ePropState
Definition: text.hxx:92
css::uno::Reference< css::beans::XPropertyState > mXPropState
Definition: text.hxx:93
css::uno::Any mAny
Definition: epptbase.hxx:98
css::uno::Reference< css::beans::XPropertySet > mXPropSet
Definition: epptbase.hxx:99
static bool GetPropertyValue(css::uno::Any &rAny, const css::uno::Reference< css::beans::XPropertySet > &, const OUString &rPropertyName, bool bTestPropertyAvailability=false)
Definition: epptso.cxx:532
static css::beans::PropertyState GetPropertyState(const css::uno::Reference< css::beans::XPropertySet > &, const OUString &rPropertyName)
Definition: epptso.cxx:569
static sal_Int16 getScriptDirection(std::u16string_view Text, sal_Int32 nPos, sal_Int16 defaultScriptDirection)
constexpr tools::Long Height() const
void setWidth(tools::Long nWidth)
void setHeight(tools::Long nHeight)
constexpr tools::Long Width() const
SvStream & WriteUInt16(sal_uInt16 nUInt16)
int GetInstance() const
Definition: pptx-text.cxx:1316
sal_uInt32 ParagraphCount() const
Definition: pptx-text.cxx:1306
TextObj(css::uno::Reference< css::text::XSimpleText > const &rXText, int nInstance, FontCollection &rFontCollection, PPTExBulletProvider &rBuProv)
Definition: pptx-text.cxx:1263
void ImplCalculateTextPositions()
Definition: pptx-text.cxx:1294
ParagraphObj * GetParagraph(int idx)
Definition: pptx-text.cxx:1301
sal_uInt32 Count() const
Definition: pptx-text.cxx:1311
std::shared_ptr< ImplTextObj > mpImplTextObj
Definition: text.hxx:240
bool HasExtendedBullets() const
Definition: pptx-text.cxx:1321
void disposeAndClear()
static VclPtr< reference_type > Create(Arg &&... arg)
void SetFontHeight(tools::Long nHeight)
void SetCharSet(rtl_TextEncoding)
void SetFamilyName(const OUString &rFamilyName)
int nCount
URL aURL
float u
UNOTOOLS_DLLPUBLIC bool IsOpenSymbol(std::u16string_view rFontName)
UNOTOOLS_DLLPUBLIC OUString GetSubsFontName(std::u16string_view rName, SubsFontFlags nFlags)
SvxFrameDirection
const sal_uInt16 idx[]
if(aStr !=aBuf) UpdateName_Impl(m_xFollowLb.get()
SvtScriptType GetScriptTypeOfLanguage(LanguageType nLang)
sal_Int16 FromSvtScriptTypeToI18N(SvtScriptType nItemType)
int i
OUString aPropName
sal_Unicode bestFitOpenSymbolToMSFont(sal_Unicode cBullet, rtl_TextEncoding &r_ioChrSet, OUString &r_ioFontName)
std::shared_ptr< T > make_shared(Args &&... args)
sal_Int16 nId
static css::uno::Reference< css::i18n::XBreakIterator > xPPTBreakIter
Definition: pptx-text.cxx:61
void ImplInit(const OUString &rName)
Definition: pptx-text.cxx:1326
sal_uInt32 mnTextSize
Definition: pptx-text.cxx:1248
std::vector< std::unique_ptr< ParagraphObj > > maList
Definition: pptx-text.cxx:1250
ImplTextObj(int nInstance)
Definition: pptx-text.cxx:1256
bool mbHasExtendedBullets
Definition: pptx-text.cxx:1251
bool bLastParagraph
Definition: text.hxx:165
bool bFirstParagraph
Definition: text.hxx:164
sal_Int16 nBulletFlags
Definition: text.hxx:41
bool bNumberingIsNumber
Definition: text.hxx:60
SvxNumType nNumberingType
Definition: text.hxx:46
bool bExtendedParameters
Definition: text.hxx:39
css::awt::FontDescriptor aFontDesc
Definition: text.hxx:55
sal_uInt32 nMappedNumType
Definition: text.hxx:59
OUString sGraphicUrl
Definition: text.hxx:44
sal_uInt16 nBulletId
Definition: text.hxx:58
sal_uInt32 nHorzAdjust
Definition: text.hxx:47
bool bExtendedBulletsUsed
Definition: text.hxx:57
sal_uInt32 nParaFlags
Definition: text.hxx:40
OUString sPrefix
Definition: text.hxx:42
sal_Int16 nBulletRealSize
Definition: text.hxx:52
sal_Int16 nDepth
Definition: text.hxx:53
sal_Int16 nTextOfs
Definition: text.hxx:51
sal_Int32 nBulletOfs
Definition: text.hxx:49
sal_uInt32 nBulletColor
Definition: text.hxx:48
Size aBuGraSize
Definition: text.hxx:45
sal_Unicode cBulletId
Definition: text.hxx:54
sal_Int16 nStartWith
Definition: text.hxx:50
OUString sSuffix
Definition: text.hxx:43
SvxNumType
SVX_NUM_NUMBER_NONE
SVX_NUM_FULL_WIDTH_ARABIC
SVX_NUM_CHARS_LOWER_LETTER_N
SVX_NUM_CIRCLE_NUMBER
SVX_NUM_CHARS_LOWER_LETTER
SVX_NUM_CHARS_UPPER_LETTER
SVX_NUM_NUMBER_UPPER_ZH_TW
SVX_NUM_ROMAN_UPPER
SVX_NUM_ROMAN_LOWER
SVX_NUM_ARABIC
SVX_NUM_CHARS_UPPER_LETTER_N
SVX_NUM_NUMBER_UPPER_ZH
SVX_NUM_BITMAP
SVX_NUM_CHAR_SPECIAL
SVX_NUM_PAGEDESC
SVX_NUM_NUMBER_LOWER_ZH
unsigned char sal_uInt8
sal_uInt16 sal_Unicode