LCOV - code coverage report
Current view: top level - sdext/source/pdfimport/tree - style.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 93 128 72.7 %
Date: 2012-08-25 Functions: 6 8 75.0 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 125 296 42.2 %

           Branch data     Line data    Source code
       1                 :            : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2                 :            : /*************************************************************************
       3                 :            :  *
       4                 :            :  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
       5                 :            :  *
       6                 :            :  * Copyright 2000, 2010 Oracle and/or its affiliates.
       7                 :            :  *
       8                 :            :  * OpenOffice.org - a multi-platform office productivity suite
       9                 :            :  *
      10                 :            :  * This file is part of OpenOffice.org.
      11                 :            :  *
      12                 :            :  * OpenOffice.org is free software: you can redistribute it and/or modify
      13                 :            :  * it under the terms of the GNU Lesser General Public License version 3
      14                 :            :  * only, as published by the Free Software Foundation.
      15                 :            :  *
      16                 :            :  * OpenOffice.org is distributed in the hope that it will be useful,
      17                 :            :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      18                 :            :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      19                 :            :  * GNU Lesser General Public License version 3 for more details
      20                 :            :  * (a copy is included in the LICENSE file that accompanied this code).
      21                 :            :  *
      22                 :            :  * You should have received a copy of the GNU Lesser General Public License
      23                 :            :  * version 3 along with OpenOffice.org.  If not, see
      24                 :            :  * <http://www.openoffice.org/license.html>
      25                 :            :  * for a copy of the LGPLv3 License.
      26                 :            :  *
      27                 :            :  ************************************************************************/
      28                 :            : 
      29                 :            : 
      30                 :            : #include "style.hxx"
      31                 :            : #include "genericelements.hxx"
      32                 :            : #include "xmlemitter.hxx"
      33                 :            : #include "pdfiprocessor.hxx"
      34                 :            : #include <rtl/ustrbuf.hxx>
      35                 :            : 
      36                 :            : #include <algorithm>
      37                 :            : 
      38                 :            : using namespace pdfi;
      39                 :            : 
      40                 :            : using ::rtl::OUString;
      41                 :            : using ::rtl::OUStringBuffer;
      42                 :            : 
      43                 :            : #define USTR(x) rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( x ) )
      44                 :            : 
      45                 :          6 : StyleContainer::StyleContainer() :
      46 [ +  - ][ +  - ]:          6 :     m_nNextId( 1 )
      47                 :            : {
      48                 :          6 : }
      49                 :            : 
      50                 :        462 : sal_Int32 StyleContainer::impl_getStyleId( const Style& rStyle, bool bSubStyle )
      51                 :            : {
      52                 :        462 :     sal_Int32 nRet = -1;
      53                 :            : 
      54                 :            :     // construct HashedStyle to find or insert
      55         [ +  - ]:        462 :     HashedStyle aSearchStyle;
      56                 :        462 :     aSearchStyle.Name                   = rStyle.Name;
      57         [ +  - ]:        462 :     aSearchStyle.Properties             = rStyle.Properties;
      58                 :        462 :     aSearchStyle.Contents               = rStyle.Contents;
      59                 :        462 :     aSearchStyle.ContainedElement       = rStyle.ContainedElement;
      60         [ +  + ]:        651 :     for( unsigned int n = 0; n < rStyle.SubStyles.size(); ++n )
      61 [ +  - ][ +  - ]:        189 :         aSearchStyle.SubStyles.push_back( impl_getStyleId( *rStyle.SubStyles[n], true ) );
      62                 :            : 
      63                 :            :     boost::unordered_map< HashedStyle, sal_Int32, StyleHash >::iterator it =
      64         [ +  - ]:        462 :         m_aStyleToId.find( aSearchStyle );
      65                 :            : 
      66 [ +  - ][ +  + ]:        462 :     if( it != m_aStyleToId.end() )
      67                 :            :     {
      68         [ +  - ]:        321 :         nRet = it->second;
      69         [ +  - ]:        321 :         HashedStyle& rFound = m_aIdToStyle[ nRet ];
      70                 :            :         // increase refcount on this style
      71                 :        321 :         rFound.RefCount++;
      72         [ +  + ]:        321 :         if( ! bSubStyle )
      73                 :        195 :             rFound.IsSubStyle = false;
      74                 :            :     }
      75                 :            :     else
      76                 :            :     {
      77                 :        141 :         nRet = m_nNextId++;
      78                 :            :         // create new style
      79         [ +  - ]:        141 :         HashedStyle& rNew = m_aIdToStyle[ nRet ];
      80         [ +  - ]:        141 :         rNew = aSearchStyle;
      81                 :        141 :         rNew.RefCount           = 1;
      82                 :        141 :         rNew.IsSubStyle         = bSubStyle;
      83                 :            :         // fill the style hash to find the id
      84         [ +  - ]:        141 :         m_aStyleToId[ rNew ] = nRet;
      85                 :            :     }
      86         [ +  - ]:        462 :     return nRet;
      87                 :            : }
      88                 :            : 
      89                 :         75 : sal_Int32 StyleContainer::getStandardStyleId( const rtl::OString& rName )
      90                 :            : {
      91         [ +  - ]:         75 :     PropertyMap aProps;
      92 [ +  - ][ +  - ]:         75 :     aProps[ USTR( "style:family" ) ] = rtl::OStringToOUString( rName, RTL_TEXTENCODING_UTF8 );
                 [ +  - ]
      93 [ +  - ][ +  - ]:         75 :     aProps[ USTR( "style:name" ) ] = USTR( "standard" );
                 [ +  - ]
      94                 :            : 
      95         [ +  - ]:         75 :     Style aStyle( "style:style", aProps );
      96 [ +  - ][ +  - ]:         75 :     return getStyleId( aStyle );
                 [ +  - ]
      97                 :            : }
      98                 :            : 
      99                 :          0 : const PropertyMap* StyleContainer::getProperties( sal_Int32 nStyleId ) const
     100                 :            : {
     101                 :            :     boost::unordered_map< sal_Int32, HashedStyle >::const_iterator it =
     102         [ #  # ]:          0 :         m_aIdToStyle.find( nStyleId );
     103 [ #  # ][ #  # ]:          0 :     return it != m_aIdToStyle.end() ? &(it->second.Properties) : NULL;
                 [ #  # ]
     104                 :            : }
     105                 :            : 
     106                 :          0 : sal_Int32 StyleContainer::setProperties( sal_Int32 nStyleId, const PropertyMap& rNewProps )
     107                 :            : {
     108                 :          0 :     sal_Int32 nRet = -1;
     109                 :            :     boost::unordered_map< sal_Int32, HashedStyle >::iterator it =
     110         [ #  # ]:          0 :         m_aIdToStyle.find( nStyleId );
     111 [ #  # ][ #  # ]:          0 :     if( it != m_aIdToStyle.end() )
     112                 :            :     {
     113 [ #  # ][ #  # ]:          0 :         if( it->second.RefCount == 1 )
     114                 :            :         {
     115         [ #  # ]:          0 :             nRet = it->first;
     116                 :            :             // erase old hash to id mapping
     117 [ #  # ][ #  # ]:          0 :             m_aStyleToId.erase( it->second );
     118                 :            :             // change properties
     119 [ #  # ][ #  # ]:          0 :             it->second.Properties = rNewProps;
     120                 :            :             // fill in new hash to id mapping
     121 [ #  # ][ #  # ]:          0 :             m_aStyleToId[ it->second ] = nRet;
     122                 :            :         }
     123                 :            :         else
     124                 :            :         {
     125                 :            :             // decrease refcound on old instance
     126         [ #  # ]:          0 :             it->second.RefCount--;
     127                 :            :             // acquire new HashedStyle
     128         [ #  # ]:          0 :             HashedStyle aSearchStyle;
     129         [ #  # ]:          0 :             aSearchStyle.Name                   = it->second.Name;
     130         [ #  # ]:          0 :             aSearchStyle.Properties             = rNewProps;
     131         [ #  # ]:          0 :             aSearchStyle.Contents               = it->second.Contents;
     132         [ #  # ]:          0 :             aSearchStyle.ContainedElement       = it->second.ContainedElement;
     133 [ #  # ][ #  # ]:          0 :             aSearchStyle.SubStyles              = it->second.SubStyles;
     134         [ #  # ]:          0 :             aSearchStyle.IsSubStyle             = it->second.IsSubStyle;
     135                 :            : 
     136                 :            :             // find out whether this new style already exists
     137                 :            :             boost::unordered_map< HashedStyle, sal_Int32, StyleHash >::iterator new_it =
     138         [ #  # ]:          0 :                 m_aStyleToId.find( aSearchStyle );
     139 [ #  # ][ #  # ]:          0 :             if( new_it != m_aStyleToId.end() )
     140                 :            :             {
     141         [ #  # ]:          0 :                 nRet = new_it->second;
     142         [ #  # ]:          0 :                 m_aIdToStyle[ nRet ].RefCount++;
     143                 :            :             }
     144                 :            :             else
     145                 :            :             {
     146                 :          0 :                 nRet = m_nNextId++;
     147                 :            :                 // create new style with new id
     148         [ #  # ]:          0 :                 HashedStyle& rNew = m_aIdToStyle[ nRet ];
     149         [ #  # ]:          0 :                 rNew = aSearchStyle;
     150                 :          0 :                 rNew.RefCount = 1;
     151                 :            :                 // fill style to id hash
     152         [ #  # ]:          0 :                 m_aStyleToId[ aSearchStyle ] = nRet;
     153         [ #  # ]:          0 :             }
     154                 :            :         }
     155                 :            :     }
     156                 :          0 :     return nRet;
     157                 :            : }
     158                 :            : 
     159                 :        393 : OUString StyleContainer::getStyleName( sal_Int32 nStyle ) const
     160                 :            : {
     161                 :        393 :     OUStringBuffer aRet( 64 );
     162                 :            : 
     163                 :            :     boost::unordered_map< sal_Int32, HashedStyle >::const_iterator style_it =
     164         [ +  - ]:        393 :         m_aIdToStyle.find( nStyle );
     165 [ +  - ][ +  - ]:        393 :     if( style_it != m_aIdToStyle.end() )
     166                 :            :     {
     167         [ +  - ]:        393 :         const HashedStyle& rStyle = style_it->second;
     168                 :            : 
     169 [ +  - ][ +  - ]:        393 :         PropertyMap::const_iterator name_it = rStyle.Properties.find( USTR("style:name") );
     170 [ +  + ][ +  - ]:        393 :         if( name_it != rStyle.Properties.end() )
     171 [ +  - ][ +  - ]:         12 :             aRet.append( name_it->second );
     172                 :            :         else
     173                 :            :         {
     174 [ +  - ][ +  - ]:        381 :             PropertyMap::const_iterator fam_it = rStyle.Properties.find( USTR("style:family" ) );
     175                 :        381 :             OUString aStyleName;
     176 [ +  + ][ +  - ]:        381 :             if( fam_it != rStyle.Properties.end() )
     177                 :            :             {
     178         [ +  - ]:        348 :                 aStyleName = fam_it->second;
     179                 :            :             }
     180                 :            :             else
     181         [ +  - ]:         33 :                 aStyleName = OStringToOUString( rStyle.Name, RTL_TEXTENCODING_ASCII_US );
     182                 :        381 :             sal_Int32 nIndex = aStyleName.lastIndexOf( ':' );
     183         [ +  - ]:        381 :             aRet.append( aStyleName.copy( nIndex+1 ) );
     184         [ +  - ]:        393 :             aRet.append( nStyle );
     185                 :            :         }
     186                 :            :     }
     187                 :            :     else
     188                 :            :     {
     189         [ #  # ]:          0 :         aRet.appendAscii( "invalid style id " );
     190         [ #  # ]:          0 :         aRet.append( nStyle );
     191                 :            :     }
     192                 :            : 
     193         [ +  - ]:        393 :     return aRet.makeStringAndClear();
     194                 :            : }
     195                 :            : 
     196                 :        141 : void StyleContainer::impl_emitStyle( sal_Int32           nStyleId,
     197                 :            :                                      EmitContext&        rContext,
     198                 :            :                                      ElementTreeVisitor& rContainedElemVisitor )
     199                 :            : {
     200         [ +  - ]:        141 :     boost::unordered_map< sal_Int32, HashedStyle >::const_iterator it = m_aIdToStyle.find( nStyleId );
     201 [ +  - ][ +  - ]:        141 :     if( it != m_aIdToStyle.end() )
     202                 :            :     {
     203         [ +  - ]:        141 :         const HashedStyle& rStyle = it->second;
     204         [ +  - ]:        141 :             PropertyMap aProps( rStyle.Properties );
     205         [ +  + ]:        141 :         if( !rStyle.IsSubStyle )
     206 [ +  - ][ +  - ]:         78 :             aProps[ USTR( "style:name" ) ] = getStyleName( nStyleId );
                 [ +  - ]
     207         [ +  - ]:        141 :         rContext.rEmitter.beginTag( rStyle.Name.getStr(), aProps );
     208                 :            : 
     209         [ +  + ]:        204 :         for( unsigned int n = 0; n < rStyle.SubStyles.size(); ++n )
     210 [ +  - ][ +  - ]:         63 :             impl_emitStyle( rStyle.SubStyles[n], rContext, rContainedElemVisitor );
     211         [ -  + ]:        141 :         if( !rStyle.Contents.isEmpty() )
     212         [ #  # ]:          0 :             rContext.rEmitter.write( rStyle.Contents );
     213         [ -  + ]:        141 :         if( rStyle.ContainedElement )
     214                 :            :             rStyle.ContainedElement->visitedBy( rContainedElemVisitor,
     215         [ #  # ]:          0 :                                                 std::list<Element*>::iterator() );
     216 [ +  - ][ +  - ]:        141 :         rContext.rEmitter.endTag( rStyle.Name.getStr() );
     217                 :            :     }
     218                 :        141 : }
     219                 :            : 
     220                 :          6 : void StyleContainer::emit( EmitContext&        rContext,
     221                 :            :                            ElementTreeVisitor& rContainedElemVisitor )
     222                 :            : {
     223 [ +  - ][ +  - ]:          6 :     std::vector< sal_Int32 > aMasterPageSection, aAutomaticStyleSection, aOfficeStyleSection;
                 [ +  - ]
     224 [ +  - ][ +  + ]:        294 :     for( boost::unordered_map< sal_Int32, HashedStyle >::iterator it = m_aIdToStyle.begin();
     225         [ +  - ]:        147 :          it != m_aIdToStyle.end(); ++it )
     226                 :            :     {
     227 [ +  - ][ +  + ]:        141 :         if( ! it->second.IsSubStyle )
     228                 :            :         {
     229 [ +  - ][ +  + ]:         78 :             if( it->second.Name.equals( "style:master-page" ) )
     230 [ +  - ][ +  - ]:          6 :                 aMasterPageSection.push_back( it->first );
     231 [ +  - ][ +  - ]:         72 :             else if( getStyleName( it->first ) == "standard" )
                 [ +  + ]
     232 [ +  - ][ +  - ]:          6 :                 aOfficeStyleSection.push_back( it->first );
     233                 :            :             else
     234 [ +  - ][ +  - ]:         66 :                 aAutomaticStyleSection.push_back( it->first );
     235                 :            :         }
     236                 :            :     }
     237                 :            : 
     238         [ +  - ]:          6 :     if( ! aMasterPageSection.empty() )
     239         [ +  - ]:          6 :         std::stable_sort( aMasterPageSection.begin(), aMasterPageSection.end(), StyleIdNameSort(&m_aIdToStyle) );
     240         [ +  - ]:          6 :     if( ! aAutomaticStyleSection.empty() )
     241         [ +  - ]:          6 :         std::stable_sort( aAutomaticStyleSection.begin(), aAutomaticStyleSection.end(), StyleIdNameSort(&m_aIdToStyle) );
     242         [ +  + ]:          6 :     if( ! aOfficeStyleSection.empty() )
     243         [ +  - ]:          3 :         std::stable_sort( aOfficeStyleSection.begin(), aOfficeStyleSection.end(), StyleIdNameSort(&m_aIdToStyle) );
     244                 :            : 
     245                 :          6 :     int n = 0, nElements = 0;
     246 [ +  - ][ +  - ]:          6 :     rContext.rEmitter.beginTag( "office:styles", PropertyMap() );
                 [ +  - ]
     247         [ +  + ]:         12 :     for( n = 0, nElements = aOfficeStyleSection.size(); n < nElements; n++ )
     248 [ +  - ][ +  - ]:          6 :         impl_emitStyle( aOfficeStyleSection[n], rContext, rContainedElemVisitor );
     249         [ +  - ]:          6 :     rContext.rEmitter.endTag( "office:styles" );
     250 [ +  - ][ +  - ]:          6 :     rContext.rEmitter.beginTag( "office:automatic-styles", PropertyMap() );
                 [ +  - ]
     251         [ +  + ]:         72 :     for( n = 0, nElements = aAutomaticStyleSection.size(); n < nElements; n++ )
     252 [ +  - ][ +  - ]:         66 :         impl_emitStyle( aAutomaticStyleSection[n], rContext, rContainedElemVisitor );
     253         [ +  - ]:          6 :     rContext.rEmitter.endTag( "office:automatic-styles" );
     254 [ +  - ][ +  - ]:          6 :     rContext.rEmitter.beginTag( "office:master-styles", PropertyMap() );
                 [ +  - ]
     255         [ +  + ]:         12 :     for( n = 0, nElements = aMasterPageSection.size(); n < nElements; n++ )
     256 [ +  - ][ +  - ]:          6 :         impl_emitStyle( aMasterPageSection[n], rContext, rContainedElemVisitor );
     257         [ +  - ]:          6 :     rContext.rEmitter.endTag( "office:master-styles" );
     258                 :          6 : }
     259                 :            : 
     260                 :            : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10