Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
5 : * This Source Code Form is subject to the terms of the Mozilla Public
6 : * License, v. 2.0. If a copy of the MPL was not distributed with this
7 : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
11 : * Licensed to the Apache Software Foundation (ASF) under one or more
12 : * contributor license agreements. See the NOTICE file distributed
13 : * with this work for additional information regarding copyright
14 : * ownership. The ASF licenses this file to you under the Apache
15 : * License, Version 2.0 (the "License"); you may not use this file
16 : * except in compliance with the License. You may obtain a copy of
17 : * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 : */
19 :
20 : #include "text.hxx"
21 :
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>
38 :
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>
47 :
48 : #include <vcl/settings.hxx>
49 : #include <vcl/metric.hxx>
50 : #include <vcl/outdev.hxx>
51 : #include <vcl/virdev.hxx>
52 :
53 4 : com::sun::star::uno::Reference< com::sun::star::i18n::XBreakIterator > xPPTBreakIter;
54 :
55 725 : 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 725 : mpFieldEntry ( NULL )
65 : {
66 725 : mXPropSet = rXPropSet;
67 :
68 725 : ImplGetPortionValues( rFontCollection, false );
69 725 : }
70 :
71 53 : 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 53 : , mpFieldEntry(NULL)
88 : {
89 53 : OUString aString( rXTextRange->getString() );
90 106 : OUString aURL;
91 :
92 53 : mnTextSize = aString.getLength();
93 53 : if ( bLast )
94 53 : mnTextSize++;
95 :
96 53 : if ( mnTextSize )
97 : {
98 53 : bool bRTL_endingParen = false;
99 53 : mpFieldEntry = NULL;
100 53 : sal_uInt32 nFieldType = 0;
101 :
102 106 : mXPropSet = ::com::sun::star::uno::Reference<
103 : ::com::sun::star::beans::XPropertySet >
104 53 : ( rXTextRange, ::com::sun::star::uno::UNO_QUERY );
105 106 : mXPropState = ::com::sun::star::uno::Reference<
106 : ::com::sun::star::beans::XPropertyState >
107 53 : ( rXTextRange, ::com::sun::star::uno::UNO_QUERY );
108 :
109 53 : bool bPropSetsValid = ( mXPropSet.is() && mXPropState.is() );
110 53 : if ( bPropSetsValid )
111 53 : nFieldType = ImplGetTextField( rXTextRange, mXPropSet, aURL );
112 53 : if ( nFieldType )
113 : {
114 21 : mpFieldEntry = new FieldEntry( nFieldType, 0, mnTextSize );
115 21 : if ( ( nFieldType >> 28 == 4 ) )
116 : {
117 0 : mpFieldEntry->aRepresentation = aString;
118 0 : mpFieldEntry->aFieldUrl = aURL;
119 : }
120 : }
121 53 : bool bSymbol = false;
122 :
123 53 : if ( bPropSetsValid && ImplGetPropertyValue( OUString( "CharFontCharSet" ), false ) )
124 : {
125 53 : sal_Int16 nCharset = 0;
126 53 : mAny >>= nCharset;
127 53 : if ( nCharset == ::com::sun::star::awt::CharSet::SYMBOL )
128 0 : bSymbol = true;
129 : }
130 53 : if ( mpFieldEntry && ( nFieldType & 0x800000 ) ) // placeholder ?
131 : {
132 21 : mnTextSize = 1;
133 21 : if ( bLast )
134 21 : mnTextSize++;
135 21 : mpText = new sal_uInt16[ mnTextSize ];
136 21 : mpText[ 0 ] = 0x2a;
137 : }
138 : else
139 : {
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 64 : if (bLast && !aString.isEmpty()
143 24 : && aString[aString.getLength() - 1] == ')'
144 32 : && FontCollection::GetScriptDirection(aString) == com::sun::star::i18n::ScriptDirection::RIGHT_TO_LEFT)
145 : {
146 0 : mnTextSize++;
147 0 : bRTL_endingParen = true;
148 : }
149 32 : mpText = new sal_uInt16[ mnTextSize ];
150 : sal_uInt16 nChar;
151 602 : for ( sal_Int32 i = 0; i < aString.getLength(); i++ )
152 : {
153 570 : nChar = (sal_uInt16)aString[ i ];
154 570 : if ( nChar == 0xa )
155 0 : nChar++;
156 570 : else if ( !bSymbol )
157 : {
158 570 : switch ( nChar )
159 : {
160 : // Currency
161 0 : case 128: nChar = 0x20AC; break;
162 : // Punctuation and other
163 0 : case 130: nChar = 0x201A; break;// SINGLE LOW-9 QUOTATION MARK
164 0 : case 131: nChar = 0x0192; break;// LATIN SMALL LETTER F WITH HOOK
165 0 : case 132: nChar = 0x201E; break;// DOUBLE LOW-9 QUOTATION MARK
166 : // LOW DOUBLE PRIME QUOTATION MARK
167 0 : case 133: nChar = 0x2026; break;// HORIZONTAL ELLIPSES
168 0 : case 134: nChar = 0x2020; break;// DAGGER
169 0 : case 135: nChar = 0x2021; break;// DOUBLE DAGGER
170 0 : case 136: nChar = 0x02C6; break;// MODIFIER LETTER CIRCUMFLEX ACCENT
171 0 : case 137: nChar = 0x2030; break;// PER MILLE SIGN
172 0 : case 138: nChar = 0x0160; break;// LATIN CAPITAL LETTER S WITH CARON
173 0 : case 139: nChar = 0x2039; break;// SINGLE LEFT-POINTING ANGLE QUOTATION MARK
174 0 : case 140: nChar = 0x0152; break;// LATIN CAPITAL LIGATURE OE
175 0 : case 142: nChar = 0x017D; break;// LATIN CAPITAL LETTER Z WITH CARON
176 0 : case 145: nChar = 0x2018; break;// LEFT SINGLE QUOTATION MARK
177 : // MODIFIER LETTER TURNED COMMA
178 0 : case 146: nChar = 0x2019; break;// RIGHT SINGLE QUOTATION MARK
179 : // MODIFIER LETTER APOSTROPHE
180 0 : case 147: nChar = 0x201C; break;// LEFT DOUBLE QUOTATION MARK
181 : // REVERSED DOUBLE PRIME QUOTATION MARK
182 0 : case 148: nChar = 0x201D; break;// RIGHT DOUBLE QUOTATION MARK
183 : // REVERSED DOUBLE PRIME QUOTATION MARK
184 0 : case 149: nChar = 0x2022; break;// BULLET
185 0 : case 150: nChar = 0x2013; break;// EN DASH
186 0 : case 151: nChar = 0x2014; break;// EM DASH
187 0 : case 152: nChar = 0x02DC; break;// SMALL TILDE
188 0 : case 153: nChar = 0x2122; break;// TRADE MARK SIGN
189 0 : case 154: nChar = 0x0161; break;// LATIN SMALL LETTER S WITH CARON
190 0 : case 155: nChar = 0x203A; break;// SINGLE RIGHT-POINTING ANGLE QUOTATION MARK
191 0 : case 156: nChar = 0x0153; break;// LATIN SMALL LIGATURE OE
192 0 : case 158: nChar = 0x017E; break;// LATIN SMALL LETTER Z WITH CARON
193 0 : case 159: nChar = 0x0178; break;// LATIN CAPITAL LETTER Y WITH DIAERESIS
194 : }
195 : }
196 570 : mpText[ i ] = nChar;
197 : }
198 : }
199 53 : if ( bRTL_endingParen )
200 0 : mpText[ mnTextSize - 2 ] = 0x200F; // Unicode Right-to-Left mark
201 :
202 53 : if ( bLast )
203 53 : mpText[ mnTextSize - 1 ] = 0xd;
204 :
205 53 : if ( bPropSetsValid )
206 53 : ImplGetPortionValues( rFontCollection, true );
207 53 : }
208 53 : }
209 :
210 0 : PortionObj::PortionObj( const PortionObj& rPortionObj )
211 0 : : PropStateValue( rPortionObj )
212 : {
213 0 : ImplConstruct( rPortionObj );
214 0 : }
215 :
216 1556 : PortionObj::~PortionObj()
217 : {
218 778 : ImplClear();
219 778 : }
220 :
221 42 : void PortionObj::Write( SvStream* pStrm, bool bLast )
222 : {
223 42 : sal_uInt32 nCount = mnTextSize;
224 42 : if ( bLast && mbLastPortion )
225 24 : nCount--;
226 546 : for ( sal_uInt32 i = 0; i < nCount; i++ )
227 504 : pStrm->WriteUInt16( mpText[ i ] );
228 42 : }
229 :
230 778 : void PortionObj::ImplGetPortionValues( FontCollection& rFontCollection, bool bGetPropStateValue )
231 : {
232 :
233 778 : bool bOk = ImplGetPropertyValue( OUString( "CharFontName" ), bGetPropStateValue );
234 778 : meFontName = ePropState;
235 778 : if ( bOk )
236 : {
237 778 : FontCollectionEntry aFontDesc( *static_cast<OUString const *>(mAny.getValue()) );
238 778 : sal_uInt32 nCount = rFontCollection.GetCount();
239 778 : mnFont = (sal_uInt16)rFontCollection.GetId( aFontDesc );
240 778 : if ( mnFont == nCount )
241 : {
242 43 : FontCollectionEntry& rFontDesc = rFontCollection.GetLast();
243 43 : if ( ImplGetPropertyValue( OUString( "CharFontCharSet" ), false ) )
244 43 : mAny >>= rFontDesc.CharSet;
245 43 : if ( ImplGetPropertyValue( OUString( "CharFontFamily" ), false ) )
246 43 : mAny >>= rFontDesc.Family;
247 43 : if ( ImplGetPropertyValue( OUString( "CharFontPitch" ), false ) )
248 43 : mAny >>= rFontDesc.Pitch;
249 778 : }
250 : }
251 :
252 778 : sal_Int16 nScriptType = SvtLanguageOptions::FromSvtScriptTypeToI18N( SvtLanguageOptions::GetScriptTypeOfLanguage( Application::GetSettings().GetLanguageTag().getLanguageType() ) );
253 778 : if ( mpText && mnTextSize && xPPTBreakIter.is() )
254 : {
255 53 : OUString sT( mpText, mnTextSize );
256 53 : nScriptType = xPPTBreakIter->getScriptType( sT, 0 );
257 : }
258 778 : if ( nScriptType != com::sun::star::i18n::ScriptType::COMPLEX )
259 : {
260 778 : bOk = ImplGetPropertyValue( OUString( "CharFontNameAsian" ), bGetPropStateValue );
261 778 : meAsianOrComplexFont = ePropState;
262 778 : if ( bOk )
263 : {
264 778 : FontCollectionEntry aFontDesc( *static_cast<OUString const *>(mAny.getValue()) );
265 778 : sal_uInt32 nCount = rFontCollection.GetCount();
266 778 : mnAsianOrComplexFont = (sal_uInt16)rFontCollection.GetId( aFontDesc );
267 778 : if ( mnAsianOrComplexFont == nCount )
268 : {
269 32 : FontCollectionEntry& rFontDesc = rFontCollection.GetLast();
270 32 : if ( ImplGetPropertyValue( OUString( "CharFontCharSetAsian" ), false ) )
271 32 : mAny >>= rFontDesc.CharSet;
272 32 : if ( ImplGetPropertyValue( OUString( "CharFontFamilyAsian" ), false ) )
273 32 : mAny >>= rFontDesc.Family;
274 32 : if ( ImplGetPropertyValue( OUString( "CharFontPitchAsian" ), false ) )
275 32 : mAny >>= rFontDesc.Pitch;
276 778 : }
277 : }
278 : }
279 : else
280 : {
281 0 : bOk = ImplGetPropertyValue( OUString( "CharFontNameComplex" ), bGetPropStateValue );
282 0 : meAsianOrComplexFont = ePropState;
283 0 : if ( bOk )
284 : {
285 0 : FontCollectionEntry aFontDesc( *static_cast<OUString const *>(mAny.getValue()) );
286 0 : sal_uInt32 nCount = rFontCollection.GetCount();
287 0 : mnAsianOrComplexFont = (sal_uInt16)rFontCollection.GetId( aFontDesc );
288 0 : if ( mnAsianOrComplexFont == nCount )
289 : {
290 0 : FontCollectionEntry& rFontDesc = rFontCollection.GetLast();
291 0 : if ( ImplGetPropertyValue( OUString( "CharFontCharSetComplex" ), false ) )
292 0 : mAny >>= rFontDesc.CharSet;
293 0 : if ( ImplGetPropertyValue( OUString( "CharFontFamilyComplex" ), false ) )
294 0 : mAny >>= rFontDesc.Family;
295 0 : if ( ImplGetPropertyValue( OUString( "CharFontPitchComplex" ), false ) )
296 0 : mAny >>= rFontDesc.Pitch;
297 0 : }
298 : }
299 : }
300 :
301 1556 : OUString aCharHeightName, aCharWeightName, aCharLocaleName, aCharPostureName;
302 778 : switch( nScriptType )
303 : {
304 : case com::sun::star::i18n::ScriptType::ASIAN :
305 : {
306 0 : aCharHeightName = "CharHeightAsian";
307 0 : aCharWeightName = "CharWeightAsian";
308 0 : aCharLocaleName = "CharLocaleAsian";
309 0 : aCharPostureName = "CharPostureAsian";
310 0 : break;
311 : }
312 : case com::sun::star::i18n::ScriptType::COMPLEX :
313 : {
314 0 : aCharHeightName = "CharHeightComplex";
315 0 : aCharWeightName = "CharWeightComplex";
316 0 : aCharLocaleName = "CharLocaleComplex";
317 0 : aCharPostureName = "CharPostureComplex";
318 0 : break;
319 : }
320 : default:
321 : {
322 778 : aCharHeightName = "CharHeight";
323 778 : aCharWeightName = "CharWeight";
324 778 : aCharLocaleName = "CharLocale";
325 778 : aCharPostureName = "CharPosture";
326 778 : break;
327 : }
328 : }
329 :
330 778 : mnCharHeight = 24;
331 778 : if ( GetPropertyValue( mAny, mXPropSet, aCharHeightName, false ) )
332 : {
333 778 : float fVal(0.0);
334 778 : if ( mAny >>= fVal )
335 : {
336 778 : mnCharHeight = (sal_uInt16)( fVal + 0.5 );
337 778 : meCharHeight = GetPropertyState( mXPropSet, aCharHeightName );
338 : }
339 : }
340 778 : if ( GetPropertyValue( mAny, mXPropSet, aCharWeightName, false ) )
341 : {
342 778 : float fFloat(0.0);
343 778 : if ( mAny >>= fFloat )
344 : {
345 778 : if ( fFloat >= ::com::sun::star::awt::FontWeight::SEMIBOLD )
346 10 : mnCharAttr |= 1;
347 778 : if ( GetPropertyState( mXPropSet, aCharWeightName ) == ::com::sun::star::beans::PropertyState_DIRECT_VALUE )
348 667 : mnCharAttrHard |= 1;
349 : }
350 : }
351 778 : if ( GetPropertyValue( mAny, mXPropSet, aCharLocaleName, false ) )
352 : {
353 778 : com::sun::star::lang::Locale eLocale;
354 778 : if ( mAny >>= eLocale )
355 778 : meCharLocale = eLocale;
356 : }
357 778 : if ( GetPropertyValue( mAny, mXPropSet, aCharPostureName, false ) )
358 : {
359 : ::com::sun::star::awt::FontSlant aFS;
360 778 : if ( mAny >>= aFS )
361 : {
362 778 : switch( aFS )
363 : {
364 : case ::com::sun::star::awt::FontSlant_OBLIQUE :
365 : case ::com::sun::star::awt::FontSlant_ITALIC :
366 0 : mnCharAttr |= 2;
367 0 : break;
368 : default:
369 778 : break;
370 : }
371 778 : if ( GetPropertyState( mXPropSet, aCharPostureName ) == ::com::sun::star::beans::PropertyState_DIRECT_VALUE )
372 667 : mnCharAttrHard |= 2;
373 : }
374 : }
375 :
376 778 : if ( ImplGetPropertyValue( OUString( "CharUnderline" ), bGetPropStateValue ) )
377 : {
378 778 : sal_Int16 nVal(0);
379 778 : mAny >>= nVal;
380 778 : switch ( nVal )
381 : {
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 0 : mnCharAttr |= 4;
386 : }
387 : }
388 778 : if ( ePropState == ::com::sun::star::beans::PropertyState_DIRECT_VALUE )
389 725 : mnCharAttrHard |= 4;
390 :
391 778 : if ( ImplGetPropertyValue( OUString( "CharShadowed" ), bGetPropStateValue ) )
392 : {
393 778 : bool bBool(false);
394 778 : mAny >>= bBool;
395 778 : if ( bBool )
396 0 : mnCharAttr |= 0x10;
397 : }
398 778 : if ( ePropState == ::com::sun::star::beans::PropertyState_DIRECT_VALUE )
399 725 : mnCharAttrHard |= 16;
400 :
401 778 : if ( ImplGetPropertyValue( OUString( "CharRelief" ), bGetPropStateValue ) )
402 : {
403 778 : sal_Int16 nVal(0);
404 778 : mAny >>= nVal;
405 778 : if ( nVal != ::com::sun::star::text::FontRelief::NONE )
406 0 : mnCharAttr |= 512;
407 : }
408 778 : if ( ePropState == ::com::sun::star::beans::PropertyState_DIRECT_VALUE )
409 725 : mnCharAttrHard |= 512;
410 :
411 778 : if ( ImplGetPropertyValue( OUString( "CharColor" ), bGetPropStateValue ) )
412 : {
413 778 : sal_uInt32 nSOColor = *( static_cast<sal_uInt32 const *>(mAny.getValue()) );
414 778 : mnCharColor = nSOColor & 0xff00ff00; // green and hibyte
415 778 : mnCharColor |= (sal_uInt8)( nSOColor ) << 16; // red and blue is switched
416 778 : mnCharColor |= (sal_uInt8)( nSOColor >> 16 );
417 : }
418 778 : meCharColor = ePropState;
419 :
420 778 : mnCharEscapement = 0;
421 778 : if ( ImplGetPropertyValue( OUString( "CharEscapement" ), bGetPropStateValue ) )
422 : {
423 778 : mAny >>= mnCharEscapement;
424 778 : if ( mnCharEscapement > 100 )
425 0 : mnCharEscapement = 33;
426 778 : else if ( mnCharEscapement < -100 )
427 0 : mnCharEscapement = -33;
428 : }
429 1556 : meCharEscapement = ePropState;
430 778 : }
431 :
432 778 : void PortionObj::ImplClear()
433 : {
434 778 : delete mpFieldEntry;
435 778 : delete[] mpText;
436 778 : }
437 :
438 0 : void PortionObj::ImplConstruct( const PortionObj& rPortionObj )
439 : {
440 0 : meCharColor = rPortionObj.meCharColor;
441 0 : meCharHeight = rPortionObj.meCharHeight;
442 0 : meFontName = rPortionObj.meFontName;
443 0 : meAsianOrComplexFont = rPortionObj.meAsianOrComplexFont;
444 0 : meCharEscapement = rPortionObj.meCharEscapement;
445 0 : meCharLocale = rPortionObj.meCharLocale;
446 0 : mnCharAttrHard = rPortionObj.mnCharAttrHard;
447 :
448 0 : mbLastPortion = rPortionObj.mbLastPortion;
449 0 : mnTextSize = rPortionObj.mnTextSize;
450 0 : mnCharColor = rPortionObj.mnCharColor;
451 0 : mnCharEscapement = rPortionObj.mnCharEscapement;
452 0 : mnCharAttr = rPortionObj.mnCharAttr;
453 0 : mnCharHeight = rPortionObj.mnCharHeight;
454 0 : mnFont = rPortionObj.mnFont;
455 0 : mnAsianOrComplexFont = rPortionObj.mnAsianOrComplexFont;
456 :
457 0 : if ( rPortionObj.mpText )
458 : {
459 0 : mpText = new sal_uInt16[ mnTextSize ];
460 0 : memcpy( mpText, rPortionObj.mpText, mnTextSize << 1 );
461 : }
462 : else
463 0 : mpText = NULL;
464 :
465 0 : if ( rPortionObj.mpFieldEntry )
466 0 : mpFieldEntry = new FieldEntry( *( rPortionObj.mpFieldEntry ) );
467 : else
468 0 : mpFieldEntry = NULL;
469 0 : }
470 :
471 53 : sal_uInt32 PortionObj::ImplCalculateTextPositions( sal_uInt32 nCurrentTextPosition )
472 : {
473 53 : if ( mpFieldEntry && ( !mpFieldEntry->nFieldStartPos ) )
474 : {
475 21 : mpFieldEntry->nFieldStartPos += nCurrentTextPosition;
476 21 : mpFieldEntry->nFieldEndPos += nCurrentTextPosition;
477 : }
478 53 : return mnTextSize;
479 : }
480 :
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
492 :
493 53 : 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 )
495 : {
496 53 : sal_uInt32 nRetValue = 0;
497 : sal_Int32 nFormat;
498 53 : ::com::sun::star::uno::Any aAny;
499 53 : if ( GetPropertyValue( aAny, rXPropSet, OUString( "TextPortionType" ), true ) )
500 : {
501 53 : OUString aTextFieldType( *static_cast<OUString const *>(aAny.getValue()) );
502 53 : if ( aTextFieldType == "TextField" )
503 : {
504 21 : if ( GetPropertyValue( aAny, rXPropSet, aTextFieldType, true ) )
505 : {
506 21 : ::com::sun::star::uno::Reference< ::com::sun::star::text::XTextField > aXTextField;
507 21 : if ( aAny >>= aXTextField )
508 : {
509 21 : if ( aXTextField.is() )
510 : {
511 : ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet >
512 21 : xFieldPropSet( aXTextField, ::com::sun::star::uno::UNO_QUERY );
513 21 : if ( xFieldPropSet.is() )
514 : {
515 21 : OUString aFieldKind( aXTextField->getPresentation( sal_True ) );
516 21 : if ( aFieldKind == "Date" )
517 : {
518 0 : if ( GetPropertyValue( aAny, xFieldPropSet, OUString( "IsFix" ), true ) )
519 : {
520 0 : bool bBool = false;
521 0 : aAny >>= bBool;
522 0 : if ( !bBool ) // Fixed DateFields does not exist in PPT
523 : {
524 0 : if ( GetPropertyValue( aAny, xFieldPropSet, OUString( "Format" ), true ) )
525 : {
526 0 : nFormat = *static_cast<sal_Int32 const *>(aAny.getValue());
527 0 : switch ( nFormat )
528 : {
529 : default:
530 : case 5 :
531 : case 4 :
532 0 : case 2 : nFormat = 0; break;
533 : case 8 :
534 : case 9 :
535 0 : case 3 : nFormat = 1; break;
536 : case 7 :
537 0 : case 6 : nFormat = 2; break;
538 : }
539 0 : nRetValue |= ( ( ( 1 << 4 ) | nFormat ) << 24 ) | 0x800000;
540 : }
541 : }
542 : }
543 : }
544 21 : else if ( aFieldKind == "URL" )
545 : {
546 0 : if ( GetPropertyValue( aAny, xFieldPropSet, OUString( "URL" ), true ) )
547 0 : rURL = *static_cast<OUString const *>(aAny.getValue());
548 0 : nRetValue = 4 << 28;
549 : }
550 21 : else if ( aFieldKind == "Page" )
551 : {
552 6 : nRetValue = 3 << 28 | 0x800000;
553 : }
554 15 : else if ( aFieldKind == "Pages" )
555 : {
556 :
557 : }
558 15 : else if ( aFieldKind == "Time" )
559 : {
560 0 : if ( GetPropertyValue( aAny, xFieldPropSet, OUString( "IsFix" ), true ) )
561 : {
562 0 : bool bBool = false;
563 0 : aAny >>= bBool;
564 0 : if ( !bBool )
565 : {
566 0 : if ( GetPropertyValue( aAny, xFieldPropSet, OUString( "IsFix" ), true ) )
567 : {
568 0 : nFormat = *static_cast<sal_Int32 const *>(aAny.getValue());
569 0 : nRetValue |= ( ( ( 2 << 4 ) | nFormat ) << 24 ) | 0x800000;
570 : }
571 : }
572 : }
573 : }
574 15 : else if ( aFieldKind == "File" )
575 : {
576 :
577 : }
578 15 : else if ( aFieldKind == "Table" )
579 : {
580 :
581 : }
582 15 : else if ( aFieldKind == "ExtTime" )
583 : {
584 0 : if ( GetPropertyValue( aAny, xFieldPropSet, OUString( "IsFix" ), true ) )
585 : {
586 0 : bool bBool = false;
587 0 : aAny >>= bBool;
588 0 : if ( !bBool )
589 : {
590 0 : if ( GetPropertyValue( aAny, xFieldPropSet, OUString( "Format" ), true ) )
591 : {
592 0 : nFormat = *static_cast<sal_Int32 const *>(aAny.getValue());
593 0 : switch ( nFormat )
594 : {
595 : default:
596 : case 6 :
597 : case 7 :
598 : case 8 :
599 0 : case 2 : nFormat = 12; break;
600 0 : case 3 : nFormat = 9; break;
601 : case 5 :
602 0 : case 4 : nFormat = 10; break;
603 :
604 : }
605 0 : nRetValue |= ( ( ( 2 << 4 ) | nFormat ) << 24 ) | 0x800000;
606 : }
607 : }
608 : }
609 : }
610 15 : else if ( aFieldKind == "ExtFile" )
611 : {
612 :
613 : }
614 15 : else if ( aFieldKind == "Author" )
615 : {
616 :
617 : }
618 15 : else if ( aFieldKind == "DateTime" )
619 : {
620 6 : nRetValue = 5 << 28 | 0x800000;
621 : }
622 9 : else if ( aFieldKind == "Header" )
623 : {
624 3 : nRetValue = 6 << 28 | 0x800000;
625 : }
626 6 : else if ( aFieldKind == "Footer" )
627 : {
628 6 : nRetValue = 7 << 28 | 0x800000;
629 21 : }
630 21 : }
631 : }
632 21 : }
633 : }
634 53 : }
635 : }
636 53 : return nRetValue;
637 : }
638 :
639 0 : PortionObj& PortionObj::operator=( const PortionObj& rPortionObj )
640 : {
641 0 : if ( this != &rPortionObj )
642 : {
643 0 : ImplClear();
644 0 : ImplConstruct( rPortionObj );
645 : }
646 0 : return *this;
647 : }
648 :
649 725 : 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 725 : , mnBiDi(0)
667 : {
668 725 : mXPropSet = rXPropSet;
669 :
670 725 : bExtendedParameters = false;
671 :
672 725 : nDepth = 0;
673 725 : nBulletFlags = 0;
674 725 : nParaFlags = 0;
675 :
676 725 : ImplGetParagraphValues( pProv, false );
677 725 : }
678 :
679 53 : 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 53 : , mnBiDi(0)
706 : {
707 53 : bExtendedParameters = false;
708 :
709 53 : nDepth = 0;
710 53 : nBulletFlags = 0;
711 53 : nParaFlags = 0;
712 :
713 106 : mXPropSet = ::com::sun::star::uno::Reference<
714 : ::com::sun::star::beans::XPropertySet >
715 53 : ( rXTextContent, ::com::sun::star::uno::UNO_QUERY );
716 :
717 106 : mXPropState = ::com::sun::star::uno::Reference<
718 : ::com::sun::star::beans::XPropertyState >
719 53 : ( rXTextContent, ::com::sun::star::uno::UNO_QUERY );
720 :
721 53 : if ( mXPropSet.is() && mXPropState.is() )
722 : {
723 : ::com::sun::star::uno::Reference< ::com::sun::star::container::XEnumerationAccess >
724 53 : aXTextPortionEA( rXTextContent, ::com::sun::star::uno::UNO_QUERY );
725 53 : if ( aXTextPortionEA.is() )
726 : {
727 : ::com::sun::star::uno::Reference< ::com::sun::star::container::XEnumeration >
728 53 : aXTextPortionE( aXTextPortionEA->createEnumeration() );
729 53 : if ( aXTextPortionE.is() )
730 : {
731 159 : while ( aXTextPortionE->hasMoreElements() )
732 : {
733 53 : ::com::sun::star::uno::Reference< ::com::sun::star::text::XTextRange > aXCursorText;
734 106 : ::com::sun::star::uno::Any aAny( aXTextPortionE->nextElement() );
735 53 : if ( aAny >>= aXCursorText )
736 : {
737 53 : PortionObj* pPortionObj = new PortionObj( aXCursorText, !aXTextPortionE->hasMoreElements(), rFontCollection );
738 53 : if ( pPortionObj->Count() )
739 53 : mvPortions.push_back( pPortionObj );
740 : else
741 0 : delete pPortionObj;
742 : }
743 53 : }
744 53 : }
745 : }
746 53 : ImplGetParagraphValues( &rProv, true );
747 : }
748 53 : }
749 :
750 0 : ParagraphObj::ParagraphObj( const ParagraphObj& rObj )
751 : : PropStateValue()
752 : , SOParagraph()
753 0 : , mvPortions()
754 : {
755 0 : ImplConstruct( rObj );
756 0 : }
757 :
758 1556 : ParagraphObj::~ParagraphObj()
759 : {
760 778 : ImplClear();
761 778 : }
762 :
763 42 : void ParagraphObj::Write( SvStream* pStrm )
764 : {
765 84 : for ( boost::ptr_vector<PortionObj>::iterator it = mvPortions.begin(); it != mvPortions.end(); ++it )
766 42 : it->Write( pStrm, mbLastParagraph );
767 42 : }
768 :
769 778 : void ParagraphObj::ImplClear()
770 : {
771 778 : mvPortions.clear();
772 778 : }
773 :
774 746 : void ParagraphObj::CalculateGraphicBulletSize( sal_uInt16 nFontHeight )
775 : {
776 746 : if ( ( (SvxExtNumType)nNumberingType == SVX_NUM_BITMAP ) && ( nBulletId != 0xffff ) )
777 : {
778 : // calculate the bulletrealsize for this grafik
779 0 : if ( aBuGraSize.Width() && aBuGraSize.Height() )
780 : {
781 0 : double fCharHeight = nFontHeight;
782 0 : double fLen = aBuGraSize.Height();
783 0 : fCharHeight = fCharHeight * 0.2540;
784 0 : double fQuo = fLen / fCharHeight;
785 0 : nBulletRealSize = (sal_Int16)( fQuo + 0.5 );
786 0 : if ( (sal_uInt16)nBulletRealSize > 400 )
787 0 : nBulletRealSize = 400;
788 : }
789 : }
790 746 : }
791 :
792 778 : void ParagraphObj::ImplGetNumberingLevel( PPTExBulletProvider* pBuProv, sal_Int16 nNumberingDepth, bool bIsBullet, bool bGetPropStateValue )
793 : {
794 778 : ::com::sun::star::uno::Any aAny;
795 778 : if ( GetPropertyValue( aAny, mXPropSet, OUString( "ParaLeftMargin" ) ) )
796 : {
797 778 : sal_Int32 nVal(0);
798 778 : if ( aAny >>= nVal )
799 778 : nTextOfs = static_cast< sal_Int16 >( nVal / ( 2540.0 / 576 ) + 0.5 ) ;
800 : }
801 778 : if ( GetPropertyValue( aAny, mXPropSet, OUString( "ParaFirstLineIndent" ) ) )
802 : {
803 778 : if ( aAny >>= nBulletOfs )
804 778 : nBulletOfs = static_cast< sal_Int32 >( nBulletOfs / ( 2540.0 / 576 ) + 0.5 );
805 : }
806 778 : if ( GetPropertyValue( aAny, mXPropSet, OUString( "NumberingIsNumber" ) ) )
807 778 : aAny >>= bNumberingIsNumber;
808 :
809 1556 : ::com::sun::star::uno::Reference< ::com::sun::star::container::XIndexReplace > aXIndexReplace;
810 :
811 778 : if ( bIsBullet && ImplGetPropertyValue( OUString( "NumberingRules" ), bGetPropStateValue ) )
812 : {
813 21 : if ( ( mAny >>= aXIndexReplace ) && nNumberingDepth < aXIndexReplace->getCount() )
814 : {
815 21 : mAny <<= aXIndexReplace->getByIndex( nNumberingDepth );
816 : ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue>
817 21 : aPropertySequence( *static_cast<css::uno::Sequence< ::com::sun::star::beans::PropertyValue> const *>(mAny.getValue()) );
818 :
819 21 : const ::com::sun::star::beans::PropertyValue* pPropValue = aPropertySequence.getArray();
820 :
821 21 : sal_Int32 nPropertyCount = aPropertySequence.getLength();
822 21 : if ( nPropertyCount )
823 : {
824 21 : bExtendedParameters = true;
825 21 : nBulletRealSize = 100;
826 21 : nMappedNumType = 0;
827 :
828 21 : OUString aGraphicURL;
829 294 : for ( sal_Int32 i = 0; i < nPropertyCount; i++ )
830 : {
831 273 : const void* pValue = pPropValue[ i ].Value.getValue();
832 273 : if ( pValue )
833 : {
834 273 : OUString aPropName( pPropValue[ i ].Name );
835 273 : if ( aPropName == "NumberingType" )
836 21 : nNumberingType = *( static_cast<sal_Int16 const *>(pValue) );
837 252 : else if ( aPropName == "Adjust" )
838 21 : nHorzAdjust = *( static_cast<sal_Int16 const *>(pValue) );
839 231 : else if ( aPropName == "BulletChar" )
840 : {
841 21 : OUString aString( *( static_cast<OUString const *>(pValue) ) );
842 21 : if ( !aString.isEmpty() )
843 21 : cBulletId = aString[ 0 ];
844 : }
845 210 : else if ( aPropName == "BulletFont" )
846 : {
847 21 : aFontDesc = *static_cast<css::awt::FontDescriptor const *>(pValue);
848 :
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 21 : if ( aFontDesc.Name.equalsIgnoreAsciiCase("StarSymbol") )
854 21 : aFontDesc.CharSet = RTL_TEXTENCODING_MS_1252;
855 :
856 : }
857 189 : else if ( aPropName == "GraphicURL" )
858 0 : aGraphicURL = *static_cast<OUString const *>(pValue);
859 189 : else if ( aPropName == "GraphicSize" )
860 : {
861 21 : if ( pPropValue[ i ].Value.getValueType() == cppu::UnoType<com::sun::star::awt::Size>::get())
862 : {
863 : // don't cast awt::Size to Size as on 64-bits they are not the same.
864 21 : ::com::sun::star::awt::Size aSize;
865 21 : pPropValue[ i ].Value >>= aSize;
866 21 : aBuGraSize.A() = aSize.Width;
867 21 : aBuGraSize.B() = aSize.Height;
868 : }
869 : }
870 168 : else if ( aPropName == "StartWith" )
871 21 : nStartWith = *static_cast<sal_Int16 const *>(pValue);
872 147 : else if ( aPropName == "LeftMargin" )
873 21 : nTextOfs = nTextOfs + static_cast< sal_Int16 >( *static_cast<sal_Int32 const *>(pValue) / ( 2540.0 / 576 ) );
874 126 : else if ( aPropName == "FirstLineOffset" )
875 21 : nBulletOfs += (sal_Int16)( *static_cast<sal_Int32 const *>(pValue) / ( 2540.0 / 576 ) );
876 105 : else if ( aPropName == "BulletColor" )
877 : {
878 21 : sal_uInt32 nSOColor = *static_cast<sal_uInt32 const *>(pValue);
879 21 : nBulletColor = nSOColor & 0xff00ff00; // green and hibyte
880 21 : nBulletColor |= (sal_uInt8)( nSOColor ) << 16; // red
881 21 : nBulletColor |= (sal_uInt8)( nSOColor >> 16 ) | 0xfe000000; // blue
882 : }
883 84 : else if ( aPropName == "BulletRelSize" )
884 : {
885 21 : nBulletRealSize = *static_cast<sal_Int16 const *>(pValue);
886 21 : nParaFlags |= 0x40;
887 21 : nBulletFlags |= 8;
888 : }
889 63 : else if ( aPropName == "Prefix" )
890 21 : sPrefix = *static_cast<OUString const *>(pValue);
891 42 : else if ( aPropName == "Suffix" )
892 21 : sSuffix = *static_cast<OUString const *>(pValue);
893 : #ifdef DBG_UTIL
894 : else if ( ! (
895 : ( aPropName == "SymbolTextDistance" )
896 : || ( aPropName == "Graphic" ) ) )
897 : {
898 : OSL_FAIL( "Unknown Property" );
899 : }
900 : #endif
901 : }
902 : }
903 :
904 21 : if ( !aGraphicURL.isEmpty() )
905 : {
906 0 : if ( aBuGraSize.Width() && aBuGraSize.Height() )
907 : {
908 0 : sal_Int32 nIndex = aGraphicURL.indexOf(':');
909 0 : if ( nIndex != -1 )
910 : {
911 0 : nIndex++;
912 0 : if ( nIndex < aGraphicURL.getLength() )
913 : {
914 0 : OString aUniqueId( OUStringToOString(aGraphicURL.copy(nIndex), RTL_TEXTENCODING_UTF8) );
915 0 : if ( !aUniqueId.isEmpty() )
916 : {
917 0 : nBulletId = pBuProv->GetId( aUniqueId, aBuGraSize );
918 0 : if ( nBulletId != 0xffff )
919 0 : bExtendedBulletsUsed = true;
920 0 : }
921 : }
922 : }
923 : }
924 : else
925 : {
926 0 : nNumberingType = SVX_NUM_NUMBER_NONE;
927 : }
928 : }
929 :
930 21 : CalculateGraphicBulletSize( ( mvPortions.empty() ) ? 24 : mvPortions.front().mnCharHeight );
931 :
932 21 : switch( nNumberingType )
933 : {
934 0 : case SVX_NUM_NUMBER_NONE : nParaFlags |= 0xf; break;
935 :
936 : case SVX_NUM_CHAR_SPECIAL : // Bullet
937 : {
938 21 : if ( IsStarSymbol(aFontDesc.Name) )
939 : {
940 21 : rtl_TextEncoding eChrSet = aFontDesc.CharSet;
941 21 : cBulletId = msfilter::util::bestFitOpenSymbolToMSFont(cBulletId, eChrSet, aFontDesc.Name);
942 21 : aFontDesc.CharSet = eChrSet;
943 : }
944 :
945 21 : if ( !aFontDesc.Name.isEmpty() )
946 : {
947 21 : nParaFlags |= 0x90; // we define the font and charset
948 : }
949 : }
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:
964 : {
965 21 : if ( nNumberingType != SVX_NUM_CHAR_SPECIAL )
966 : {
967 0 : bExtendedBulletsUsed = true;
968 0 : if ( nNumberingDepth & 1 )
969 0 : cBulletId = 0x2013; // defaulting bullet characters for ppt97
970 0 : else if ( nNumberingDepth == 4 )
971 0 : cBulletId = 0xbb;
972 : else
973 0 : cBulletId = 0x2022;
974 :
975 0 : switch( (SvxExtNumType)nNumberingType )
976 : {
977 : case SVX_NUM_CHARS_UPPER_LETTER :
978 : case SVX_NUM_CHARS_UPPER_LETTER_N :
979 : {
980 0 : if ( sSuffix == ")" )
981 : {
982 0 : if ( sPrefix == "(" )
983 0 : nMappedNumType = 0xa0001; // (A)
984 : else
985 0 : nMappedNumType = 0xb0001; // A)
986 : }
987 : else
988 0 : nMappedNumType = 0x10001; // A.
989 : }
990 0 : break;
991 : case SVX_NUM_CHARS_LOWER_LETTER :
992 : case SVX_NUM_CHARS_LOWER_LETTER_N :
993 : {
994 0 : if ( sSuffix == ")" )
995 : {
996 0 : if ( sPrefix == "(" )
997 0 : nMappedNumType = 0x80001; // (a)
998 : else
999 0 : nMappedNumType = 0x90001; // a)
1000 : }
1001 : else
1002 0 : nMappedNumType = 0x00001; // a.
1003 : }
1004 0 : break;
1005 : case SVX_NUM_ROMAN_UPPER :
1006 : {
1007 0 : if ( sSuffix == ")" )
1008 : {
1009 0 : if ( sPrefix == "(" )
1010 0 : nMappedNumType = 0xe0001; // (I)
1011 : else
1012 0 : nMappedNumType = 0xf0001; // I)
1013 : }
1014 : else
1015 0 : nMappedNumType = 0x70001; // I.
1016 : }
1017 0 : break;
1018 : case SVX_NUM_ROMAN_LOWER :
1019 : {
1020 0 : if ( sSuffix == ")" )
1021 : {
1022 0 : if ( sPrefix == "(" )
1023 0 : nMappedNumType = 0x40001; // (i)
1024 : else
1025 0 : nMappedNumType = 0x50001; // i)
1026 : }
1027 : else
1028 0 : nMappedNumType = 0x60001; // i.
1029 : }
1030 0 : break;
1031 : case SVX_NUM_ARABIC :
1032 : {
1033 0 : if ( sSuffix == ")" )
1034 : {
1035 0 : if ( sPrefix == "(" )
1036 0 : nMappedNumType = 0xc0001; // (1)
1037 : else
1038 0 : nMappedNumType = 0x20001; // 1)
1039 : }
1040 : else
1041 : {
1042 0 : if ( sSuffix.isEmpty() && sPrefix.isEmpty() )
1043 0 : nMappedNumType = 0xd0001; // 1
1044 : else
1045 0 : nMappedNumType = 0x30001; // 1.
1046 : }
1047 : }
1048 0 : break;
1049 : case SVX_NUM_NUMBER_UPPER_ZH :
1050 : {
1051 0 : if ( !sSuffix.isEmpty() )
1052 0 : nMappedNumType = 0x110001; // Simplified Chinese with single-byte period.
1053 : else
1054 0 : nMappedNumType = 0x100001; // Simplified Chinese.
1055 : }
1056 0 : break;
1057 : case SVX_NUM_CIRCLE_NUMBER :
1058 : {
1059 0 : nMappedNumType = 0x120001; // Double byte circle numbers.
1060 : }
1061 0 : break;
1062 : case SVX_NUM_NUMBER_UPPER_ZH_TW :
1063 : {
1064 0 : if ( !sSuffix.isEmpty() )
1065 0 : nMappedNumType = 0x160001; // Traditional Chinese with single-byte period.
1066 : else
1067 0 : nMappedNumType = 0x150001; // Traditional Chinese.
1068 : }
1069 0 : break;
1070 : case SVX_NUM_NUMBER_LOWER_ZH :
1071 : {
1072 0 : if ( sSuffix == OUString( sal_Unicode(0xff0e)) )
1073 0 : nMappedNumType = 0x260001; // Japanese with double-byte period.
1074 0 : else if ( !sSuffix.isEmpty() )
1075 0 : nMappedNumType = 0x1B0001; // Japanese/Korean with single-byte period.
1076 : else
1077 0 : nMappedNumType = 0x1A0001; // Japanese/Korean.
1078 : }
1079 0 : break;
1080 : case SVX_NUM_FULL_WIDTH_ARABIC :
1081 : {
1082 0 : if ( !sSuffix.isEmpty() )
1083 0 : nMappedNumType = 0x1D0001; // Double-byte Arabic numbers with double-byte period.
1084 : else
1085 0 : nMappedNumType = 0x1C0001; // Double-byte Arabic numbers.
1086 : }
1087 0 : break;
1088 : default:
1089 0 : break;
1090 : }
1091 : }
1092 21 : nParaFlags |= 0x2f;
1093 21 : nBulletFlags |= 6;
1094 21 : if ( mbIsBullet && bNumberingIsNumber )
1095 21 : nBulletFlags |= 1;
1096 : }
1097 21 : }
1098 21 : }
1099 : }
1100 : }
1101 778 : nBulletOfs = nTextOfs + nBulletOfs;
1102 778 : if ( nBulletOfs < 0 )
1103 778 : nBulletOfs = 0;
1104 778 : }
1105 :
1106 778 : void ParagraphObj::ImplGetParagraphValues( PPTExBulletProvider* pBuProv, bool bGetPropStateValue )
1107 : {
1108 778 : ::com::sun::star::uno::Any aAny;
1109 778 : if ( GetPropertyValue( aAny, mXPropSet, "NumberingLevel", true ) )
1110 : {
1111 21 : if ( bGetPropStateValue )
1112 21 : meBullet = GetPropertyState( mXPropSet, "NumberingLevel" );
1113 21 : nDepth = *static_cast<sal_Int16 const *>(aAny.getValue());
1114 :
1115 21 : if ( nDepth < 0 )
1116 : {
1117 0 : mbIsBullet = false;
1118 0 : nDepth = 0;
1119 : }
1120 : else
1121 : {
1122 21 : if ( nDepth > 4 )
1123 6 : nDepth = 4;
1124 21 : mbIsBullet = true;
1125 : }
1126 : }
1127 : else
1128 : {
1129 757 : nDepth = 0;
1130 757 : mbIsBullet = false;
1131 : }
1132 778 : ImplGetNumberingLevel( pBuProv, nDepth, mbIsBullet, bGetPropStateValue );
1133 :
1134 778 : if ( ImplGetPropertyValue( OUString( "ParaTabStops" ), bGetPropStateValue ) )
1135 778 : maTabStop = *static_cast<css::uno::Sequence< ::com::sun::star::style::TabStop> const *>(mAny.getValue());
1136 778 : sal_Int16 eTextAdjust( ::com::sun::star::style::ParagraphAdjust_LEFT );
1137 778 : if ( GetPropertyValue( aAny, mXPropSet, OUString( "ParaAdjust" ), bGetPropStateValue ) )
1138 778 : aAny >>= eTextAdjust;
1139 778 : switch ( (::com::sun::star::style::ParagraphAdjust)eTextAdjust )
1140 : {
1141 : case ::com::sun::star::style::ParagraphAdjust_CENTER :
1142 299 : mnTextAdjust = 1;
1143 299 : break;
1144 : case ::com::sun::star::style::ParagraphAdjust_RIGHT :
1145 9 : mnTextAdjust = 2;
1146 9 : break;
1147 : case ::com::sun::star::style::ParagraphAdjust_BLOCK :
1148 0 : mnTextAdjust = 3;
1149 0 : break;
1150 : default :
1151 : case ::com::sun::star::style::ParagraphAdjust_LEFT :
1152 470 : mnTextAdjust = 0;
1153 470 : break;
1154 : }
1155 778 : meTextAdjust = ePropState;
1156 :
1157 778 : if ( ImplGetPropertyValue( OUString( "ParaLineSpacing" ), bGetPropStateValue ) )
1158 : {
1159 : ::com::sun::star::style::LineSpacing aLineSpacing
1160 778 : = *static_cast<css::style::LineSpacing const *>(mAny.getValue());
1161 778 : switch ( aLineSpacing.Mode )
1162 : {
1163 : case ::com::sun::star::style::LineSpacingMode::FIX :
1164 0 : mnLineSpacing = (sal_Int16)(-( aLineSpacing.Height ) );
1165 0 : mbFixedLineSpacing = true;
1166 0 : break;
1167 : case ::com::sun::star::style::LineSpacingMode::MINIMUM :
1168 : case ::com::sun::star::style::LineSpacingMode::LEADING :
1169 0 : mnLineSpacing = (sal_Int16)(-( aLineSpacing.Height ) );
1170 0 : mbFixedLineSpacing = false;
1171 0 : break;
1172 :
1173 : case ::com::sun::star::style::LineSpacingMode::PROP :
1174 : default:
1175 778 : mnLineSpacing = (sal_Int16)( aLineSpacing.Height );
1176 778 : break;
1177 : }
1178 : }
1179 778 : meLineSpacing = ePropState;
1180 :
1181 778 : if ( ImplGetPropertyValue( OUString( "ParaBottomMargin" ), bGetPropStateValue ) )
1182 : {
1183 778 : double fSpacing = *static_cast<sal_uInt32 const *>(mAny.getValue()) + ( 2540.0 / 576.0 ) - 1;
1184 778 : mnLineSpacingBottom = (sal_Int16)(-( fSpacing * 576.0 / 2540.0 ) );
1185 : }
1186 778 : meLineSpacingBottom = ePropState;
1187 :
1188 778 : if ( ImplGetPropertyValue( OUString( "ParaTopMargin" ), bGetPropStateValue ) )
1189 : {
1190 778 : double fSpacing = *static_cast<sal_uInt32 const *>(mAny.getValue()) + ( 2540.0 / 576.0 ) - 1;
1191 778 : mnLineSpacingTop = (sal_Int16)(-( fSpacing * 576.0 / 2540.0 ) );
1192 : }
1193 778 : meLineSpacingTop = ePropState;
1194 :
1195 778 : if ( ImplGetPropertyValue( OUString( "ParaIsForbiddenRules" ), bGetPropStateValue ) )
1196 778 : mAny >>= mbForbiddenRules;
1197 778 : meForbiddenRules = ePropState;
1198 :
1199 778 : if ( ImplGetPropertyValue( OUString( "ParaIsHangingPunctuation" ), bGetPropStateValue ) )
1200 778 : mAny >>= mbParagraphPunctation;
1201 778 : meParagraphPunctation = ePropState;
1202 :
1203 778 : mnBiDi = 0;
1204 778 : if ( ImplGetPropertyValue( OUString( "WritingMode" ), bGetPropStateValue ) )
1205 : {
1206 778 : sal_Int16 nWritingMode = 0;
1207 778 : mAny >>= nWritingMode;
1208 :
1209 778 : SvxFrameDirection eWritingMode( (SvxFrameDirection)nWritingMode );
1210 778 : if ( ( eWritingMode == FRMDIR_HORI_RIGHT_TOP )
1211 778 : || ( eWritingMode == FRMDIR_VERT_TOP_RIGHT ) )
1212 : {
1213 0 : mnBiDi = 1;
1214 : }
1215 : }
1216 778 : meBiDi = ePropState;
1217 778 : }
1218 :
1219 0 : void ParagraphObj::ImplConstruct( const ParagraphObj& rParagraphObj )
1220 : {
1221 0 : mbIsBullet = rParagraphObj.mbIsBullet;
1222 0 : meBullet = rParagraphObj.meBullet;
1223 0 : meTextAdjust = rParagraphObj.meTextAdjust;
1224 0 : meLineSpacing = rParagraphObj.meLineSpacing;
1225 0 : meLineSpacingTop = rParagraphObj.meLineSpacingTop;
1226 0 : meLineSpacingBottom = rParagraphObj.meLineSpacingBottom;
1227 0 : meForbiddenRules = rParagraphObj.meForbiddenRules;
1228 0 : meParagraphPunctation = rParagraphObj.meParagraphPunctation;
1229 0 : meBiDi =rParagraphObj.meBiDi;
1230 0 : mbFixedLineSpacing = rParagraphObj.mbFixedLineSpacing;
1231 0 : mnTextSize = rParagraphObj.mnTextSize;
1232 0 : mnTextAdjust = rParagraphObj.mnTextAdjust;
1233 0 : mnLineSpacing = rParagraphObj.mnLineSpacing;
1234 0 : mnLineSpacingTop = rParagraphObj.mnLineSpacingTop;
1235 0 : mnLineSpacingBottom = rParagraphObj.mnLineSpacingBottom;
1236 0 : mbFirstParagraph = rParagraphObj.mbFirstParagraph;
1237 0 : mbLastParagraph = rParagraphObj.mbLastParagraph;
1238 0 : mbParagraphPunctation = rParagraphObj.mbParagraphPunctation;
1239 0 : mbForbiddenRules = rParagraphObj.mbForbiddenRules;
1240 0 : mnBiDi = rParagraphObj.mnBiDi;
1241 :
1242 0 : for ( boost::ptr_vector<PortionObj>::const_iterator it = rParagraphObj.begin(); it != rParagraphObj.end(); ++it )
1243 0 : mvPortions.push_back( new PortionObj( *it ) );
1244 :
1245 0 : maTabStop = rParagraphObj.maTabStop;
1246 0 : bExtendedParameters = rParagraphObj.bExtendedParameters;
1247 0 : nParaFlags = rParagraphObj.nParaFlags;
1248 0 : nBulletFlags = rParagraphObj.nBulletFlags;
1249 0 : sPrefix = rParagraphObj.sPrefix;
1250 0 : sSuffix = rParagraphObj.sSuffix;
1251 0 : sGraphicUrl = rParagraphObj.sGraphicUrl; // String to a graphic
1252 0 : aBuGraSize = rParagraphObj.aBuGraSize;
1253 0 : nNumberingType = rParagraphObj.nNumberingType; // this is actually a SvxEnum
1254 0 : nHorzAdjust = rParagraphObj.nHorzAdjust;
1255 0 : nBulletColor = rParagraphObj.nBulletColor;
1256 0 : nBulletOfs = rParagraphObj.nBulletOfs;
1257 0 : nStartWith = rParagraphObj.nStartWith; // start of numbering
1258 0 : nTextOfs = rParagraphObj.nTextOfs;
1259 0 : nBulletRealSize = rParagraphObj.nBulletRealSize; // scale in percent
1260 0 : nDepth = rParagraphObj.nDepth; // actual depth
1261 0 : cBulletId = rParagraphObj.cBulletId; // if Numbering Type == CharSpecial
1262 0 : aFontDesc = rParagraphObj.aFontDesc;
1263 :
1264 0 : bExtendedBulletsUsed = rParagraphObj.bExtendedBulletsUsed;
1265 0 : nBulletId = rParagraphObj.nBulletId;
1266 0 : }
1267 :
1268 53 : sal_uInt32 ParagraphObj::ImplCalculateTextPositions( sal_uInt32 nCurrentTextPosition )
1269 : {
1270 53 : mnTextSize = 0;
1271 106 : for ( boost::ptr_vector<PortionObj>::iterator it = mvPortions.begin(); it != mvPortions.end(); ++it )
1272 53 : mnTextSize += it->ImplCalculateTextPositions( nCurrentTextPosition + mnTextSize );
1273 53 : return mnTextSize;
1274 : }
1275 :
1276 0 : ParagraphObj& ParagraphObj::operator=( const ParagraphObj& rParagraphObj )
1277 : {
1278 0 : if ( this != &rParagraphObj )
1279 : {
1280 0 : ImplClear();
1281 0 : ImplConstruct( rParagraphObj );
1282 : }
1283 0 : return *this;
1284 : }
1285 :
1286 : struct ImplTextObj
1287 : {
1288 : sal_uInt32 mnTextSize;
1289 : int mnInstance;
1290 : std::vector<ParagraphObj*> maList;
1291 : bool mbHasExtendedBullets;
1292 : bool mbFixedCellHeightUsed;
1293 :
1294 : ImplTextObj( int nInstance );
1295 : ~ImplTextObj();
1296 : };
1297 :
1298 35 : ImplTextObj::ImplTextObj( int nInstance )
1299 35 : : maList()
1300 : {
1301 35 : mnTextSize = 0;
1302 35 : mnInstance = nInstance;
1303 35 : mbHasExtendedBullets = false;
1304 35 : mbFixedCellHeightUsed = false;
1305 35 : }
1306 :
1307 70 : ImplTextObj::~ImplTextObj()
1308 : {
1309 88 : for ( std::vector<ParagraphObj*>::const_iterator it = maList.begin(); it != maList.end(); ++it )
1310 53 : delete *it;
1311 35 : }
1312 :
1313 35 : TextObj::TextObj( ::com::sun::star::uno::Reference< ::com::sun::star::text::XSimpleText > & rXTextRef,
1314 : int nInstance, FontCollection& rFontCollection, PPTExBulletProvider& rProv ):
1315 35 : mpImplTextObj(new ImplTextObj(nInstance))
1316 : {
1317 : ::com::sun::star::uno::Reference< ::com::sun::star::container::XEnumerationAccess >
1318 35 : aXTextParagraphEA( rXTextRef, ::com::sun::star::uno::UNO_QUERY );
1319 :
1320 35 : if ( aXTextParagraphEA.is() )
1321 : {
1322 : ::com::sun::star::uno::Reference< ::com::sun::star::container::XEnumeration >
1323 35 : aXTextParagraphE( aXTextParagraphEA->createEnumeration() );
1324 35 : if ( aXTextParagraphE.is() )
1325 : {
1326 35 : ParaFlags aParaFlags;
1327 123 : while ( aXTextParagraphE->hasMoreElements() )
1328 : {
1329 53 : ::com::sun::star::uno::Reference< ::com::sun::star::text::XTextContent > aXParagraph;
1330 106 : ::com::sun::star::uno::Any aAny( aXTextParagraphE->nextElement() );
1331 53 : if ( aAny >>= aXParagraph )
1332 : {
1333 53 : if ( !aXTextParagraphE->hasMoreElements() )
1334 35 : aParaFlags.bLastParagraph = true;
1335 53 : ParagraphObj* pPara = new ParagraphObj( aXParagraph, aParaFlags, rFontCollection, rProv );
1336 53 : mpImplTextObj->mbHasExtendedBullets |= pPara->bExtendedBulletsUsed;
1337 53 : mpImplTextObj->maList.push_back( pPara );
1338 53 : aParaFlags.bFirstParagraph = false;
1339 : }
1340 53 : }
1341 35 : }
1342 : }
1343 35 : ImplCalculateTextPositions();
1344 35 : }
1345 :
1346 35 : void TextObj::ImplCalculateTextPositions()
1347 : {
1348 35 : mpImplTextObj->mnTextSize = 0;
1349 88 : for ( sal_uInt32 i = 0; i < ParagraphCount(); ++i )
1350 53 : mpImplTextObj->mnTextSize += GetParagraph(i)->ImplCalculateTextPositions( mpImplTextObj->mnTextSize );
1351 35 : }
1352 :
1353 277 : ParagraphObj* TextObj::GetParagraph(int idx)
1354 : {
1355 277 : return mpImplTextObj->maList[idx];
1356 : }
1357 :
1358 423 : sal_uInt32 TextObj::ParagraphCount() const
1359 : {
1360 423 : return mpImplTextObj->maList.size();
1361 : }
1362 :
1363 24 : sal_uInt32 TextObj::Count() const
1364 : {
1365 24 : return mpImplTextObj->mnTextSize;
1366 : }
1367 :
1368 42 : int TextObj::GetInstance() const
1369 : {
1370 42 : return mpImplTextObj->mnInstance;
1371 : }
1372 :
1373 42 : bool TextObj::HasExtendedBullets()
1374 : {
1375 42 : return mpImplTextObj->mbHasExtendedBullets;
1376 : }
1377 :
1378 1710 : FontCollectionEntry::~FontCollectionEntry()
1379 : {
1380 1710 : }
1381 :
1382 1606 : void FontCollectionEntry::ImplInit( const OUString& rName )
1383 : {
1384 1606 : OUString aSubstName( GetSubsFontName( rName, SubsFontFlags::ONLYONE | SubsFontFlags::MS ) );
1385 1606 : if ( !aSubstName.isEmpty() )
1386 : {
1387 518 : Name = aSubstName;
1388 518 : bIsConverted = true;
1389 : }
1390 : else
1391 : {
1392 1088 : Name = rName;
1393 1088 : bIsConverted = false;
1394 1606 : }
1395 1606 : }
1396 :
1397 58 : FontCollection::~FontCollection()
1398 : {
1399 29 : pVDev.disposeAndClear();
1400 29 : xPPTBreakIter = NULL;
1401 29 : }
1402 :
1403 29 : FontCollection::FontCollection() :
1404 29 : pVDev ( NULL )
1405 : {
1406 : com::sun::star::uno::Reference< com::sun::star::uno::XComponentContext >
1407 29 : xContext = ::comphelper::getProcessComponentContext();
1408 29 : xPPTBreakIter = com::sun::star::i18n::BreakIterator::create( xContext );
1409 29 : }
1410 :
1411 0 : short FontCollection::GetScriptDirection( const OUString& rString )
1412 : {
1413 0 : short nRet = ScriptTypeDetector::getScriptDirection( rString, 0, com::sun::star::i18n::ScriptDirection::NEUTRAL );
1414 0 : return nRet;
1415 : }
1416 :
1417 1606 : sal_uInt32 FontCollection::GetId( FontCollectionEntry& rEntry )
1418 : {
1419 1606 : if( !rEntry.Name.isEmpty() )
1420 : {
1421 1585 : const sal_uInt32 nFonts = maFonts.size();
1422 :
1423 4177 : for( sal_uInt32 i = 0; i < nFonts; i++ )
1424 : {
1425 4073 : const FontCollectionEntry* pEntry = GetById( i );
1426 4073 : if( pEntry->Name == rEntry.Name )
1427 1481 : return i;
1428 : }
1429 104 : vcl::Font aFont;
1430 104 : aFont.SetCharSet( rEntry.CharSet );
1431 104 : aFont.SetName( rEntry.Original );
1432 104 : aFont.SetHeight( 100 );
1433 :
1434 104 : if ( !pVDev )
1435 29 : pVDev = VclPtr<VirtualDevice>::Create();
1436 :
1437 104 : pVDev->SetFont( aFont );
1438 208 : FontMetric aMetric( pVDev->GetFontMetric() );
1439 :
1440 104 : sal_uInt16 nTxtHeight = (sal_uInt16)aMetric.GetAscent() + (sal_uInt16)aMetric.GetDescent();
1441 :
1442 104 : if ( nTxtHeight )
1443 : {
1444 104 : double fScaling = (double)nTxtHeight / 120.0;
1445 104 : if ( ( fScaling > 0.50 ) && ( fScaling < 1.5 ) )
1446 104 : rEntry.Scaling = fScaling;
1447 : }
1448 :
1449 104 : maFonts.push_back(new FontCollectionEntry(rEntry));
1450 208 : return nFonts;
1451 : }
1452 21 : return 0;
1453 : }
1454 :
1455 4840 : const FontCollectionEntry* FontCollection::GetById( sal_uInt32 nId )
1456 : {
1457 4840 : return nId < maFonts.size() ? &maFonts[nId] : NULL;
1458 12 : }
1459 :
1460 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|