LCOV - code coverage report
Current view: top level - sc/source/filter/oox - drawingbase.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 75 126 59.5 %
Date: 2012-08-25 Functions: 11 16 68.8 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 44 124 35.5 %

           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                 :            : #include "drawingbase.hxx"
      30                 :            : 
      31                 :            : #include <com/sun/star/awt/Rectangle.hpp>
      32                 :            : #include "oox/helper/attributelist.hxx"
      33                 :            : #include "oox/helper/binaryinputstream.hxx"
      34                 :            : #include "unitconverter.hxx"
      35                 :            : #include "oox/helper/propertyset.hxx"
      36                 :            : #include "oox/token/properties.hxx"
      37                 :            : 
      38                 :            : namespace oox {
      39                 :            : namespace xls {
      40                 :            : 
      41                 :            : // ============================================================================
      42                 :            : 
      43                 :            : using namespace ::com::sun::star::awt;
      44                 :            : using namespace ::com::sun::star::table;
      45                 :            : using namespace ::oox::drawingml;
      46                 :            : 
      47                 :            : using ::rtl::OUString;
      48                 :            : 
      49                 :            : // ============================================================================
      50                 :            : 
      51                 :            : namespace {
      52                 :            : 
      53                 :            : /** Converts the passed 32-bit integer value from 1/100 mm to EMUs. */
      54                 :         36 : inline sal_Int64 lclHmmToEmu( sal_Int32 nValue )
      55                 :            : {
      56         [ +  - ]:         36 :     return (nValue < 0) ? -1 : convertHmmToEmu( nValue );
      57                 :            : }
      58                 :            : 
      59                 :            : /** Converts the passed 64-bit integer value from EMUs to 1/100 mm. */
      60                 :         24 : inline sal_Int32 lclEmuToHmm( sal_Int64 nValue )
      61                 :            : {
      62         [ +  - ]:         24 :     return (nValue < 0) ? -1 : convertEmuToHmm( nValue );
      63                 :            : }
      64                 :            : 
      65                 :            : } // namespace
      66                 :            : 
      67                 :            : // ============================================================================
      68                 :            : 
      69                 :         12 : CellAnchorModel::CellAnchorModel() :
      70                 :            :     mnCol( -1 ),
      71                 :            :     mnRow( -1 ),
      72                 :            :     mnColOffset( 0 ),
      73                 :         12 :     mnRowOffset( 0 )
      74                 :            : {
      75                 :         12 : }
      76                 :            : 
      77                 :            : // ----------------------------------------------------------------------------
      78                 :            : 
      79                 :          6 : AnchorClientDataModel::AnchorClientDataModel() :
      80                 :            :     mbLocksWithSheet( true ),
      81                 :          6 :     mbPrintsWithSheet( true )
      82                 :            : {
      83                 :          6 : }
      84                 :            : 
      85                 :            : // ============================================================================
      86                 :            : 
      87                 :          6 : ShapeAnchor::ShapeAnchor( const WorksheetHelper& rHelper ) :
      88                 :            :     WorksheetHelper( rHelper ),
      89                 :            :     meAnchorType( ANCHOR_INVALID ),
      90                 :            :     meCellAnchorType( CELLANCHOR_EMU ),
      91                 :          6 :     mnEditAs( XML_twoCell )
      92                 :            : {
      93                 :          6 : }
      94                 :            : 
      95                 :          0 : void ShapeAnchor::importAnchor( sal_Int32 nElement, const AttributeList& rAttribs )
      96                 :            : {
      97   [ #  #  #  # ]:          0 :     switch( nElement )
      98                 :            :     {
      99                 :            :         case XDR_TOKEN( absoluteAnchor ):
     100                 :          0 :             meAnchorType = ANCHOR_ABSOLUTE;
     101                 :          0 :         break;
     102                 :            :         case XDR_TOKEN( oneCellAnchor ):
     103                 :          0 :             meAnchorType = ANCHOR_ONECELL;
     104                 :          0 :         break;
     105                 :            :         case XDR_TOKEN( twoCellAnchor ):
     106                 :          0 :             meAnchorType = ANCHOR_TWOCELL;
     107                 :          0 :             mnEditAs = rAttribs.getToken( XML_editAs, XML_twoCell );
     108                 :          0 :         break;
     109                 :            :         default:
     110                 :            :             OSL_ENSURE( false, "ShapeAnchor::importAnchor - unexpected element" );
     111                 :            :     }
     112                 :          0 :     meCellAnchorType = CELLANCHOR_EMU;
     113                 :          0 : }
     114                 :            : 
     115                 :          0 : void ShapeAnchor::importPos( const AttributeList& rAttribs )
     116                 :            : {
     117                 :            :     OSL_ENSURE( meAnchorType == ANCHOR_ABSOLUTE, "ShapeAnchor::importPos - unexpected 'xdr:pos' element" );
     118                 :          0 :     maPos.X = rAttribs.getHyper( XML_x, 0 );
     119                 :          0 :     maPos.Y = rAttribs.getHyper( XML_y, 0 );
     120                 :          0 : }
     121                 :            : 
     122                 :          0 : void ShapeAnchor::importExt( const AttributeList& rAttribs )
     123                 :            : {
     124                 :            :     OSL_ENSURE( (meAnchorType == ANCHOR_ABSOLUTE) || (meAnchorType == ANCHOR_ONECELL), "ShapeAnchor::importExt - unexpected 'xdr:ext' element" );
     125                 :          0 :     maSize.Width = rAttribs.getHyper( XML_cx, 0 );
     126                 :          0 :     maSize.Height = rAttribs.getHyper( XML_cy, 0 );
     127                 :          0 : }
     128                 :            : 
     129                 :          0 : void ShapeAnchor::importClientData( const AttributeList& rAttribs )
     130                 :            : {
     131                 :          0 :     maClientData.mbLocksWithSheet  = rAttribs.getBool( XML_fLocksWithSheet, true );
     132                 :          0 :     maClientData.mbPrintsWithSheet = rAttribs.getBool( XML_fPrintsWithSheet, true );
     133                 :          0 : }
     134                 :            : 
     135                 :          0 : void ShapeAnchor::setCellPos( sal_Int32 nElement, sal_Int32 nParentContext, const OUString& rValue )
     136                 :            : {
     137                 :          0 :     CellAnchorModel* pCellAnchor = 0;
     138      [ #  #  # ]:          0 :     switch( nParentContext )
     139                 :            :     {
     140                 :            :         case XDR_TOKEN( from ):
     141                 :            :             OSL_ENSURE( (meAnchorType == ANCHOR_ONECELL) || (meAnchorType == ANCHOR_TWOCELL), "ShapeAnchor::setCellPos - unexpected 'xdr:from' element" );
     142                 :          0 :             pCellAnchor = &maFrom;
     143                 :          0 :         break;
     144                 :            :         case XDR_TOKEN( to ):
     145                 :            :             OSL_ENSURE( meAnchorType == ANCHOR_TWOCELL, "ShapeAnchor::setCellPos - unexpected 'xdr:to' element" );
     146                 :          0 :             pCellAnchor = &maTo;
     147                 :          0 :         break;
     148                 :            :         default:
     149                 :            :             OSL_ENSURE( false, "ShapeAnchor::setCellPos - unexpected parent element" );
     150                 :            :     }
     151 [ #  # ][ #  #  :          0 :     if( pCellAnchor ) switch( nElement )
                #  #  # ]
     152                 :            :     {
     153                 :          0 :         case XDR_TOKEN( col ):      pCellAnchor->mnCol = rValue.toInt32();          break;
     154                 :          0 :         case XDR_TOKEN( row ):      pCellAnchor->mnRow = rValue.toInt32();          break;
     155                 :          0 :         case XDR_TOKEN( colOff ):   pCellAnchor->mnColOffset = rValue.toInt64();    break;
     156                 :          0 :         case XDR_TOKEN( rowOff ):   pCellAnchor->mnRowOffset = rValue.toInt64();    break;
     157                 :            :         default:    OSL_ENSURE( false, "ShapeAnchor::setCellPos - unexpected element" );
     158                 :            :     }
     159                 :          0 : }
     160                 :            : 
     161                 :          6 : void ShapeAnchor::importVmlAnchor( const OUString& rAnchor )
     162                 :            : {
     163                 :          6 :     meAnchorType = ANCHOR_VML;
     164                 :          6 :     meCellAnchorType = CELLANCHOR_PIXEL;
     165                 :            : 
     166         [ +  - ]:          6 :     ::std::vector< OUString > aTokens;
     167                 :          6 :     sal_Int32 nIndex = 0;
     168         [ +  + ]:         54 :     while( nIndex >= 0 )
     169         [ +  - ]:         48 :         aTokens.push_back( rAnchor.getToken( 0, ',', nIndex ).trim() );
     170                 :            : 
     171                 :            :     OSL_ENSURE( aTokens.size() >= 8, "ShapeAnchor::importVmlAnchor - missing anchor tokens" );
     172         [ +  - ]:          6 :     if( aTokens.size() >= 8 )
     173                 :            :     {
     174                 :          6 :         maFrom.mnCol       = aTokens[ 0 ].toInt32();
     175                 :          6 :         maFrom.mnColOffset = aTokens[ 1 ].toInt32();
     176                 :          6 :         maFrom.mnRow       = aTokens[ 2 ].toInt32();
     177                 :          6 :         maFrom.mnRowOffset = aTokens[ 3 ].toInt32();
     178                 :          6 :         maTo.mnCol         = aTokens[ 4 ].toInt32();
     179                 :          6 :         maTo.mnColOffset   = aTokens[ 5 ].toInt32();
     180                 :          6 :         maTo.mnRow         = aTokens[ 6 ].toInt32();
     181                 :          6 :         maTo.mnRowOffset   = aTokens[ 7 ].toInt32();
     182                 :          6 :     }
     183                 :          6 : }
     184                 :            : 
     185                 :          6 : EmuRectangle ShapeAnchor::calcAnchorRectEmu( const Size& rPageSizeHmm ) const
     186                 :            : {
     187         [ +  - ]:          6 :     AddressConverter& rAddrConv = getAddressConverter();
     188                 :          6 :     EmuSize aPageSize( lclHmmToEmu( rPageSizeHmm.Width ), lclHmmToEmu( rPageSizeHmm.Height ) );
     189                 :          6 :     EmuRectangle aAnchorRect( -1, -1, -1, -1 );
     190                 :            : 
     191                 :            :     // calculate shape position
     192   [ -  +  -  - ]:          6 :     switch( meAnchorType )
     193                 :            :     {
     194                 :            :         case ANCHOR_ABSOLUTE:
     195                 :            :             OSL_ENSURE( maPos.isValid(), "ShapeAnchor::calcAnchorRectEmu - invalid position" );
     196 [ #  # ][ #  # ]:          0 :             if( maPos.isValid() && (maPos.X < aPageSize.Width) && (maPos.Y < aPageSize.Height) )
         [ #  # ][ #  # ]
     197                 :          0 :                 aAnchorRect.setPos( maPos );
     198                 :          0 :         break;
     199                 :            :         case ANCHOR_ONECELL:
     200                 :            :         case ANCHOR_TWOCELL:
     201                 :            :         case ANCHOR_VML:
     202                 :            :             OSL_ENSURE( maFrom.isValid(), "ShapeAnchor::calcAnchorRectEmu - invalid position" );
     203 [ +  - ][ +  - ]:          6 :             if( maFrom.isValid() && rAddrConv.checkCol( maFrom.mnCol, true ) && rAddrConv.checkRow( maFrom.mnRow, true ) )
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
     204                 :            :             {
     205         [ +  - ]:          6 :                 EmuPoint aPoint = calcCellAnchorEmu( maFrom );
     206 [ +  - ][ +  - ]:          6 :                 if( (aPoint.X < aPageSize.Width) && (aPoint.Y < aPageSize.Height) )
     207                 :          6 :                     aAnchorRect.setPos( aPoint );
     208                 :            :             }
     209                 :          6 :         break;
     210                 :            :         case ANCHOR_INVALID:
     211                 :            :             OSL_ENSURE( false, "ShapeAnchor::calcAnchorRectEmu - invalid anchor" );
     212                 :          0 :         break;
     213                 :            :     }
     214                 :            : 
     215                 :            :     // calculate shape size
     216 [ +  - ][ +  - ]:          6 :     if( (aAnchorRect.X >= 0) && (aAnchorRect.Y >= 0) ) switch( meAnchorType )
           [ -  +  -  - ]
     217                 :            :     {
     218                 :            :         case ANCHOR_ABSOLUTE:
     219                 :            :         case ANCHOR_ONECELL:
     220                 :            :             OSL_ENSURE( maSize.isValid(), "ShapeAnchor::calcAnchorRectEmu - invalid size" );
     221         [ #  # ]:          0 :             if( maSize.isValid() )
     222                 :            :             {
     223         [ #  # ]:          0 :                 aAnchorRect.Width = ::std::min< sal_Int64 >( maSize.Width, aPageSize.Width - aAnchorRect.X );
     224         [ #  # ]:          0 :                 aAnchorRect.Height = ::std::min< sal_Int64 >( maSize.Height, aPageSize.Height - aAnchorRect.Y );
     225                 :            :             }
     226                 :          0 :         break;
     227                 :            :         case ANCHOR_TWOCELL:
     228                 :            :         case ANCHOR_VML:
     229                 :            :             OSL_ENSURE( maTo.isValid(), "ShapeAnchor::calcAnchorRectEmu - invalid position" );
     230         [ +  - ]:          6 :             if( maTo.isValid() )
     231                 :            :             {
     232                 :            :                 /*  Pass a valid cell address to calcCellAnchorEmu(), otherwise
     233                 :            :                     nothing useful is returned, even if either row or column is valid. */
     234 [ +  - ][ +  - ]:          6 :                 CellAddress aToCell = rAddrConv.createValidCellAddress( BinAddress( maTo.mnCol, maTo.mnRow ), getSheetIndex(), true );
     235                 :          6 :                 CellAnchorModel aValidTo = maTo;
     236                 :          6 :                 aValidTo.mnCol = aToCell.Column;
     237                 :          6 :                 aValidTo.mnRow = aToCell.Row;
     238         [ +  - ]:          6 :                 EmuPoint aPoint = calcCellAnchorEmu( aValidTo );
     239                 :            :                 // width (if column index is valid, use the calculated offset, otherwise stretch to maximum available X position)
     240                 :          6 :                 aAnchorRect.Width = aPageSize.Width - aAnchorRect.X;
     241         [ +  - ]:          6 :                 if( aToCell.Column == maTo.mnCol )
     242         [ +  - ]:          6 :                     aAnchorRect.Width = ::std::min< sal_Int64 >( aPoint.X - aAnchorRect.X + 1, aAnchorRect.Width );
     243                 :            :                 // height (if row index is valid, use the calculated offset, otherwise stretch to maximum available Y position)
     244                 :          6 :                 aAnchorRect.Height = aPageSize.Height - aAnchorRect.Y;
     245         [ +  - ]:          6 :                 if( aToCell.Row == maTo.mnRow )
     246         [ +  - ]:          6 :                     aAnchorRect.Height = ::std::min< sal_Int64 >( aPoint.Y - aAnchorRect.Y + 1, aAnchorRect.Height );
     247                 :            :             }
     248                 :          6 :         break;
     249                 :            :         case ANCHOR_INVALID:
     250                 :          6 :         break;
     251                 :            :     }
     252                 :            : 
     253                 :            :     // add 0.75 mm (27,000 EMUs) in X direction to correct display error
     254         [ +  - ]:          6 :     if( aAnchorRect.X >= 0 )
     255                 :          6 :         aAnchorRect.X += 27000;
     256                 :            :     // remove 0.25 mm (9,000 EMUs) in Y direction to correct display error
     257         [ +  + ]:          6 :     if( aAnchorRect.Y >= 9000 )
     258                 :          6 :         aAnchorRect.Y -= 9000;
     259                 :            : 
     260                 :          6 :     return aAnchorRect;
     261                 :            : }
     262                 :            : 
     263                 :          6 : Rectangle ShapeAnchor::calcAnchorRectHmm( const Size& rPageSizeHmm ) const
     264                 :            : {
     265         [ +  - ]:          6 :     EmuRectangle aAnchorRect = calcAnchorRectEmu( rPageSizeHmm );
     266 [ +  - ][ +  - ]:          6 :     return Rectangle( lclEmuToHmm( aAnchorRect.X ), lclEmuToHmm( aAnchorRect.Y ), lclEmuToHmm( aAnchorRect.Width ), lclEmuToHmm( aAnchorRect.Height ) );
         [ +  - ][ +  - ]
     267                 :            : }
     268                 :            : 
     269                 :         12 : EmuPoint ShapeAnchor::calcCellAnchorEmu( const CellAnchorModel& rModel ) const
     270                 :            : {
     271                 :            :     // calculate position of top-left edge of the cell
     272         [ +  - ]:         12 :     Point aPoint = getCellPosition( rModel.mnCol, rModel.mnRow );
     273                 :         12 :     EmuPoint aEmuPoint( lclHmmToEmu( aPoint.X ), lclHmmToEmu( aPoint.Y ) );
     274                 :            : 
     275                 :            :     // add the offset inside the cell
     276   [ -  +  -  - ]:         12 :     switch( meCellAnchorType )
     277                 :            :     {
     278                 :            :         case CELLANCHOR_EMU:
     279                 :          0 :             aEmuPoint.X += rModel.mnColOffset;
     280                 :          0 :             aEmuPoint.Y += rModel.mnRowOffset;
     281                 :          0 :         break;
     282                 :            : 
     283                 :            :         case CELLANCHOR_PIXEL:
     284                 :            :         {
     285         [ +  - ]:         12 :             const UnitConverter& rUnitConv = getUnitConverter();
     286         [ +  - ]:         12 :             aEmuPoint.X += static_cast< sal_Int64 >( rUnitConv.scaleValue( static_cast< double >( rModel.mnColOffset ), UNIT_SCREENX, UNIT_EMU ) );
     287         [ +  - ]:         12 :             aEmuPoint.Y += static_cast< sal_Int64 >( rUnitConv.scaleValue( static_cast< double >( rModel.mnRowOffset ), UNIT_SCREENY, UNIT_EMU ) );
     288                 :            :         }
     289                 :         12 :         break;
     290                 :            : 
     291                 :            :         case CELLANCHOR_COLROW:
     292                 :            :         {
     293         [ #  # ]:          0 :             Size aCellSize = getCellSize( rModel.mnCol, rModel.mnRow );
     294                 :          0 :             EmuSize aEmuSize( lclHmmToEmu( aCellSize.Width ), lclHmmToEmu( aCellSize.Height ) );
     295                 :            :             // X offset is given in 1/1024 of column width
     296         [ #  # ]:          0 :             aEmuPoint.X += static_cast< sal_Int64 >( aEmuSize.Width * getLimitedValue< double >( static_cast< double >( rModel.mnColOffset ) / 1024.0, 0.0, 1.0 ) + 0.5 );
     297                 :            :             // Y offset is given in 1/256 of row height
     298         [ #  # ]:          0 :             aEmuPoint.Y += static_cast< sal_Int64 >( aEmuSize.Height * getLimitedValue< double >( static_cast< double >( rModel.mnRowOffset ) / 256.0, 0.0, 1.0 ) + 0.5 );
     299                 :            :         }
     300                 :         12 :         break;
     301                 :            :     }
     302                 :            : 
     303                 :         12 :     return aEmuPoint;
     304                 :            : }
     305                 :            : 
     306                 :            : // ============================================================================
     307                 :            : 
     308                 :            : } // namespace xls
     309 [ +  - ][ +  - ]:         24 : } // namespace oox
     310                 :            : 
     311                 :            : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10