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

Generated by: LCOV version 1.10