LCOV - code coverage report
Current view: top level - libreoffice/sd/source/filter/eppt - pptx-text.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 2 739 0.3 %
Date: 2012-12-27 Functions: 2 39 5.1 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.10