1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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 .
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
) :
60 mnAsianOrComplexFont( 0xffff ),
62 mbLastPortion ( true ),
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
)
83 , mnAsianOrComplexFont(0xffff)
85 , mbLastPortion(bLast
)
89 OUString
aString( rXTextRange
->getString() );
92 mnTextSize
= aString
.getLength();
98 bool bRTL_endingParen
= false;
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
);
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;
127 if ( nCharset
== ::com::sun::star::awt::CharSet::SYMBOL
)
130 if ( mpFieldEntry
&& ( nFieldType
& 0x800000 ) ) // placeholder ?
135 mpText
= new sal_uInt16
[ mnTextSize
];
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
)
147 bRTL_endingParen
= true;
149 mpText
= new sal_uInt16
[ mnTextSize
];
151 for ( sal_Int32 i
= 0; i
< aString
.getLength(); i
++ )
153 nChar
= (sal_uInt16
)aString
[ i
];
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
199 if ( bRTL_endingParen
)
200 mpText
[ mnTextSize
- 2 ] = 0x200F; // Unicode Right-to-Left mark
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()
221 void PortionObj::Write( SvStream
* pStrm
, bool bLast
)
223 sal_uInt32 nCount
= mnTextSize
;
224 if ( bLast
&& mbLastPortion
)
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
;
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
;
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
;
281 bOk
= ImplGetPropertyValue( OUString( "CharFontNameComplex" ), bGetPropStateValue
);
282 meAsianOrComplexFont
= ePropState
;
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";
312 case com::sun::star::i18n::ScriptType::COMPLEX
:
314 aCharHeightName
= "CharHeightComplex";
315 aCharWeightName
= "CharWeightComplex";
316 aCharLocaleName
= "CharLocaleComplex";
317 aCharPostureName
= "CharPostureComplex";
322 aCharHeightName
= "CharHeight";
323 aCharWeightName
= "CharWeight";
324 aCharLocaleName
= "CharLocale";
325 aCharPostureName
= "CharPosture";
331 if ( GetPropertyValue( mAny
, mXPropSet
, aCharHeightName
, false ) )
336 mnCharHeight
= (sal_uInt16
)( fVal
+ 0.5 );
337 meCharHeight
= GetPropertyState( mXPropSet
, aCharHeightName
);
340 if ( GetPropertyValue( mAny
, mXPropSet
, aCharWeightName
, false ) )
343 if ( mAny
>>= fFloat
)
345 if ( fFloat
>= ::com::sun::star::awt::FontWeight::SEMIBOLD
)
347 if ( GetPropertyState( mXPropSet
, aCharWeightName
) == ::com::sun::star::beans::PropertyState_DIRECT_VALUE
)
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
;
364 case ::com::sun::star::awt::FontSlant_OBLIQUE
:
365 case ::com::sun::star::awt::FontSlant_ITALIC
:
371 if ( GetPropertyState( mXPropSet
, aCharPostureName
) == ::com::sun::star::beans::PropertyState_DIRECT_VALUE
)
376 if ( ImplGetPropertyValue( OUString( "CharUnderline" ), bGetPropStateValue
) )
382 case ::com::sun::star::awt::FontUnderline::SINGLE
:
383 case ::com::sun::star::awt::FontUnderline::DOUBLE
:
384 case ::com::sun::star::awt::FontUnderline::DOTTED
:
388 if ( ePropState
== ::com::sun::star::beans::PropertyState_DIRECT_VALUE
)
391 if ( ImplGetPropertyValue( OUString( "CharShadowed" ), bGetPropStateValue
) )
398 if ( ePropState
== ::com::sun::star::beans::PropertyState_DIRECT_VALUE
)
399 mnCharAttrHard
|= 16;
401 if ( ImplGetPropertyValue( OUString( "CharRelief" ), bGetPropStateValue
) )
405 if ( nVal
!= ::com::sun::star::text::FontRelief::NONE
)
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()
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 );
465 if ( rPortionObj
.mpFieldEntry
)
466 mpFieldEntry
= new FieldEntry( *( rPortionObj
.mpFieldEntry
) );
471 sal_uInt32
PortionObj::ImplCalculateTextPositions( sal_uInt32 nCurrentTextPosition
)
473 if ( mpFieldEntry
&& ( !mpFieldEntry
->nFieldStartPos
) )
475 mpFieldEntry
->nFieldStartPos
+= nCurrentTextPosition
;
476 mpFieldEntry
->nFieldEndPos
+= nCurrentTextPosition
;
481 // Return: 0 = no TextField
482 // bit28->31 text field type :
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;
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 ) )
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());
532 case 2 : nFormat
= 0; break;
535 case 3 : nFormat
= 1; break;
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());
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 ) )
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 ) )
590 if ( GetPropertyValue( aAny
, xFieldPropSet
, OUString( "Format" ), true ) )
592 nFormat
= *static_cast<sal_Int32
const *>(aAny
.getValue());
599 case 2 : nFormat
= 12; break;
600 case 3 : nFormat
= 9; break;
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;
639 PortionObj
& PortionObj::operator=( const PortionObj
& rPortionObj
)
641 if ( this != &rPortionObj
)
644 ImplConstruct( rPortionObj
);
649 ParagraphObj::ParagraphObj(const ::com::sun::star::uno::Reference
< ::com::sun::star::beans::XPropertySet
> & rXPropSet
,
650 PPTExBulletProvider
* pProv
)
654 , maMapModeSrc(MAP_100TH_MM
)
655 , maMapModeDest(MAP_INCH
, Point(), Fraction( 1, 576 ), Fraction( 1, 576 ))
657 , mbFirstParagraph(false)
658 , mbLastParagraph(false)
661 , mbFixedLineSpacing(false)
662 , mnLineSpacingTop(0)
663 , mnLineSpacingBottom(0)
664 , mbForbiddenRules(false)
665 , mbParagraphPunctation(false)
668 mXPropSet
= rXPropSet
;
670 bExtendedParameters
= false;
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
)
684 , maMapModeSrc(MAP_100TH_MM
)
685 , maMapModeDest(MAP_INCH
, Point(), Fraction( 1, 576 ), Fraction( 1, 576 ))
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
)
700 , mbFixedLineSpacing(false)
701 , mnLineSpacingTop(0)
702 , mnLineSpacingBottom(0)
703 , mbForbiddenRules(false)
704 , mbParagraphPunctation(false)
707 bExtendedParameters
= false;
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
);
746 ImplGetParagraphValues( &rProv
, true );
750 ParagraphObj::ParagraphObj( const ParagraphObj
& rObj
)
755 ImplConstruct( rObj
);
758 ParagraphObj::~ParagraphObj()
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()
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" ) ) )
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;
828 OUString aGraphicURL
;
829 for ( sal_Int32 i
= 0; i
< nPropertyCount
; i
++ )
831 const void* pValue
= pPropValue
[ i
].Value
.getValue();
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
);
889 else if ( aPropName
== "Prefix" )
890 sPrefix
= *static_cast<OUString
const *>(pValue
);
891 else if ( aPropName
== "Suffix" )
892 sSuffix
= *static_cast<OUString
const *>(pValue
);
895 ( aPropName
== "SymbolTextDistance" )
896 || ( aPropName
== "Graphic" ) ) )
898 OSL_FAIL( "Unknown Property" );
904 if ( !aGraphicURL
.isEmpty() )
906 if ( aBuGraSize
.Width() && aBuGraSize
.Height() )
908 sal_Int32 nIndex
= aGraphicURL
.indexOf(':');
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;
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 )
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)
985 nMappedNumType
= 0xb0001; // A)
988 nMappedNumType
= 0x10001; // A.
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)
999 nMappedNumType
= 0x90001; // a)
1002 nMappedNumType
= 0x00001; // a.
1005 case SVX_NUM_ROMAN_UPPER
:
1007 if ( sSuffix
== ")" )
1009 if ( sPrefix
== "(" )
1010 nMappedNumType
= 0xe0001; // (I)
1012 nMappedNumType
= 0xf0001; // I)
1015 nMappedNumType
= 0x70001; // I.
1018 case SVX_NUM_ROMAN_LOWER
:
1020 if ( sSuffix
== ")" )
1022 if ( sPrefix
== "(" )
1023 nMappedNumType
= 0x40001; // (i)
1025 nMappedNumType
= 0x50001; // i)
1028 nMappedNumType
= 0x60001; // i.
1031 case SVX_NUM_ARABIC
:
1033 if ( sSuffix
== ")" )
1035 if ( sPrefix
== "(" )
1036 nMappedNumType
= 0xc0001; // (1)
1038 nMappedNumType
= 0x20001; // 1)
1042 if ( sSuffix
.isEmpty() && sPrefix
.isEmpty() )
1043 nMappedNumType
= 0xd0001; // 1
1045 nMappedNumType
= 0x30001; // 1.
1049 case SVX_NUM_NUMBER_UPPER_ZH
:
1051 if ( !sSuffix
.isEmpty() )
1052 nMappedNumType
= 0x110001; // Simplified Chinese with single-byte period.
1054 nMappedNumType
= 0x100001; // Simplified Chinese.
1057 case SVX_NUM_CIRCLE_NUMBER
:
1059 nMappedNumType
= 0x120001; // Double byte circle numbers.
1062 case SVX_NUM_NUMBER_UPPER_ZH_TW
:
1064 if ( !sSuffix
.isEmpty() )
1065 nMappedNumType
= 0x160001; // Traditional Chinese with single-byte period.
1067 nMappedNumType
= 0x150001; // Traditional Chinese.
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.
1077 nMappedNumType
= 0x1A0001; // Japanese/Korean.
1080 case SVX_NUM_FULL_WIDTH_ARABIC
:
1082 if ( !sSuffix
.isEmpty() )
1083 nMappedNumType
= 0x1D0001; // Double-byte Arabic numbers with double-byte period.
1085 nMappedNumType
= 0x1C0001; // Double-byte Arabic numbers.
1094 if ( mbIsBullet
&& bNumberingIsNumber
)
1101 nBulletOfs
= nTextOfs
+ nBulletOfs
;
1102 if ( 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());
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
:
1144 case ::com::sun::star::style::ParagraphAdjust_RIGHT
:
1147 case ::com::sun::star::style::ParagraphAdjust_BLOCK
:
1151 case ::com::sun::star::style::ParagraphAdjust_LEFT
:
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;
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;
1173 case ::com::sun::star::style::LineSpacingMode::PROP
:
1175 mnLineSpacing
= (sal_Int16
)( aLineSpacing
.Height
);
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
;
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
) )
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
)
1271 for ( boost::ptr_vector
<PortionObj
>::iterator it
= mvPortions
.begin(); it
!= mvPortions
.end(); ++it
)
1272 mnTextSize
+= it
->ImplCalculateTextPositions( nCurrentTextPosition
+ mnTextSize
);
1276 ParagraphObj
& ParagraphObj::operator=( const ParagraphObj
& rParagraphObj
)
1278 if ( this != &rParagraphObj
)
1281 ImplConstruct( rParagraphObj
);
1288 sal_uInt32 mnTextSize
;
1290 std::vector
<ParagraphObj
*> maList
;
1291 bool mbHasExtendedBullets
;
1292 bool mbFixedCellHeightUsed
;
1294 ImplTextObj( int nInstance
);
1298 ImplTextObj::ImplTextObj( int nInstance
)
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
)
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() )
1388 bIsConverted
= true;
1393 bIsConverted
= false;
1397 FontCollection::~FontCollection()
1399 pVDev
.disposeAndClear();
1400 xPPTBreakIter
= NULL
;
1403 FontCollection::FontCollection() :
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
);
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
)
1430 aFont
.SetCharSet( rEntry
.CharSet
);
1431 aFont
.SetName( rEntry
.Original
);
1432 aFont
.SetHeight( 100 );
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();
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
));
1455 const FontCollectionEntry
* FontCollection::GetById( sal_uInt32 nId
)
1457 return nId
< maFonts
.size() ? &maFonts
[nId
] : NULL
;
1460 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */