LCOV - code coverage report
Current view: top level - sdext/source/pdfimport/tree - genericelements.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 97 231 42.0 %
Date: 2012-08-25 Functions: 21 30 70.0 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 74 302 24.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                 :            : 
      30                 :            : #include "xmlemitter.hxx"
      31                 :            : #include "genericelements.hxx"
      32                 :            : #include "pdfiprocessor.hxx"
      33                 :            : #include "pdfihelper.hxx"
      34                 :            : #include "style.hxx"
      35                 :            : 
      36                 :            : 
      37                 :            : #include <basegfx/polygon/b2dpolypolygontools.hxx>
      38                 :            : #include <basegfx/range/b2drange.hxx>
      39                 :            : 
      40                 :            : namespace pdfi
      41                 :            : {
      42                 :            : 
      43                 :          6 : ElementFactory::~ElementFactory()
      44                 :            : {
      45         [ -  + ]:         12 : }
      46                 :            : 
      47                 :        801 : Element::~Element()
      48                 :            : {
      49         [ +  + ]:       1026 :     while( !Children.empty() )
      50                 :            :     {
      51         [ +  - ]:        225 :         Element* pCurr( Children.front() );
      52 [ +  - ][ +  - ]:        225 :         delete pCurr;
      53         [ +  - ]:        225 :         Children.pop_front();
      54                 :            :     }
      55         [ -  + ]:        801 : }
      56                 :            : 
      57                 :        288 : void Element::applyToChildren( ElementTreeVisitor& rVisitor )
      58                 :            : {
      59         [ +  + ]:        732 :     for( std::list< Element* >::iterator it = Children.begin(); it != Children.end(); ++it )
      60         [ +  - ]:        444 :         (*it)->visitedBy( rVisitor, it );
      61                 :        288 : }
      62                 :            : 
      63                 :          0 : void Element::setParent( std::list<Element*>::iterator& el, Element* pNewParent )
      64                 :            : {
      65         [ #  # ]:          0 :     if( pNewParent )
      66                 :            :     {
      67                 :          0 :         pNewParent->Children.splice( pNewParent->Children.end(), (*el)->Parent->Children, el );
      68                 :          0 :         (*el)->Parent = pNewParent;
      69                 :            :     }
      70                 :          0 : }
      71                 :            : 
      72                 :       1806 : void Element::updateGeometryWith( const Element* pMergeFrom )
      73                 :            : {
      74 [ +  + ][ +  + ]:       1806 :     if( w == 0 && h == 0 )
      75                 :            :     {
      76                 :        132 :         x = pMergeFrom->x;
      77                 :        132 :         y = pMergeFrom->y;
      78                 :        132 :         w = pMergeFrom->w;
      79                 :        132 :         h = pMergeFrom->h;
      80                 :            :     }
      81                 :            :     else
      82                 :            :     {
      83         [ -  + ]:       1674 :         if( pMergeFrom->x < x )
      84                 :            :         {
      85                 :          0 :             w += x - pMergeFrom->x;
      86                 :          0 :             x = pMergeFrom->x;
      87                 :            :         }
      88         [ +  - ]:       1674 :         if( pMergeFrom->x+pMergeFrom->w > x+w )
      89                 :       1674 :             w = pMergeFrom->w+pMergeFrom->x - x;
      90         [ -  + ]:       1674 :         if( pMergeFrom->y < y )
      91                 :            :         {
      92                 :          0 :             h += y - pMergeFrom->y;
      93                 :          0 :             y = pMergeFrom->y;
      94                 :            :         }
      95         [ -  + ]:       1674 :         if( pMergeFrom->y+pMergeFrom->h > y+h )
      96                 :          0 :             h = pMergeFrom->h+pMergeFrom->y - y;
      97                 :            :     }
      98                 :       1806 : }
      99                 :            : 
     100                 :            : 
     101                 :            : #if OSL_DEBUG_LEVEL > 1
     102                 :            : #include <typeinfo>
     103                 :            : void Element::emitStructure( int nLevel)
     104                 :            : {
     105                 :            :     OSL_TRACE( "%*s<%s %p> (%.1f,%.1f)+(%.1fx%.1f)\n",
     106                 :            :                nLevel, "", typeid( *this ).name(), this,
     107                 :            :                x, y, w, h );
     108                 :            :     for( std::list< Element* >::iterator it = Children.begin(); it != Children.end(); ++it )
     109                 :            :         (*it)->emitStructure(nLevel+1 );
     110                 :            :     OSL_TRACE( "%*s</%s>", nLevel, "", typeid( *this ).name() );
     111                 :            : }
     112                 :            : #endif
     113                 :            : 
     114                 :          0 : void ListElement::visitedBy( ElementTreeVisitor& visitor, const std::list< Element* >::const_iterator& )
     115                 :            : {
     116                 :            :     // this is only an inner node
     117                 :          0 :     applyToChildren(visitor);
     118                 :          0 : }
     119                 :            : 
     120                 :          0 : void HyperlinkElement::visitedBy( ElementTreeVisitor&                          rVisitor,
     121                 :            :                                   const std::list< Element* >::const_iterator& rParentIt )
     122                 :            : {
     123                 :          0 :     rVisitor.visit(*this,rParentIt);
     124                 :          0 : }
     125                 :            : 
     126                 :        231 : void TextElement::visitedBy( ElementTreeVisitor&                          rVisitor,
     127                 :            :                              const std::list< Element* >::const_iterator& rParentIt )
     128                 :            : {
     129                 :        231 :     rVisitor.visit(*this,rParentIt);
     130                 :        231 : }
     131                 :            : 
     132                 :        231 : void FrameElement::visitedBy( ElementTreeVisitor&                          rVisitor,
     133                 :            :                               const std::list< Element* >::const_iterator& rParentIt )
     134                 :            : {
     135                 :        231 :     rVisitor.visit(*this,rParentIt);
     136                 :        231 : }
     137                 :            : 
     138                 :          0 : void ImageElement::visitedBy( ElementTreeVisitor&                          rVisitor,
     139                 :            :                               const std::list< Element* >::const_iterator& rParentIt)
     140                 :            : {
     141                 :          0 :     rVisitor.visit( *this, rParentIt);
     142                 :          0 : }
     143                 :            : 
     144                 :         18 : PolyPolyElement::PolyPolyElement( Element*                       pParent,
     145                 :            :                                   sal_Int32                      nGCId,
     146                 :            :                                   const basegfx::B2DPolyPolygon& rPolyPoly,
     147                 :            :                                   sal_Int8                       nAction )
     148                 :            :     : DrawElement( pParent, nGCId ),
     149                 :            :       PolyPoly( rPolyPoly ),
     150         [ +  - ]:         18 :       Action( nAction )
     151                 :            : {
     152                 :         18 : }
     153                 :            : 
     154                 :         45 : void PolyPolyElement::updateGeometry()
     155                 :            : {
     156         [ +  - ]:         45 :     basegfx::B2DRange aRange;
     157 [ +  - ][ +  + ]:         45 :     if( PolyPoly.areControlPointsUsed() )
     158 [ +  - ][ +  - ]:         15 :         aRange = basegfx::tools::getRange( basegfx::tools::adaptiveSubdivideByAngle( PolyPoly ) );
                 [ +  - ]
     159                 :            :     else
     160         [ +  - ]:         30 :         aRange = basegfx::tools::getRange( PolyPoly );
     161         [ +  - ]:         45 :     x = aRange.getMinX();
     162         [ +  - ]:         45 :     y = aRange.getMinY();
     163         [ +  - ]:         45 :     w = aRange.getWidth();
     164         [ +  - ]:         45 :     h = aRange.getHeight();
     165                 :            : 
     166                 :            :     // fdo#32330 - non-closed paths will not show up filled in LibO
     167         [ +  + ]:         45 :     if( Action & (PATH_FILL | PATH_EOFILL) )
     168         [ +  - ]:         15 :         PolyPoly.setClosed(true);
     169                 :         45 : }
     170                 :            : 
     171                 :         63 : void PolyPolyElement::visitedBy( ElementTreeVisitor&                          rVisitor,
     172                 :            :                                  const std::list< Element* >::const_iterator& rParentIt)
     173                 :            : {
     174                 :         63 :     rVisitor.visit( *this, rParentIt);
     175                 :         63 : }
     176                 :            : 
     177                 :            : #if OSL_DEBUG_LEVEL > 1
     178                 :            : void PolyPolyElement::emitStructure( int nLevel)
     179                 :            : {
     180                 :            :     OSL_TRACE( "%*s<%s %p>", nLevel, "", typeid( *this ).name(), this  );
     181                 :            :     OSL_TRACE( "path=" );
     182                 :            :     int nPoly = PolyPoly.count();
     183                 :            :     for( int i = 0; i < nPoly; i++ )
     184                 :            :     {
     185                 :            :         basegfx::B2DPolygon aPoly = PolyPoly.getB2DPolygon( i );
     186                 :            :         int nPoints = aPoly.count();
     187                 :            :         for( int n = 0; n < nPoints; n++ )
     188                 :            :         {
     189                 :            :             basegfx::B2DPoint aPoint = aPoly.getB2DPoint( n );
     190                 :            :             OSL_TRACE( " (%g,%g)", aPoint.getX(), aPoint.getY() );
     191                 :            :         }
     192                 :            :         OSL_TRACE( "\n" );
     193                 :            :     }
     194                 :            :     for( std::list< Element* >::iterator it = Children.begin(); it != Children.end(); ++it )
     195                 :            :         (*it)->emitStructure( nLevel+1 );
     196                 :            :     OSL_TRACE( "%*s</%s>", nLevel, "", typeid( *this ).name() );
     197                 :            : }
     198                 :            : #endif
     199                 :            : 
     200                 :        234 : void ParagraphElement::visitedBy( ElementTreeVisitor&                          rVisitor,
     201                 :            :                                   const std::list< Element* >::const_iterator& rParentIt )
     202                 :            : {
     203                 :        234 :     rVisitor.visit(*this,rParentIt);
     204                 :        234 : }
     205                 :            : 
     206                 :          0 : bool ParagraphElement::isSingleLined( PDFIProcessor& rProc ) const
     207                 :            : {
     208                 :          0 :     std::list< Element* >::const_iterator it = Children.begin();
     209                 :          0 :     TextElement* pText = NULL, *pLastText = NULL;
     210         [ #  # ]:          0 :     while( it != Children.end() )
     211                 :            :     {
     212                 :            :         // a paragraph containing subparagraphs cannot be single lined
     213 [ #  # ][ #  # ]:          0 :         if( dynamic_cast< ParagraphElement* >(*it) != NULL )
                 [ #  # ]
     214                 :          0 :             return false;
     215                 :            : 
     216         [ #  # ]:          0 :         pText = dynamic_cast< TextElement* >(*it);
     217         [ #  # ]:          0 :         if( pText )
     218                 :            :         {
     219         [ #  # ]:          0 :             const FontAttributes& rFont = rProc.getFont( pText->FontId );
     220         [ #  # ]:          0 :             if( pText->h > rFont.size*1.5 )
     221                 :          0 :                 return  false;
     222         [ #  # ]:          0 :             if( pLastText )
     223                 :            :             {
     224 [ #  # ][ #  # ]:          0 :                 if( pText->y > pLastText->y+pLastText->h ||
     225                 :            :                     pLastText->y > pText->y+pText->h )
     226                 :          0 :                     return false;
     227                 :            :             }
     228                 :            :             else
     229                 :          0 :                 pLastText = pText;
     230                 :            :         }
     231                 :          0 :         ++it;
     232                 :            :     }
     233                 :            : 
     234                 :            :     // a paragraph without a single text is not considered single lined
     235                 :          0 :     return pLastText != NULL;
     236                 :            : }
     237                 :            : 
     238                 :          0 : double ParagraphElement::getLineHeight( PDFIProcessor& rProc ) const
     239                 :            : {
     240                 :          0 :     double line_h = 0;
     241         [ #  # ]:          0 :     for( std::list< Element* >::const_iterator it = Children.begin(); it != Children.end(); ++it )
     242                 :            :     {
     243         [ #  # ]:          0 :         ParagraphElement* pPara = dynamic_cast< ParagraphElement* >(*it);
     244                 :          0 :         TextElement* pText = NULL;
     245         [ #  # ]:          0 :         if( pPara )
     246                 :            :         {
     247         [ #  # ]:          0 :             double lh = pPara->getLineHeight( rProc );
     248         [ #  # ]:          0 :             if( lh > line_h )
     249                 :          0 :                 line_h = lh;
     250                 :            :         }
     251 [ #  # ][ #  # ]:          0 :         else if( (pText = dynamic_cast< TextElement* >( *it )) != NULL )
     252                 :            :         {
     253         [ #  # ]:          0 :             const FontAttributes& rFont = rProc.getFont( pText->FontId );
     254                 :          0 :             double lh = pText->h;
     255         [ #  # ]:          0 :             if( pText->h > rFont.size*1.5 )
     256                 :          0 :                 lh = rFont.size;
     257         [ #  # ]:          0 :             if( lh > line_h )
     258                 :          0 :                 line_h = lh;
     259                 :            :         }
     260                 :            :     }
     261                 :          0 :     return line_h;
     262                 :            : }
     263                 :            : 
     264                 :          0 : TextElement* ParagraphElement::getFirstTextChild() const
     265                 :            : {
     266                 :          0 :     TextElement* pText = NULL;
     267 [ #  # ][ #  # ]:          0 :     for( std::list< Element* >::const_iterator it = Children.begin();
                 [ #  # ]
     268         [ #  # ]:          0 :          it != Children.end() && ! pText; ++it )
     269                 :            :     {
     270         [ #  # ]:          0 :         pText = dynamic_cast<TextElement*>(*it);
     271                 :            :     }
     272                 :          0 :     return pText;
     273                 :            : }
     274                 :            : 
     275         [ +  - ]:          6 : PageElement::~PageElement()
     276                 :            : {
     277         [ -  + ]:          6 :     if( HeaderElement )
     278 [ #  # ][ #  # ]:          0 :         delete HeaderElement;
     279         [ -  + ]:          6 :     if( FooterElement )
     280 [ #  # ][ #  # ]:          0 :         delete FooterElement;
     281         [ -  + ]:         12 : }
     282                 :            : 
     283                 :         18 : void PageElement::visitedBy( ElementTreeVisitor&                          rVisitor,
     284                 :            :                              const std::list< Element* >::const_iterator& rParentIt )
     285                 :            : {
     286                 :         18 :      rVisitor.visit(*this, rParentIt);
     287                 :         18 : }
     288                 :            : 
     289                 :          0 : void PageElement::updateParagraphGeometry( Element* pEle )
     290                 :            : {
     291                 :            :     // update geometry of children
     292         [ #  # ]:          0 :     for( std::list< Element* >::iterator it = pEle->Children.begin();
     293                 :          0 :          it != pEle->Children.end(); ++it )
     294                 :            :     {
     295         [ #  # ]:          0 :         updateParagraphGeometry( *it );
     296                 :            :     }
     297                 :            :     // if this is a paragraph itself, then update according to children geometry
     298 [ #  # ][ #  # ]:          0 :     if( dynamic_cast<ParagraphElement*>(pEle) )
                 [ #  # ]
     299                 :            :     {
     300         [ #  # ]:          0 :         for( std::list< Element* >::iterator it = pEle->Children.begin();
     301                 :          0 :              it != pEle->Children.end(); ++it )
     302                 :            :         {
     303                 :          0 :             Element* pChild = NULL;
     304         [ #  # ]:          0 :             TextElement* pText = dynamic_cast<TextElement*>(*it);
     305         [ #  # ]:          0 :             if( pText )
     306                 :          0 :                 pChild = pText;
     307                 :            :             else
     308                 :            :             {
     309         [ #  # ]:          0 :                 ParagraphElement* pPara = dynamic_cast<ParagraphElement*>(*it);
     310         [ #  # ]:          0 :                 if( pPara )
     311                 :          0 :                     pChild = pPara;
     312                 :            :             }
     313         [ #  # ]:          0 :             if( pChild )
     314                 :          0 :                 pEle->updateGeometryWith( pChild );
     315                 :            :         }
     316                 :            :     }
     317                 :          0 : }
     318                 :            : 
     319                 :          6 : bool PageElement::resolveHyperlink( std::list<Element*>::iterator link_it, std::list<Element*>& rElements )
     320                 :            : {
     321         [ -  + ]:          6 :     HyperlinkElement* pLink = dynamic_cast<HyperlinkElement*>(*link_it);
     322         [ -  + ]:          6 :     if( ! pLink ) // sanity check
     323                 :          0 :         return false;
     324                 :            : 
     325         [ +  + ]:         90 :     for( std::list<Element*>::iterator it = rElements.begin(); it != rElements.end(); ++it )
     326                 :            :     {
     327 [ +  - ][ -  +  :         84 :         if( (*it)->x >= pLink->x && (*it)->x + (*it)->w <= pLink->x + pLink->w &&
             #  #  #  # ]
                 [ -  + ]
     328                 :          0 :             (*it)->y >= pLink->y && (*it)->y + (*it)->h <= pLink->y + pLink->h )
     329                 :            :         {
     330         [ #  # ]:          0 :             TextElement* pText = dynamic_cast<TextElement*>(*it);
     331         [ #  # ]:          0 :             if( pText )
     332                 :            :             {
     333         [ #  # ]:          0 :                 if( pLink->Children.empty() )
     334                 :            :                 {
     335                 :            :                     // insert the hyperlink before the frame
     336         [ #  # ]:          0 :                     rElements.splice( it, Hyperlinks.Children, link_it );
     337                 :          0 :                     pLink->Parent = (*it)->Parent;
     338                 :            :                 }
     339                 :            :                 // move text element into hyperlink
     340                 :          0 :                 std::list<Element*>::iterator next = it;
     341                 :          0 :                 ++next;
     342         [ #  # ]:          0 :                 Element::setParent( it, pLink );
     343                 :          0 :                 it = next;
     344                 :          0 :                 --it;
     345                 :          0 :                 continue;
     346                 :            :             }
     347                 :            :             // a link can contain multiple text elements or a single frame
     348         [ #  # ]:          0 :             if( ! pLink->Children.empty() )
     349                 :          0 :                 continue;
     350 [ #  # ][ #  # ]:          0 :             if( dynamic_cast<ParagraphElement*>(*it)  )
                 [ #  # ]
     351                 :            :             {
     352 [ #  # ][ #  # ]:          0 :                 if( resolveHyperlink( link_it, (*it)->Children ) )
     353                 :          0 :                     break;
     354                 :          0 :                 continue;
     355                 :            :             }
     356         [ #  # ]:          0 :             FrameElement* pFrame = dynamic_cast<FrameElement*>(*it);
     357         [ #  # ]:          0 :             if( pFrame )
     358                 :            :             {
     359                 :            :                 // insert the hyperlink before the frame
     360         [ #  # ]:          0 :                 rElements.splice( it, Hyperlinks.Children, link_it );
     361                 :          0 :                 pLink->Parent = (*it)->Parent;
     362                 :            :                 // move frame into hyperlink
     363         [ #  # ]:          0 :                 Element::setParent( it, pLink );
     364                 :          0 :                 break;
     365                 :            :             }
     366                 :            :         }
     367                 :            :     }
     368                 :          6 :     return ! pLink->Children.empty();
     369                 :            : }
     370                 :            : 
     371                 :          6 : void PageElement::resolveHyperlinks()
     372                 :            : {
     373         [ +  + ]:         12 :     while( ! Hyperlinks.Children.empty() )
     374                 :            :     {
     375         [ +  - ]:          6 :         if( ! resolveHyperlink( Hyperlinks.Children.begin(), Children ) )
     376                 :            :         {
     377         [ +  - ]:          6 :             delete Hyperlinks.Children.front();
     378                 :          6 :             Hyperlinks.Children.pop_front();
     379                 :            :         }
     380                 :            :     }
     381                 :          6 : }
     382                 :            : 
     383                 :          6 : void PageElement::resolveFontStyles( PDFIProcessor& rProc )
     384                 :            : {
     385                 :          6 :     resolveUnderlines(rProc);
     386                 :          6 : }
     387                 :            : 
     388                 :          6 : void PageElement::resolveUnderlines( PDFIProcessor& rProc )
     389                 :            : {
     390                 :            :     // FIXME: currently the algorithm used is quadratic
     391                 :            :     // this could be solved by some sorting beforehand
     392                 :            : 
     393                 :          6 :     std::list< Element* >::iterator poly_it = Children.begin();
     394         [ +  + ]:         90 :     while( poly_it != Children.end() )
     395                 :            :     {
     396         [ -  + ]:         84 :         PolyPolyElement* pPoly = dynamic_cast< PolyPolyElement* >(*poly_it);
     397 [ +  + ][ -  + ]:         84 :         if( ! pPoly || ! pPoly->Children.empty() )
                 [ +  + ]
     398                 :            :         {
     399                 :         66 :             ++poly_it;
     400                 :         66 :             continue;
     401                 :            :         }
     402                 :            :         /* check for: no filling
     403                 :            :         *             only two points (FIXME: handle small rectangles, too)
     404                 :            :         *             y coordinates of points are equal
     405                 :            :         */
     406         [ +  + ]:         18 :         if( pPoly->Action != PATH_STROKE )
     407                 :            :         {
     408                 :          6 :             ++poly_it;
     409                 :          6 :             continue;
     410                 :            :         }
     411 [ +  - ][ -  + ]:         12 :         if( pPoly->PolyPoly.count() != 1 )
     412                 :            :         {
     413                 :          0 :             ++poly_it;
     414                 :          0 :             continue;
     415                 :            :         }
     416                 :            : 
     417                 :         12 :         bool bRemovePoly = false;
     418         [ +  - ]:         12 :         basegfx::B2DPolygon aPoly = pPoly->PolyPoly.getB2DPolygon(0);
     419         [ +  - ]:         36 :         if( aPoly.count() != 2 ||
           [ +  -  +  - ]
                 [ +  - ]
     420 [ +  - ][ +  - ]:         24 :             aPoly.getB2DPoint(0).getY() != aPoly.getB2DPoint(1).getY() )
         [ +  - ][ +  - ]
           [ #  #  #  # ]
     421                 :            :         {
     422                 :         12 :             ++poly_it;
     423                 :         12 :             continue;
     424                 :            :         }
     425         [ #  # ]:          0 :         double l_x = aPoly.getB2DPoint(0).getX();
     426         [ #  # ]:          0 :         double r_x = aPoly.getB2DPoint(1).getX();
     427                 :            :         double u_y;
     428         [ #  # ]:          0 :         if( r_x < l_x )
     429                 :            :         {
     430                 :          0 :             u_y = r_x; r_x = l_x; l_x = u_y;
     431                 :            :         }
     432         [ #  # ]:          0 :         u_y = aPoly.getB2DPoint(0).getY();
     433         [ #  # ]:          0 :         for( std::list< Element*>::iterator it = Children.begin();
     434                 :          0 :              it != Children.end(); ++it )
     435                 :            :         {
     436                 :          0 :             Element* pEle = *it;
     437 [ #  # ][ #  # ]:          0 :             if( pEle->y <= u_y && pEle->y + pEle->h*1.1 >= u_y )
     438                 :            :             {
     439                 :            :                 // first: is the element underlined completely ?
     440 [ #  # ][ #  # ]:          0 :                 if( pEle->x + pEle->w*0.1 >= l_x &&
     441                 :            :                     pEle->x + pEle->w*0.9 <= r_x )
     442                 :            :                 {
     443         [ #  # ]:          0 :                     TextElement* pText = dynamic_cast< TextElement* >(pEle);
     444         [ #  # ]:          0 :                     if( pText )
     445                 :            :                     {
     446         [ #  # ]:          0 :                         const GraphicsContext& rTextGC = rProc.getGraphicsContext( pText->GCId );
     447 [ #  # ][ #  # ]:          0 :                         if( ! rTextGC.isRotatedOrSkewed() )
     448                 :            :                         {
     449                 :          0 :                             bRemovePoly = true;
     450                 :            :                             // retrieve ID for modified font
     451         [ #  # ]:          0 :                             FontAttributes aAttr = rProc.getFont( pText->FontId );
     452                 :          0 :                             aAttr.isUnderline = true;
     453         [ #  # ]:          0 :                             pText->FontId = rProc.getFontId( aAttr );
     454                 :            :                         }
     455                 :            :                     }
     456 [ #  # ][ #  # ]:          0 :                     else if( dynamic_cast< HyperlinkElement* >(pEle) )
                 [ #  # ]
     457                 :          0 :                         bRemovePoly = true;
     458                 :            :                 }
     459                 :            :                 // second: hyperlinks may be larger than their underline
     460                 :            :                 // since they are just arbitrary rectangles in the action definition
     461 [ #  # ][ #  # ]:          0 :                 else if( dynamic_cast< HyperlinkElement* >(pEle) != NULL &&
         [ #  # ][ #  # ]
                 [ #  # ]
     462                 :            :                          l_x >= pEle->x && r_x <= pEle->x+pEle->w )
     463                 :            :                 {
     464                 :          0 :                     bRemovePoly = true;
     465                 :            :                 }
     466                 :            :             }
     467                 :            :         }
     468         [ #  # ]:          0 :         if( bRemovePoly )
     469                 :            :         {
     470                 :          0 :             std::list< Element* >::iterator next_it = poly_it;
     471                 :          0 :             ++next_it;
     472         [ #  # ]:          0 :             Children.erase( poly_it );
     473 [ #  # ][ #  # ]:          0 :             delete pPoly;
     474                 :          0 :             poly_it = next_it;
     475                 :            :         }
     476                 :            :         else
     477                 :          0 :             ++poly_it;
     478 [ +  - ][ -  + ]:         84 :     }
     479                 :          6 : }
     480                 :            : 
     481                 :          6 : DocumentElement::~DocumentElement()
     482                 :            : {
     483         [ -  + ]:         12 : }
     484                 :            : 
     485                 :         18 : void DocumentElement::visitedBy( ElementTreeVisitor&                          rVisitor,
     486                 :            :                                  const std::list< Element* >::const_iterator& rParentIt)
     487                 :            : {
     488                 :         18 :     rVisitor.visit(*this, rParentIt);
     489                 :         18 : }
     490                 :            : 
     491                 :            : 
     492                 :            : }
     493                 :            : 
     494                 :            : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10