LCOV - code coverage report
Current view: top level - filter/source/svg - svgfontexport.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 1 158 0.6 %
Date: 2012-08-25 Functions: 2 10 20.0 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 2 311 0.6 %

           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 2008 by Sun Microsystems, Inc.
       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 "svgfontexport.hxx"
      31                 :            : #include "svgfilter.hxx"
      32                 :            : #include "svgwriter.hxx"
      33                 :            : 
      34                 :            : 
      35                 :            : #include <vcl/unohelp.hxx>
      36                 :            : #include <vcl/font.hxx>
      37                 :            : #include <vcl/outdev.hxx>
      38                 :            : 
      39                 :            : static const sal_Int32 nFontEM = 2048;
      40                 :            : 
      41                 :            : // -----------------
      42                 :            : // - SVGFontExport -
      43                 :            : // -----------------
      44                 :            : 
      45                 :          0 : SVGFontExport::SVGFontExport( SVGExport& rExport, const ::std::vector< ObjectRepresentation >& rObjects ) :
      46                 :            :     mrExport( rExport ),
      47                 :            :     maObjects( rObjects ),
      48         [ #  # ]:          0 :     mnCurFontId( 0 )
      49                 :            : {
      50                 :          0 : }
      51                 :            : 
      52                 :            : // -----------------------------------------------------------------------------
      53                 :            : 
      54                 :          0 : SVGFontExport::~SVGFontExport()
      55                 :            : {
      56                 :          0 : }
      57                 :            : 
      58                 :            : // -----------------------------------------------------------------------------
      59                 :            : 
      60                 :          0 : SVGFontExport::GlyphSet& SVGFontExport::implGetGlyphSet( const Font& rFont )
      61                 :            : {
      62                 :          0 :     FontWeight      eWeight( WEIGHT_NORMAL );
      63                 :          0 :     FontItalic      eItalic( ITALIC_NONE );
      64 [ #  # ][ #  # ]:          0 :     ::rtl::OUString aFontName( rFont.GetName() );
      65                 :          0 :     sal_Int32       nNextTokenPos( 0 );
      66                 :            : 
      67 [ #  # ][ #  # ]:          0 :     switch( rFont.GetWeight() )
      68                 :            :     {
      69                 :            :         case WEIGHT_BOLD:
      70                 :            :         case WEIGHT_ULTRABOLD:
      71                 :            :         case WEIGHT_BLACK:
      72                 :          0 :             eWeight = WEIGHT_BOLD;
      73                 :          0 :         break;
      74                 :            : 
      75                 :            :         default:
      76                 :          0 :         break;
      77                 :            :     }
      78                 :            : 
      79 [ #  # ][ #  # ]:          0 :     if( rFont.GetItalic() != ITALIC_NONE )
      80                 :          0 :         eItalic = ITALIC_NORMAL;
      81                 :            : 
      82 [ #  # ][ #  # ]:          0 :     return( maGlyphTree[ aFontName.getToken( 0, ';', nNextTokenPos ) ][ eWeight ][ eItalic ] );
                 [ #  # ]
      83                 :            : }
      84                 :            : 
      85                 :            : // -----------------------------------------------------------------------------
      86                 :            : 
      87                 :          0 : void SVGFontExport::implCollectGlyphs()
      88                 :            : {
      89         [ #  # ]:          0 :     VirtualDevice                   aVDev;
      90         [ #  # ]:          0 :     ObjectVector::const_iterator    aIter( maObjects.begin() );
      91                 :            : 
      92         [ #  # ]:          0 :     aVDev.EnableOutput( sal_False );
      93                 :            : 
      94 [ #  # ][ #  # ]:          0 :     while( aIter != maObjects.end() )
      95                 :            :     {
      96         [ #  # ]:          0 :         if( (*aIter).HasRepresentation() )
      97                 :            :         {
      98                 :          0 :             const GDIMetaFile& rMtf = (*aIter).GetRepresentation();
      99                 :            : 
     100         [ #  # ]:          0 :             aVDev.Push();
     101                 :            : 
     102 [ #  # ][ #  # ]:          0 :             for( size_t i = 0, nCount = rMtf.GetActionSize(); i < nCount; ++i )
     103                 :            :             {
     104                 :          0 :                 ::rtl::OUString     aText;
     105         [ #  # ]:          0 :                 MetaAction*         pAction = rMtf.GetAction( i );
     106                 :          0 :                 const sal_uInt16    nType = pAction->GetType();
     107                 :            : 
     108   [ #  #  #  #  :          0 :                 switch( nType )
                      # ]
     109                 :            :                 {
     110                 :            :                     case( META_TEXT_ACTION ):
     111                 :            :                     {
     112                 :          0 :                         const MetaTextAction* pA = (const MetaTextAction*) pAction;
     113 [ #  # ][ #  # ]:          0 :                         aText = String( pA->GetText(), pA->GetIndex(), pA->GetLen() );
         [ #  # ][ #  # ]
                 [ #  # ]
     114                 :            :                     }
     115                 :          0 :                     break;
     116                 :            : 
     117                 :            :                     case( META_TEXTRECT_ACTION ):
     118                 :            :                     {
     119                 :          0 :                         const MetaTextRectAction* pA = (const MetaTextRectAction*) pAction;
     120                 :          0 :                         aText = pA->GetText();
     121                 :            :                     }
     122                 :          0 :                     break;
     123                 :            : 
     124                 :            :                     case( META_TEXTARRAY_ACTION ):
     125                 :            :                     {
     126                 :          0 :                         const MetaTextArrayAction*  pA = (const MetaTextArrayAction*) pAction;
     127 [ #  # ][ #  # ]:          0 :                         aText = String( pA->GetText(), pA->GetIndex(), pA->GetLen() );
         [ #  # ][ #  # ]
                 [ #  # ]
     128                 :            :                     }
     129                 :          0 :                     break;
     130                 :            : 
     131                 :            :                     case( META_STRETCHTEXT_ACTION ):
     132                 :            :                     {
     133                 :          0 :                         const MetaStretchTextAction* pA = (const MetaStretchTextAction*) pAction;
     134 [ #  # ][ #  # ]:          0 :                         aText = String( pA->GetText(), pA->GetIndex(), pA->GetLen() );
         [ #  # ][ #  # ]
                 [ #  # ]
     135                 :            :                     }
     136                 :          0 :                     break;
     137                 :            : 
     138                 :            :                     default:
     139         [ #  # ]:          0 :                         pAction->Execute( &aVDev );
     140                 :          0 :                     break;
     141                 :            :                 }
     142                 :            : 
     143         [ #  # ]:          0 :                 if( !aText.isEmpty() )
     144                 :            :                 {
     145         [ #  # ]:          0 :                     GlyphSet& rGlyphSet = implGetGlyphSet( aVDev.GetFont() );
     146                 :            :                     ::com::sun::star::uno::Reference< ::com::sun::star::i18n::XBreakIterator > xBI(
     147         [ #  # ]:          0 :                         ::vcl::unohelper::CreateBreakIterator() );
     148                 :            : 
     149         [ #  # ]:          0 :                     if( xBI.is() )
     150                 :            :                     {
     151 [ #  # ][ #  # ]:          0 :                         const ::com::sun::star::lang::Locale&   rLocale = Application::GetSettings().GetLocale();
     152                 :          0 :                         sal_Int32                               nCurPos = 0, nLastPos = -1;
     153                 :            : 
     154 [ #  # ][ #  # ]:          0 :                         while( ( nCurPos < aText.getLength() ) && ( nCurPos > nLastPos ) )
                 [ #  # ]
     155                 :            :                         {
     156                 :          0 :                             sal_Int32 nCount2 = 1;
     157                 :            : 
     158                 :          0 :                             nLastPos = nCurPos;
     159         [ #  # ]:          0 :                             nCurPos = xBI->nextCharacters( aText, nCurPos, rLocale,
     160                 :            :                                                            ::com::sun::star::i18n::CharacterIteratorMode::SKIPCELL,
     161         [ #  # ]:          0 :                                                            nCount2, nCount2 );
     162                 :            : 
     163         [ #  # ]:          0 :                             rGlyphSet.insert( aText.copy( nLastPos, nCurPos - nLastPos ) );
     164                 :            :                         }
     165                 :            :                     }
     166                 :            :                     else
     167                 :            :                     {
     168                 :          0 :                         const sal_Unicode* pStr = aText.getStr();
     169                 :            : 
     170         [ #  # ]:          0 :                         for( sal_uInt32 k = 0, nLen = aText.getLength(); k < nLen; ++k )
     171         [ #  # ]:          0 :                             rGlyphSet.insert( rtl::OUString( pStr[ k ] ) );
     172                 :          0 :                     }
     173                 :            :                 }
     174                 :          0 :             }
     175                 :            : 
     176         [ #  # ]:          0 :             aVDev.Pop();
     177                 :            :         }
     178                 :            : 
     179                 :          0 :         ++aIter;
     180         [ #  # ]:          0 :     }
     181                 :          0 : }
     182                 :            : 
     183                 :            : // -----------------------------------------------------------------------------
     184                 :            : 
     185                 :          0 : void SVGFontExport::implEmbedFont( const Font& rFont )
     186                 :            : {
     187         [ #  # ]:          0 :     if( mrExport.IsEmbedFonts() )
     188                 :            :     {
     189                 :          0 :         GlyphSet& rGlyphSet = implGetGlyphSet( rFont );
     190                 :            : 
     191         [ #  # ]:          0 :         if( !rGlyphSet.empty() )
     192                 :            :         {
     193                 :          0 :             GlyphSet::const_iterator    aIter( rGlyphSet.begin() );
     194         [ #  # ]:          0 :             const ::rtl::OUString       aEmbeddedFontStr( B2UCONST( "EmbeddedFont_" ) );
     195                 :            : 
     196                 :            :             {
     197         [ #  # ]:          0 :                 SvXMLElementExport  aExp( mrExport, XML_NAMESPACE_NONE, "defs", sal_True, sal_True );
     198                 :          0 :                 ::rtl::OUString     aCurIdStr( aEmbeddedFontStr );
     199                 :          0 :                 ::rtl::OUString     aUnitsPerEM( ::rtl::OUString::valueOf( nFontEM ) );
     200         [ #  # ]:          0 :                 VirtualDevice       aVDev;
     201         [ #  # ]:          0 :                 Font                aFont( rFont );
     202                 :            : 
     203         [ #  # ]:          0 :                 aFont.SetSize( Size( 0, nFontEM ) );
     204         [ #  # ]:          0 :                 aFont.SetAlign( ALIGN_BASELINE );
     205                 :            : 
     206 [ #  # ][ #  # ]:          0 :                 aVDev.SetMapMode( MAP_100TH_MM );
                 [ #  # ]
     207         [ #  # ]:          0 :                 aVDev.SetFont( aFont );
     208                 :            : 
     209         [ #  # ]:          0 :                 mrExport.AddAttribute( XML_NAMESPACE_NONE, "id", aCurIdStr += ::rtl::OUString::valueOf( ++mnCurFontId ) );
     210         [ #  # ]:          0 :                 mrExport.AddAttribute( XML_NAMESPACE_NONE, "horiz-adv-x", aUnitsPerEM );
     211                 :            : 
     212                 :            :                 {
     213         [ #  # ]:          0 :                     SvXMLElementExport  aExp2( mrExport, XML_NAMESPACE_NONE, "font", sal_True, sal_True );
     214                 :          0 :                     ::rtl::OUString     aFontWeight;
     215                 :          0 :                     ::rtl::OUString     aFontStyle;
     216                 :          0 :                     const Size         aSize( nFontEM, nFontEM );
     217                 :            : 
     218                 :            :                     // Font Weight
     219 [ #  # ][ #  # ]:          0 :                     if( aFont.GetWeight() != WEIGHT_NORMAL )
     220         [ #  # ]:          0 :                         aFontWeight = B2UCONST( "bold" );
     221                 :            :                     else
     222         [ #  # ]:          0 :                         aFontWeight = B2UCONST( "normal" );
     223                 :            : 
     224                 :            :                     // Font Italic
     225 [ #  # ][ #  # ]:          0 :                     if( aFont.GetItalic() != ITALIC_NONE )
     226         [ #  # ]:          0 :                         aFontStyle = B2UCONST( "italic" );
     227                 :            :                     else
     228         [ #  # ]:          0 :                         aFontStyle = B2UCONST( "normal" );
     229                 :            : 
     230 [ #  # ][ #  # ]:          0 :                     mrExport.AddAttribute( XML_NAMESPACE_NONE, "font-family", GetMappedFontName( rFont.GetName() ) );
         [ #  # ][ #  # ]
     231         [ #  # ]:          0 :                     mrExport.AddAttribute( XML_NAMESPACE_NONE, "units-per-em", aUnitsPerEM );
     232         [ #  # ]:          0 :                     mrExport.AddAttribute( XML_NAMESPACE_NONE, "font-weight", aFontWeight );
     233         [ #  # ]:          0 :                     mrExport.AddAttribute( XML_NAMESPACE_NONE, "font-style", aFontStyle );
     234 [ #  # ][ #  # ]:          0 :                     mrExport.AddAttribute( XML_NAMESPACE_NONE, "ascent", ::rtl::OUString::valueOf( aVDev.GetFontMetric().GetAscent() ) );
         [ #  # ][ #  # ]
     235 [ #  # ][ #  # ]:          0 :                     mrExport.AddAttribute( XML_NAMESPACE_NONE, "descent", ::rtl::OUString::valueOf( aVDev.GetFontMetric().GetDescent() ) );
         [ #  # ][ #  # ]
     236                 :            : 
     237                 :            :                     {
     238 [ #  # ][ #  # ]:          0 :                         SvXMLElementExport aExp3( mrExport, XML_NAMESPACE_NONE, "font-face", sal_True, sal_True );
     239                 :            :                     }
     240                 :            : 
     241         [ #  # ]:          0 :                     mrExport.AddAttribute( XML_NAMESPACE_NONE, "horiz-adv-x", ::rtl::OUString::valueOf( aSize.Width() ) );
     242                 :            : 
     243                 :            :                     {
     244                 :          0 :                         const Point         aPos;
     245 [ #  # ][ #  # ]:          0 :                         const PolyPolygon   aMissingGlyphPolyPoly( Rectangle( aPos, aSize ) );
         [ #  # ][ #  # ]
     246                 :            : 
     247 [ #  # ][ #  # ]:          0 :                         mrExport.AddAttribute( XML_NAMESPACE_NONE, "d", SVGActionWriter::GetPathString( aMissingGlyphPolyPoly, sal_False ) );
     248                 :            : 
     249                 :            :                         {
     250 [ #  # ][ #  # ]:          0 :                             SvXMLElementExport  aExp4( mrExport, XML_NAMESPACE_NONE, "missing-glyph", sal_True, sal_True );
     251         [ #  # ]:          0 :                         }
     252                 :            :                     }
     253                 :            : 
     254         [ #  # ]:          0 :                     while( aIter != rGlyphSet.end() )
     255                 :            :                     {
     256         [ #  # ]:          0 :                         implEmbedGlyph( aVDev, *aIter );
     257                 :          0 :                         ++aIter;
     258         [ #  # ]:          0 :                     }
     259 [ #  # ][ #  # ]:          0 :                 }
                 [ #  # ]
     260                 :          0 :             }
     261                 :            :         }
     262                 :            :     }
     263                 :          0 : }
     264                 :            : 
     265                 :            : // -----------------------------------------------------------------------------
     266                 :            : 
     267                 :          0 : void SVGFontExport::implEmbedGlyph( OutputDevice& rOut, const ::rtl::OUString& rCellStr )
     268                 :            : {
     269         [ #  # ]:          0 :     PolyPolygon         aPolyPoly;
     270                 :          0 :     const sal_Unicode   nSpace = ' ';
     271                 :            : 
     272 [ #  # ][ #  # ]:          0 :     if( rOut.GetTextOutline( aPolyPoly, rCellStr ) )
         [ #  # ][ #  # ]
     273                 :            :     {
     274         [ #  # ]:          0 :         Rectangle aBoundRect;
     275                 :            : 
     276         [ #  # ]:          0 :         aPolyPoly.Scale( 1.0, -1.0 );
     277                 :            : 
     278 [ #  # ][ #  # ]:          0 :         if( !rOut.GetTextBoundRect( aBoundRect, rCellStr ) )
         [ #  # ][ #  # ]
     279 [ #  # ][ #  # ]:          0 :             aBoundRect = Rectangle( Point( 0, 0 ), Size( rOut.GetTextWidth( rCellStr ), 0 ) );
         [ #  # ][ #  # ]
     280                 :            : 
     281         [ #  # ]:          0 :         mrExport.AddAttribute( XML_NAMESPACE_NONE, "unicode", rCellStr );
     282                 :            : 
     283 [ #  # ][ #  # ]:          0 :         if( rCellStr[ 0 ] == nSpace && rCellStr.getLength() == 1 )
                 [ #  # ]
     284 [ #  # ][ #  # ]:          0 :             aBoundRect = Rectangle( Point( 0, 0 ), Size( rOut.GetTextWidth( rtl::OUString(' ') ), 0 ) );
         [ #  # ][ #  # ]
     285                 :            : 
     286 [ #  # ][ #  # ]:          0 :         mrExport.AddAttribute( XML_NAMESPACE_NONE, "horiz-adv-x", ::rtl::OUString::valueOf( aBoundRect.GetWidth() ) );
     287                 :            : 
     288         [ #  # ]:          0 :         const ::rtl::OUString aPathString( SVGActionWriter::GetPathString( aPolyPoly, sal_False ) );
     289         [ #  # ]:          0 :         if( !aPathString.isEmpty() )
     290                 :            :         {
     291         [ #  # ]:          0 :             mrExport.AddAttribute( XML_NAMESPACE_NONE, "d", aPathString );
     292                 :            :         }
     293                 :            : 
     294                 :            :         {
     295 [ #  # ][ #  # ]:          0 :             SvXMLElementExport aExp( mrExport, XML_NAMESPACE_NONE, "glyph", sal_True, sal_True );
     296                 :          0 :         }
     297         [ #  # ]:          0 :     }
     298                 :          0 : }
     299                 :            : 
     300                 :            : // -----------------------------------------------------------------------------
     301                 :            : 
     302                 :          0 : void SVGFontExport::EmbedFonts()
     303                 :            : {
     304         [ #  # ]:          0 :     implCollectGlyphs();
     305                 :            : 
     306                 :          0 :     GlyphTree::const_iterator aGlyphTreeIter( maGlyphTree.begin() );
     307                 :            : 
     308         [ #  # ]:          0 :     while( aGlyphTreeIter != maGlyphTree.end() )
     309                 :            :     {
     310                 :          0 :         const FontWeightMap&            rFontWeightMap = (*aGlyphTreeIter).second;
     311                 :          0 :         FontWeightMap::const_iterator   aFontWeightIter( rFontWeightMap.begin() );
     312                 :            : 
     313         [ #  # ]:          0 :         while( aFontWeightIter != rFontWeightMap.end() )
     314                 :            :         {
     315                 :          0 :             const FontItalicMap&            rFontItalicMap = (*aFontWeightIter).second;
     316                 :          0 :             FontItalicMap::const_iterator   aFontItalicIter( rFontItalicMap.begin() );
     317                 :            : 
     318         [ #  # ]:          0 :             while( aFontItalicIter != rFontItalicMap.end() )
     319                 :            :             {
     320         [ #  # ]:          0 :                 Font aFont;
     321                 :            : 
     322         [ #  # ]:          0 :                 aFont.SetName( (*aGlyphTreeIter).first );
     323         [ #  # ]:          0 :                 aFont.SetWeight( (*aFontWeightIter).first );
     324         [ #  # ]:          0 :                 aFont.SetItalic( (*aFontItalicIter).first );
     325                 :            : 
     326         [ #  # ]:          0 :                 implEmbedFont( aFont );
     327                 :            : 
     328                 :          0 :                 ++aFontItalicIter;
     329         [ #  # ]:          0 :             }
     330                 :            : 
     331                 :          0 :             ++aFontWeightIter;
     332                 :            :         }
     333                 :            : 
     334                 :          0 :         ++aGlyphTreeIter;
     335                 :            :     }
     336                 :          0 : }
     337                 :            : 
     338                 :            : // -----------------------------------------------------------------------------
     339                 :            : 
     340                 :          0 : ::rtl::OUString SVGFontExport::GetMappedFontName( const ::rtl::OUString& rFontName ) const
     341                 :            : {
     342                 :          0 :     sal_Int32       nNextTokenPos( 0 );
     343                 :          0 :     ::rtl::OUString aRet( rFontName.getToken( 0, ';', nNextTokenPos ) );
     344                 :            : 
     345         [ #  # ]:          0 :     if( mnCurFontId )
     346         [ #  # ]:          0 :         aRet += B2UCONST( " embedded" );
     347                 :            : 
     348                 :          0 :     return aRet;
     349 [ +  - ][ +  - ]:         18 : }
     350                 :            : 
     351                 :            : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10