LCOV - code coverage report
Current view: top level - vcl/generic/fontmanager - helper.cxx (source / functions) Hit Total Coverage
Test: commit 0e63ca4fde4e446f346e35849c756a30ca294aab Lines: 99 189 52.4 %
Date: 2014-04-11 Functions: 6 7 85.7 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /*
       3             :  * This file is part of the LibreOffice project.
       4             :  *
       5             :  * This Source Code Form is subject to the terms of the Mozilla Public
       6             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       7             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       8             :  *
       9             :  * This file incorporates work covered by the following license notice:
      10             :  *
      11             :  *   Licensed to the Apache Software Foundation (ASF) under one or more
      12             :  *   contributor license agreements. See the NOTICE file distributed
      13             :  *   with this work for additional information regarding copyright
      14             :  *   ownership. The ASF licenses this file to you under the Apache
      15             :  *   License, Version 2.0 (the "License"); you may not use this file
      16             :  *   except in compliance with the License. You may obtain a copy of
      17             :  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
      18             :  */
      19             : 
      20             : #include <config_folders.h>
      21             : 
      22             : #include <cstring>
      23             : #include <sys/stat.h>
      24             : #include <unistd.h>
      25             : #include <limits.h>
      26             : #include <osl/file.hxx>
      27             : #include <osl/process.h>
      28             : #include <osl/thread.h>
      29             : #include <rtl/bootstrap.hxx>
      30             : #include <rtl/ustring.hxx>
      31             : #include <tools/urlobj.hxx>
      32             : #include "vcl/helper.hxx"
      33             : #include "vcl/ppdparser.hxx"
      34             : #include <boost/scoped_array.hpp>
      35             : 
      36             : using ::rtl::Bootstrap;
      37             : 
      38             : namespace psp {
      39             : 
      40         816 : OUString getOfficePath( enum whichOfficePath ePath )
      41             : {
      42         816 :     static OUString aInstallationRootPath;
      43         816 :     static OUString aUserPath;
      44         816 :     static OUString aConfigPath;
      45         816 :     static OUString aEmpty;
      46             :     static bool bOnce = false;
      47             : 
      48         816 :     if( ! bOnce )
      49             :     {
      50         137 :         bOnce = true;
      51         137 :         OUString aIni;
      52         137 :         Bootstrap::get( "BRAND_BASE_DIR", aInstallationRootPath );
      53         137 :         aIni = aInstallationRootPath + "/" LIBO_ETC_FOLDER "/" + SAL_CONFIGFILE( "bootstrap" );
      54         274 :         Bootstrap aBootstrap( aIni );
      55         137 :         aBootstrap.getFrom( "CustomDataUrl", aConfigPath );
      56         137 :         aBootstrap.getFrom( "UserInstallation", aUserPath );
      57         274 :         OUString aUPath = aUserPath;
      58             : 
      59         137 :         if( aConfigPath.startsWith( "file://" ) )
      60             :         {
      61           0 :             OUString aSysPath;
      62           0 :             if( osl_getSystemPathFromFileURL( aConfigPath.pData, &aSysPath.pData ) == osl_File_E_None )
      63           0 :                 aConfigPath = aSysPath;
      64             :         }
      65         137 :         if( aInstallationRootPath.startsWith( "file://" ) )
      66             :         {
      67         137 :             OUString aSysPath;
      68         137 :             if( osl_getSystemPathFromFileURL( aInstallationRootPath.pData, &aSysPath.pData ) == osl_File_E_None )
      69         137 :                 aInstallationRootPath = aSysPath;
      70             :         }
      71         137 :         if( aUserPath.startsWith( "file://" ) )
      72             :         {
      73         137 :             OUString aSysPath;
      74         137 :             if( osl_getSystemPathFromFileURL( aUserPath.pData, &aSysPath.pData ) == osl_File_E_None )
      75         137 :                 aUserPath = aSysPath;
      76             :         }
      77             :         // ensure user path exists
      78         137 :         aUPath += "/user/psprint";
      79             :         #if OSL_DEBUG_LEVEL > 1
      80             :         oslFileError eErr =
      81             :         #endif
      82         274 :         osl_createDirectoryPath( aUPath.pData, NULL, NULL );
      83             :         #if OSL_DEBUG_LEVEL > 1
      84             :         fprintf( stderr, "try to create \"%s\" = %d\n", OUStringToOString( aUPath, RTL_TEXTENCODING_UTF8 ).getStr(), eErr );
      85             :         #endif
      86             :     }
      87             : 
      88         816 :     switch( ePath )
      89             :     {
      90         137 :         case ConfigPath: return aConfigPath;
      91         271 :         case InstallationRootPath: return aInstallationRootPath;
      92         408 :         case UserPath: return aUserPath;
      93             :     }
      94           0 :     return aEmpty;
      95             : }
      96             : 
      97         134 : static OString getEnvironmentPath( const char* pKey )
      98             : {
      99         134 :     OString aPath;
     100             : 
     101         134 :     const char* pValue = getenv( pKey );
     102         134 :     if( pValue && *pValue )
     103             :     {
     104           0 :         aPath = OString( pValue );
     105             :     }
     106         134 :     return aPath;
     107             : }
     108             : 
     109             : } // namespace psp
     110             : 
     111         134 : void psp::getPrinterPathList( std::list< OUString >& rPathList, const char* pSubDir )
     112             : {
     113         134 :     rPathList.clear();
     114         134 :     rtl_TextEncoding aEncoding = osl_getThreadTextEncoding();
     115             : 
     116         134 :     OUStringBuffer aPathBuffer( 256 );
     117             : 
     118             :     // append net path
     119         134 :     aPathBuffer.append( getOfficePath( psp::InstallationRootPath ) );
     120         134 :     if( !aPathBuffer.isEmpty() )
     121             :     {
     122         134 :         aPathBuffer.appendAscii( "/" LIBO_SHARE_FOLDER "/psprint" );
     123         134 :         if( pSubDir )
     124             :         {
     125          52 :             aPathBuffer.append( '/' );
     126          52 :             aPathBuffer.appendAscii( pSubDir );
     127             :         }
     128         134 :         rPathList.push_back( aPathBuffer.makeStringAndClear() );
     129             :     }
     130             :     // append user path
     131         134 :     aPathBuffer.append( getOfficePath( psp::UserPath ) );
     132         134 :     if( !aPathBuffer.isEmpty() )
     133             :     {
     134         134 :         aPathBuffer.appendAscii( "/user/psprint" );
     135         134 :         if( pSubDir )
     136             :         {
     137          52 :             aPathBuffer.append( '/' );
     138          52 :             aPathBuffer.appendAscii( pSubDir );
     139             :         }
     140         134 :         rPathList.push_back( aPathBuffer.makeStringAndClear() );
     141             :     }
     142             : 
     143         268 :     OString aPath( getEnvironmentPath("SAL_PSPRINT") );
     144         134 :     sal_Int32 nIndex = 0;
     145         134 :     do
     146             :     {
     147         134 :         OString aDir( aPath.getToken( 0, ':', nIndex ) );
     148         134 :         if( aDir.isEmpty() )
     149         134 :             continue;
     150             : 
     151           0 :         if( pSubDir )
     152             :         {
     153           0 :             aDir += "/";
     154           0 :             aDir += pSubDir;
     155             :         }
     156             :         struct stat aStat;
     157           0 :         if( stat( aDir.getStr(), &aStat ) || ! S_ISDIR( aStat.st_mode ) )
     158           0 :             continue;
     159             : 
     160           0 :         rPathList.push_back( OStringToOUString( aDir, aEncoding ) );
     161         134 :     } while( nIndex != -1 );
     162             : 
     163             :     #ifdef SYSTEM_PPD_DIR
     164             :     if( pSubDir && rtl_str_compare( pSubDir, PRINTER_PPDDIR ) == 0 )
     165             :     {
     166             :         rPathList.push_back( OStringToOUString( OString( SYSTEM_PPD_DIR ), RTL_TEXTENCODING_UTF8 ) );
     167             :     }
     168             :     #endif
     169             : 
     170         134 :     if( rPathList.empty() )
     171             :     {
     172             :         // last resort: next to program file (mainly for setup)
     173           0 :         OUString aExe;
     174           0 :         if( osl_getExecutableFile( &aExe.pData ) == osl_Process_E_None )
     175             :         {
     176           0 :             INetURLObject aDir( aExe );
     177           0 :             aDir.removeSegment();
     178           0 :             aExe = aDir.GetMainURL( INetURLObject::NO_DECODE );
     179           0 :             OUString aSysPath;
     180           0 :             if( osl_getSystemPathFromFileURL( aExe.pData, &aSysPath.pData ) == osl_File_E_None )
     181             :             {
     182           0 :                 rPathList.push_back( aSysPath );
     183           0 :             }
     184           0 :         }
     185         134 :     }
     186         134 : }
     187             : 
     188         137 : OUString psp::getFontPath()
     189             : {
     190         137 :     static OUString aPath;
     191             : 
     192         137 :     if (aPath.isEmpty())
     193             :     {
     194         137 :         OUStringBuffer aPathBuffer( 512 );
     195             : 
     196         274 :         OUString aConfigPath( getOfficePath( psp::ConfigPath ) );
     197         274 :         OUString aInstallationRootPath( getOfficePath( psp::InstallationRootPath ) );
     198         274 :         OUString aUserPath( getOfficePath( psp::UserPath ) );
     199         137 :         if( !aConfigPath.isEmpty() )
     200             :         {
     201             :             // #i53530# Path from CustomDataUrl will completely
     202             :             // replace net and user paths if the path exists
     203           0 :             aPathBuffer.append(aConfigPath);
     204           0 :             aPathBuffer.appendAscii("/" LIBO_SHARE_FOLDER "/fonts");
     205             :             // check existance of config path
     206             :             struct stat aStat;
     207           0 :             if( 0 != stat( OUStringToOString( aPathBuffer.makeStringAndClear(), osl_getThreadTextEncoding() ).getStr(), &aStat )
     208           0 :                 || ! S_ISDIR( aStat.st_mode ) )
     209           0 :                 aConfigPath = OUString();
     210             :             else
     211             :             {
     212           0 :                 aPathBuffer.append(aConfigPath);
     213           0 :                 aPathBuffer.appendAscii("/" LIBO_SHARE_FOLDER "/fonts");
     214             :             }
     215             :         }
     216         137 :         if( aConfigPath.isEmpty() )
     217             :         {
     218         137 :             if( !aInstallationRootPath.isEmpty() )
     219             :             {
     220         137 :                 aPathBuffer.append( aInstallationRootPath );
     221         137 :                 aPathBuffer.appendAscii( "/" LIBO_SHARE_FOLDER "/fonts/truetype;");
     222         137 :                 aPathBuffer.append( aInstallationRootPath );
     223         137 :                 aPathBuffer.appendAscii( "/" LIBO_SHARE_FOLDER "/fonts/type1;" );
     224             :             }
     225         137 :             if( !aUserPath.isEmpty() )
     226             :             {
     227         137 :                 aPathBuffer.append( aUserPath );
     228         137 :                 aPathBuffer.appendAscii( "/user/fonts" );
     229             :             }
     230             :         }
     231             : 
     232         274 :         aPath = aPathBuffer.makeStringAndClear();
     233             : #if OSL_DEBUG_LEVEL > 1
     234             :         fprintf( stderr, "initializing font path to \"%s\"\n", OUStringToOString( aPath, RTL_TEXTENCODING_ISO_8859_1 ).getStr() );
     235             : #endif
     236             :     }
     237         137 :     return aPath;
     238             : }
     239             : 
     240           0 : bool psp::convertPfbToPfa( ::osl::File& rInFile, ::osl::File& rOutFile )
     241             : {
     242             :     static const unsigned char hexDigits[] =
     243             :         {
     244             :             '0', '1', '2', '3', '4', '5', '6', '7',
     245             :             '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'
     246             :         };
     247             : 
     248           0 :     bool bSuccess = true;
     249           0 :     bool bEof = false;
     250             :     unsigned char buffer[256];
     251             :     sal_uInt64 nRead;
     252           0 :     sal_uInt64 nOrgPos = 0;
     253           0 :     rInFile.getPos( nOrgPos );
     254             : 
     255           0 :     while( bSuccess && ! bEof )
     256             :     {
     257             :         // read leading bytes
     258           0 :         bEof = ((0 != rInFile.read( buffer, 6, nRead)) || (nRead != 6));
     259           0 :         if( bEof )
     260           0 :             break;
     261           0 :         unsigned int nType = buffer[ 1 ];
     262           0 :         unsigned int nBytesToRead = buffer[2] | buffer[3] << 8 | buffer[4] << 16 | buffer[5] << 24;
     263           0 :         if( buffer[0] != 0x80 ) // test for pfb magic number
     264             :         {
     265             :             // this migt be a pfa font already
     266           0 :             if( ! rInFile.read( buffer+6, 9, nRead ) && nRead == 9 &&
     267           0 :                 ( ! std::strncmp( (char*)buffer, "%!FontType1-", 12 ) ||
     268           0 :                   ! std::strncmp( (char*)buffer, "%!PS-AdobeFont-", 15 ) ) )
     269             :             {
     270           0 :                 sal_uInt64 nWrite = 0;
     271           0 :                 if( rOutFile.write( buffer, 15, nWrite ) || nWrite != 15 )
     272           0 :                     bSuccess = false;
     273           0 :                 while( bSuccess &&
     274           0 :                        ! rInFile.read( buffer, sizeof( buffer ), nRead ) &&
     275           0 :                        nRead != 0 )
     276             :                 {
     277           0 :                     if( rOutFile.write( buffer, nRead, nWrite ) ||
     278           0 :                         nWrite != nRead )
     279           0 :                         bSuccess = false;
     280             :                 }
     281           0 :                 bEof = true;
     282             :             }
     283             :             else
     284           0 :                 bSuccess = false;
     285             :         }
     286           0 :         else if( nType == 1 || nType == 2 )
     287             :         {
     288           0 :             boost::scoped_array<unsigned char> pBuffer(new unsigned char[ nBytesToRead+1 ]);
     289             : 
     290           0 :             if( ! rInFile.read( pBuffer.get(), nBytesToRead, nRead ) && nRead == nBytesToRead )
     291             :             {
     292           0 :                 if( nType == 1 )
     293             :                 {
     294             :                     // ascii data, convert dos lineends( \r\n ) and
     295             :                     // m_ac lineends( \r ) to \n
     296           0 :                     boost::scoped_array<unsigned char> pWriteBuffer(new unsigned char[ nBytesToRead ]);
     297           0 :                     unsigned int nBytesToWrite = 0;
     298           0 :                     for( unsigned int i = 0; i < nBytesToRead; i++ )
     299             :                     {
     300           0 :                         if( pBuffer[i] != '\r' )
     301           0 :                             pWriteBuffer[ nBytesToWrite++ ] = pBuffer[i];
     302           0 :                         else if( pBuffer[ i+1 ] == '\n' )
     303             :                         {
     304           0 :                             i++;
     305           0 :                             pWriteBuffer[ nBytesToWrite++ ] = '\n';
     306             :                         }
     307             :                         else
     308           0 :                             pWriteBuffer[ nBytesToWrite++ ] = '\n';
     309             :                     }
     310           0 :                     if( rOutFile.write( pWriteBuffer.get(), nBytesToWrite, nRead ) || nRead != nBytesToWrite )
     311           0 :                         bSuccess = false;
     312             :                 }
     313             :                 else
     314             :                 {
     315             :                     // binary data
     316           0 :                     unsigned int nBuffer = 0;
     317           0 :                     for( unsigned int i = 0; i < nBytesToRead && bSuccess; i++ )
     318             :                     {
     319           0 :                         buffer[ nBuffer++ ] = hexDigits[ pBuffer[ i ] >> 4 ];
     320           0 :                         buffer[ nBuffer++ ] = hexDigits[ pBuffer[ i ] & 15 ];
     321           0 :                         if( nBuffer >= 80 )
     322             :                         {
     323           0 :                             buffer[ nBuffer++ ] = '\n';
     324           0 :                             if( rOutFile.write( buffer, nBuffer, nRead ) || nRead != nBuffer )
     325           0 :                                 bSuccess = false;
     326           0 :                             nBuffer = 0;
     327             :                         }
     328             :                     }
     329           0 :                     if( nBuffer > 0 && bSuccess )
     330             :                     {
     331           0 :                         buffer[ nBuffer++ ] = '\n';
     332           0 :                         if( rOutFile.write( buffer, nBuffer, nRead ) || nRead != nBuffer )
     333           0 :                             bSuccess = false;
     334             :                     }
     335             :                 }
     336             :             }
     337             :             else
     338           0 :                 bSuccess = false;
     339             :         }
     340           0 :         else if( nType == 3 )
     341           0 :             bEof = true;
     342             :         else
     343           0 :             bSuccess = false;
     344             :     }
     345             : 
     346           0 :     return bSuccess;
     347             : }
     348             : 
     349       42367 : void psp::normPath( OString& rPath )
     350             : {
     351             :     char buf[PATH_MAX];
     352             : 
     353             :     // double slashes and slash at end are probably
     354             :     // removed by realpath anyway, but since this runs
     355             :     // on many different platforms let's play it safe
     356       42367 :     OString aPath = rPath.replaceAll("//", "/");
     357             : 
     358       42367 :     if( aPath.endsWith("/") )
     359           0 :         aPath = aPath.copy(0, aPath.getLength()-1);
     360             : 
     361      126939 :     if( ( aPath.indexOf("./") != -1 ||
     362       42205 :           aPath.indexOf( '~' ) != -1 )
     363       42529 :         && realpath( aPath.getStr(), buf ) )
     364             :     {
     365          81 :         rPath = buf;
     366             :     }
     367             :     else
     368             :     {
     369       42286 :         rPath = aPath;
     370       42367 :     }
     371       42367 : }
     372             : 
     373       41956 : void psp::splitPath( OString& rPath, OString& rDir, OString& rBase )
     374             : {
     375       41956 :     normPath( rPath );
     376       41956 :     sal_Int32 nIndex = rPath.lastIndexOf( '/' );
     377       41956 :     if( nIndex > 0 )
     378       41956 :         rDir = rPath.copy( 0, nIndex );
     379           0 :     else if( nIndex == 0 ) // root dir
     380           0 :         rDir = rPath.copy( 0, 1 );
     381       41956 :     if( rPath.getLength() > nIndex+1 )
     382       41956 :         rBase = rPath.copy( nIndex+1 );
     383       41956 : }
     384             : 
     385             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10