bump product version to 5.0.4.1
[LibreOffice.git] / sd / source / filter / eppt / pptx-text.cxx
bloba89019901a146e67d4f3ef599fda1b70f0e135e2
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #include "text.hxx"
22 #include <com/sun/star/awt/CharSet.hpp>
23 #include <com/sun/star/awt/FontWeight.hpp>
24 #include <com/sun/star/awt/FontUnderline.hpp>
25 #include <com/sun/star/beans/XPropertyState.hpp>
26 #include <com/sun/star/container/XEnumerationAccess.hpp>
27 #include <com/sun/star/container/XIndexReplace.hpp>
28 #include <com/sun/star/i18n/BreakIterator.hpp>
29 #include <com/sun/star/i18n/ScriptDirection.hpp>
30 #include <com/sun/star/i18n/ScriptType.hpp>
31 #include <com/sun/star/text/FontRelief.hpp>
32 #include <com/sun/star/text/XTextField.hpp>
33 #include <com/sun/star/text/XTextRange.hpp>
34 #include <com/sun/star/style/LineSpacing.hpp>
35 #include <com/sun/star/style/LineSpacingMode.hpp>
36 #include <com/sun/star/style/ParagraphAdjust.hpp>
37 #include <com/sun/star/style/TabStop.hpp>
39 #include <comphelper/processfactory.hxx>
40 #include <editeng/svxenum.hxx>
41 #include <editeng/frmdir.hxx>
42 #include <filter/msfilter/util.hxx>
43 #include <i18nutil/scripttypedetector.hxx>
44 #include <sfx2/app.hxx>
45 #include <svl/languageoptions.hxx>
46 #include <oox/export/drawingml.hxx>
48 #include <vcl/settings.hxx>
49 #include <vcl/metric.hxx>
50 #include <vcl/outdev.hxx>
51 #include <vcl/virdev.hxx>
53 com::sun::star::uno::Reference< com::sun::star::i18n::XBreakIterator > xPPTBreakIter;
55 PortionObj::PortionObj( const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > & rXPropSet,
56 FontCollection& rFontCollection ) :
57 mnCharAttrHard ( 0 ),
58 mnCharAttr ( 0 ),
59 mnFont ( 0 ),
60 mnAsianOrComplexFont( 0xffff ),
61 mnTextSize ( 0 ),
62 mbLastPortion ( true ),
63 mpText ( NULL ),
64 mpFieldEntry ( NULL )
66 mXPropSet = rXPropSet;
68 ImplGetPortionValues( rFontCollection, false );
71 PortionObj::PortionObj(::com::sun::star::uno::Reference< ::com::sun::star::text::XTextRange > & rXTextRange,
72 bool bLast, FontCollection& rFontCollection)
73 : meCharColor(css::beans::PropertyState_AMBIGUOUS_VALUE)
74 , meCharHeight(css::beans::PropertyState_AMBIGUOUS_VALUE)
75 , meFontName(css::beans::PropertyState_AMBIGUOUS_VALUE)
76 , meAsianOrComplexFont(css::beans::PropertyState_AMBIGUOUS_VALUE)
77 , meCharEscapement(css::beans::PropertyState_AMBIGUOUS_VALUE)
78 , mnCharAttrHard(0)
79 , mnCharColor(0)
80 , mnCharAttr(0)
81 , mnCharHeight(0)
82 , mnFont(0)
83 , mnAsianOrComplexFont(0xffff)
84 , mnCharEscapement(0)
85 , mbLastPortion(bLast)
86 , mpText(NULL)
87 , mpFieldEntry(NULL)
89 OUString aString( rXTextRange->getString() );
90 OUString aURL;
92 mnTextSize = aString.getLength();
93 if ( bLast )
94 mnTextSize++;
96 if ( mnTextSize )
98 bool bRTL_endingParen = false;
99 mpFieldEntry = NULL;
100 sal_uInt32 nFieldType = 0;
102 mXPropSet = ::com::sun::star::uno::Reference<
103 ::com::sun::star::beans::XPropertySet >
104 ( rXTextRange, ::com::sun::star::uno::UNO_QUERY );
105 mXPropState = ::com::sun::star::uno::Reference<
106 ::com::sun::star::beans::XPropertyState >
107 ( rXTextRange, ::com::sun::star::uno::UNO_QUERY );
109 bool bPropSetsValid = ( mXPropSet.is() && mXPropState.is() );
110 if ( bPropSetsValid )
111 nFieldType = ImplGetTextField( rXTextRange, mXPropSet, aURL );
112 if ( nFieldType )
114 mpFieldEntry = new FieldEntry( nFieldType, 0, mnTextSize );
115 if ( ( nFieldType >> 28 == 4 ) )
117 mpFieldEntry->aRepresentation = aString;
118 mpFieldEntry->aFieldUrl = aURL;
121 bool bSymbol = false;
123 if ( bPropSetsValid && ImplGetPropertyValue( OUString( "CharFontCharSet" ), false ) )
125 sal_Int16 nCharset = 0;
126 mAny >>= nCharset;
127 if ( nCharset == ::com::sun::star::awt::CharSet::SYMBOL )
128 bSymbol = true;
130 if ( mpFieldEntry && ( nFieldType & 0x800000 ) ) // placeholder ?
132 mnTextSize = 1;
133 if ( bLast )
134 mnTextSize++;
135 mpText = new sal_uInt16[ mnTextSize ];
136 mpText[ 0 ] = 0x2a;
138 else
140 // For i39516 - a closing parenthesis that ends an RTL string is displayed backwards by PPT
141 // Solution: add a Unicode Right-to-Left Mark, following the method described in i18024
142 if (bLast && !aString.isEmpty()
143 && aString[aString.getLength() - 1] == ')'
144 && FontCollection::GetScriptDirection(aString) == com::sun::star::i18n::ScriptDirection::RIGHT_TO_LEFT)
146 mnTextSize++;
147 bRTL_endingParen = true;
149 mpText = new sal_uInt16[ mnTextSize ];
150 sal_uInt16 nChar;
151 for ( sal_Int32 i = 0; i < aString.getLength(); i++ )
153 nChar = (sal_uInt16)aString[ i ];
154 if ( nChar == 0xa )
155 nChar++;
156 else if ( !bSymbol )
158 switch ( nChar )
160 // Currency
161 case 128: nChar = 0x20AC; break;
162 // Punctuation and other
163 case 130: nChar = 0x201A; break;// SINGLE LOW-9 QUOTATION MARK
164 case 131: nChar = 0x0192; break;// LATIN SMALL LETTER F WITH HOOK
165 case 132: nChar = 0x201E; break;// DOUBLE LOW-9 QUOTATION MARK
166 // LOW DOUBLE PRIME QUOTATION MARK
167 case 133: nChar = 0x2026; break;// HORIZONTAL ELLIPSES
168 case 134: nChar = 0x2020; break;// DAGGER
169 case 135: nChar = 0x2021; break;// DOUBLE DAGGER
170 case 136: nChar = 0x02C6; break;// MODIFIER LETTER CIRCUMFLEX ACCENT
171 case 137: nChar = 0x2030; break;// PER MILLE SIGN
172 case 138: nChar = 0x0160; break;// LATIN CAPITAL LETTER S WITH CARON
173 case 139: nChar = 0x2039; break;// SINGLE LEFT-POINTING ANGLE QUOTATION MARK
174 case 140: nChar = 0x0152; break;// LATIN CAPITAL LIGATURE OE
175 case 142: nChar = 0x017D; break;// LATIN CAPITAL LETTER Z WITH CARON
176 case 145: nChar = 0x2018; break;// LEFT SINGLE QUOTATION MARK
177 // MODIFIER LETTER TURNED COMMA
178 case 146: nChar = 0x2019; break;// RIGHT SINGLE QUOTATION MARK
179 // MODIFIER LETTER APOSTROPHE
180 case 147: nChar = 0x201C; break;// LEFT DOUBLE QUOTATION MARK
181 // REVERSED DOUBLE PRIME QUOTATION MARK
182 case 148: nChar = 0x201D; break;// RIGHT DOUBLE QUOTATION MARK
183 // REVERSED DOUBLE PRIME QUOTATION MARK
184 case 149: nChar = 0x2022; break;// BULLET
185 case 150: nChar = 0x2013; break;// EN DASH
186 case 151: nChar = 0x2014; break;// EM DASH
187 case 152: nChar = 0x02DC; break;// SMALL TILDE
188 case 153: nChar = 0x2122; break;// TRADE MARK SIGN
189 case 154: nChar = 0x0161; break;// LATIN SMALL LETTER S WITH CARON
190 case 155: nChar = 0x203A; break;// SINGLE RIGHT-POINTING ANGLE QUOTATION MARK
191 case 156: nChar = 0x0153; break;// LATIN SMALL LIGATURE OE
192 case 158: nChar = 0x017E; break;// LATIN SMALL LETTER Z WITH CARON
193 case 159: nChar = 0x0178; break;// LATIN CAPITAL LETTER Y WITH DIAERESIS
196 mpText[ i ] = nChar;
199 if ( bRTL_endingParen )
200 mpText[ mnTextSize - 2 ] = 0x200F; // Unicode Right-to-Left mark
202 if ( bLast )
203 mpText[ mnTextSize - 1 ] = 0xd;
205 if ( bPropSetsValid )
206 ImplGetPortionValues( rFontCollection, true );
210 PortionObj::PortionObj( const PortionObj& rPortionObj )
211 : PropStateValue( rPortionObj )
213 ImplConstruct( rPortionObj );
216 PortionObj::~PortionObj()
218 ImplClear();
221 void PortionObj::Write( SvStream* pStrm, bool bLast )
223 sal_uInt32 nCount = mnTextSize;
224 if ( bLast && mbLastPortion )
225 nCount--;
226 for ( sal_uInt32 i = 0; i < nCount; i++ )
227 pStrm->WriteUInt16( mpText[ i ] );
230 void PortionObj::ImplGetPortionValues( FontCollection& rFontCollection, bool bGetPropStateValue )
233 bool bOk = ImplGetPropertyValue( OUString( "CharFontName" ), bGetPropStateValue );
234 meFontName = ePropState;
235 if ( bOk )
237 FontCollectionEntry aFontDesc( *static_cast<OUString const *>(mAny.getValue()) );
238 sal_uInt32 nCount = rFontCollection.GetCount();
239 mnFont = (sal_uInt16)rFontCollection.GetId( aFontDesc );
240 if ( mnFont == nCount )
242 FontCollectionEntry& rFontDesc = rFontCollection.GetLast();
243 if ( ImplGetPropertyValue( OUString( "CharFontCharSet" ), false ) )
244 mAny >>= rFontDesc.CharSet;
245 if ( ImplGetPropertyValue( OUString( "CharFontFamily" ), false ) )
246 mAny >>= rFontDesc.Family;
247 if ( ImplGetPropertyValue( OUString( "CharFontPitch" ), false ) )
248 mAny >>= rFontDesc.Pitch;
252 sal_Int16 nScriptType = SvtLanguageOptions::FromSvtScriptTypeToI18N( SvtLanguageOptions::GetScriptTypeOfLanguage( Application::GetSettings().GetLanguageTag().getLanguageType() ) );
253 if ( mpText && mnTextSize && xPPTBreakIter.is() )
255 OUString sT( mpText, mnTextSize );
256 nScriptType = xPPTBreakIter->getScriptType( sT, 0 );
258 if ( nScriptType != com::sun::star::i18n::ScriptType::COMPLEX )
260 bOk = ImplGetPropertyValue( OUString( "CharFontNameAsian" ), bGetPropStateValue );
261 meAsianOrComplexFont = ePropState;
262 if ( bOk )
264 FontCollectionEntry aFontDesc( *static_cast<OUString const *>(mAny.getValue()) );
265 sal_uInt32 nCount = rFontCollection.GetCount();
266 mnAsianOrComplexFont = (sal_uInt16)rFontCollection.GetId( aFontDesc );
267 if ( mnAsianOrComplexFont == nCount )
269 FontCollectionEntry& rFontDesc = rFontCollection.GetLast();
270 if ( ImplGetPropertyValue( OUString( "CharFontCharSetAsian" ), false ) )
271 mAny >>= rFontDesc.CharSet;
272 if ( ImplGetPropertyValue( OUString( "CharFontFamilyAsian" ), false ) )
273 mAny >>= rFontDesc.Family;
274 if ( ImplGetPropertyValue( OUString( "CharFontPitchAsian" ), false ) )
275 mAny >>= rFontDesc.Pitch;
279 else
281 bOk = ImplGetPropertyValue( OUString( "CharFontNameComplex" ), bGetPropStateValue );
282 meAsianOrComplexFont = ePropState;
283 if ( bOk )
285 FontCollectionEntry aFontDesc( *static_cast<OUString const *>(mAny.getValue()) );
286 sal_uInt32 nCount = rFontCollection.GetCount();
287 mnAsianOrComplexFont = (sal_uInt16)rFontCollection.GetId( aFontDesc );
288 if ( mnAsianOrComplexFont == nCount )
290 FontCollectionEntry& rFontDesc = rFontCollection.GetLast();
291 if ( ImplGetPropertyValue( OUString( "CharFontCharSetComplex" ), false ) )
292 mAny >>= rFontDesc.CharSet;
293 if ( ImplGetPropertyValue( OUString( "CharFontFamilyComplex" ), false ) )
294 mAny >>= rFontDesc.Family;
295 if ( ImplGetPropertyValue( OUString( "CharFontPitchComplex" ), false ) )
296 mAny >>= rFontDesc.Pitch;
301 OUString aCharHeightName, aCharWeightName, aCharLocaleName, aCharPostureName;
302 switch( nScriptType )
304 case com::sun::star::i18n::ScriptType::ASIAN :
306 aCharHeightName = "CharHeightAsian";
307 aCharWeightName = "CharWeightAsian";
308 aCharLocaleName = "CharLocaleAsian";
309 aCharPostureName = "CharPostureAsian";
310 break;
312 case com::sun::star::i18n::ScriptType::COMPLEX :
314 aCharHeightName = "CharHeightComplex";
315 aCharWeightName = "CharWeightComplex";
316 aCharLocaleName = "CharLocaleComplex";
317 aCharPostureName = "CharPostureComplex";
318 break;
320 default:
322 aCharHeightName = "CharHeight";
323 aCharWeightName = "CharWeight";
324 aCharLocaleName = "CharLocale";
325 aCharPostureName = "CharPosture";
326 break;
330 mnCharHeight = 24;
331 if ( GetPropertyValue( mAny, mXPropSet, aCharHeightName, false ) )
333 float fVal(0.0);
334 if ( mAny >>= fVal )
336 mnCharHeight = (sal_uInt16)( fVal + 0.5 );
337 meCharHeight = GetPropertyState( mXPropSet, aCharHeightName );
340 if ( GetPropertyValue( mAny, mXPropSet, aCharWeightName, false ) )
342 float fFloat(0.0);
343 if ( mAny >>= fFloat )
345 if ( fFloat >= ::com::sun::star::awt::FontWeight::SEMIBOLD )
346 mnCharAttr |= 1;
347 if ( GetPropertyState( mXPropSet, aCharWeightName ) == ::com::sun::star::beans::PropertyState_DIRECT_VALUE )
348 mnCharAttrHard |= 1;
351 if ( GetPropertyValue( mAny, mXPropSet, aCharLocaleName, false ) )
353 com::sun::star::lang::Locale eLocale;
354 if ( mAny >>= eLocale )
355 meCharLocale = eLocale;
357 if ( GetPropertyValue( mAny, mXPropSet, aCharPostureName, false ) )
359 ::com::sun::star::awt::FontSlant aFS;
360 if ( mAny >>= aFS )
362 switch( aFS )
364 case ::com::sun::star::awt::FontSlant_OBLIQUE :
365 case ::com::sun::star::awt::FontSlant_ITALIC :
366 mnCharAttr |= 2;
367 break;
368 default:
369 break;
371 if ( GetPropertyState( mXPropSet, aCharPostureName ) == ::com::sun::star::beans::PropertyState_DIRECT_VALUE )
372 mnCharAttrHard |= 2;
376 if ( ImplGetPropertyValue( OUString( "CharUnderline" ), bGetPropStateValue ) )
378 sal_Int16 nVal(0);
379 mAny >>= nVal;
380 switch ( nVal )
382 case ::com::sun::star::awt::FontUnderline::SINGLE :
383 case ::com::sun::star::awt::FontUnderline::DOUBLE :
384 case ::com::sun::star::awt::FontUnderline::DOTTED :
385 mnCharAttr |= 4;
388 if ( ePropState == ::com::sun::star::beans::PropertyState_DIRECT_VALUE )
389 mnCharAttrHard |= 4;
391 if ( ImplGetPropertyValue( OUString( "CharShadowed" ), bGetPropStateValue ) )
393 bool bBool(false);
394 mAny >>= bBool;
395 if ( bBool )
396 mnCharAttr |= 0x10;
398 if ( ePropState == ::com::sun::star::beans::PropertyState_DIRECT_VALUE )
399 mnCharAttrHard |= 16;
401 if ( ImplGetPropertyValue( OUString( "CharRelief" ), bGetPropStateValue ) )
403 sal_Int16 nVal(0);
404 mAny >>= nVal;
405 if ( nVal != ::com::sun::star::text::FontRelief::NONE )
406 mnCharAttr |= 512;
408 if ( ePropState == ::com::sun::star::beans::PropertyState_DIRECT_VALUE )
409 mnCharAttrHard |= 512;
411 if ( ImplGetPropertyValue( OUString( "CharColor" ), bGetPropStateValue ) )
413 sal_uInt32 nSOColor = *( static_cast<sal_uInt32 const *>(mAny.getValue()) );
414 mnCharColor = nSOColor & 0xff00ff00; // green and hibyte
415 mnCharColor |= (sal_uInt8)( nSOColor ) << 16; // red and blue is switched
416 mnCharColor |= (sal_uInt8)( nSOColor >> 16 );
418 meCharColor = ePropState;
420 mnCharEscapement = 0;
421 if ( ImplGetPropertyValue( OUString( "CharEscapement" ), bGetPropStateValue ) )
423 mAny >>= mnCharEscapement;
424 if ( mnCharEscapement > 100 )
425 mnCharEscapement = 33;
426 else if ( mnCharEscapement < -100 )
427 mnCharEscapement = -33;
429 meCharEscapement = ePropState;
432 void PortionObj::ImplClear()
434 delete mpFieldEntry;
435 delete[] mpText;
438 void PortionObj::ImplConstruct( const PortionObj& rPortionObj )
440 meCharColor = rPortionObj.meCharColor;
441 meCharHeight = rPortionObj.meCharHeight;
442 meFontName = rPortionObj.meFontName;
443 meAsianOrComplexFont = rPortionObj.meAsianOrComplexFont;
444 meCharEscapement = rPortionObj.meCharEscapement;
445 meCharLocale = rPortionObj.meCharLocale;
446 mnCharAttrHard = rPortionObj.mnCharAttrHard;
448 mbLastPortion = rPortionObj.mbLastPortion;
449 mnTextSize = rPortionObj.mnTextSize;
450 mnCharColor = rPortionObj.mnCharColor;
451 mnCharEscapement = rPortionObj.mnCharEscapement;
452 mnCharAttr = rPortionObj.mnCharAttr;
453 mnCharHeight = rPortionObj.mnCharHeight;
454 mnFont = rPortionObj.mnFont;
455 mnAsianOrComplexFont = rPortionObj.mnAsianOrComplexFont;
457 if ( rPortionObj.mpText )
459 mpText = new sal_uInt16[ mnTextSize ];
460 memcpy( mpText, rPortionObj.mpText, mnTextSize << 1 );
462 else
463 mpText = NULL;
465 if ( rPortionObj.mpFieldEntry )
466 mpFieldEntry = new FieldEntry( *( rPortionObj.mpFieldEntry ) );
467 else
468 mpFieldEntry = NULL;
471 sal_uInt32 PortionObj::ImplCalculateTextPositions( sal_uInt32 nCurrentTextPosition )
473 if ( mpFieldEntry && ( !mpFieldEntry->nFieldStartPos ) )
475 mpFieldEntry->nFieldStartPos += nCurrentTextPosition;
476 mpFieldEntry->nFieldEndPos += nCurrentTextPosition;
478 return mnTextSize;
481 // Return: 0 = no TextField
482 // bit28->31 text field type :
483 // 1 = Date
484 // 2 = Time
485 // 3 = SlideNumber
486 // 4 = Url
487 // 5 = DateTime
488 // 6 = header
489 // 7 = footer
490 // bit24->27 text field sub type (optional)
491 // 23-> PPT Textfield needs a placeholder
493 sal_uInt32 PortionObj::ImplGetTextField( ::com::sun::star::uno::Reference< ::com::sun::star::text::XTextRange > & ,
494 const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > & rXPropSet, OUString& rURL )
496 sal_uInt32 nRetValue = 0;
497 sal_Int32 nFormat;
498 ::com::sun::star::uno::Any aAny;
499 if ( GetPropertyValue( aAny, rXPropSet, OUString( "TextPortionType" ), true ) )
501 OUString aTextFieldType( *static_cast<OUString const *>(aAny.getValue()) );
502 if ( aTextFieldType == "TextField" )
504 if ( GetPropertyValue( aAny, rXPropSet, aTextFieldType, true ) )
506 ::com::sun::star::uno::Reference< ::com::sun::star::text::XTextField > aXTextField;
507 if ( aAny >>= aXTextField )
509 if ( aXTextField.is() )
511 ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet >
512 xFieldPropSet( aXTextField, ::com::sun::star::uno::UNO_QUERY );
513 if ( xFieldPropSet.is() )
515 OUString aFieldKind( aXTextField->getPresentation( sal_True ) );
516 if ( aFieldKind == "Date" )
518 if ( GetPropertyValue( aAny, xFieldPropSet, OUString( "IsFix" ), true ) )
520 bool bBool = false;
521 aAny >>= bBool;
522 if ( !bBool ) // Fixed DateFields does not exist in PPT
524 if ( GetPropertyValue( aAny, xFieldPropSet, OUString( "Format" ), true ) )
526 nFormat = *static_cast<sal_Int32 const *>(aAny.getValue());
527 switch ( nFormat )
529 default:
530 case 5 :
531 case 4 :
532 case 2 : nFormat = 0; break;
533 case 8 :
534 case 9 :
535 case 3 : nFormat = 1; break;
536 case 7 :
537 case 6 : nFormat = 2; break;
539 nRetValue |= ( ( ( 1 << 4 ) | nFormat ) << 24 ) | 0x800000;
544 else if ( aFieldKind == "URL" )
546 if ( GetPropertyValue( aAny, xFieldPropSet, OUString( "URL" ), true ) )
547 rURL = *static_cast<OUString const *>(aAny.getValue());
548 nRetValue = 4 << 28;
550 else if ( aFieldKind == "Page" )
552 nRetValue = 3 << 28 | 0x800000;
554 else if ( aFieldKind == "Pages" )
558 else if ( aFieldKind == "Time" )
560 if ( GetPropertyValue( aAny, xFieldPropSet, OUString( "IsFix" ), true ) )
562 bool bBool = false;
563 aAny >>= bBool;
564 if ( !bBool )
566 if ( GetPropertyValue( aAny, xFieldPropSet, OUString( "IsFix" ), true ) )
568 nFormat = *static_cast<sal_Int32 const *>(aAny.getValue());
569 nRetValue |= ( ( ( 2 << 4 ) | nFormat ) << 24 ) | 0x800000;
574 else if ( aFieldKind == "File" )
578 else if ( aFieldKind == "Table" )
582 else if ( aFieldKind == "ExtTime" )
584 if ( GetPropertyValue( aAny, xFieldPropSet, OUString( "IsFix" ), true ) )
586 bool bBool = false;
587 aAny >>= bBool;
588 if ( !bBool )
590 if ( GetPropertyValue( aAny, xFieldPropSet, OUString( "Format" ), true ) )
592 nFormat = *static_cast<sal_Int32 const *>(aAny.getValue());
593 switch ( nFormat )
595 default:
596 case 6 :
597 case 7 :
598 case 8 :
599 case 2 : nFormat = 12; break;
600 case 3 : nFormat = 9; break;
601 case 5 :
602 case 4 : nFormat = 10; break;
605 nRetValue |= ( ( ( 2 << 4 ) | nFormat ) << 24 ) | 0x800000;
610 else if ( aFieldKind == "ExtFile" )
614 else if ( aFieldKind == "Author" )
618 else if ( aFieldKind == "DateTime" )
620 nRetValue = 5 << 28 | 0x800000;
622 else if ( aFieldKind == "Header" )
624 nRetValue = 6 << 28 | 0x800000;
626 else if ( aFieldKind == "Footer" )
628 nRetValue = 7 << 28 | 0x800000;
636 return nRetValue;
639 PortionObj& PortionObj::operator=( const PortionObj& rPortionObj )
641 if ( this != &rPortionObj )
643 ImplClear();
644 ImplConstruct( rPortionObj );
646 return *this;
649 ParagraphObj::ParagraphObj(const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > & rXPropSet,
650 PPTExBulletProvider* pProv)
651 : PropStateValue()
652 , SOParagraph()
653 , mvPortions()
654 , maMapModeSrc(MAP_100TH_MM)
655 , maMapModeDest(MAP_INCH, Point(), Fraction( 1, 576 ), Fraction( 1, 576 ))
656 , mnTextSize(0)
657 , mbFirstParagraph(false)
658 , mbLastParagraph(false)
659 , mnTextAdjust(0)
660 , mnLineSpacing(0)
661 , mbFixedLineSpacing(false)
662 , mnLineSpacingTop(0)
663 , mnLineSpacingBottom(0)
664 , mbForbiddenRules(false)
665 , mbParagraphPunctation(false)
666 , mnBiDi(0)
668 mXPropSet = rXPropSet;
670 bExtendedParameters = false;
672 nDepth = 0;
673 nBulletFlags = 0;
674 nParaFlags = 0;
676 ImplGetParagraphValues( pProv, false );
679 ParagraphObj::ParagraphObj(::com::sun::star::uno::Reference< ::com::sun::star::text::XTextContent > & rXTextContent,
680 ParaFlags aParaFlags, FontCollection& rFontCollection, PPTExBulletProvider& rProv )
681 : PropStateValue()
682 , SOParagraph()
683 , mvPortions()
684 , maMapModeSrc(MAP_100TH_MM)
685 , maMapModeDest(MAP_INCH, Point(), Fraction( 1, 576 ), Fraction( 1, 576 ))
686 , mnTextSize(0)
687 , mbIsBullet(false)
688 , mbFirstParagraph( aParaFlags.bFirstParagraph )
689 , mbLastParagraph( aParaFlags.bLastParagraph )
690 , meBullet(css::beans::PropertyState_AMBIGUOUS_VALUE)
691 , meTextAdjust(css::beans::PropertyState_AMBIGUOUS_VALUE)
692 , meLineSpacing(css::beans::PropertyState_AMBIGUOUS_VALUE)
693 , meLineSpacingTop(css::beans::PropertyState_AMBIGUOUS_VALUE)
694 , meLineSpacingBottom(css::beans::PropertyState_AMBIGUOUS_VALUE)
695 , meForbiddenRules(css::beans::PropertyState_AMBIGUOUS_VALUE)
696 , meParagraphPunctation(css::beans::PropertyState_AMBIGUOUS_VALUE)
697 , meBiDi(css::beans::PropertyState_AMBIGUOUS_VALUE)
698 , mnTextAdjust(0)
699 , mnLineSpacing(0)
700 , mbFixedLineSpacing(false)
701 , mnLineSpacingTop(0)
702 , mnLineSpacingBottom(0)
703 , mbForbiddenRules(false)
704 , mbParagraphPunctation(false)
705 , mnBiDi(0)
707 bExtendedParameters = false;
709 nDepth = 0;
710 nBulletFlags = 0;
711 nParaFlags = 0;
713 mXPropSet = ::com::sun::star::uno::Reference<
714 ::com::sun::star::beans::XPropertySet >
715 ( rXTextContent, ::com::sun::star::uno::UNO_QUERY );
717 mXPropState = ::com::sun::star::uno::Reference<
718 ::com::sun::star::beans::XPropertyState >
719 ( rXTextContent, ::com::sun::star::uno::UNO_QUERY );
721 if ( mXPropSet.is() && mXPropState.is() )
723 ::com::sun::star::uno::Reference< ::com::sun::star::container::XEnumerationAccess >
724 aXTextPortionEA( rXTextContent, ::com::sun::star::uno::UNO_QUERY );
725 if ( aXTextPortionEA.is() )
727 ::com::sun::star::uno::Reference< ::com::sun::star::container::XEnumeration >
728 aXTextPortionE( aXTextPortionEA->createEnumeration() );
729 if ( aXTextPortionE.is() )
731 while ( aXTextPortionE->hasMoreElements() )
733 ::com::sun::star::uno::Reference< ::com::sun::star::text::XTextRange > aXCursorText;
734 ::com::sun::star::uno::Any aAny( aXTextPortionE->nextElement() );
735 if ( aAny >>= aXCursorText )
737 PortionObj* pPortionObj = new PortionObj( aXCursorText, !aXTextPortionE->hasMoreElements(), rFontCollection );
738 if ( pPortionObj->Count() )
739 mvPortions.push_back( pPortionObj );
740 else
741 delete pPortionObj;
746 ImplGetParagraphValues( &rProv, true );
750 ParagraphObj::ParagraphObj( const ParagraphObj& rObj )
751 : PropStateValue()
752 , SOParagraph()
753 , mvPortions()
755 ImplConstruct( rObj );
758 ParagraphObj::~ParagraphObj()
760 ImplClear();
763 void ParagraphObj::Write( SvStream* pStrm )
765 for ( boost::ptr_vector<PortionObj>::iterator it = mvPortions.begin(); it != mvPortions.end(); ++it )
766 it->Write( pStrm, mbLastParagraph );
769 void ParagraphObj::ImplClear()
771 mvPortions.clear();
774 void ParagraphObj::CalculateGraphicBulletSize( sal_uInt16 nFontHeight )
776 if ( ( (SvxExtNumType)nNumberingType == SVX_NUM_BITMAP ) && ( nBulletId != 0xffff ) )
778 // calculate the bulletrealsize for this grafik
779 if ( aBuGraSize.Width() && aBuGraSize.Height() )
781 double fCharHeight = nFontHeight;
782 double fLen = aBuGraSize.Height();
783 fCharHeight = fCharHeight * 0.2540;
784 double fQuo = fLen / fCharHeight;
785 nBulletRealSize = (sal_Int16)( fQuo + 0.5 );
786 if ( (sal_uInt16)nBulletRealSize > 400 )
787 nBulletRealSize = 400;
792 void ParagraphObj::ImplGetNumberingLevel( PPTExBulletProvider* pBuProv, sal_Int16 nNumberingDepth, bool bIsBullet, bool bGetPropStateValue )
794 ::com::sun::star::uno::Any aAny;
795 if ( GetPropertyValue( aAny, mXPropSet, OUString( "ParaLeftMargin" ) ) )
797 sal_Int32 nVal(0);
798 if ( aAny >>= nVal )
799 nTextOfs = static_cast< sal_Int16 >( nVal / ( 2540.0 / 576 ) + 0.5 ) ;
801 if ( GetPropertyValue( aAny, mXPropSet, OUString( "ParaFirstLineIndent" ) ) )
803 if ( aAny >>= nBulletOfs )
804 nBulletOfs = static_cast< sal_Int32 >( nBulletOfs / ( 2540.0 / 576 ) + 0.5 );
806 if ( GetPropertyValue( aAny, mXPropSet, OUString( "NumberingIsNumber" ) ) )
807 aAny >>= bNumberingIsNumber;
809 ::com::sun::star::uno::Reference< ::com::sun::star::container::XIndexReplace > aXIndexReplace;
811 if ( bIsBullet && ImplGetPropertyValue( OUString( "NumberingRules" ), bGetPropStateValue ) )
813 if ( ( mAny >>= aXIndexReplace ) && nNumberingDepth < aXIndexReplace->getCount() )
815 mAny <<= aXIndexReplace->getByIndex( nNumberingDepth );
816 ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue>
817 aPropertySequence( *static_cast<css::uno::Sequence< ::com::sun::star::beans::PropertyValue> const *>(mAny.getValue()) );
819 const ::com::sun::star::beans::PropertyValue* pPropValue = aPropertySequence.getArray();
821 sal_Int32 nPropertyCount = aPropertySequence.getLength();
822 if ( nPropertyCount )
824 bExtendedParameters = true;
825 nBulletRealSize = 100;
826 nMappedNumType = 0;
828 OUString aGraphicURL;
829 for ( sal_Int32 i = 0; i < nPropertyCount; i++ )
831 const void* pValue = pPropValue[ i ].Value.getValue();
832 if ( pValue )
834 OUString aPropName( pPropValue[ i ].Name );
835 if ( aPropName == "NumberingType" )
836 nNumberingType = *( static_cast<sal_Int16 const *>(pValue) );
837 else if ( aPropName == "Adjust" )
838 nHorzAdjust = *( static_cast<sal_Int16 const *>(pValue) );
839 else if ( aPropName == "BulletChar" )
841 OUString aString( *( static_cast<OUString const *>(pValue) ) );
842 if ( !aString.isEmpty() )
843 cBulletId = aString[ 0 ];
845 else if ( aPropName == "BulletFont" )
847 aFontDesc = *static_cast<css::awt::FontDescriptor const *>(pValue);
849 // Our numbullet dialog has set the wrong textencoding for our "StarSymbol" font,
850 // instead of a Unicode encoding the encoding RTL_TEXTENCODING_SYMBOL was used.
851 // Because there might exist a lot of damaged documemts I added this two lines
852 // which fixes the bullet problem for the export.
853 if ( aFontDesc.Name.equalsIgnoreAsciiCase("StarSymbol") )
854 aFontDesc.CharSet = RTL_TEXTENCODING_MS_1252;
857 else if ( aPropName == "GraphicURL" )
858 aGraphicURL = *static_cast<OUString const *>(pValue);
859 else if ( aPropName == "GraphicSize" )
861 if ( pPropValue[ i ].Value.getValueType() == cppu::UnoType<com::sun::star::awt::Size>::get())
863 // don't cast awt::Size to Size as on 64-bits they are not the same.
864 ::com::sun::star::awt::Size aSize;
865 pPropValue[ i ].Value >>= aSize;
866 aBuGraSize.A() = aSize.Width;
867 aBuGraSize.B() = aSize.Height;
870 else if ( aPropName == "StartWith" )
871 nStartWith = *static_cast<sal_Int16 const *>(pValue);
872 else if ( aPropName == "LeftMargin" )
873 nTextOfs = nTextOfs + static_cast< sal_Int16 >( *static_cast<sal_Int32 const *>(pValue) / ( 2540.0 / 576 ) );
874 else if ( aPropName == "FirstLineOffset" )
875 nBulletOfs += (sal_Int16)( *static_cast<sal_Int32 const *>(pValue) / ( 2540.0 / 576 ) );
876 else if ( aPropName == "BulletColor" )
878 sal_uInt32 nSOColor = *static_cast<sal_uInt32 const *>(pValue);
879 nBulletColor = nSOColor & 0xff00ff00; // green and hibyte
880 nBulletColor |= (sal_uInt8)( nSOColor ) << 16; // red
881 nBulletColor |= (sal_uInt8)( nSOColor >> 16 ) | 0xfe000000; // blue
883 else if ( aPropName == "BulletRelSize" )
885 nBulletRealSize = *static_cast<sal_Int16 const *>(pValue);
886 nParaFlags |= 0x40;
887 nBulletFlags |= 8;
889 else if ( aPropName == "Prefix" )
890 sPrefix = *static_cast<OUString const *>(pValue);
891 else if ( aPropName == "Suffix" )
892 sSuffix = *static_cast<OUString const *>(pValue);
893 #ifdef DBG_UTIL
894 else if ( ! (
895 ( aPropName == "SymbolTextDistance" )
896 || ( aPropName == "Graphic" ) ) )
898 OSL_FAIL( "Unknown Property" );
900 #endif
904 if ( !aGraphicURL.isEmpty() )
906 if ( aBuGraSize.Width() && aBuGraSize.Height() )
908 sal_Int32 nIndex = aGraphicURL.indexOf(':');
909 if ( nIndex != -1 )
911 nIndex++;
912 if ( nIndex < aGraphicURL.getLength() )
914 OString aUniqueId( OUStringToOString(aGraphicURL.copy(nIndex), RTL_TEXTENCODING_UTF8) );
915 if ( !aUniqueId.isEmpty() )
917 nBulletId = pBuProv->GetId( aUniqueId, aBuGraSize );
918 if ( nBulletId != 0xffff )
919 bExtendedBulletsUsed = true;
924 else
926 nNumberingType = SVX_NUM_NUMBER_NONE;
930 CalculateGraphicBulletSize( ( mvPortions.empty() ) ? 24 : mvPortions.front().mnCharHeight );
932 switch( nNumberingType )
934 case SVX_NUM_NUMBER_NONE : nParaFlags |= 0xf; break;
936 case SVX_NUM_CHAR_SPECIAL : // Bullet
938 if ( IsStarSymbol(aFontDesc.Name) )
940 rtl_TextEncoding eChrSet = aFontDesc.CharSet;
941 cBulletId = msfilter::util::bestFitOpenSymbolToMSFont(cBulletId, eChrSet, aFontDesc.Name);
942 aFontDesc.CharSet = eChrSet;
945 if ( !aFontDesc.Name.isEmpty() )
947 nParaFlags |= 0x90; // we define the font and charset
950 case SVX_NUM_CHARS_UPPER_LETTER : // count from a-z, aa - az, ba - bz, ...
951 case SVX_NUM_CHARS_LOWER_LETTER :
952 case SVX_NUM_ROMAN_UPPER :
953 case SVX_NUM_ROMAN_LOWER :
954 case SVX_NUM_ARABIC :
955 case SVX_NUM_PAGEDESC : // numbering from the page template
956 case SVX_NUM_BITMAP :
957 case SVX_NUM_CHARS_UPPER_LETTER_N : // count from a-z, aa-zz, aaa-zzz
958 case SVX_NUM_CHARS_LOWER_LETTER_N :
959 case SVX_NUM_NUMBER_UPPER_ZH:
960 case SVX_NUM_CIRCLE_NUMBER:
961 case SVX_NUM_NUMBER_UPPER_ZH_TW:
962 case SVX_NUM_NUMBER_LOWER_ZH:
963 case SVX_NUM_FULL_WIDTH_ARABIC:
965 if ( nNumberingType != SVX_NUM_CHAR_SPECIAL )
967 bExtendedBulletsUsed = true;
968 if ( nNumberingDepth & 1 )
969 cBulletId = 0x2013; // defaulting bullet characters for ppt97
970 else if ( nNumberingDepth == 4 )
971 cBulletId = 0xbb;
972 else
973 cBulletId = 0x2022;
975 switch( (SvxExtNumType)nNumberingType )
977 case SVX_NUM_CHARS_UPPER_LETTER :
978 case SVX_NUM_CHARS_UPPER_LETTER_N :
980 if ( sSuffix == ")" )
982 if ( sPrefix == "(" )
983 nMappedNumType = 0xa0001; // (A)
984 else
985 nMappedNumType = 0xb0001; // A)
987 else
988 nMappedNumType = 0x10001; // A.
990 break;
991 case SVX_NUM_CHARS_LOWER_LETTER :
992 case SVX_NUM_CHARS_LOWER_LETTER_N :
994 if ( sSuffix == ")" )
996 if ( sPrefix == "(" )
997 nMappedNumType = 0x80001; // (a)
998 else
999 nMappedNumType = 0x90001; // a)
1001 else
1002 nMappedNumType = 0x00001; // a.
1004 break;
1005 case SVX_NUM_ROMAN_UPPER :
1007 if ( sSuffix == ")" )
1009 if ( sPrefix == "(" )
1010 nMappedNumType = 0xe0001; // (I)
1011 else
1012 nMappedNumType = 0xf0001; // I)
1014 else
1015 nMappedNumType = 0x70001; // I.
1017 break;
1018 case SVX_NUM_ROMAN_LOWER :
1020 if ( sSuffix == ")" )
1022 if ( sPrefix == "(" )
1023 nMappedNumType = 0x40001; // (i)
1024 else
1025 nMappedNumType = 0x50001; // i)
1027 else
1028 nMappedNumType = 0x60001; // i.
1030 break;
1031 case SVX_NUM_ARABIC :
1033 if ( sSuffix == ")" )
1035 if ( sPrefix == "(" )
1036 nMappedNumType = 0xc0001; // (1)
1037 else
1038 nMappedNumType = 0x20001; // 1)
1040 else
1042 if ( sSuffix.isEmpty() && sPrefix.isEmpty() )
1043 nMappedNumType = 0xd0001; // 1
1044 else
1045 nMappedNumType = 0x30001; // 1.
1048 break;
1049 case SVX_NUM_NUMBER_UPPER_ZH :
1051 if ( !sSuffix.isEmpty() )
1052 nMappedNumType = 0x110001; // Simplified Chinese with single-byte period.
1053 else
1054 nMappedNumType = 0x100001; // Simplified Chinese.
1056 break;
1057 case SVX_NUM_CIRCLE_NUMBER :
1059 nMappedNumType = 0x120001; // Double byte circle numbers.
1061 break;
1062 case SVX_NUM_NUMBER_UPPER_ZH_TW :
1064 if ( !sSuffix.isEmpty() )
1065 nMappedNumType = 0x160001; // Traditional Chinese with single-byte period.
1066 else
1067 nMappedNumType = 0x150001; // Traditional Chinese.
1069 break;
1070 case SVX_NUM_NUMBER_LOWER_ZH :
1072 if ( sSuffix == OUString( sal_Unicode(0xff0e)) )
1073 nMappedNumType = 0x260001; // Japanese with double-byte period.
1074 else if ( !sSuffix.isEmpty() )
1075 nMappedNumType = 0x1B0001; // Japanese/Korean with single-byte period.
1076 else
1077 nMappedNumType = 0x1A0001; // Japanese/Korean.
1079 break;
1080 case SVX_NUM_FULL_WIDTH_ARABIC :
1082 if ( !sSuffix.isEmpty() )
1083 nMappedNumType = 0x1D0001; // Double-byte Arabic numbers with double-byte period.
1084 else
1085 nMappedNumType = 0x1C0001; // Double-byte Arabic numbers.
1087 break;
1088 default:
1089 break;
1092 nParaFlags |= 0x2f;
1093 nBulletFlags |= 6;
1094 if ( mbIsBullet && bNumberingIsNumber )
1095 nBulletFlags |= 1;
1101 nBulletOfs = nTextOfs + nBulletOfs;
1102 if ( nBulletOfs < 0 )
1103 nBulletOfs = 0;
1106 void ParagraphObj::ImplGetParagraphValues( PPTExBulletProvider* pBuProv, bool bGetPropStateValue )
1108 ::com::sun::star::uno::Any aAny;
1109 if ( GetPropertyValue( aAny, mXPropSet, "NumberingLevel", true ) )
1111 if ( bGetPropStateValue )
1112 meBullet = GetPropertyState( mXPropSet, "NumberingLevel" );
1113 nDepth = *static_cast<sal_Int16 const *>(aAny.getValue());
1115 if ( nDepth < 0 )
1117 mbIsBullet = false;
1118 nDepth = 0;
1120 else
1122 if ( nDepth > 4 )
1123 nDepth = 4;
1124 mbIsBullet = true;
1127 else
1129 nDepth = 0;
1130 mbIsBullet = false;
1132 ImplGetNumberingLevel( pBuProv, nDepth, mbIsBullet, bGetPropStateValue );
1134 if ( ImplGetPropertyValue( OUString( "ParaTabStops" ), bGetPropStateValue ) )
1135 maTabStop = *static_cast<css::uno::Sequence< ::com::sun::star::style::TabStop> const *>(mAny.getValue());
1136 sal_Int16 eTextAdjust( ::com::sun::star::style::ParagraphAdjust_LEFT );
1137 if ( GetPropertyValue( aAny, mXPropSet, OUString( "ParaAdjust" ), bGetPropStateValue ) )
1138 aAny >>= eTextAdjust;
1139 switch ( (::com::sun::star::style::ParagraphAdjust)eTextAdjust )
1141 case ::com::sun::star::style::ParagraphAdjust_CENTER :
1142 mnTextAdjust = 1;
1143 break;
1144 case ::com::sun::star::style::ParagraphAdjust_RIGHT :
1145 mnTextAdjust = 2;
1146 break;
1147 case ::com::sun::star::style::ParagraphAdjust_BLOCK :
1148 mnTextAdjust = 3;
1149 break;
1150 default :
1151 case ::com::sun::star::style::ParagraphAdjust_LEFT :
1152 mnTextAdjust = 0;
1153 break;
1155 meTextAdjust = ePropState;
1157 if ( ImplGetPropertyValue( OUString( "ParaLineSpacing" ), bGetPropStateValue ) )
1159 ::com::sun::star::style::LineSpacing aLineSpacing
1160 = *static_cast<css::style::LineSpacing const *>(mAny.getValue());
1161 switch ( aLineSpacing.Mode )
1163 case ::com::sun::star::style::LineSpacingMode::FIX :
1164 mnLineSpacing = (sal_Int16)(-( aLineSpacing.Height ) );
1165 mbFixedLineSpacing = true;
1166 break;
1167 case ::com::sun::star::style::LineSpacingMode::MINIMUM :
1168 case ::com::sun::star::style::LineSpacingMode::LEADING :
1169 mnLineSpacing = (sal_Int16)(-( aLineSpacing.Height ) );
1170 mbFixedLineSpacing = false;
1171 break;
1173 case ::com::sun::star::style::LineSpacingMode::PROP :
1174 default:
1175 mnLineSpacing = (sal_Int16)( aLineSpacing.Height );
1176 break;
1179 meLineSpacing = ePropState;
1181 if ( ImplGetPropertyValue( OUString( "ParaBottomMargin" ), bGetPropStateValue ) )
1183 double fSpacing = *static_cast<sal_uInt32 const *>(mAny.getValue()) + ( 2540.0 / 576.0 ) - 1;
1184 mnLineSpacingBottom = (sal_Int16)(-( fSpacing * 576.0 / 2540.0 ) );
1186 meLineSpacingBottom = ePropState;
1188 if ( ImplGetPropertyValue( OUString( "ParaTopMargin" ), bGetPropStateValue ) )
1190 double fSpacing = *static_cast<sal_uInt32 const *>(mAny.getValue()) + ( 2540.0 / 576.0 ) - 1;
1191 mnLineSpacingTop = (sal_Int16)(-( fSpacing * 576.0 / 2540.0 ) );
1193 meLineSpacingTop = ePropState;
1195 if ( ImplGetPropertyValue( OUString( "ParaIsForbiddenRules" ), bGetPropStateValue ) )
1196 mAny >>= mbForbiddenRules;
1197 meForbiddenRules = ePropState;
1199 if ( ImplGetPropertyValue( OUString( "ParaIsHangingPunctuation" ), bGetPropStateValue ) )
1200 mAny >>= mbParagraphPunctation;
1201 meParagraphPunctation = ePropState;
1203 mnBiDi = 0;
1204 if ( ImplGetPropertyValue( OUString( "WritingMode" ), bGetPropStateValue ) )
1206 sal_Int16 nWritingMode = 0;
1207 mAny >>= nWritingMode;
1209 SvxFrameDirection eWritingMode( (SvxFrameDirection)nWritingMode );
1210 if ( ( eWritingMode == FRMDIR_HORI_RIGHT_TOP )
1211 || ( eWritingMode == FRMDIR_VERT_TOP_RIGHT ) )
1213 mnBiDi = 1;
1216 meBiDi = ePropState;
1219 void ParagraphObj::ImplConstruct( const ParagraphObj& rParagraphObj )
1221 mbIsBullet = rParagraphObj.mbIsBullet;
1222 meBullet = rParagraphObj.meBullet;
1223 meTextAdjust = rParagraphObj.meTextAdjust;
1224 meLineSpacing = rParagraphObj.meLineSpacing;
1225 meLineSpacingTop = rParagraphObj.meLineSpacingTop;
1226 meLineSpacingBottom = rParagraphObj.meLineSpacingBottom;
1227 meForbiddenRules = rParagraphObj.meForbiddenRules;
1228 meParagraphPunctation = rParagraphObj.meParagraphPunctation;
1229 meBiDi =rParagraphObj.meBiDi;
1230 mbFixedLineSpacing = rParagraphObj.mbFixedLineSpacing;
1231 mnTextSize = rParagraphObj.mnTextSize;
1232 mnTextAdjust = rParagraphObj.mnTextAdjust;
1233 mnLineSpacing = rParagraphObj.mnLineSpacing;
1234 mnLineSpacingTop = rParagraphObj.mnLineSpacingTop;
1235 mnLineSpacingBottom = rParagraphObj.mnLineSpacingBottom;
1236 mbFirstParagraph = rParagraphObj.mbFirstParagraph;
1237 mbLastParagraph = rParagraphObj.mbLastParagraph;
1238 mbParagraphPunctation = rParagraphObj.mbParagraphPunctation;
1239 mbForbiddenRules = rParagraphObj.mbForbiddenRules;
1240 mnBiDi = rParagraphObj.mnBiDi;
1242 for ( boost::ptr_vector<PortionObj>::const_iterator it = rParagraphObj.begin(); it != rParagraphObj.end(); ++it )
1243 mvPortions.push_back( new PortionObj( *it ) );
1245 maTabStop = rParagraphObj.maTabStop;
1246 bExtendedParameters = rParagraphObj.bExtendedParameters;
1247 nParaFlags = rParagraphObj.nParaFlags;
1248 nBulletFlags = rParagraphObj.nBulletFlags;
1249 sPrefix = rParagraphObj.sPrefix;
1250 sSuffix = rParagraphObj.sSuffix;
1251 sGraphicUrl = rParagraphObj.sGraphicUrl; // String to a graphic
1252 aBuGraSize = rParagraphObj.aBuGraSize;
1253 nNumberingType = rParagraphObj.nNumberingType; // this is actually a SvxEnum
1254 nHorzAdjust = rParagraphObj.nHorzAdjust;
1255 nBulletColor = rParagraphObj.nBulletColor;
1256 nBulletOfs = rParagraphObj.nBulletOfs;
1257 nStartWith = rParagraphObj.nStartWith; // start of numbering
1258 nTextOfs = rParagraphObj.nTextOfs;
1259 nBulletRealSize = rParagraphObj.nBulletRealSize; // scale in percent
1260 nDepth = rParagraphObj.nDepth; // actual depth
1261 cBulletId = rParagraphObj.cBulletId; // if Numbering Type == CharSpecial
1262 aFontDesc = rParagraphObj.aFontDesc;
1264 bExtendedBulletsUsed = rParagraphObj.bExtendedBulletsUsed;
1265 nBulletId = rParagraphObj.nBulletId;
1268 sal_uInt32 ParagraphObj::ImplCalculateTextPositions( sal_uInt32 nCurrentTextPosition )
1270 mnTextSize = 0;
1271 for ( boost::ptr_vector<PortionObj>::iterator it = mvPortions.begin(); it != mvPortions.end(); ++it )
1272 mnTextSize += it->ImplCalculateTextPositions( nCurrentTextPosition + mnTextSize );
1273 return mnTextSize;
1276 ParagraphObj& ParagraphObj::operator=( const ParagraphObj& rParagraphObj )
1278 if ( this != &rParagraphObj )
1280 ImplClear();
1281 ImplConstruct( rParagraphObj );
1283 return *this;
1286 struct ImplTextObj
1288 sal_uInt32 mnTextSize;
1289 int mnInstance;
1290 std::vector<ParagraphObj*> maList;
1291 bool mbHasExtendedBullets;
1292 bool mbFixedCellHeightUsed;
1294 ImplTextObj( int nInstance );
1295 ~ImplTextObj();
1298 ImplTextObj::ImplTextObj( int nInstance )
1299 : maList()
1301 mnTextSize = 0;
1302 mnInstance = nInstance;
1303 mbHasExtendedBullets = false;
1304 mbFixedCellHeightUsed = false;
1307 ImplTextObj::~ImplTextObj()
1309 for ( std::vector<ParagraphObj*>::const_iterator it = maList.begin(); it != maList.end(); ++it )
1310 delete *it;
1313 TextObj::TextObj( ::com::sun::star::uno::Reference< ::com::sun::star::text::XSimpleText > & rXTextRef,
1314 int nInstance, FontCollection& rFontCollection, PPTExBulletProvider& rProv ):
1315 mpImplTextObj(new ImplTextObj(nInstance))
1317 ::com::sun::star::uno::Reference< ::com::sun::star::container::XEnumerationAccess >
1318 aXTextParagraphEA( rXTextRef, ::com::sun::star::uno::UNO_QUERY );
1320 if ( aXTextParagraphEA.is() )
1322 ::com::sun::star::uno::Reference< ::com::sun::star::container::XEnumeration >
1323 aXTextParagraphE( aXTextParagraphEA->createEnumeration() );
1324 if ( aXTextParagraphE.is() )
1326 ParaFlags aParaFlags;
1327 while ( aXTextParagraphE->hasMoreElements() )
1329 ::com::sun::star::uno::Reference< ::com::sun::star::text::XTextContent > aXParagraph;
1330 ::com::sun::star::uno::Any aAny( aXTextParagraphE->nextElement() );
1331 if ( aAny >>= aXParagraph )
1333 if ( !aXTextParagraphE->hasMoreElements() )
1334 aParaFlags.bLastParagraph = true;
1335 ParagraphObj* pPara = new ParagraphObj( aXParagraph, aParaFlags, rFontCollection, rProv );
1336 mpImplTextObj->mbHasExtendedBullets |= pPara->bExtendedBulletsUsed;
1337 mpImplTextObj->maList.push_back( pPara );
1338 aParaFlags.bFirstParagraph = false;
1343 ImplCalculateTextPositions();
1346 void TextObj::ImplCalculateTextPositions()
1348 mpImplTextObj->mnTextSize = 0;
1349 for ( sal_uInt32 i = 0; i < ParagraphCount(); ++i )
1350 mpImplTextObj->mnTextSize += GetParagraph(i)->ImplCalculateTextPositions( mpImplTextObj->mnTextSize );
1353 ParagraphObj* TextObj::GetParagraph(int idx)
1355 return mpImplTextObj->maList[idx];
1358 sal_uInt32 TextObj::ParagraphCount() const
1360 return mpImplTextObj->maList.size();
1363 sal_uInt32 TextObj::Count() const
1365 return mpImplTextObj->mnTextSize;
1368 int TextObj::GetInstance() const
1370 return mpImplTextObj->mnInstance;
1373 bool TextObj::HasExtendedBullets()
1375 return mpImplTextObj->mbHasExtendedBullets;
1378 FontCollectionEntry::~FontCollectionEntry()
1382 void FontCollectionEntry::ImplInit( const OUString& rName )
1384 OUString aSubstName( GetSubsFontName( rName, SubsFontFlags::ONLYONE | SubsFontFlags::MS ) );
1385 if ( !aSubstName.isEmpty() )
1387 Name = aSubstName;
1388 bIsConverted = true;
1390 else
1392 Name = rName;
1393 bIsConverted = false;
1397 FontCollection::~FontCollection()
1399 pVDev.disposeAndClear();
1400 xPPTBreakIter = NULL;
1403 FontCollection::FontCollection() :
1404 pVDev ( NULL )
1406 com::sun::star::uno::Reference< com::sun::star::uno::XComponentContext >
1407 xContext = ::comphelper::getProcessComponentContext();
1408 xPPTBreakIter = com::sun::star::i18n::BreakIterator::create( xContext );
1411 short FontCollection::GetScriptDirection( const OUString& rString )
1413 short nRet = ScriptTypeDetector::getScriptDirection( rString, 0, com::sun::star::i18n::ScriptDirection::NEUTRAL );
1414 return nRet;
1417 sal_uInt32 FontCollection::GetId( FontCollectionEntry& rEntry )
1419 if( !rEntry.Name.isEmpty() )
1421 const sal_uInt32 nFonts = maFonts.size();
1423 for( sal_uInt32 i = 0; i < nFonts; i++ )
1425 const FontCollectionEntry* pEntry = GetById( i );
1426 if( pEntry->Name == rEntry.Name )
1427 return i;
1429 vcl::Font aFont;
1430 aFont.SetCharSet( rEntry.CharSet );
1431 aFont.SetName( rEntry.Original );
1432 aFont.SetHeight( 100 );
1434 if ( !pVDev )
1435 pVDev = VclPtr<VirtualDevice>::Create();
1437 pVDev->SetFont( aFont );
1438 FontMetric aMetric( pVDev->GetFontMetric() );
1440 sal_uInt16 nTxtHeight = (sal_uInt16)aMetric.GetAscent() + (sal_uInt16)aMetric.GetDescent();
1442 if ( nTxtHeight )
1444 double fScaling = (double)nTxtHeight / 120.0;
1445 if ( ( fScaling > 0.50 ) && ( fScaling < 1.5 ) )
1446 rEntry.Scaling = fScaling;
1449 maFonts.push_back(new FontCollectionEntry(rEntry));
1450 return nFonts;
1452 return 0;
1455 const FontCollectionEntry* FontCollection::GetById( sal_uInt32 nId )
1457 return nId < maFonts.size() ? &maFonts[nId] : NULL;
1460 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */