LCOV - code coverage report
Current view: top level - svx/source/customshapes - EnhancedCustomShapeFontWork.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 2 511 0.4 %
Date: 2012-08-25 Functions: 2 28 7.1 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 2 895 0.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                 :            : #include "EnhancedCustomShapeFontWork.hxx"
      30                 :            : #include <tools/solar.h>               // UINTXX
      31                 :            : #include <svx/svddef.hxx>
      32                 :            : #include <svx/svdogrp.hxx>
      33                 :            : #include <svx/svdopath.hxx>
      34                 :            : #include <vcl/metric.hxx>
      35                 :            : #include <svx/svdpage.hxx>
      36                 :            : #include <svx/sdasitm.hxx>
      37                 :            : #include <svx/sdasaitm.hxx>
      38                 :            : #include <svx/sdtfsitm.hxx>
      39                 :            : #include <vcl/virdev.hxx>
      40                 :            : #include <svx/svditer.hxx>
      41                 :            : #include <editeng/eeitem.hxx>
      42                 :            : #include <editeng/frmdiritem.hxx>
      43                 :            : #include <editeng/fontitem.hxx>
      44                 :            : #include <editeng/postitem.hxx>
      45                 :            : #include <editeng/wghtitem.hxx>
      46                 :            : #include <editeng/charscaleitem.hxx>
      47                 :            : #include "svx/EnhancedCustomShapeTypeNames.hxx"
      48                 :            : #include <svx/svdorect.hxx>
      49                 :            : #include <svx/svdoashp.hxx>
      50                 :            : #include <editeng/outliner.hxx>
      51                 :            : #include <editeng/outlobj.hxx>
      52                 :            : #include <editeng/editobj.hxx>
      53                 :            : #include <editeng/editeng.hxx>
      54                 :            : #include <svx/svdmodel.hxx>
      55                 :            : #include <vector>
      56                 :            : #include <numeric>
      57                 :            : #include <algorithm>
      58                 :            : #include <comphelper/processfactory.hxx>
      59                 :            : #include <com/sun/star/i18n/ScriptType.hpp>
      60                 :            : #include <basegfx/polygon/b2dpolypolygontools.hxx>
      61                 :            : #include <com/sun/star/lang/XMultiServiceFactory.hpp>
      62                 :            : #include <com/sun/star/i18n/CharacterIteratorMode.hpp>
      63                 :            : #include <basegfx/polygon/b2dpolygontools.hxx>
      64                 :            : 
      65                 :            : using namespace com::sun::star;
      66                 :            : using namespace com::sun::star::uno;
      67                 :            : 
      68         [ #  # ]:          0 : struct FWCharacterData                  // representing a single character
      69                 :            : {
      70                 :            :     std::vector< PolyPolygon >          vOutlines;
      71                 :            :     Rectangle                           aBoundRect;
      72                 :            : };
      73 [ #  # ][ #  # ]:          0 : struct FWParagraphData                  // representing a single paragraph
                 [ #  # ]
      74                 :            : {
      75                 :            :     rtl::OUString                       aString;
      76                 :            :     std::vector< FWCharacterData >      vCharacters;
      77                 :            :     Rectangle                           aBoundRect;
      78                 :            :     sal_Int16                           nFrameDirection;
      79                 :            : };
      80         [ #  # ]:          0 : struct FWTextArea                       // representing multiple concluding paragraphs
      81                 :            : {
      82                 :            :     std::vector< FWParagraphData >      vParagraphs;
      83                 :            :     Rectangle                           aBoundRect;
      84                 :            : };
      85                 :          0 : struct FWData                           // representing the whole text
      86                 :            : {
      87                 :            :     std::vector< FWTextArea >           vTextAreas;
      88                 :            :     double                              fHorizontalTextScaling;
      89                 :            :     sal_uInt32                          nMaxParagraphsPerTextArea;
      90                 :            :     sal_Int32                           nSingleLineHeight;
      91                 :            :     sal_Bool                            bSingleLineMode;
      92                 :            : };
      93                 :            : 
      94                 :            : 
      95                 :          0 : sal_Bool InitializeFontWorkData( const SdrObject* pCustomShape, const sal_uInt16 nOutlinesCount2d, FWData& rFWData )
      96                 :            : {
      97                 :          0 :     sal_Bool bNoErr = sal_False;
      98                 :          0 :     sal_Bool bSingleLineMode = sal_False;
      99                 :          0 :     sal_uInt16 nTextAreaCount = nOutlinesCount2d;
     100         [ #  # ]:          0 :     if ( nOutlinesCount2d & 1 )
     101                 :          0 :         bSingleLineMode = sal_True;
     102                 :            :     else
     103                 :          0 :         nTextAreaCount >>= 1;
     104                 :            : 
     105         [ #  # ]:          0 :     if ( nTextAreaCount )
     106                 :            :     {
     107                 :          0 :         rFWData.bSingleLineMode = bSingleLineMode;
     108                 :            : 
     109                 :            :         // setting the strings
     110                 :          0 :         OutlinerParaObject* pParaObj = ((SdrObjCustomShape*)pCustomShape)->GetOutlinerParaObject();
     111         [ #  # ]:          0 :         if ( pParaObj )
     112                 :            :         {
     113                 :          0 :             const EditTextObject& rTextObj = pParaObj->GetTextObject();
     114                 :          0 :             sal_Int32 nParagraphsLeft = rTextObj.GetParagraphCount();
     115                 :            : 
     116                 :          0 :             rFWData.nMaxParagraphsPerTextArea = ( ( nParagraphsLeft - 1 ) / nTextAreaCount ) + 1;
     117                 :          0 :             sal_Int16 j = 0;
     118 [ #  # ][ #  # ]:          0 :             while( nParagraphsLeft && nTextAreaCount )
                 [ #  # ]
     119                 :            :             {
     120         [ #  # ]:          0 :                 FWTextArea aTextArea;
     121                 :          0 :                 sal_Int32 i, nParagraphs = ( ( nParagraphsLeft - 1 ) / nTextAreaCount ) + 1;
     122         [ #  # ]:          0 :                 for ( i = 0; i < nParagraphs; ++i, ++j )
     123                 :            :                 {
     124         [ #  # ]:          0 :                     FWParagraphData aParagraphData;
     125 [ #  # ][ #  # ]:          0 :                     aParagraphData.aString = rTextObj.GetText( j );
                 [ #  # ]
     126                 :            : 
     127         [ #  # ]:          0 :                     const SfxItemSet& rParaSet = rTextObj.GetParaAttribs( j );  // retrieving some paragraph attributes
     128         [ #  # ]:          0 :                     aParagraphData.nFrameDirection = ((SvxFrameDirectionItem&)rParaSet.Get( EE_PARA_WRITINGDIR )).GetValue();
     129         [ #  # ]:          0 :                     aTextArea.vParagraphs.push_back( aParagraphData );
     130         [ #  # ]:          0 :                 }
     131         [ #  # ]:          0 :                 rFWData.vTextAreas.push_back( aTextArea );
     132                 :          0 :                 nParagraphsLeft -= nParagraphs;
     133                 :          0 :                 nTextAreaCount--;
     134                 :          0 :             }
     135                 :          0 :             bNoErr = sal_True;
     136                 :            :         }
     137                 :            :     }
     138                 :          0 :     return bNoErr;
     139                 :            : }
     140                 :            : 
     141                 :          0 : double GetLength( const Polygon& rPolygon )
     142                 :            : {
     143                 :          0 :     double fLength = 0;
     144         [ #  # ]:          0 :     if ( rPolygon.GetSize() > 1 )
     145                 :            :     {
     146                 :          0 :         sal_uInt16 nCount = rPolygon.GetSize();
     147         [ #  # ]:          0 :         while( --nCount )
     148                 :          0 :             fLength += ((Polygon&)rPolygon).CalcDistance( nCount, nCount - 1 );
     149                 :            :     }
     150                 :          0 :     return fLength;
     151                 :            : }
     152                 :            : 
     153                 :            : 
     154                 :            : /* CalculateHorizontalScalingFactor returns the horizontal scaling factor for
     155                 :            : the whole text object, so that each text will match its corresponding 2d Outline */
     156                 :          0 : void CalculateHorizontalScalingFactor( const SdrObject* pCustomShape,
     157                 :            :                                         FWData& rFWData, const PolyPolygon& rOutline2d )
     158                 :            : {
     159                 :          0 :     double fScalingFactor = 1.0;
     160                 :          0 :     sal_Bool bScalingFactorDefined = sal_False;
     161                 :            : 
     162                 :          0 :     sal_uInt16 i = 0;
     163                 :          0 :     sal_Bool bSingleLineMode = sal_False;
     164         [ #  # ]:          0 :     sal_uInt16 nOutlinesCount2d = rOutline2d.Count();
     165                 :            : 
     166         [ #  # ]:          0 :     Font aFont;
     167         [ #  # ]:          0 :     SvxFontItem& rFontItem = (SvxFontItem&)pCustomShape->GetMergedItem( EE_CHAR_FONTINFO );
     168 [ #  # ][ #  # ]:          0 :     aFont.SetHeight( pCustomShape->GetLogicRect().GetHeight() / rFWData.nMaxParagraphsPerTextArea );
                 [ #  # ]
     169         [ #  # ]:          0 :     aFont.SetAlign( ALIGN_TOP );
     170 [ #  # ][ #  # ]:          0 :     aFont.SetName( rFontItem.GetFamilyName() );
     171         [ #  # ]:          0 :     aFont.SetFamily( rFontItem.GetFamily() );
     172         [ #  # ]:          0 :     aFont.SetStyleName( rFontItem.GetStyleName() );
     173         [ #  # ]:          0 :     aFont.SetOrientation( 0 );
     174                 :            :     // initializing virtual device
     175                 :            : 
     176         [ #  # ]:          0 :     VirtualDevice aVirDev( 1 );
     177 [ #  # ][ #  # ]:          0 :     aVirDev.SetMapMode( MAP_100TH_MM );
                 [ #  # ]
     178         [ #  # ]:          0 :     aVirDev.SetFont( aFont );
     179                 :            : 
     180         [ #  # ]:          0 :     if ( nOutlinesCount2d & 1 )
     181                 :          0 :         bSingleLineMode = sal_True;
     182                 :            : 
     183                 :          0 :     std::vector< FWTextArea >::iterator aTextAreaIter = rFWData.vTextAreas.begin();
     184                 :          0 :     std::vector< FWTextArea >::iterator aTextAreaIEnd = rFWData.vTextAreas.end();
     185 [ #  # ][ #  # ]:          0 :     while( aTextAreaIter != aTextAreaIEnd )
     186                 :            :     {
     187                 :            :         // calculating the width of the corresponding 2d text area
     188 [ #  # ][ #  # ]:          0 :         double fWidth = GetLength( rOutline2d.GetObject( i++ ) );
     189         [ #  # ]:          0 :         if ( !bSingleLineMode )
     190                 :            :         {
     191 [ #  # ][ #  # ]:          0 :             fWidth += GetLength( rOutline2d.GetObject( i++ ) );
     192                 :          0 :             fWidth /= 2.0;
     193                 :            :         }
     194         [ #  # ]:          0 :         std::vector< FWParagraphData >::const_iterator aParagraphIter( aTextAreaIter->vParagraphs.begin() );
     195         [ #  # ]:          0 :         std::vector< FWParagraphData >::const_iterator aParagraphIEnd( aTextAreaIter->vParagraphs.end() );
     196 [ #  # ][ #  # ]:          0 :         while( aParagraphIter != aParagraphIEnd )
     197                 :            :         {
     198 [ #  # ][ #  # ]:          0 :             double fTextWidth = aVirDev.GetTextWidth( aParagraphIter->aString );
                 [ #  # ]
     199         [ #  # ]:          0 :             if ( fTextWidth > 0.0 )
     200                 :            :             {
     201                 :          0 :                 double fScale = fWidth / fTextWidth;
     202         [ #  # ]:          0 :                 if ( !bScalingFactorDefined )
     203                 :            :                 {
     204                 :          0 :                     fScalingFactor = fScale;
     205                 :          0 :                     bScalingFactorDefined = sal_True;
     206                 :            :                 }
     207                 :            :                 else
     208                 :            :                 {
     209         [ #  # ]:          0 :                     if ( fScale < fScalingFactor )
     210                 :          0 :                         fScalingFactor = fScale;
     211                 :            :                 }
     212                 :            :             }
     213                 :          0 :             ++aParagraphIter;
     214                 :            :         }
     215                 :          0 :         ++aTextAreaIter;
     216                 :            :     }
     217 [ #  # ][ #  # ]:          0 :     rFWData.fHorizontalTextScaling = fScalingFactor;
     218                 :          0 : }
     219                 :            : 
     220                 :          0 : void GetTextAreaOutline( const FWData& rFWData, const SdrObject* pCustomShape, FWTextArea& rTextArea, sal_Bool bSameLetterHeights )
     221                 :            : {
     222         [ #  # ]:          0 :     sal_Bool bIsVertical = ((SdrObjCustomShape*)pCustomShape)->IsVerticalWriting();
     223                 :          0 :     sal_Int32 nVerticalOffset = rFWData.nMaxParagraphsPerTextArea > rTextArea.vParagraphs.size()
     224         [ #  # ]:          0 :                                     ? rFWData.nSingleLineHeight / 2 : 0;
     225                 :            : 
     226                 :          0 :     std::vector< FWParagraphData >::iterator aParagraphIter( rTextArea.vParagraphs.begin() );
     227                 :          0 :     std::vector< FWParagraphData >::iterator aParagraphIEnd( rTextArea.vParagraphs.end() );
     228 [ #  # ][ #  # ]:          0 :     while( aParagraphIter != aParagraphIEnd )
     229                 :            :     {
     230                 :          0 :         const rtl::OUString& rText = aParagraphIter->aString;
     231         [ #  # ]:          0 :         if ( !rText.isEmpty() )
     232                 :            :         {
     233                 :            :             // generating vcl/font
     234                 :          0 :             sal_uInt16 nScriptType = i18n::ScriptType::LATIN;
     235         [ #  # ]:          0 :             Reference< i18n::XBreakIterator > xBI( EnhancedCustomShapeFontWork::GetBreakIterator() );
     236         [ #  # ]:          0 :             if ( xBI.is() )
     237                 :            :             {
     238 [ #  # ][ #  # ]:          0 :                 nScriptType = xBI->getScriptType( rText, 0 );
     239         [ #  # ]:          0 :                 if( i18n::ScriptType::WEAK == nScriptType )
     240                 :            :                 {
     241                 :          0 :                     sal_uInt16 nChg = 0;
     242 [ #  # ][ #  # ]:          0 :                     nChg = (xub_StrLen)xBI->endOfScript( rText, nChg, nScriptType );
     243         [ #  # ]:          0 :                     if( nChg < rText.getLength() )
     244 [ #  # ][ #  # ]:          0 :                         nScriptType = xBI->getScriptType( rText, nChg );
     245                 :            :                     else
     246                 :          0 :                         nScriptType = i18n::ScriptType::LATIN;
     247                 :            :                 }
     248                 :            :             }
     249                 :          0 :             sal_uInt16 nFntItm = EE_CHAR_FONTINFO;
     250         [ #  # ]:          0 :             if ( nScriptType == i18n::ScriptType::COMPLEX )
     251                 :          0 :                 nFntItm = EE_CHAR_FONTINFO_CTL;
     252         [ #  # ]:          0 :             else if ( nScriptType == i18n::ScriptType::ASIAN )
     253                 :          0 :                 nFntItm = EE_CHAR_FONTINFO_CJK;
     254         [ #  # ]:          0 :             SvxFontItem& rFontItem = (SvxFontItem&)pCustomShape->GetMergedItem( nFntItm );
     255         [ #  # ]:          0 :             Font aFont;
     256         [ #  # ]:          0 :             aFont.SetHeight( rFWData.nSingleLineHeight );
     257         [ #  # ]:          0 :             aFont.SetAlign( ALIGN_TOP );
     258                 :            : 
     259 [ #  # ][ #  # ]:          0 :             aFont.SetName( rFontItem.GetFamilyName() );
     260         [ #  # ]:          0 :             aFont.SetFamily( rFontItem.GetFamily() );
     261         [ #  # ]:          0 :             aFont.SetStyleName( rFontItem.GetStyleName() );
     262         [ #  # ]:          0 :             aFont.SetOrientation( 0 );
     263                 :            : 
     264         [ #  # ]:          0 :             SvxPostureItem& rPostureItem = (SvxPostureItem&)pCustomShape->GetMergedItem( EE_CHAR_ITALIC );
     265         [ #  # ]:          0 :             aFont.SetItalic( rPostureItem.GetPosture() );
     266                 :            : 
     267         [ #  # ]:          0 :             SvxWeightItem& rWeightItem = (SvxWeightItem&)pCustomShape->GetMergedItem( EE_CHAR_WEIGHT );
     268         [ #  # ]:          0 :             aFont.SetWeight( rWeightItem.GetWeight() );
     269                 :            : 
     270                 :            :             // initializing virtual device
     271         [ #  # ]:          0 :             VirtualDevice aVirDev( 1 );
     272 [ #  # ][ #  # ]:          0 :             aVirDev.SetMapMode( MAP_100TH_MM );
                 [ #  # ]
     273         [ #  # ]:          0 :             aVirDev.SetFont( aFont );
     274         [ #  # ]:          0 :             aVirDev.EnableRTL( sal_True );
     275         [ #  # ]:          0 :             if ( aParagraphIter->nFrameDirection == FRMDIR_HORI_RIGHT_TOP )
     276         [ #  # ]:          0 :                 aVirDev.SetLayoutMode( TEXT_LAYOUT_BIDI_RTL );
     277                 :            : 
     278         [ #  # ]:          0 :             SvxCharScaleWidthItem& rCharScaleWidthItem = (SvxCharScaleWidthItem&)pCustomShape->GetMergedItem( EE_CHAR_FONTWIDTH );
     279                 :          0 :             sal_uInt16 nCharScaleWidth = rCharScaleWidthItem.GetValue();
     280                 :          0 :             sal_Int32* pDXArry = NULL;
     281                 :          0 :             sal_Int32 nWidth = 0;
     282                 :            : 
     283                 :            :             // VERTICAL
     284         [ #  # ]:          0 :             if ( bIsVertical )
     285                 :            :             {
     286                 :            :                 // vertical _> each single character needs to be rotated by 90
     287                 :            :                 sal_Int32 i;
     288                 :          0 :                 sal_Int32 nHeight = 0;
     289         [ #  # ]:          0 :                 Rectangle aSingleCharacterUnion;
     290         [ #  # ]:          0 :                 for ( i = 0; i < rText.getLength(); i++ )
     291                 :            :                 {
     292         [ #  # ]:          0 :                     FWCharacterData aCharacterData;
     293                 :          0 :                     rtl::OUString aCharText( (sal_Unicode)rText[ i ] );
     294 [ #  # ][ #  # ]:          0 :                     if ( aVirDev.GetTextOutlines( aCharacterData.vOutlines, aCharText, 0, 0, STRING_LEN, sal_True, nWidth, pDXArry ) )
         [ #  # ][ #  # ]
     295                 :            :                     {
     296 [ #  # ][ #  # ]:          0 :                         sal_Int32 nTextWidth = aVirDev.GetTextWidth( aCharText, 0, STRING_LEN );
                 [ #  # ]
     297                 :          0 :                         std::vector< PolyPolygon >::iterator aOutlineIter = aCharacterData.vOutlines.begin();
     298                 :          0 :                         std::vector< PolyPolygon >::iterator aOutlineIEnd = aCharacterData.vOutlines.end();
     299 [ #  # ][ #  # ]:          0 :                         if ( aOutlineIter == aOutlineIEnd )
     300                 :            :                         {
     301                 :          0 :                             nHeight += rFWData.nSingleLineHeight;
     302                 :            :                         }
     303                 :            :                         else
     304                 :            :                         {
     305 [ #  # ][ #  # ]:          0 :                             while ( aOutlineIter != aOutlineIEnd )
     306                 :            :                             {
     307                 :            :                                 // rotating
     308 [ #  # ][ #  # ]:          0 :                                 aOutlineIter->Rotate( Point( nTextWidth / 2, rFWData.nSingleLineHeight / 2 ), 900 );
     309 [ #  # ][ #  # ]:          0 :                                 aCharacterData.aBoundRect.Union( aOutlineIter->GetBoundRect() );
                 [ #  # ]
     310         [ #  # ]:          0 :                                 ++aOutlineIter;
     311                 :            :                             }
     312                 :          0 :                             aOutlineIter = aCharacterData.vOutlines.begin();
     313                 :          0 :                             aOutlineIEnd = aCharacterData.vOutlines.end();
     314 [ #  # ][ #  # ]:          0 :                             while ( aOutlineIter != aOutlineIEnd )
     315                 :            :                             {
     316                 :          0 :                                 sal_Int32 nM = - aCharacterData.aBoundRect.Left() + nHeight;
     317 [ #  # ][ #  # ]:          0 :                                 aOutlineIter->Move( nM, 0 );
     318         [ #  # ]:          0 :                                 aCharacterData.aBoundRect.Move( nM, 0 );
     319         [ #  # ]:          0 :                                 ++aOutlineIter;
     320                 :            :                             }
     321         [ #  # ]:          0 :                             nHeight += aCharacterData.aBoundRect.GetWidth() + ( rFWData.nSingleLineHeight / 5 );
     322         [ #  # ]:          0 :                             aSingleCharacterUnion.Union( aCharacterData.aBoundRect );
     323                 :            :                         }
     324                 :            :                     }
     325         [ #  # ]:          0 :                     aParagraphIter->vCharacters.push_back( aCharacterData );
     326                 :          0 :                 }
     327                 :          0 :                 std::vector< FWCharacterData >::iterator aCharacterIter( aParagraphIter->vCharacters.begin() );
     328                 :          0 :                 std::vector< FWCharacterData >::iterator aCharacterIEnd( aParagraphIter->vCharacters.end() );
     329 [ #  # ][ #  # ]:          0 :                 while ( aCharacterIter != aCharacterIEnd )
     330                 :            :                 {
     331                 :          0 :                     std::vector< PolyPolygon >::iterator aOutlineIter( aCharacterIter->vOutlines.begin() );
     332                 :          0 :                     std::vector< PolyPolygon >::iterator aOutlineIEnd( aCharacterIter->vOutlines.end() );
     333 [ #  # ][ #  # ]:          0 :                     while ( aOutlineIter != aOutlineIEnd )
     334                 :            :                     {
     335 [ #  # ][ #  # ]:          0 :                         aOutlineIter->Move( ( aSingleCharacterUnion.GetWidth() - aCharacterIter->aBoundRect.GetWidth() ) / 2, 0 );
         [ #  # ][ #  # ]
     336         [ #  # ]:          0 :                         ++aOutlineIter;
     337                 :            :                     }
     338                 :          0 :                     ++aCharacterIter;
     339                 :            :                 }
     340                 :            :             }
     341                 :            :             else
     342                 :            :             {
     343 [ #  # ][ #  # ]:          0 :                 if ( ( nCharScaleWidth != 100 ) && nCharScaleWidth )
     344                 :            :                 {   // applying character spacing
     345         [ #  # ]:          0 :                     pDXArry = new sal_Int32[ rText.getLength() ];
     346 [ #  # ][ #  # ]:          0 :                     aVirDev.GetTextArray( rText, pDXArry, 0, STRING_LEN );
                 [ #  # ]
     347         [ #  # ]:          0 :                     FontMetric aFontMetric( aVirDev.GetFontMetric() );
     348 [ #  # ][ #  # ]:          0 :                     aFont.SetWidth( (sal_Int32)( (double)aFontMetric.GetWidth() * ( (double)100 / (double)nCharScaleWidth ) ) );
     349 [ #  # ][ #  # ]:          0 :                     aVirDev.SetFont( aFont );
     350                 :            :                 }
     351         [ #  # ]:          0 :                 FWCharacterData aCharacterData;
     352 [ #  # ][ #  # ]:          0 :                 if ( aVirDev.GetTextOutlines( aCharacterData.vOutlines, rText, 0, 0, STRING_LEN, sal_True, nWidth, pDXArry ) )
         [ #  # ][ #  # ]
     353                 :            :                 {
     354         [ #  # ]:          0 :                     aParagraphIter->vCharacters.push_back( aCharacterData );
     355                 :          0 :                 }
     356                 :            :             }
     357         [ #  # ]:          0 :             delete[] pDXArry;
     358                 :            : 
     359                 :            :             // veritcal alignment
     360                 :          0 :             std::vector< FWCharacterData >::iterator aCharacterIter( aParagraphIter->vCharacters.begin() );
     361                 :          0 :             std::vector< FWCharacterData >::iterator aCharacterIEnd ( aParagraphIter->vCharacters.end() );
     362 [ #  # ][ #  # ]:          0 :             while ( aCharacterIter != aCharacterIEnd )
     363                 :            :             {
     364                 :          0 :                 std::vector< PolyPolygon >::iterator aOutlineIter( aCharacterIter->vOutlines.begin() );
     365                 :          0 :                 std::vector< PolyPolygon >::iterator aOutlineIEnd( aCharacterIter->vOutlines.end() );
     366 [ #  # ][ #  # ]:          0 :                 while( aOutlineIter != aOutlineIEnd )
     367                 :            :                 {
     368                 :            : 
     369 [ #  # ][ #  # ]:          0 :                     PolyPolygon& rPolyPoly = *aOutlineIter++;
     370                 :            : 
     371         [ #  # ]:          0 :                     if ( nVerticalOffset )
     372         [ #  # ]:          0 :                         rPolyPoly.Move( 0, nVerticalOffset );
     373                 :            : 
     374                 :            :                     // retrieving the boundrect for the paragraph
     375         [ #  # ]:          0 :                     Rectangle aBoundRect( rPolyPoly.GetBoundRect() );
     376         [ #  # ]:          0 :                     aParagraphIter->aBoundRect.Union( aBoundRect );
     377                 :            :                 }
     378                 :          0 :                 ++aCharacterIter;
     379 [ #  # ][ #  # ]:          0 :             }
     380                 :            :         }
     381                 :            :         // updating the boundrect for the text area by merging the current paragraph boundrect
     382 [ #  # ][ #  # ]:          0 :         if ( aParagraphIter->aBoundRect.IsEmpty() )
     383                 :            :         {
     384 [ #  # ][ #  # ]:          0 :             if ( rTextArea.aBoundRect.IsEmpty() )
     385         [ #  # ]:          0 :                 rTextArea.aBoundRect = Rectangle( Point( 0, 0 ), Size( 1, rFWData.nSingleLineHeight ) );
     386                 :            :             else
     387                 :          0 :                 rTextArea.aBoundRect.Bottom() += rFWData.nSingleLineHeight;
     388                 :            :         }
     389                 :            :         else
     390                 :            :         {
     391                 :          0 :             Rectangle& rParagraphBoundRect = aParagraphIter->aBoundRect;
     392         [ #  # ]:          0 :             rTextArea.aBoundRect.Union( rParagraphBoundRect );
     393                 :            : 
     394         [ #  # ]:          0 :             if ( bSameLetterHeights )
     395                 :            :             {
     396                 :          0 :                 std::vector< FWCharacterData >::iterator aCharacterIter( aParagraphIter->vCharacters.begin() );
     397                 :          0 :                 std::vector< FWCharacterData >::iterator aCharacterIEnd( aParagraphIter->vCharacters.end() );
     398 [ #  # ][ #  # ]:          0 :                 while ( aCharacterIter != aCharacterIEnd )
     399                 :            :                 {
     400                 :          0 :                     std::vector< PolyPolygon >::iterator aOutlineIter( aCharacterIter->vOutlines.begin() );
     401                 :          0 :                     std::vector< PolyPolygon >::iterator aOutlineIEnd( aCharacterIter->vOutlines.end() );
     402 [ #  # ][ #  # ]:          0 :                     while( aOutlineIter != aOutlineIEnd )
     403                 :            :                     {
     404 [ #  # ][ #  # ]:          0 :                         Rectangle aPolyPolyBoundRect( aOutlineIter->GetBoundRect() );
     405 [ #  # ][ #  # ]:          0 :                         if ( aPolyPolyBoundRect.GetHeight() != rParagraphBoundRect.GetHeight() )
                 [ #  # ]
     406 [ #  # ][ #  # ]:          0 :                             aOutlineIter->Scale( 1.0, (double)rParagraphBoundRect.GetHeight() / aPolyPolyBoundRect.GetHeight() );
         [ #  # ][ #  # ]
     407 [ #  # ][ #  # ]:          0 :                         aPolyPolyBoundRect = aOutlineIter->GetBoundRect();
     408                 :          0 :                         sal_Int32 nMove = aPolyPolyBoundRect.Top() - rParagraphBoundRect.Top();
     409         [ #  # ]:          0 :                         if ( nMove )
     410 [ #  # ][ #  # ]:          0 :                             aOutlineIter->Move( 0, -nMove );
     411         [ #  # ]:          0 :                         ++aOutlineIter;
     412                 :            :                     }
     413                 :          0 :                     ++aCharacterIter;
     414                 :            :                 }
     415                 :            :             }
     416                 :            :         }
     417         [ #  # ]:          0 :         if ( bIsVertical )
     418                 :          0 :             nVerticalOffset -= rFWData.nSingleLineHeight;
     419                 :            :         else
     420                 :          0 :             nVerticalOffset += rFWData.nSingleLineHeight;
     421                 :          0 :         ++aParagraphIter;
     422                 :            :     }
     423                 :          0 : }
     424                 :            : 
     425                 :          0 : void GetFontWorkOutline( FWData& rFWData, const SdrObject* pCustomShape )
     426                 :            : {
     427         [ #  # ]:          0 :     SdrTextHorzAdjust eHorzAdjust( ((SdrTextHorzAdjustItem&)pCustomShape->GetMergedItem( SDRATTR_TEXT_HORZADJUST )).GetValue() );
     428         [ #  # ]:          0 :     SdrFitToSizeType  eFTS( ((SdrTextFitToSizeTypeItem&)pCustomShape->GetMergedItem( SDRATTR_TEXT_FITTOSIZE )).GetValue() );
     429                 :            : 
     430                 :          0 :     std::vector< FWTextArea >::iterator aTextAreaIter = rFWData.vTextAreas.begin();
     431                 :          0 :     std::vector< FWTextArea >::iterator aTextAreaIEnd = rFWData.vTextAreas.end();
     432                 :            : 
     433 [ #  # ][ #  # ]:          0 :     rFWData.nSingleLineHeight = (sal_Int32)( ( (double)pCustomShape->GetLogicRect().GetHeight()
     434                 :          0 :                                                 / rFWData.nMaxParagraphsPerTextArea ) * rFWData.fHorizontalTextScaling );
     435                 :            : 
     436                 :          0 :     sal_Bool bSameLetterHeights = sal_False;
     437         [ #  # ]:          0 :     SdrCustomShapeGeometryItem& rGeometryItem = (SdrCustomShapeGeometryItem&)pCustomShape->GetMergedItem( SDRATTR_CUSTOMSHAPE_GEOMETRY );
     438                 :          0 :     const rtl::OUString sTextPath( "TextPath"  );
     439                 :          0 :     const rtl::OUString sSameLetterHeights( "SameLetterHeights"  );
     440         [ #  # ]:          0 :     com::sun::star::uno::Any* pAny = rGeometryItem.GetPropertyValueByName( sTextPath, sSameLetterHeights );
     441         [ #  # ]:          0 :     if ( pAny )
     442                 :          0 :         *pAny >>= bSameLetterHeights;
     443                 :            : 
     444 [ #  # ][ #  # ]:          0 :     while ( aTextAreaIter != aTextAreaIEnd )
     445                 :            :     {
     446         [ #  # ]:          0 :         GetTextAreaOutline( rFWData, pCustomShape, *aTextAreaIter, bSameLetterHeights );
     447         [ #  # ]:          0 :         if ( eFTS == SDRTEXTFIT_ALLLINES )
     448                 :            :         {
     449                 :          0 :             std::vector< FWParagraphData >::iterator aParagraphIter( aTextAreaIter->vParagraphs.begin() );
     450                 :          0 :             std::vector< FWParagraphData >::iterator aParagraphIEnd( aTextAreaIter->vParagraphs.end() );
     451 [ #  # ][ #  # ]:          0 :             while ( aParagraphIter != aParagraphIEnd )
     452                 :            :             {
     453         [ #  # ]:          0 :                 sal_Int32 nParaWidth = aParagraphIter->aBoundRect.GetWidth();
     454         [ #  # ]:          0 :                 if ( nParaWidth )
     455                 :            :                 {
     456         [ #  # ]:          0 :                     double fScale = (double)aTextAreaIter->aBoundRect.GetWidth() / nParaWidth;
     457                 :            : 
     458                 :          0 :                     std::vector< FWCharacterData >::iterator aCharacterIter( aParagraphIter->vCharacters.begin() );
     459                 :          0 :                     std::vector< FWCharacterData >::iterator aCharacterIEnd( aParagraphIter->vCharacters.end() );
     460 [ #  # ][ #  # ]:          0 :                     while ( aCharacterIter != aCharacterIEnd )
     461                 :            :                     {
     462                 :          0 :                         std::vector< PolyPolygon >::iterator aOutlineIter = aCharacterIter->vOutlines.begin();
     463                 :          0 :                         std::vector< PolyPolygon >::iterator aOutlineIEnd = aCharacterIter->vOutlines.end();
     464 [ #  # ][ #  # ]:          0 :                         while( aOutlineIter != aOutlineIEnd )
     465                 :            :                         {
     466 [ #  # ][ #  # ]:          0 :                             aOutlineIter->Scale( fScale, 1.0 );
     467         [ #  # ]:          0 :                             ++aOutlineIter;
     468                 :            :                         }
     469                 :          0 :                         ++aCharacterIter;
     470                 :            :                     }
     471                 :            :                 }
     472                 :          0 :                 ++aParagraphIter;
     473                 :            :             }
     474                 :            :         }
     475                 :            :         else
     476                 :            :         {
     477      [ #  #  # ]:          0 :             switch( eHorzAdjust )
     478                 :            :             {
     479                 :            :                 case SDRTEXTHORZADJUST_RIGHT :
     480                 :            :                 case SDRTEXTHORZADJUST_CENTER:
     481                 :            :                 {
     482                 :          0 :                     std::vector< FWParagraphData >::iterator aParagraphIter( aTextAreaIter->vParagraphs.begin() );
     483                 :          0 :                     std::vector< FWParagraphData >::iterator aParagraphIEnd( aTextAreaIter->vParagraphs.end() );
     484 [ #  # ][ #  # ]:          0 :                     while ( aParagraphIter != aParagraphIEnd )
     485                 :            :                     {
     486                 :          0 :                         sal_Int32 nHorzDiff = 0;
     487         [ #  # ]:          0 :                         if ( eHorzAdjust == SDRTEXTHORZADJUST_CENTER )
     488 [ #  # ][ #  # ]:          0 :                             nHorzDiff = ( aTextAreaIter->aBoundRect.GetWidth() - aParagraphIter->aBoundRect.GetWidth() ) / 2;
     489         [ #  # ]:          0 :                         else if ( eHorzAdjust == SDRTEXTHORZADJUST_RIGHT )
     490 [ #  # ][ #  # ]:          0 :                             nHorzDiff = ( aTextAreaIter->aBoundRect.GetWidth() - aParagraphIter->aBoundRect.GetWidth() );
     491         [ #  # ]:          0 :                         if ( nHorzDiff )
     492                 :            :                         {
     493                 :          0 :                             std::vector< FWCharacterData >::iterator aCharacterIter( aParagraphIter->vCharacters.begin() );
     494                 :          0 :                             std::vector< FWCharacterData >::iterator aCharacterIEnd( aParagraphIter->vCharacters.end() );
     495 [ #  # ][ #  # ]:          0 :                             while ( aCharacterIter != aCharacterIEnd )
     496                 :            :                             {
     497                 :          0 :                                 std::vector< PolyPolygon >::iterator aOutlineIter = aCharacterIter->vOutlines.begin();
     498                 :          0 :                                 std::vector< PolyPolygon >::iterator aOutlineIEnd = aCharacterIter->vOutlines.end();
     499 [ #  # ][ #  # ]:          0 :                                 while( aOutlineIter != aOutlineIEnd )
     500                 :            :                                 {
     501 [ #  # ][ #  # ]:          0 :                                     aOutlineIter->Move( nHorzDiff, 0 );
     502         [ #  # ]:          0 :                                     ++aOutlineIter;
     503                 :            :                                 }
     504                 :          0 :                                 ++aCharacterIter;
     505                 :            :                             }
     506                 :            :                         }
     507                 :          0 :                         ++aParagraphIter;
     508                 :            :                     }
     509                 :            :                 }
     510                 :          0 :                 break;
     511                 :            :                 default:
     512                 :          0 :                 case SDRTEXTHORZADJUST_BLOCK : break;   // don't know
     513                 :          0 :                 case SDRTEXTHORZADJUST_LEFT : break;    // already left aligned -> nothing to do
     514                 :            :             }
     515                 :            :         }
     516                 :          0 :         ++aTextAreaIter;
     517                 :          0 :     }
     518                 :          0 : }
     519                 :            : 
     520                 :          0 : basegfx::B2DPolyPolygon GetOutlinesFromShape2d( const SdrObject* pShape2d )
     521                 :            : {
     522         [ #  # ]:          0 :     basegfx::B2DPolyPolygon aOutlines2d;
     523                 :            : 
     524         [ #  # ]:          0 :     SdrObjListIter aObjListIter( *pShape2d, IM_DEEPWITHGROUPS );
     525         [ #  # ]:          0 :     while( aObjListIter.IsMore() )
     526                 :            :     {
     527         [ #  # ]:          0 :         SdrObject* pPartObj = aObjListIter.Next();
     528 [ #  # ][ #  # ]:          0 :         if ( pPartObj->ISA( SdrPathObj ) )
                 [ #  # ]
     529                 :            :         {
     530         [ #  # ]:          0 :             basegfx::B2DPolyPolygon aCandidate(((SdrPathObj*)pPartObj)->GetPathPoly());
     531 [ #  # ][ #  # ]:          0 :             if(aCandidate.areControlPointsUsed())
     532                 :            :             {
     533 [ #  # ][ #  # ]:          0 :                 aCandidate = basegfx::tools::adaptiveSubdivideByAngle(aCandidate);
                 [ #  # ]
     534                 :            :             }
     535 [ #  # ][ #  # ]:          0 :             aOutlines2d.append(aCandidate);
     536                 :            :         }
     537                 :            :     }
     538                 :            : 
     539                 :          0 :     return aOutlines2d;
     540                 :            : }
     541                 :            : 
     542                 :          0 : void CalcDistances( const Polygon& rPoly, std::vector< double >& rDistances )
     543                 :            : {
     544                 :          0 :     sal_uInt16 i, nCount = rPoly.GetSize();
     545         [ #  # ]:          0 :     if ( nCount > 1 )
     546                 :            :     {
     547         [ #  # ]:          0 :         for ( i = 0; i < nCount; i++ )
     548                 :            :         {
     549 [ #  # ][ #  # ]:          0 :             double fDistance = i ? ((Polygon&)rPoly).CalcDistance( i, i - 1 ) : 0.0;
     550         [ #  # ]:          0 :             rDistances.push_back( fDistance );
     551                 :            :         }
     552                 :          0 :         std::partial_sum( rDistances.begin(), rDistances.end(), rDistances.begin() );
     553                 :          0 :         double fLength = rDistances[ rDistances.size() - 1 ];
     554         [ #  # ]:          0 :         if ( fLength > 0.0 )
     555                 :            :         {
     556                 :          0 :             std::vector< double >::iterator aIter = rDistances.begin();
     557                 :          0 :             std::vector< double >::iterator aEnd = rDistances.end();
     558 [ #  # ][ #  # ]:          0 :             while ( aIter != aEnd )
     559 [ #  # ][ #  # ]:          0 :                 *aIter++ /= fLength;
     560                 :            :         }
     561                 :            :     }
     562                 :          0 : }
     563                 :            : 
     564                 :          0 : void InsertMissingOutlinePoints( const Polygon& /*rOutlinePoly*/, const std::vector< double >& rDistances, const Rectangle& rTextAreaBoundRect, Polygon& rPoly )
     565                 :            : {
     566                 :          0 :     sal_uInt16 i = 0;
     567                 :          0 :     double fLastDistance = 0.0;
     568 [ #  # ][ #  # ]:          0 :     for ( i = 0; i < rPoly.GetSize(); i++ )
     569                 :            :     {
     570         [ #  # ]:          0 :         Point& rPoint = rPoly[ i ];
     571         [ #  # ]:          0 :         double fDistance = (double)( rPoint.X() - rTextAreaBoundRect.Left() ) / (double)rTextAreaBoundRect.GetWidth();
     572         [ #  # ]:          0 :         if ( i )
     573                 :            :         {
     574         [ #  # ]:          0 :             if ( fDistance > fLastDistance )
     575                 :            :             {
     576         [ #  # ]:          0 :                 std::vector< double >::const_iterator aIter = std::upper_bound( rDistances.begin(), rDistances.end(), fLastDistance );
     577 [ #  # ][ #  # ]:          0 :                 if  ( aIter != rDistances.end() && ( *aIter > fLastDistance ) && ( *aIter < fDistance ) )
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
           [ #  #  #  # ]
     578                 :            :                 {
     579         [ #  # ]:          0 :                     Point& rPt0 = rPoly[ i - 1 ];
     580                 :          0 :                     sal_Int32 fX = rPoint.X() - rPt0.X();
     581                 :          0 :                     sal_Int32 fY = rPoint.Y() - rPt0.Y();
     582         [ #  # ]:          0 :                     double fd = ( 1.0 / ( fDistance - fLastDistance ) ) * ( *aIter - fLastDistance );
     583         [ #  # ]:          0 :                     rPoly.Insert( i, Point( (sal_Int32)( rPt0.X() + fX * fd ), (sal_Int32)( rPt0.Y() + fY * fd ) ) );
     584         [ #  # ]:          0 :                     fDistance = *aIter;
     585                 :            :                 }
     586                 :            :             }
     587         [ #  # ]:          0 :             else if ( fDistance < fLastDistance )
     588                 :            :             {
     589         [ #  # ]:          0 :                 std::vector< double >::const_iterator aIter = std::lower_bound( rDistances.begin(), rDistances.end(), fLastDistance );
     590 [ #  # ][ #  # ]:          0 :                 if  ( aIter-- != rDistances.begin() )
                 [ #  # ]
     591                 :            :                 {
     592 [ #  # ][ #  # ]:          0 :                     if ( ( *aIter > fDistance ) && ( *aIter < fLastDistance ) )
         [ #  # ][ #  # ]
                 [ #  # ]
     593                 :            :                     {
     594         [ #  # ]:          0 :                         Point& rPt0 = rPoly[ i - 1 ];
     595                 :          0 :                         sal_Int32 fX = rPoint.X() - rPt0.X();
     596                 :          0 :                         sal_Int32 fY = rPoint.Y() - rPt0.Y();
     597         [ #  # ]:          0 :                         double fd = ( 1.0 / ( fDistance - fLastDistance ) ) * ( *aIter - fLastDistance );
     598         [ #  # ]:          0 :                         rPoly.Insert( i, Point( (sal_Int32)( rPt0.X() + fX * fd ), (sal_Int32)( rPt0.Y() + fY * fd ) ) );
     599         [ #  # ]:          0 :                         fDistance = *aIter;
     600                 :            :                     }
     601                 :            :                 }
     602                 :            :             }
     603                 :            :         }
     604                 :          0 :         fLastDistance = fDistance;
     605                 :            :     }
     606                 :          0 : }
     607                 :            : 
     608                 :          0 : void GetPoint( const Polygon& rPoly, const std::vector< double >& rDistances, const double& fX, double& fx1, double& fy1 )
     609                 :            : {
     610                 :          0 :     fy1 = fx1 = 0.0;
     611         [ #  # ]:          0 :     if ( rPoly.GetSize() > 1 )
     612                 :            :     {
     613         [ #  # ]:          0 :         std::vector< double >::const_iterator aIter = std::lower_bound( rDistances.begin(), rDistances.end(), fX );
     614         [ #  # ]:          0 :         sal_uInt16 nIdx = sal::static_int_cast<sal_uInt16>( std::distance( rDistances.begin(), aIter ) );
     615 [ #  # ][ #  # ]:          0 :         if ( aIter == rDistances.end() )
     616                 :          0 :             nIdx--;
     617         [ #  # ]:          0 :         const Point& rPt = rPoly[ nIdx ];
     618                 :          0 :         fx1 = rPt.X();
     619                 :          0 :         fy1 = rPt.Y();
     620 [ #  # ][ #  # ]:          0 :         if ( nIdx && ( aIter != rDistances.end() ) && ( *aIter != fX ) )
         [ #  # ][ #  # ]
                 [ #  # ]
           [ #  #  #  # ]
                 [ #  # ]
     621                 :            :         {
     622         [ #  # ]:          0 :             nIdx = sal::static_int_cast<sal_uInt16>( std::distance( rDistances.begin(), aIter ) );
     623 [ #  # ][ #  # ]:          0 :             double fDist0 = *( aIter - 1 );
     624         [ #  # ]:          0 :             double fd = ( 1.0 / ( *aIter - fDist0 ) ) * ( fX - fDist0 );
     625         [ #  # ]:          0 :             const Point& rPt2 = rPoly[ nIdx - 1 ];
     626                 :          0 :             double fWidth = rPt.X() - rPt2.X();
     627                 :          0 :             double fHeight= rPt.Y() - rPt2.Y();
     628                 :          0 :             fWidth *= fd;
     629                 :          0 :             fHeight*= fd;
     630                 :          0 :             fx1 = rPt2.X() + fWidth;
     631                 :          0 :             fy1 = rPt2.Y() + fHeight;
     632                 :            :         }
     633                 :            :     }
     634                 :          0 : }
     635                 :            : 
     636                 :          0 : void FitTextOutlinesToShapeOutlines( const PolyPolygon& aOutlines2d, FWData& rFWData )
     637                 :            : {
     638                 :          0 :     std::vector< FWTextArea >::iterator aTextAreaIter = rFWData.vTextAreas.begin();
     639                 :          0 :     std::vector< FWTextArea >::iterator aTextAreaIEnd = rFWData.vTextAreas.end();
     640                 :            : 
     641                 :          0 :     sal_uInt16 nOutline2dIdx = 0;
     642 [ #  # ][ #  # ]:          0 :     while( aTextAreaIter != aTextAreaIEnd )
     643                 :            :     {
     644                 :          0 :         Rectangle rTextAreaBoundRect = aTextAreaIter->aBoundRect;
     645                 :          0 :         sal_Int32 nLeft = rTextAreaBoundRect.Left();
     646                 :          0 :         sal_Int32 nTop = rTextAreaBoundRect.Top();
     647         [ #  # ]:          0 :         sal_Int32 nWidth = rTextAreaBoundRect.GetWidth();
     648         [ #  # ]:          0 :         sal_Int32 nHeight= rTextAreaBoundRect.GetHeight();
     649 [ #  # ][ #  # ]:          0 :         if ( rFWData.bSingleLineMode && nHeight && nWidth )
                 [ #  # ]
     650                 :            :         {
     651 [ #  # ][ #  # ]:          0 :             if ( nOutline2dIdx >= aOutlines2d.Count() )
     652                 :            :                 break;
     653         [ #  # ]:          0 :             const Polygon& rOutlinePoly( aOutlines2d[ nOutline2dIdx++ ] );
     654         [ #  # ]:          0 :             const sal_uInt16 nPointCount = rOutlinePoly.GetSize();
     655         [ #  # ]:          0 :             if ( nPointCount > 1 )
     656                 :            :             {
     657         [ #  # ]:          0 :                 std::vector< double > vDistances;
     658         [ #  # ]:          0 :                 vDistances.reserve( nPointCount );
     659         [ #  # ]:          0 :                 CalcDistances( rOutlinePoly, vDistances );
     660         [ #  # ]:          0 :                 if ( !vDistances.empty() )
     661                 :            :                 {
     662                 :          0 :                     std::vector< FWParagraphData >::iterator aParagraphIter( aTextAreaIter->vParagraphs.begin() );
     663                 :          0 :                     std::vector< FWParagraphData >::iterator aParagraphIEnd( aTextAreaIter->vParagraphs.end() );
     664 [ #  # ][ #  # ]:          0 :                     while( aParagraphIter != aParagraphIEnd )
     665                 :            :                     {
     666                 :          0 :                         std::vector< FWCharacterData >::iterator aCharacterIter( aParagraphIter->vCharacters.begin() );
     667                 :          0 :                         std::vector< FWCharacterData >::iterator aCharacterIEnd( aParagraphIter->vCharacters.end() );
     668 [ #  # ][ #  # ]:          0 :                         while ( aCharacterIter != aCharacterIEnd )
     669                 :            :                         {
     670                 :          0 :                             std::vector< PolyPolygon >::iterator aOutlineIter = aCharacterIter->vOutlines.begin();
     671                 :          0 :                             std::vector< PolyPolygon >::iterator aOutlineIEnd = aCharacterIter->vOutlines.end();
     672 [ #  # ][ #  # ]:          0 :                             while( aOutlineIter != aOutlineIEnd )
     673                 :            :                             {
     674         [ #  # ]:          0 :                                 PolyPolygon& rPolyPoly = *aOutlineIter;
     675         [ #  # ]:          0 :                                 Rectangle aBoundRect( rPolyPoly.GetBoundRect() );
     676                 :          0 :                                 double fx1 = aBoundRect.Left() - nLeft;
     677                 :          0 :                                 double fx2 = aBoundRect.Right() - nLeft;
     678                 :            :                                 double fy1, fy2;
     679                 :          0 :                                 double fM1 = fx1 / (double)nWidth;
     680                 :          0 :                                 double fM2 = fx2 / (double)nWidth;
     681                 :            : 
     682         [ #  # ]:          0 :                                 GetPoint( rOutlinePoly, vDistances, fM1, fx1, fy1 );
     683         [ #  # ]:          0 :                                 GetPoint( rOutlinePoly, vDistances, fM2, fx2, fy2 );
     684                 :            : 
     685                 :          0 :                                 double fvx = ( fy2 - fy1 );
     686                 :          0 :                                 double fvy = - ( fx2 - fx1 );
     687                 :          0 :                                 fx1 = fx1 + ( ( fx2 - fx1 ) * 0.5 );
     688                 :          0 :                                 fy1 = fy1 + ( ( fy2 - fy1 ) * 0.5 );
     689                 :            : 
     690                 :          0 :                                 double fAngle = atan2( -fvx, -fvy );
     691                 :          0 :                                 double fL = hypot( fvx, fvy );
     692                 :          0 :                                 fvx = fvx / fL;
     693                 :          0 :                                 fvy = fvy / fL;
     694 [ #  # ][ #  # ]:          0 :                                 fL = (double)( aTextAreaIter->aBoundRect.GetHeight() / 2.0 + aTextAreaIter->aBoundRect.Top() ) - aParagraphIter->aBoundRect.Center().Y();
     695                 :          0 :                                 fvx *= fL;
     696                 :          0 :                                 fvy *= fL;
     697 [ #  # ][ #  # ]:          0 :                                 rPolyPoly.Rotate( Point( aBoundRect.Center().X(), aParagraphIter->aBoundRect.Center().Y() ), sin( fAngle ), cos( fAngle ) );
                 [ #  # ]
     698 [ #  # ][ #  # ]:          0 :                                 rPolyPoly.Move( (sal_Int32)( ( fx1 + fvx )- aBoundRect.Center().X() ), (sal_Int32)( ( fy1 + fvy ) - aParagraphIter->aBoundRect.Center().Y() ) );
                 [ #  # ]
     699                 :            : 
     700         [ #  # ]:          0 :                                 ++aOutlineIter;
     701                 :            :                             }
     702                 :          0 :                             ++aCharacterIter;
     703                 :            :                         }
     704                 :          0 :                         ++aParagraphIter;
     705                 :            :                     }
     706                 :          0 :                 }
     707                 :          0 :             }
     708                 :            :         }
     709                 :            :         else
     710                 :            :         {
     711 [ #  # ][ #  # ]:          0 :             if ( ( nOutline2dIdx + 1 ) >= aOutlines2d.Count() )
     712                 :            :                 break;
     713         [ #  # ]:          0 :             const Polygon& rOutlinePoly( aOutlines2d[ nOutline2dIdx++ ] );
     714         [ #  # ]:          0 :             const Polygon& rOutlinePoly2( aOutlines2d[ nOutline2dIdx++ ] );
     715         [ #  # ]:          0 :             const sal_uInt16 nPointCount = rOutlinePoly.GetSize();
     716         [ #  # ]:          0 :             const sal_uInt16 nPointCount2 = rOutlinePoly2.GetSize();
     717 [ #  # ][ #  # ]:          0 :             if ( ( nPointCount > 1 ) && ( nPointCount2 > 1 ) )
     718                 :            :             {
     719         [ #  # ]:          0 :                 std::vector< double > vDistances;
     720         [ #  # ]:          0 :                 vDistances.reserve( nPointCount );
     721         [ #  # ]:          0 :                 std::vector< double > vDistances2;
     722         [ #  # ]:          0 :                 vDistances2.reserve( nPointCount2 );
     723         [ #  # ]:          0 :                 CalcDistances( rOutlinePoly, vDistances );
     724         [ #  # ]:          0 :                 CalcDistances( rOutlinePoly2, vDistances2 );
     725                 :          0 :                 std::vector< FWParagraphData >::iterator aParagraphIter = aTextAreaIter->vParagraphs.begin();
     726                 :          0 :                 std::vector< FWParagraphData >::iterator aParagraphIEnd = aTextAreaIter->vParagraphs.end();
     727 [ #  # ][ #  # ]:          0 :                 while( aParagraphIter != aParagraphIEnd )
     728                 :            :                 {
     729                 :          0 :                     std::vector< FWCharacterData >::iterator aCharacterIter( aParagraphIter->vCharacters.begin() );
     730                 :          0 :                     std::vector< FWCharacterData >::iterator aCharacterIEnd( aParagraphIter->vCharacters.end() );
     731 [ #  # ][ #  # ]:          0 :                     while ( aCharacterIter != aCharacterIEnd )
     732                 :            :                     {
     733                 :          0 :                         std::vector< PolyPolygon >::iterator aOutlineIter = aCharacterIter->vOutlines.begin();
     734                 :          0 :                         std::vector< PolyPolygon >::iterator aOutlineIEnd = aCharacterIter->vOutlines.end();
     735 [ #  # ][ #  # ]:          0 :                         while( aOutlineIter != aOutlineIEnd )
     736                 :            :                         {
     737         [ #  # ]:          0 :                             PolyPolygon& rPolyPoly = *aOutlineIter;
     738         [ #  # ]:          0 :                             sal_uInt16 i, nPolyCount = rPolyPoly.Count();
     739         [ #  # ]:          0 :                             for ( i = 0; i < nPolyCount; i++ )
     740                 :            :                             {
     741                 :            :                                 // #i35928#
     742 [ #  # ][ #  # ]:          0 :                                 basegfx::B2DPolygon aCandidate(rPolyPoly[ i ].getB2DPolygon());
     743                 :            : 
     744 [ #  # ][ #  # ]:          0 :                                 if(aCandidate.areControlPointsUsed())
     745                 :            :                                 {
     746 [ #  # ][ #  # ]:          0 :                                     aCandidate = basegfx::tools::adaptiveSubdivideByAngle(aCandidate);
                 [ #  # ]
     747                 :            :                                 }
     748                 :            : 
     749                 :            :                                 // create local polygon copy to work on
     750         [ #  # ]:          0 :                                  Polygon aLocalPoly(aCandidate);
     751                 :            : 
     752         [ #  # ]:          0 :                                 InsertMissingOutlinePoints( rOutlinePoly, vDistances, rTextAreaBoundRect, aLocalPoly );
     753         [ #  # ]:          0 :                                 InsertMissingOutlinePoints( rOutlinePoly2, vDistances2, rTextAreaBoundRect, aLocalPoly );
     754                 :            : 
     755         [ #  # ]:          0 :                                 sal_uInt16 j, _nPointCount = aLocalPoly.GetSize();
     756         [ #  # ]:          0 :                                 for ( j = 0; j < _nPointCount; j++ )
     757                 :            :                                 {
     758         [ #  # ]:          0 :                                     Point& rPoint = aLocalPoly[ j ];
     759                 :          0 :                                     rPoint.X() -= nLeft;
     760                 :          0 :                                     rPoint.Y() -= nTop;
     761                 :          0 :                                     double fX = (double)rPoint.X() / (double)nWidth;
     762                 :          0 :                                     double fY = (double)rPoint.Y() / (double)nHeight;
     763                 :            : 
     764                 :            :                                     double fx1, fy1, fx2, fy2;
     765         [ #  # ]:          0 :                                     GetPoint( rOutlinePoly, vDistances, fX, fx1, fy1 );
     766         [ #  # ]:          0 :                                     GetPoint( rOutlinePoly2, vDistances2, fX, fx2, fy2 );
     767                 :          0 :                                     double fWidth = fx2 - fx1;
     768                 :          0 :                                     double fHeight= fy2 - fy1;
     769                 :          0 :                                     rPoint.X() = (sal_Int32)( fx1 + fWidth * fY );
     770                 :          0 :                                     rPoint.Y() = (sal_Int32)( fy1 + fHeight* fY );
     771                 :            :                                 }
     772                 :            : 
     773                 :            :                                 // write back polygon
     774 [ #  # ][ #  # ]:          0 :                                 rPolyPoly[ i ] = aLocalPoly;
     775 [ #  # ][ #  # ]:          0 :                             }
     776         [ #  # ]:          0 :                             ++aOutlineIter;
     777                 :            :                         }
     778                 :          0 :                         ++aCharacterIter;
     779                 :            :                     }
     780                 :          0 :                     ++aParagraphIter;
     781                 :          0 :                 }
     782                 :            :             }
     783                 :            :         }
     784                 :          0 :         ++aTextAreaIter;
     785                 :            :     }
     786                 :          0 : }
     787                 :            : 
     788                 :          0 : SdrObject* CreateSdrObjectFromParagraphOutlines( const FWData& rFWData, const SdrObject* pCustomShape )
     789                 :            : {
     790                 :          0 :     SdrObject* pRet = NULL;
     791         [ #  # ]:          0 :     basegfx::B2DPolyPolygon aPolyPoly;
     792         [ #  # ]:          0 :     if ( !rFWData.vTextAreas.empty() )
     793                 :            :     {
     794                 :          0 :         std::vector< FWTextArea >::const_iterator aTextAreaIter = rFWData.vTextAreas.begin();
     795                 :          0 :         std::vector< FWTextArea >::const_iterator aTextAreaIEnd = rFWData.vTextAreas.end();
     796 [ #  # ][ #  # ]:          0 :         while ( aTextAreaIter != aTextAreaIEnd )
     797                 :            :         {
     798                 :          0 :             std::vector< FWParagraphData >::const_iterator aParagraphIter = aTextAreaIter->vParagraphs.begin();
     799                 :          0 :             std::vector< FWParagraphData >::const_iterator aParagraphIEnd = aTextAreaIter->vParagraphs.end();
     800 [ #  # ][ #  # ]:          0 :             while ( aParagraphIter != aParagraphIEnd )
     801                 :            :             {
     802                 :          0 :                 std::vector< FWCharacterData >::const_iterator aCharacterIter( aParagraphIter->vCharacters.begin() );
     803                 :          0 :                 std::vector< FWCharacterData >::const_iterator aCharacterIEnd( aParagraphIter->vCharacters.end() );
     804 [ #  # ][ #  # ]:          0 :                 while ( aCharacterIter != aCharacterIEnd )
     805                 :            :                 {
     806                 :          0 :                     std::vector< PolyPolygon >::const_iterator aOutlineIter = aCharacterIter->vOutlines.begin();
     807                 :          0 :                     std::vector< PolyPolygon >::const_iterator aOutlineIEnd = aCharacterIter->vOutlines.end();
     808 [ #  # ][ #  # ]:          0 :                     while( aOutlineIter != aOutlineIEnd )
     809                 :            :                     {
     810 [ #  # ][ #  # ]:          0 :                         aPolyPoly.append( aOutlineIter->getB2DPolyPolygon() );
         [ #  # ][ #  # ]
     811         [ #  # ]:          0 :                         ++aOutlineIter;
     812                 :            :                     }
     813                 :          0 :                     ++aCharacterIter;
     814                 :            :                 }
     815                 :          0 :                 ++aParagraphIter;
     816                 :            :             }
     817                 :          0 :             ++aTextAreaIter;
     818                 :            :         }
     819                 :            : 
     820 [ #  # ][ #  # ]:          0 :         pRet = new SdrPathObj( OBJ_POLY, aPolyPoly );
     821                 :            : 
     822 [ #  # ][ #  # ]:          0 :         Point aP( pCustomShape->GetSnapRect().Center() );
     823 [ #  # ][ #  # ]:          0 :         Size aS( pCustomShape->GetLogicRect().GetSize() );
     824                 :          0 :         aP.X() -= aS.Width() / 2;
     825                 :          0 :         aP.Y() -= aS.Height() / 2;
     826         [ #  # ]:          0 :         Rectangle aLogicRect( aP, aS );
     827                 :            : 
     828 [ #  # ][ #  # ]:          0 :         SfxItemSet aSet( pCustomShape->GetMergedItemSet() );
     829         [ #  # ]:          0 :         aSet.ClearItem( SDRATTR_TEXTDIRECTION );    //SJ: vertical writing is not required, by removing this item no outliner is created
     830 [ #  # ][ #  # ]:          0 :         aSet.Put(SdrShadowItem(sal_False)); // #i37011# NO shadow for FontWork geometry
                 [ #  # ]
     831 [ #  # ][ #  # ]:          0 :         pRet->SetMergedItemSet( aSet );             // * otherwise we would crash, because the outliner tries to create a Paraobject, but there is no model
     832                 :            :     }
     833         [ #  # ]:          0 :     return pRet;
     834                 :            : }
     835                 :            : 
     836                 :        139 : ::com::sun::star::uno::Reference < ::com::sun::star::i18n::XBreakIterator > EnhancedCustomShapeFontWork::mxBreakIterator = 0;
     837                 :            : 
     838                 :          0 : Reference < i18n::XBreakIterator > EnhancedCustomShapeFontWork::GetBreakIterator()
     839                 :            : {
     840         [ #  # ]:          0 :     if ( !mxBreakIterator.is() )
     841                 :            :     {
     842         [ #  # ]:          0 :         Reference< lang::XMultiServiceFactory > xMSF = ::comphelper::getProcessServiceFactory();
     843 [ #  # ][ #  # ]:          0 :         Reference < XInterface > xI = xMSF->createInstance( rtl::OUString("com.sun.star.i18n.BreakIterator") );
     844         [ #  # ]:          0 :         if ( xI.is() )
     845                 :            :         {
     846 [ #  # ][ #  # ]:          0 :             Any x = xI->queryInterface( ::getCppuType((const Reference< i18n::XBreakIterator >*)0) );
                 [ #  # ]
     847         [ #  # ]:          0 :             x >>= mxBreakIterator;
     848                 :          0 :         }
     849                 :            :     }
     850                 :          0 :     return mxBreakIterator;
     851                 :            : }
     852                 :            : 
     853                 :          0 : SdrObject* EnhancedCustomShapeFontWork::CreateFontWork( const SdrObject* pShape2d, const SdrObject* pCustomShape )
     854                 :            : {
     855                 :          0 :     SdrObject* pRet = NULL;
     856                 :            : 
     857 [ #  # ][ #  # ]:          0 :     PolyPolygon aOutlines2d( GetOutlinesFromShape2d( pShape2d ) );
                 [ #  # ]
     858         [ #  # ]:          0 :     sal_uInt16 nOutlinesCount2d = aOutlines2d.Count();
     859         [ #  # ]:          0 :     if ( nOutlinesCount2d )
     860                 :            :     {
     861         [ #  # ]:          0 :         FWData aFWData;
     862 [ #  # ][ #  # ]:          0 :         if ( InitializeFontWorkData( pCustomShape, nOutlinesCount2d, aFWData ) )
     863                 :            :         {
     864                 :            :             /* retrieves the horizontal scaling factor that has to be used
     865                 :            :             to fit each paragraph text into its corresponding 2d outline */
     866         [ #  # ]:          0 :             CalculateHorizontalScalingFactor( pCustomShape, aFWData, aOutlines2d );
     867                 :            : 
     868                 :            :             /* retrieving the Outlines for the each Paragraph. */
     869                 :            : 
     870         [ #  # ]:          0 :             GetFontWorkOutline( aFWData, pCustomShape );
     871                 :            : 
     872         [ #  # ]:          0 :             FitTextOutlinesToShapeOutlines( aOutlines2d, aFWData );
     873                 :            : 
     874         [ #  # ]:          0 :             pRet = CreateSdrObjectFromParagraphOutlines( aFWData, pCustomShape );
     875                 :          0 :         }
     876                 :            :     }
     877         [ #  # ]:          0 :     return pRet;
     878 [ +  - ][ +  - ]:        417 : }
     879                 :            : 
     880                 :            : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10