bump product version to 4.1.6.2
[LibreOffice.git] / sd / source / filter / eppt / pptx-text.cxx
blobcc0c769acdc91aac6b085e5dfac276a5eebde653
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> // for SubstituteBullet
47 #include <vcl/metric.hxx>
48 #include <vcl/outdev.hxx>
49 #include <vcl/virdev.hxx>
51 com::sun::star::uno::Reference< com::sun::star::i18n::XBreakIterator > xPPTBreakIter;
53 PortionObj::PortionObj( const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > & rXPropSet,
54 FontCollection& rFontCollection ) :
55 mnCharAttrHard ( 0 ),
56 mnCharAttr ( 0 ),
57 mnFont ( 0 ),
58 mnAsianOrComplexFont( 0xffff ),
59 mnTextSize ( 0 ),
60 mbLastPortion ( sal_True ),
61 mpText ( NULL ),
62 mpFieldEntry ( NULL )
64 mXPropSet = rXPropSet;
66 ImplGetPortionValues( rFontCollection, sal_False );
69 PortionObj::PortionObj( ::com::sun::star::uno::Reference< ::com::sun::star::text::XTextRange > & rXTextRange,
70 sal_Bool bLast, FontCollection& rFontCollection ) :
71 mnCharAttrHard ( 0 ),
72 mnCharAttr ( 0 ),
73 mnFont ( 0 ),
74 mnAsianOrComplexFont ( 0xffff ),
75 mbLastPortion ( bLast ),
76 mpText ( NULL ),
77 mpFieldEntry ( NULL )
79 String aString( rXTextRange->getString() );
80 String aURL;
81 sal_Bool bRTL_endingParen = sal_False;
83 mnTextSize = aString.Len();
84 if ( bLast )
85 mnTextSize++;
87 if ( mnTextSize )
89 mpFieldEntry = NULL;
90 sal_uInt32 nFieldType = 0;
92 mXPropSet = ::com::sun::star::uno::Reference<
93 ::com::sun::star::beans::XPropertySet >
94 ( rXTextRange, ::com::sun::star::uno::UNO_QUERY );
95 mXPropState = ::com::sun::star::uno::Reference<
96 ::com::sun::star::beans::XPropertyState >
97 ( rXTextRange, ::com::sun::star::uno::UNO_QUERY );
99 sal_Bool bPropSetsValid = ( mXPropSet.is() && mXPropState.is() );
100 if ( bPropSetsValid )
101 nFieldType = ImplGetTextField( rXTextRange, mXPropSet, aURL );
102 if ( nFieldType )
104 mpFieldEntry = new FieldEntry( nFieldType, 0, mnTextSize );
105 if ( ( nFieldType >> 28 == 4 ) )
107 mpFieldEntry->aRepresentation = aString;
108 mpFieldEntry->aFieldUrl = aURL;
111 sal_Bool bSymbol = sal_False;
113 if ( bPropSetsValid && ImplGetPropertyValue( OUString( "CharFontCharSet" ), sal_False ) )
115 sal_Int16 nCharset = 0;
116 mAny >>= nCharset;
117 if ( nCharset == ::com::sun::star::awt::CharSet::SYMBOL )
118 bSymbol = sal_True;
120 if ( mpFieldEntry && ( nFieldType & 0x800000 ) ) // placeholder ?
122 mnTextSize = 1;
123 if ( bLast )
124 mnTextSize++;
125 mpText = new sal_uInt16[ mnTextSize ];
126 mpText[ 0 ] = 0x2a;
128 else
130 const sal_Unicode* pText = aString.GetBuffer();
131 // For i39516 - a closing parenthesis that ends an RTL string is displayed backwards by PPT
132 // Solution: add a Unicode Right-to-Left Mark, following the method described in i18024
133 if ( bLast && pText[ aString.Len() - 1 ] == sal_Unicode(')') && rFontCollection.GetScriptDirection( aString ) == com::sun::star::i18n::ScriptDirection::RIGHT_TO_LEFT )
135 mnTextSize++;
136 bRTL_endingParen = sal_True;
138 mpText = new sal_uInt16[ mnTextSize ];
139 sal_uInt16 nChar;
140 for ( int i = 0; i < aString.Len(); i++ )
142 nChar = (sal_uInt16)pText[ i ];
143 if ( nChar == 0xa )
144 nChar++;
145 else if ( !bSymbol )
147 switch ( nChar )
149 // Currency
150 case 128: nChar = 0x20AC; break;
151 // Punctuation and other
152 case 130: nChar = 0x201A; break;// SINGLE LOW-9 QUOTATION MARK
153 case 131: nChar = 0x0192; break;// LATIN SMALL LETTER F WITH HOOK
154 case 132: nChar = 0x201E; break;// DOUBLE LOW-9 QUOTATION MARK
155 // LOW DOUBLE PRIME QUOTATION MARK
156 case 133: nChar = 0x2026; break;// HORIZONTAL ELLIPSES
157 case 134: nChar = 0x2020; break;// DAGGER
158 case 135: nChar = 0x2021; break;// DOUBLE DAGGER
159 case 136: nChar = 0x02C6; break;// MODIFIER LETTER CIRCUMFLEX ACCENT
160 case 137: nChar = 0x2030; break;// PER MILLE SIGN
161 case 138: nChar = 0x0160; break;// LATIN CAPITAL LETTER S WITH CARON
162 case 139: nChar = 0x2039; break;// SINGLE LEFT-POINTING ANGLE QUOTATION MARK
163 case 140: nChar = 0x0152; break;// LATIN CAPITAL LIGATURE OE
164 case 142: nChar = 0x017D; break;// LATIN CAPITAL LETTER Z WITH CARON
165 case 145: nChar = 0x2018; break;// LEFT SINGLE QUOTATION MARK
166 // MODIFIER LETTER TURNED COMMA
167 case 146: nChar = 0x2019; break;// RIGHT SINGLE QUOTATION MARK
168 // MODIFIER LETTER APOSTROPHE
169 case 147: nChar = 0x201C; break;// LEFT DOUBLE QUOTATION MARK
170 // REVERSED DOUBLE PRIME QUOTATION MARK
171 case 148: nChar = 0x201D; break;// RIGHT DOUBLE QUOTATION MARK
172 // REVERSED DOUBLE PRIME QUOTATION MARK
173 case 149: nChar = 0x2022; break;// BULLET
174 case 150: nChar = 0x2013; break;// EN DASH
175 case 151: nChar = 0x2014; break;// EM DASH
176 case 152: nChar = 0x02DC; break;// SMALL TILDE
177 case 153: nChar = 0x2122; break;// TRADE MARK SIGN
178 case 154: nChar = 0x0161; break;// LATIN SMALL LETTER S WITH CARON
179 case 155: nChar = 0x203A; break;// SINGLE RIGHT-POINTING ANGLE QUOTATION MARK
180 case 156: nChar = 0x0153; break;// LATIN SMALL LIGATURE OE
181 case 158: nChar = 0x017E; break;// LATIN SMALL LETTER Z WITH CARON
182 case 159: nChar = 0x0178; break;// LATIN CAPITAL LETTER Y WITH DIAERESIS
185 mpText[ i ] = nChar;
188 if ( bRTL_endingParen )
189 mpText[ mnTextSize - 2 ] = 0x200F; // Unicode Right-to-Left mark
191 if ( bLast )
192 mpText[ mnTextSize - 1 ] = 0xd;
194 if ( bPropSetsValid )
195 ImplGetPortionValues( rFontCollection, sal_True );
199 PortionObj::PortionObj( const PortionObj& rPortionObj )
200 : PropStateValue( rPortionObj )
202 ImplConstruct( rPortionObj );
205 PortionObj::~PortionObj()
207 ImplClear();
210 void PortionObj::Write( SvStream* pStrm, sal_Bool bLast )
212 sal_uInt32 nCount = mnTextSize;
213 if ( bLast && mbLastPortion )
214 nCount--;
215 for ( sal_uInt32 i = 0; i < nCount; i++ )
216 *pStrm << (sal_uInt16)mpText[ i ];
219 void PortionObj::ImplGetPortionValues( FontCollection& rFontCollection, sal_Bool bGetPropStateValue )
222 sal_Bool bOk = ImplGetPropertyValue( OUString( "CharFontName" ), bGetPropStateValue );
223 meFontName = ePropState;
224 if ( bOk )
226 FontCollectionEntry aFontDesc( *(OUString*)mAny.getValue() );
227 sal_uInt32 nCount = rFontCollection.GetCount();
228 mnFont = (sal_uInt16)rFontCollection.GetId( aFontDesc );
229 if ( mnFont == nCount )
231 FontCollectionEntry& rFontDesc = rFontCollection.GetLast();
232 if ( ImplGetPropertyValue( OUString( "CharFontCharSet" ), sal_False ) )
233 mAny >>= rFontDesc.CharSet;
234 if ( ImplGetPropertyValue( OUString( "CharFontFamily" ), sal_False ) )
235 mAny >>= rFontDesc.Family;
236 if ( ImplGetPropertyValue( OUString( "CharFontPitch" ), sal_False ) )
237 mAny >>= rFontDesc.Pitch;
241 sal_Int16 nScriptType = SvtLanguageOptions::GetScriptTypeOfLanguage( Application::GetSettings().GetLanguageTag().getLanguageType() );
242 if ( mpText && mnTextSize && xPPTBreakIter.is() )
244 OUString sT( mpText, mnTextSize );
245 nScriptType = xPPTBreakIter->getScriptType( sT, 0 );
247 if ( nScriptType != com::sun::star::i18n::ScriptType::COMPLEX )
249 bOk = ImplGetPropertyValue( OUString( "CharFontNameAsian" ), bGetPropStateValue );
250 meAsianOrComplexFont = ePropState;
251 if ( bOk )
253 FontCollectionEntry aFontDesc( *(OUString*)mAny.getValue() );
254 sal_uInt32 nCount = rFontCollection.GetCount();
255 mnAsianOrComplexFont = (sal_uInt16)rFontCollection.GetId( aFontDesc );
256 if ( mnAsianOrComplexFont == nCount )
258 FontCollectionEntry& rFontDesc = rFontCollection.GetLast();
259 if ( ImplGetPropertyValue( OUString( "CharFontCharSetAsian" ), sal_False ) )
260 mAny >>= rFontDesc.CharSet;
261 if ( ImplGetPropertyValue( OUString( "CharFontFamilyAsian" ), sal_False ) )
262 mAny >>= rFontDesc.Family;
263 if ( ImplGetPropertyValue( OUString( "CharFontPitchAsian" ), sal_False ) )
264 mAny >>= rFontDesc.Pitch;
268 else
270 bOk = ImplGetPropertyValue( OUString( "CharFontNameComplex" ), bGetPropStateValue );
271 meAsianOrComplexFont = ePropState;
272 if ( bOk )
274 FontCollectionEntry aFontDesc( *(OUString*)mAny.getValue() );
275 sal_uInt32 nCount = rFontCollection.GetCount();
276 mnAsianOrComplexFont = (sal_uInt16)rFontCollection.GetId( aFontDesc );
277 if ( mnAsianOrComplexFont == nCount )
279 FontCollectionEntry& rFontDesc = rFontCollection.GetLast();
280 if ( ImplGetPropertyValue( OUString( "CharFontCharSetComplex" ), sal_False ) )
281 mAny >>= rFontDesc.CharSet;
282 if ( ImplGetPropertyValue( OUString( "CharFontFamilyComplex" ), sal_False ) )
283 mAny >>= rFontDesc.Family;
284 if ( ImplGetPropertyValue( OUString( "CharFontPitchComplex" ), sal_False ) )
285 mAny >>= rFontDesc.Pitch;
290 OUString aCharHeightName, aCharWeightName, aCharLocaleName, aCharPostureName;
291 switch( nScriptType )
293 case com::sun::star::i18n::ScriptType::ASIAN :
295 aCharHeightName = "CharHeightAsian";
296 aCharWeightName = "CharWeightAsian";
297 aCharLocaleName = "CharLocaleAsian";
298 aCharPostureName = "CharPostureAsian";
299 break;
301 case com::sun::star::i18n::ScriptType::COMPLEX :
303 aCharHeightName = "CharHeightComplex";
304 aCharWeightName = "CharWeightComplex";
305 aCharLocaleName = "CharLocaleComplex";
306 aCharPostureName = "CharPostureComplex";
307 break;
309 default:
311 aCharHeightName = "CharHeight";
312 aCharWeightName = "CharWeight";
313 aCharLocaleName = "CharLocale";
314 aCharPostureName = "CharPosture";
315 break;
319 mnCharHeight = 24;
320 if ( GetPropertyValue( mAny, mXPropSet, aCharHeightName, sal_False ) )
322 float fVal(0.0);
323 if ( mAny >>= fVal )
325 mnCharHeight = (sal_uInt16)( fVal + 0.5 );
326 meCharHeight = GetPropertyState( mXPropSet, aCharHeightName );
329 if ( GetPropertyValue( mAny, mXPropSet, aCharWeightName, sal_False ) )
331 float fFloat(0.0);
332 if ( mAny >>= fFloat )
334 if ( fFloat >= ::com::sun::star::awt::FontWeight::SEMIBOLD )
335 mnCharAttr |= 1;
336 if ( GetPropertyState( mXPropSet, aCharWeightName ) == ::com::sun::star::beans::PropertyState_DIRECT_VALUE )
337 mnCharAttrHard |= 1;
340 if ( GetPropertyValue( mAny, mXPropSet, aCharLocaleName, sal_False ) )
342 com::sun::star::lang::Locale eLocale;
343 if ( mAny >>= eLocale )
344 meCharLocale = eLocale;
346 if ( GetPropertyValue( mAny, mXPropSet, aCharPostureName, sal_False ) )
348 ::com::sun::star::awt::FontSlant aFS;
349 if ( mAny >>= aFS )
351 switch( aFS )
353 case ::com::sun::star::awt::FontSlant_OBLIQUE :
354 case ::com::sun::star::awt::FontSlant_ITALIC :
355 mnCharAttr |= 2;
356 break;
357 default:
358 break;
360 if ( GetPropertyState( mXPropSet, aCharPostureName ) == ::com::sun::star::beans::PropertyState_DIRECT_VALUE )
361 mnCharAttrHard |= 2;
365 if ( ImplGetPropertyValue( OUString( "CharUnderline" ), bGetPropStateValue ) )
367 sal_Int16 nVal(0);
368 mAny >>= nVal;
369 switch ( nVal )
371 case ::com::sun::star::awt::FontUnderline::SINGLE :
372 case ::com::sun::star::awt::FontUnderline::DOUBLE :
373 case ::com::sun::star::awt::FontUnderline::DOTTED :
374 mnCharAttr |= 4;
377 if ( ePropState == ::com::sun::star::beans::PropertyState_DIRECT_VALUE )
378 mnCharAttrHard |= 4;
380 if ( ImplGetPropertyValue( OUString( "CharShadowed" ), bGetPropStateValue ) )
382 sal_Bool bBool(sal_False);
383 mAny >>= bBool;
384 if ( bBool )
385 mnCharAttr |= 0x10;
387 if ( ePropState == ::com::sun::star::beans::PropertyState_DIRECT_VALUE )
388 mnCharAttrHard |= 16;
390 if ( ImplGetPropertyValue( OUString( "CharRelief" ), bGetPropStateValue ) )
392 sal_Int16 nVal(0);
393 mAny >>= nVal;
394 if ( nVal != ::com::sun::star::text::FontRelief::NONE )
395 mnCharAttr |= 512;
397 if ( ePropState == ::com::sun::star::beans::PropertyState_DIRECT_VALUE )
398 mnCharAttrHard |= 512;
400 if ( ImplGetPropertyValue( OUString( "CharColor" ), bGetPropStateValue ) )
402 sal_uInt32 nSOColor = *( (sal_uInt32*)mAny.getValue() );
403 mnCharColor = nSOColor & 0xff00ff00; // green and hibyte
404 mnCharColor |= (sal_uInt8)( nSOColor ) << 16; // red and blue is switched
405 mnCharColor |= (sal_uInt8)( nSOColor >> 16 );
407 meCharColor = ePropState;
409 mnCharEscapement = 0;
410 if ( ImplGetPropertyValue( OUString( "CharEscapement" ), bGetPropStateValue ) )
412 mAny >>= mnCharEscapement;
413 if ( mnCharEscapement > 100 )
414 mnCharEscapement = 33;
415 else if ( mnCharEscapement < -100 )
416 mnCharEscapement = -33;
418 meCharEscapement = ePropState;
421 void PortionObj::ImplClear()
423 delete (FieldEntry*)mpFieldEntry;
424 delete[] mpText;
427 void PortionObj::ImplConstruct( const PortionObj& rPortionObj )
429 mbLastPortion = rPortionObj.mbLastPortion;
430 mnTextSize = rPortionObj.mnTextSize;
431 mnCharColor = rPortionObj.mnCharColor;
432 mnCharEscapement = rPortionObj.mnCharEscapement;
433 mnCharAttr = rPortionObj.mnCharAttr;
434 mnCharHeight = rPortionObj.mnCharHeight;
435 mnFont = rPortionObj.mnFont;
436 mnAsianOrComplexFont = rPortionObj.mnAsianOrComplexFont;
438 if ( rPortionObj.mpText )
440 mpText = new sal_uInt16[ mnTextSize ];
441 memcpy( mpText, rPortionObj.mpText, mnTextSize << 1 );
443 else
444 mpText = NULL;
446 if ( rPortionObj.mpFieldEntry )
447 mpFieldEntry = new FieldEntry( *( rPortionObj.mpFieldEntry ) );
448 else
449 mpFieldEntry = NULL;
452 sal_uInt32 PortionObj::ImplCalculateTextPositions( sal_uInt32 nCurrentTextPosition )
454 if ( mpFieldEntry && ( !mpFieldEntry->nFieldStartPos ) )
456 mpFieldEntry->nFieldStartPos += nCurrentTextPosition;
457 mpFieldEntry->nFieldEndPos += nCurrentTextPosition;
459 return mnTextSize;
462 // -----------------------------------------------------------------------
463 // Return: 0 = no TextField
464 // bit28->31 text field type :
465 // 1 = Date
466 // 2 = Time
467 // 3 = SlideNumber
468 // 4 = Url
469 // 5 = DateTime
470 // 6 = header
471 // 7 = footer
472 // bit24->27 text field sub type (optional)
473 // 23-> PPT Textfield needs a placeholder
475 sal_uInt32 PortionObj::ImplGetTextField( ::com::sun::star::uno::Reference< ::com::sun::star::text::XTextRange > & ,
476 const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > & rXPropSet, String& rURL )
478 sal_uInt32 nRetValue = 0;
479 sal_Int32 nFormat;
480 ::com::sun::star::uno::Any aAny;
481 if ( GetPropertyValue( aAny, rXPropSet, OUString( "TextPortionType" ), sal_True ) )
483 OUString aTextFieldType( *(OUString*)aAny.getValue() );
484 if ( aTextFieldType == "TextField" )
486 if ( GetPropertyValue( aAny, rXPropSet, aTextFieldType, sal_True ) )
488 ::com::sun::star::uno::Reference< ::com::sun::star::text::XTextField > aXTextField;
489 if ( aAny >>= aXTextField )
491 if ( aXTextField.is() )
493 ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet >
494 xFieldPropSet( aXTextField, ::com::sun::star::uno::UNO_QUERY );
495 if ( xFieldPropSet.is() )
497 OUString aFieldKind( aXTextField->getPresentation( sal_True ) );
498 if ( aFieldKind == "Date" )
500 if ( GetPropertyValue( aAny, xFieldPropSet, OUString( "IsFix" ) ), sal_True )
502 sal_Bool bBool = sal_False;
503 aAny >>= bBool;
504 if ( !bBool ) // Fixed DateFields does not exist in PPT
506 if ( GetPropertyValue( aAny, xFieldPropSet, OUString( "Format" ) ), sal_True )
508 nFormat = *(sal_Int32*)aAny.getValue();
509 switch ( nFormat )
511 default:
512 case 5 :
513 case 4 :
514 case 2 : nFormat = 0; break;
515 case 8 :
516 case 9 :
517 case 3 : nFormat = 1; break;
518 case 7 :
519 case 6 : nFormat = 2; break;
521 nRetValue |= ( ( ( 1 << 4 ) | nFormat ) << 24 ) | 0x800000;
526 else if ( aFieldKind == "URL" )
528 if ( GetPropertyValue( aAny, xFieldPropSet, OUString( "URL" ) ), sal_True )
529 rURL = String( *(OUString*)aAny.getValue() );
530 nRetValue = 4 << 28;
532 else if ( aFieldKind == "Page" )
534 nRetValue = 3 << 28 | 0x800000;
536 else if ( aFieldKind == "Pages" )
540 else if ( aFieldKind == "Time" )
542 if ( GetPropertyValue( aAny, xFieldPropSet, OUString( "IsFix" ) ), sal_True )
544 sal_Bool bBool = sal_False;
545 aAny >>= bBool;
546 if ( !bBool )
548 if ( GetPropertyValue( aAny, xFieldPropSet, OUString( "IsFix" ) ), sal_True )
550 nFormat = *(sal_Int32*)aAny.getValue();
551 nRetValue |= ( ( ( 2 << 4 ) | nFormat ) << 24 ) | 0x800000;
556 else if ( aFieldKind == "File" )
560 else if ( aFieldKind == "Table" )
564 else if ( aFieldKind == "ExtTime" )
566 if ( GetPropertyValue( aAny, xFieldPropSet, OUString( "IsFix" ) ), sal_True )
568 sal_Bool bBool = sal_False;
569 aAny >>= bBool;
570 if ( !bBool )
572 if ( GetPropertyValue( aAny, xFieldPropSet, OUString( "Format" ) ), sal_True )
574 nFormat = *(sal_Int32*)aAny.getValue();
575 switch ( nFormat )
577 default:
578 case 6 :
579 case 7 :
580 case 8 :
581 case 2 : nFormat = 12; break;
582 case 3 : nFormat = 9; break;
583 case 5 :
584 case 4 : nFormat = 10; break;
587 nRetValue |= ( ( ( 2 << 4 ) | nFormat ) << 24 ) | 0x800000;
592 else if ( aFieldKind == "ExtFile" )
596 else if ( aFieldKind == "Author" )
600 else if ( aFieldKind == "DateTime" )
602 nRetValue = 5 << 28 | 0x800000;
604 else if ( aFieldKind == "Header" )
606 nRetValue = 6 << 28 | 0x800000;
608 else if ( aFieldKind == "Footer" )
610 nRetValue = 7 << 28 | 0x800000;
618 return nRetValue;
621 PortionObj& PortionObj::operator=( const PortionObj& rPortionObj )
623 if ( this != &rPortionObj )
625 ImplClear();
626 ImplConstruct( rPortionObj );
628 return *this;
631 ParagraphObj::ParagraphObj(const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > & rXPropSet,
632 PPTExBulletProvider& rProv)
633 : maMapModeSrc(MAP_100TH_MM)
634 , maMapModeDest(MAP_INCH, Point(), Fraction( 1, 576 ), Fraction( 1, 576 ))
635 , mnTextSize(0)
636 , mbFirstParagraph(false)
637 , mbLastParagraph(false)
638 , mnTextAdjust(0)
639 , mnLineSpacing(0)
640 , mbFixedLineSpacing(false)
641 , mnLineSpacingTop(0)
642 , mnLineSpacingBottom(0)
643 , mbForbiddenRules(false)
644 , mbParagraphPunctation(false)
645 , mnBiDi(0)
647 mXPropSet = rXPropSet;
649 bExtendedParameters = sal_False;
651 nDepth = 0;
652 nBulletFlags = 0;
653 nParaFlags = 0;
655 ImplGetParagraphValues( rProv, sal_False );
658 ParagraphObj::ParagraphObj(::com::sun::star::uno::Reference< ::com::sun::star::text::XTextContent > & rXTextContent,
659 ParaFlags aParaFlags, FontCollection& rFontCollection, PPTExBulletProvider& rProv )
660 : maMapModeSrc(MAP_100TH_MM)
661 , maMapModeDest(MAP_INCH, Point(), Fraction( 1, 576 ), Fraction( 1, 576 ))
662 , mnTextSize(0)
663 , mbIsBullet(false)
664 , mbFirstParagraph( aParaFlags.bFirstParagraph )
665 , mbLastParagraph( aParaFlags.bLastParagraph )
666 , mnTextAdjust(0)
667 , mnLineSpacing(0)
668 , mbFixedLineSpacing(false)
669 , mnLineSpacingTop(0)
670 , mnLineSpacingBottom(0)
671 , mbForbiddenRules(false)
672 , mbParagraphPunctation(false)
673 , mnBiDi(0)
675 bExtendedParameters = sal_False;
677 nDepth = 0;
678 nBulletFlags = 0;
679 nParaFlags = 0;
681 mXPropSet = ::com::sun::star::uno::Reference<
682 ::com::sun::star::beans::XPropertySet >
683 ( rXTextContent, ::com::sun::star::uno::UNO_QUERY );
685 mXPropState = ::com::sun::star::uno::Reference<
686 ::com::sun::star::beans::XPropertyState >
687 ( rXTextContent, ::com::sun::star::uno::UNO_QUERY );
689 if ( mXPropSet.is() && mXPropState.is() )
691 ::com::sun::star::uno::Reference< ::com::sun::star::container::XEnumerationAccess >
692 aXTextPortionEA( rXTextContent, ::com::sun::star::uno::UNO_QUERY );
693 if ( aXTextPortionEA.is() )
695 ::com::sun::star::uno::Reference< ::com::sun::star::container::XEnumeration >
696 aXTextPortionE( aXTextPortionEA->createEnumeration() );
697 if ( aXTextPortionE.is() )
699 while ( aXTextPortionE->hasMoreElements() )
701 ::com::sun::star::uno::Reference< ::com::sun::star::text::XTextRange > aXCursorText;
702 ::com::sun::star::uno::Any aAny( aXTextPortionE->nextElement() );
703 if ( aAny >>= aXCursorText )
705 PortionObj* pPortionObj = new PortionObj( aXCursorText, !aXTextPortionE->hasMoreElements(), rFontCollection );
706 if ( pPortionObj->Count() )
707 push_back( pPortionObj );
708 else
709 delete pPortionObj;
714 ImplGetParagraphValues( rProv, sal_True );
718 ParagraphObj::ParagraphObj( const ParagraphObj& rObj )
719 : std::vector<PortionObj*>()
720 , PropStateValue()
721 , SOParagraph()
723 ImplConstruct( rObj );
726 ParagraphObj::~ParagraphObj()
728 ImplClear();
731 void ParagraphObj::Write( SvStream* pStrm )
733 for ( const_iterator it = begin(); it != end(); ++it )
734 (*it)->Write( pStrm, mbLastParagraph );
737 void ParagraphObj::ImplClear()
739 for ( const_iterator it = begin(); it != end(); ++it )
740 delete *it;
743 void ParagraphObj::CalculateGraphicBulletSize( sal_uInt16 nFontHeight )
745 if ( ( (SvxExtNumType)nNumberingType == SVX_NUM_BITMAP ) && ( nBulletId != 0xffff ) )
747 // calculate the bulletrealsize for this grafik
748 if ( aBuGraSize.Width() && aBuGraSize.Height() )
750 double fCharHeight = nFontHeight;
751 double fLen = aBuGraSize.Height();
752 fCharHeight = fCharHeight * 0.2540;
753 double fQuo = fLen / fCharHeight;
754 nBulletRealSize = (sal_Int16)( fQuo + 0.5 );
755 if ( (sal_uInt16)nBulletRealSize > 400 )
756 nBulletRealSize = 400;
761 void ParagraphObj::ImplGetNumberingLevel( PPTExBulletProvider& rBuProv, sal_Int16 nNumberingDepth, sal_Bool bIsBullet, sal_Bool bGetPropStateValue )
763 ::com::sun::star::uno::Any aAny;
764 if ( GetPropertyValue( aAny, mXPropSet, OUString( "ParaLeftMargin" ) ) )
766 sal_Int32 nVal(0);
767 if ( aAny >>= nVal )
768 nTextOfs = static_cast< sal_Int16 >( nVal / ( 2540.0 / 576 ) + 0.5 ) ;
770 if ( GetPropertyValue( aAny, mXPropSet, OUString( "ParaFirstLineIndent" ) ) )
772 if ( aAny >>= nBulletOfs )
773 nBulletOfs = static_cast< sal_Int32 >( nBulletOfs / ( 2540.0 / 576 ) + 0.5 );
775 if ( GetPropertyValue( aAny, mXPropSet, OUString( "NumberingIsNumber" ) ) )
776 aAny >>= bNumberingIsNumber;
778 ::com::sun::star::uno::Reference< ::com::sun::star::container::XIndexReplace > aXIndexReplace;
780 if ( bIsBullet && ImplGetPropertyValue( OUString( "NumberingRules" ), bGetPropStateValue ) )
782 if ( ( mAny >>= aXIndexReplace ) && nNumberingDepth < aXIndexReplace->getCount() )
784 mAny <<= aXIndexReplace->getByIndex( nNumberingDepth );
785 ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue>
786 aPropertySequence( *( ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue>*)mAny.getValue() );
788 const ::com::sun::star::beans::PropertyValue* pPropValue = aPropertySequence.getArray();
790 sal_Int32 nPropertyCount = aPropertySequence.getLength();
791 if ( nPropertyCount )
793 bExtendedParameters = sal_True;
794 nBulletRealSize = 100;
795 nMappedNumType = 0;
797 String aGraphicURL;
798 for ( sal_Int32 i = 0; i < nPropertyCount; i++ )
800 const void* pValue = pPropValue[ i ].Value.getValue();
801 if ( pValue )
803 OUString aPropName( pPropValue[ i ].Name );
804 if ( aPropName == "NumberingType" )
805 nNumberingType = *( (sal_Int16*)pValue );
806 else if ( aPropName == "Adjust" )
807 nHorzAdjust = *( (sal_Int16*)pValue );
808 else if ( aPropName == "BulletChar" )
810 OUString aString( *( (OUString*)pValue ) );
811 if ( !aString.isEmpty() )
812 cBulletId = aString[ 0 ];
814 else if ( aPropName == "BulletFont" )
816 aFontDesc = *( (::com::sun::star::awt::FontDescriptor*)pValue );
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 documemts I added this two lines
821 // which fixes the bullet problem for the export.
822 if ( aFontDesc.Name == "StarSymbol" )
823 aFontDesc.CharSet = RTL_TEXTENCODING_MS_1252;
826 else if ( aPropName == "GraphicURL" )
827 aGraphicURL = ( *(OUString*)pValue );
828 else if ( aPropName == "GraphicSize" )
830 if ( pPropValue[ i ].Value.getValueType() == ::getCppuType( (::com::sun::star::awt::Size*)0) )
832 // don't cast awt::Size to Size as on 64-bits they are not the same.
833 ::com::sun::star::awt::Size aSize;
834 pPropValue[ i ].Value >>= aSize;
835 aBuGraSize.A() = aSize.Width;
836 aBuGraSize.B() = aSize.Height;
839 else if ( aPropName == "StartWith" )
840 nStartWith = *( (sal_Int16*)pValue );
841 else if ( aPropName == "LeftMargin" )
842 nTextOfs = nTextOfs + static_cast< sal_Int16 >( *( (sal_Int32*)pValue ) / ( 2540.0 / 576 ) );
843 else if ( aPropName == "FirstLineOffset" )
844 nBulletOfs += (sal_Int16)( *( (sal_Int32*)pValue ) / ( 2540.0 / 576 ) );
845 else if ( aPropName == "BulletColor" )
847 sal_uInt32 nSOColor = *( (sal_uInt32*)pValue );
848 nBulletColor = nSOColor & 0xff00ff00; // green and hibyte
849 nBulletColor |= (sal_uInt8)( nSOColor ) << 16; // red
850 nBulletColor |= (sal_uInt8)( nSOColor >> 16 ) | 0xfe000000; // blue
852 else if ( aPropName == "BulletRelSize" )
854 nBulletRealSize = *( (sal_Int16*)pValue );
855 nParaFlags |= 0x40;
856 nBulletFlags |= 8;
858 else if ( aPropName == "Prefix" )
859 sPrefix = ( *(OUString*)pValue );
860 else if ( aPropName == "Suffix" )
861 sSuffix = ( *(OUString*)pValue );
862 #ifdef DBG_UTIL
863 else if ( ! (
864 ( aPropName == "SymbolTextDistance" )
865 || ( aPropName == "Graphic" ) ) )
867 OSL_FAIL( "Unknown Property" );
869 #endif
873 if ( aGraphicURL.Len() )
875 if ( aBuGraSize.Width() && aBuGraSize.Height() )
877 xub_StrLen nIndex = aGraphicURL.Search( (sal_Unicode)':', 0 );
878 if ( nIndex != STRING_NOTFOUND )
880 nIndex++;
881 if ( aGraphicURL.Len() > nIndex )
883 OString aUniqueId(OUStringToOString(aGraphicURL.Copy(nIndex, aGraphicURL.Len() - nIndex), RTL_TEXTENCODING_UTF8));
884 if ( !aUniqueId.isEmpty() )
886 nBulletId = rBuProv.GetId( aUniqueId, aBuGraSize );
887 if ( nBulletId != 0xffff )
888 bExtendedBulletsUsed = sal_True;
893 else
895 nNumberingType = SVX_NUM_NUMBER_NONE;
899 PortionObj* pPortion = front();
900 CalculateGraphicBulletSize( ( pPortion ) ? pPortion->mnCharHeight : 24 );
902 switch( nNumberingType )
904 case SVX_NUM_NUMBER_NONE : nParaFlags |= 0xf; break;
906 case SVX_NUM_CHAR_SPECIAL : // Bullet
908 if ( aFontDesc.Name.equals("starsymbol") || aFontDesc.Name.equals("opensymbol") )
910 rtl_TextEncoding eChrSet = aFontDesc.CharSet;
911 cBulletId = msfilter::util::bestFitOpenSymbolToMSFont(cBulletId, eChrSet, aFontDesc.Name);
912 aFontDesc.CharSet = eChrSet;
915 if ( !aFontDesc.Name.isEmpty() )
917 nParaFlags |= 0x90; // we define the font and charset
920 case SVX_NUM_CHARS_UPPER_LETTER : // count from a-z, aa - az, ba - bz, ...
921 case SVX_NUM_CHARS_LOWER_LETTER :
922 case SVX_NUM_ROMAN_UPPER :
923 case SVX_NUM_ROMAN_LOWER :
924 case SVX_NUM_ARABIC :
925 case SVX_NUM_PAGEDESC : // numbering from the page template
926 case SVX_NUM_BITMAP :
927 case SVX_NUM_CHARS_UPPER_LETTER_N : // count from a-z, aa-zz, aaa-zzz
928 case SVX_NUM_CHARS_LOWER_LETTER_N :
929 case SVX_NUM_NUMBER_UPPER_ZH:
930 case SVX_NUM_CIRCLE_NUMBER:
931 case SVX_NUM_NUMBER_UPPER_ZH_TW:
932 case SVX_NUM_NUMBER_LOWER_ZH:
933 case SVX_NUM_FULL_WIDTH_ARABIC:
935 if ( nNumberingType != SVX_NUM_CHAR_SPECIAL )
937 bExtendedBulletsUsed = sal_True;
938 if ( nNumberingDepth & 1 )
939 cBulletId = 0x2013; // defaulting bullet characters for ppt97
940 else if ( nNumberingDepth == 4 )
941 cBulletId = 0xbb;
942 else
943 cBulletId = 0x2022;
945 switch( (SvxExtNumType)nNumberingType )
947 case SVX_NUM_CHARS_UPPER_LETTER :
948 case SVX_NUM_CHARS_UPPER_LETTER_N :
950 if ( sSuffix == String( RTL_CONSTASCII_USTRINGPARAM( ")" ) ) )
952 if ( sPrefix == String( RTL_CONSTASCII_USTRINGPARAM( "(" ) ) )
953 nMappedNumType = 0xa0001; // (A)
954 else
955 nMappedNumType = 0xb0001; // A)
957 else
958 nMappedNumType = 0x10001; // A.
960 break;
961 case SVX_NUM_CHARS_LOWER_LETTER :
962 case SVX_NUM_CHARS_LOWER_LETTER_N :
964 if ( sSuffix == String( RTL_CONSTASCII_USTRINGPARAM( ")" ) ) )
966 if ( sPrefix == String( RTL_CONSTASCII_USTRINGPARAM( "(" ) ) )
967 nMappedNumType = 0x80001; // (a)
968 else
969 nMappedNumType = 0x90001; // a)
971 else
972 nMappedNumType = 0x00001; // a.
974 break;
975 case SVX_NUM_ROMAN_UPPER :
977 if ( sSuffix == String( RTL_CONSTASCII_USTRINGPARAM( ")" ) ) )
979 if ( sPrefix == String( RTL_CONSTASCII_USTRINGPARAM( "(" ) ) )
980 nMappedNumType = 0xe0001; // (I)
981 else
982 nMappedNumType = 0xf0001; // I)
984 else
985 nMappedNumType = 0x70001; // I.
987 break;
988 case SVX_NUM_ROMAN_LOWER :
990 if ( sSuffix == String( RTL_CONSTASCII_USTRINGPARAM( ")" ) ) )
992 if ( sPrefix == String( RTL_CONSTASCII_USTRINGPARAM( "(" ) ) )
993 nMappedNumType = 0x40001; // (i)
994 else
995 nMappedNumType = 0x50001; // i)
997 else
998 nMappedNumType = 0x60001; // i.
1000 break;
1001 case SVX_NUM_ARABIC :
1003 if ( sSuffix == String( RTL_CONSTASCII_USTRINGPARAM( ")" ) ) )
1005 if ( sPrefix == String( RTL_CONSTASCII_USTRINGPARAM( "(" ) ) )
1006 nMappedNumType = 0xc0001; // (1)
1007 else
1008 nMappedNumType = 0x20001; // 1)
1010 else
1012 if ( ! ( sSuffix.Len() + sPrefix.Len() ) )
1013 nMappedNumType = 0xd0001; // 1
1014 else
1015 nMappedNumType = 0x30001; // 1.
1018 break;
1019 case SVX_NUM_NUMBER_UPPER_ZH :
1021 if ( sSuffix.Len() )
1022 nMappedNumType = 0x110001; // Simplified Chinese with single-byte period.
1023 else
1024 nMappedNumType = 0x100001; // Simplified Chinese.
1026 break;
1027 case SVX_NUM_CIRCLE_NUMBER :
1029 nMappedNumType = 0x120001; // Double byte circle numbers.
1031 break;
1032 case SVX_NUM_NUMBER_UPPER_ZH_TW :
1034 if ( sSuffix.Len() )
1035 nMappedNumType = 0x160001; // Traditional Chinese with single-byte period.
1036 else
1037 nMappedNumType = 0x150001; // Traditional Chinese.
1039 break;
1040 case SVX_NUM_NUMBER_LOWER_ZH :
1042 if ( sSuffix == OUString( sal_Unicode(0xff0e)) )
1043 nMappedNumType = 0x260001; // Japanese with double-byte period.
1044 else if ( sSuffix.Len() )
1045 nMappedNumType = 0x1B0001; // Japanese/Korean with single-byte period.
1046 else
1047 nMappedNumType = 0x1A0001; // Japanese/Korean.
1049 break;
1050 case SVX_NUM_FULL_WIDTH_ARABIC :
1052 if ( sSuffix.Len() )
1053 nMappedNumType = 0x1D0001; // Double-byte Arabic numbers with double-byte period.
1054 else
1055 nMappedNumType = 0x1C0001; // Double-byte Arabic numbers.
1057 break;
1058 default:
1059 break;
1062 nParaFlags |= 0x2f;
1063 nBulletFlags |= 6;
1064 if ( mbIsBullet && bNumberingIsNumber )
1065 nBulletFlags |= 1;
1071 nBulletOfs = nTextOfs + nBulletOfs;
1072 if ( nBulletOfs < 0 )
1073 nBulletOfs = 0;
1076 void ParagraphObj::ImplGetParagraphValues( PPTExBulletProvider& rBuProv, sal_Bool bGetPropStateValue )
1078 static String sNumberingLevel ( RTL_CONSTASCII_USTRINGPARAM( "NumberingLevel" ) );
1080 ::com::sun::star::uno::Any aAny;
1081 if ( GetPropertyValue( aAny, mXPropSet, sNumberingLevel, sal_True ) )
1083 if ( bGetPropStateValue )
1084 meBullet = GetPropertyState( mXPropSet, sNumberingLevel );
1085 nDepth = *( (sal_Int16*)aAny.getValue() );
1087 if ( nDepth < 0 )
1089 mbIsBullet = sal_False;
1090 nDepth = 0;
1092 else
1094 if ( nDepth > 4 )
1095 nDepth = 4;
1096 mbIsBullet = sal_True;
1099 else
1101 nDepth = 0;
1102 mbIsBullet = sal_False;
1104 ImplGetNumberingLevel( rBuProv, nDepth, mbIsBullet, bGetPropStateValue );
1106 if ( ImplGetPropertyValue( OUString( "ParaTabStops" ), bGetPropStateValue ) )
1107 maTabStop = *( ::com::sun::star::uno::Sequence< ::com::sun::star::style::TabStop>*)mAny.getValue();
1108 sal_Int16 eTextAdjust( ::com::sun::star::style::ParagraphAdjust_LEFT );
1109 if ( GetPropertyValue( aAny, mXPropSet, OUString( "ParaAdjust" ), bGetPropStateValue ) )
1110 aAny >>= eTextAdjust;
1111 switch ( (::com::sun::star::style::ParagraphAdjust)eTextAdjust )
1113 case ::com::sun::star::style::ParagraphAdjust_CENTER :
1114 mnTextAdjust = 1;
1115 break;
1116 case ::com::sun::star::style::ParagraphAdjust_RIGHT :
1117 mnTextAdjust = 2;
1118 break;
1119 case ::com::sun::star::style::ParagraphAdjust_BLOCK :
1120 mnTextAdjust = 3;
1121 break;
1122 default :
1123 case ::com::sun::star::style::ParagraphAdjust_LEFT :
1124 mnTextAdjust = 0;
1125 break;
1127 meTextAdjust = ePropState;
1129 if ( ImplGetPropertyValue( OUString( "ParaLineSpacing" ), bGetPropStateValue ) )
1131 ::com::sun::star::style::LineSpacing aLineSpacing
1132 = *( (::com::sun::star::style::LineSpacing*)mAny.getValue() );
1133 switch ( aLineSpacing.Mode )
1135 case ::com::sun::star::style::LineSpacingMode::FIX :
1136 mnLineSpacing = (sal_Int16)(-( aLineSpacing.Height ) );
1137 mbFixedLineSpacing = sal_True;
1138 break;
1139 case ::com::sun::star::style::LineSpacingMode::MINIMUM :
1140 case ::com::sun::star::style::LineSpacingMode::LEADING :
1141 mnLineSpacing = (sal_Int16)(-( aLineSpacing.Height ) );
1142 mbFixedLineSpacing = sal_False;
1143 break;
1145 case ::com::sun::star::style::LineSpacingMode::PROP :
1146 default:
1147 mnLineSpacing = (sal_Int16)( aLineSpacing.Height );
1148 break;
1151 meLineSpacing = ePropState;
1153 if ( ImplGetPropertyValue( OUString( "ParaBottomMargin" ), bGetPropStateValue ) )
1155 double fSpacing = *( (sal_uInt32*)mAny.getValue() ) + ( 2540.0 / 576.0 ) - 1;
1156 mnLineSpacingBottom = (sal_Int16)(-( fSpacing * 576.0 / 2540.0 ) );
1158 meLineSpacingBottom = ePropState;
1160 if ( ImplGetPropertyValue( OUString( "ParaTopMargin" ), bGetPropStateValue ) )
1162 double fSpacing = *( (sal_uInt32*)mAny.getValue() ) + ( 2540.0 / 576.0 ) - 1;
1163 mnLineSpacingTop = (sal_Int16)(-( fSpacing * 576.0 / 2540.0 ) );
1165 meLineSpacingTop = ePropState;
1167 if ( ImplGetPropertyValue( OUString( "ParaIsForbiddenRules" ), bGetPropStateValue ) )
1168 mAny >>= mbForbiddenRules;
1169 meForbiddenRules = ePropState;
1171 if ( ImplGetPropertyValue( OUString( "ParaIsHangingPunctuation" ), bGetPropStateValue ) )
1172 mAny >>= mbParagraphPunctation;
1173 meParagraphPunctation = ePropState;
1175 mnBiDi = 0;
1176 if ( ImplGetPropertyValue( OUString( "WritingMode" ), bGetPropStateValue ) )
1178 sal_Int16 nWritingMode = 0;
1179 mAny >>= nWritingMode;
1181 SvxFrameDirection eWritingMode( (SvxFrameDirection)nWritingMode );
1182 if ( ( eWritingMode == FRMDIR_HORI_RIGHT_TOP )
1183 || ( eWritingMode == FRMDIR_VERT_TOP_RIGHT ) )
1185 mnBiDi = 1;
1188 meBiDi = ePropState;
1191 void ParagraphObj::ImplConstruct( const ParagraphObj& rParagraphObj )
1193 mnTextSize = rParagraphObj.mnTextSize;
1194 mnTextAdjust = rParagraphObj.mnTextAdjust;
1195 mnLineSpacing = rParagraphObj.mnLineSpacing;
1196 mnLineSpacingTop = rParagraphObj.mnLineSpacingTop;
1197 mnLineSpacingBottom = rParagraphObj.mnLineSpacingBottom;
1198 mbFirstParagraph = rParagraphObj.mbFirstParagraph;
1199 mbLastParagraph = rParagraphObj.mbLastParagraph;
1200 mbParagraphPunctation = rParagraphObj.mbParagraphPunctation;
1201 mbForbiddenRules = rParagraphObj.mbForbiddenRules;
1202 mnBiDi = rParagraphObj.mnBiDi;
1204 for ( ParagraphObj::const_iterator it = rParagraphObj.begin(); it != rParagraphObj.end(); ++it )
1205 push_back( new PortionObj( **it ) );
1207 maTabStop = rParagraphObj.maTabStop;
1208 bExtendedParameters = rParagraphObj.bExtendedParameters;
1209 nParaFlags = rParagraphObj.nParaFlags;
1210 nBulletFlags = rParagraphObj.nBulletFlags;
1211 sPrefix = rParagraphObj.sPrefix;
1212 sSuffix = rParagraphObj.sSuffix;
1213 sGraphicUrl = rParagraphObj.sGraphicUrl; // String to a graphic
1214 aBuGraSize = rParagraphObj.aBuGraSize;
1215 nNumberingType = rParagraphObj.nNumberingType; // this is actually a SvxEnum
1216 nHorzAdjust = rParagraphObj.nHorzAdjust;
1217 nBulletColor = rParagraphObj.nBulletColor;
1218 nBulletOfs = rParagraphObj.nBulletOfs;
1219 nStartWith = rParagraphObj.nStartWith; // start of numbering
1220 nTextOfs = rParagraphObj.nTextOfs;
1221 nBulletRealSize = rParagraphObj.nBulletRealSize; // scale in percent
1222 nDepth = rParagraphObj.nDepth; // actual depth
1223 cBulletId = rParagraphObj.cBulletId; // if Numbering Type == CharSpecial
1224 aFontDesc = rParagraphObj.aFontDesc;
1226 bExtendedBulletsUsed = rParagraphObj.bExtendedBulletsUsed;
1227 nBulletId = rParagraphObj.nBulletId;
1230 sal_uInt32 ParagraphObj::ImplCalculateTextPositions( sal_uInt32 nCurrentTextPosition )
1232 mnTextSize = 0;
1233 for ( const_iterator it = begin(); it != end(); ++it )
1234 mnTextSize += (*it)->ImplCalculateTextPositions( nCurrentTextPosition + mnTextSize );
1235 return mnTextSize;
1238 ParagraphObj& ParagraphObj::operator=( const ParagraphObj& rParagraphObj )
1240 if ( this != &rParagraphObj )
1242 ImplClear();
1243 ImplConstruct( rParagraphObj );
1245 return *this;
1248 struct ImplTextObj
1250 sal_uInt32 mnTextSize;
1251 int mnInstance;
1252 std::vector<ParagraphObj*> maList;
1253 sal_Bool mbHasExtendedBullets;
1254 sal_Bool mbFixedCellHeightUsed;
1256 ImplTextObj( int nInstance );
1257 ~ImplTextObj();
1260 ImplTextObj::ImplTextObj( int nInstance )
1261 : maList()
1263 mnTextSize = 0;
1264 mnInstance = nInstance;
1265 mbHasExtendedBullets = sal_False;
1266 mbFixedCellHeightUsed = sal_False;
1269 ImplTextObj::~ImplTextObj()
1271 for ( std::vector<ParagraphObj*>::const_iterator it = maList.begin(); it != maList.end(); ++it )
1272 delete *it;
1275 TextObj::TextObj( ::com::sun::star::uno::Reference< ::com::sun::star::text::XSimpleText > & rXTextRef,
1276 int nInstance, FontCollection& rFontCollection, PPTExBulletProvider& rProv ):
1277 mpImplTextObj(new ImplTextObj(nInstance))
1279 ::com::sun::star::uno::Reference< ::com::sun::star::container::XEnumerationAccess >
1280 aXTextParagraphEA( rXTextRef, ::com::sun::star::uno::UNO_QUERY );
1282 if ( aXTextParagraphEA.is() )
1284 ::com::sun::star::uno::Reference< ::com::sun::star::container::XEnumeration >
1285 aXTextParagraphE( aXTextParagraphEA->createEnumeration() );
1286 if ( aXTextParagraphE.is() )
1288 ParaFlags aParaFlags;
1289 while ( aXTextParagraphE->hasMoreElements() )
1291 ::com::sun::star::uno::Reference< ::com::sun::star::text::XTextContent > aXParagraph;
1292 ::com::sun::star::uno::Any aAny( aXTextParagraphE->nextElement() );
1293 if ( aAny >>= aXParagraph )
1295 if ( !aXTextParagraphE->hasMoreElements() )
1296 aParaFlags.bLastParagraph = sal_True;
1297 ParagraphObj* pPara = new ParagraphObj( aXParagraph, aParaFlags, rFontCollection, rProv );
1298 mpImplTextObj->mbHasExtendedBullets |= pPara->bExtendedBulletsUsed;
1299 mpImplTextObj->maList.push_back( pPara );
1300 aParaFlags.bFirstParagraph = sal_False;
1305 ImplCalculateTextPositions();
1308 void TextObj::ImplCalculateTextPositions()
1310 mpImplTextObj->mnTextSize = 0;
1311 for ( sal_uInt32 i = 0; i < ParagraphCount(); ++i )
1312 mpImplTextObj->mnTextSize += GetParagraph(i)->ImplCalculateTextPositions( mpImplTextObj->mnTextSize );
1315 ParagraphObj* TextObj::GetParagraph(int idx)
1317 return mpImplTextObj->maList[idx];
1320 sal_uInt32 TextObj::ParagraphCount() const
1322 return mpImplTextObj->maList.size();
1325 sal_uInt32 TextObj::Count() const
1327 return mpImplTextObj->mnTextSize;
1330 int TextObj::GetInstance() const
1332 return mpImplTextObj->mnInstance;
1335 sal_Bool TextObj::HasExtendedBullets()
1337 return mpImplTextObj->mbHasExtendedBullets;
1340 FontCollectionEntry::~FontCollectionEntry()
1344 void FontCollectionEntry::ImplInit( const String& rName )
1346 String aSubstName( GetSubsFontName( rName, SUBSFONT_ONLYONE | SUBSFONT_MS ) );
1347 if ( aSubstName.Len() )
1349 Name = aSubstName;
1350 bIsConverted = sal_True;
1352 else
1354 Name = rName;
1355 bIsConverted = sal_False;
1359 FontCollection::~FontCollection()
1361 delete pVDev;
1362 xPPTBreakIter = NULL;
1365 FontCollection::FontCollection() :
1366 pVDev ( NULL )
1368 com::sun::star::uno::Reference< com::sun::star::uno::XComponentContext >
1369 xContext = ::comphelper::getProcessComponentContext();
1370 xPPTBreakIter = com::sun::star::i18n::BreakIterator::create( xContext );
1373 short FontCollection::GetScriptDirection( const OUString& rString ) const
1375 short nRet = ScriptTypeDetector::getScriptDirection( rString, 0, com::sun::star::i18n::ScriptDirection::NEUTRAL );
1376 return nRet;
1379 sal_uInt32 FontCollection::GetId( FontCollectionEntry& rEntry )
1381 if( rEntry.Name.Len() )
1383 const sal_uInt32 nFonts = maFonts.size();
1385 for( sal_uInt32 i = 0; i < nFonts; i++ )
1387 const FontCollectionEntry* pEntry = GetById( i );
1388 if( pEntry->Name == rEntry.Name )
1389 return i;
1391 Font aFont;
1392 aFont.SetCharSet( rEntry.CharSet );
1393 aFont.SetName( rEntry.Original );
1394 aFont.SetHeight( 100 );
1396 if ( !pVDev )
1397 pVDev = new VirtualDevice;
1399 pVDev->SetFont( aFont );
1400 FontMetric aMetric( pVDev->GetFontMetric() );
1402 sal_uInt16 nTxtHeight = (sal_uInt16)aMetric.GetAscent() + (sal_uInt16)aMetric.GetDescent();
1404 if ( nTxtHeight )
1406 double fScaling = (double)nTxtHeight / 120.0;
1407 if ( ( fScaling > 0.50 ) && ( fScaling < 1.5 ) )
1408 rEntry.Scaling = fScaling;
1411 maFonts.push_back(new FontCollectionEntry(rEntry));
1412 return nFonts;
1414 return 0;
1417 const FontCollectionEntry* FontCollection::GetById( sal_uInt32 nId )
1419 return nId < maFonts.size() ? &maFonts[nId] : NULL;
1422 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */