LCOV - code coverage report
Current view: top level - vcl/generic/fontmanager - helper.cxx (source / functions) Hit Total Coverage
Test: commit c8344322a7af75b84dd3ca8f78b05543a976dfd5 Lines: 99 193 51.3 %
Date: 2015-06-13 12:38:46 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        1136 : OUString getOfficePath( enum whichOfficePath ePath )
      41             : {
      42        1136 :     static OUString aInstallationRootPath;
      43        1136 :     static OUString aUserPath;
      44        1136 :     static OUString aConfigPath;
      45        1136 :     static OUString aEmpty;
      46             :     static bool bOnce = false;
      47             : 
      48        1136 :     if( ! bOnce )
      49             :     {
      50         205 :         bOnce = true;
      51         205 :         OUString aIni;
      52         205 :         Bootstrap::get( "BRAND_BASE_DIR", aInstallationRootPath );
      53         205 :         aIni = aInstallationRootPath + "/" LIBO_ETC_FOLDER "/" SAL_CONFIGFILE( "bootstrap" );
      54         410 :         Bootstrap aBootstrap( aIni );
      55         205 :         aBootstrap.getFrom( "CustomDataUrl", aConfigPath );
      56         205 :         aBootstrap.getFrom( "UserInstallation", aUserPath );
      57         410 :         OUString aUPath = aUserPath;
      58             : 
      59         205 :         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         205 :         if( aInstallationRootPath.startsWith( "file://" ) )
      66             :         {
      67         205 :             OUString aSysPath;
      68         205 :             if( osl_getSystemPathFromFileURL( aInstallationRootPath.pData, &aSysPath.pData ) == osl_File_E_None )
      69         205 :                 aInstallationRootPath = aSysPath;
      70             :         }
      71         205 :         if( aUserPath.startsWith( "file://" ) )
      72             :         {
      73         205 :             OUString aSysPath;
      74         205 :             if( osl_getSystemPathFromFileURL( aUserPath.pData, &aSysPath.pData ) == osl_File_E_None )
      75         205 :                 aUserPath = aSysPath;
      76             :         }
      77             :         // ensure user path exists
      78         205 :         aUPath += "/user/psprint";
      79             :         #if OSL_DEBUG_LEVEL > 1
      80             :         oslFileError eErr =
      81             :         #endif
      82         410 :         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        1136 :     switch( ePath )
      89             :     {
      90         205 :         case ConfigPath: return aConfigPath;
      91         363 :         case InstallationRootPath: return aInstallationRootPath;
      92         568 :         case UserPath: return aUserPath;
      93             :     }
      94           0 :     return aEmpty;
      95             : }
      96             : 
      97         158 : static OString getEnvironmentPath( const char* pKey )
      98             : {
      99         158 :     OString aPath;
     100             : 
     101         158 :     const char* pValue = getenv( pKey );
     102         158 :     if( pValue && *pValue )
     103             :     {
     104           0 :         aPath = OString( pValue );
     105             :     }
     106         158 :     return aPath;
     107             : }
     108             : 
     109             : } // namespace psp
     110             : 
     111         158 : void psp::getPrinterPathList( std::list< OUString >& rPathList, const char* pSubDir )
     112             : {
     113         158 :     rPathList.clear();
     114         158 :     rtl_TextEncoding aEncoding = osl_getThreadTextEncoding();
     115             : 
     116         158 :     OUStringBuffer aPathBuffer( 256 );
     117             : 
     118             :     // append net path
     119         158 :     aPathBuffer.append( getOfficePath( psp::InstallationRootPath ) );
     120         158 :     if( !aPathBuffer.isEmpty() )
     121             :     {
     122         158 :         aPathBuffer.appendAscii( "/" LIBO_SHARE_FOLDER "/psprint" );
     123         158 :         if( pSubDir )
     124             :         {
     125          79 :             aPathBuffer.append( '/' );
     126          79 :             aPathBuffer.appendAscii( pSubDir );
     127             :         }
     128         158 :         rPathList.push_back( aPathBuffer.makeStringAndClear() );
     129             :     }
     130             :     // append user path
     131         158 :     aPathBuffer.append( getOfficePath( psp::UserPath ) );
     132         158 :     if( !aPathBuffer.isEmpty() )
     133             :     {
     134         158 :         aPathBuffer.appendAscii( "/user/psprint" );
     135         158 :         if( pSubDir )
     136             :         {
     137          79 :             aPathBuffer.append( '/' );
     138          79 :             aPathBuffer.appendAscii( pSubDir );
     139             :         }
     140         158 :         rPathList.push_back( aPathBuffer.makeStringAndClear() );
     141             :     }
     142             : 
     143         316 :     OString aPath( getEnvironmentPath("SAL_PSPRINT") );
     144         158 :     sal_Int32 nIndex = 0;
     145         158 :     do
     146             :     {
     147         158 :         OString aDir( aPath.getToken( 0, ':', nIndex ) );
     148         158 :         if( aDir.isEmpty() )
     149         158 :             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         158 :     } 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         158 :     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         158 :     }
     186         158 : }
     187             : 
     188         205 : OUString psp::getFontPath()
     189             : {
     190         205 :     static OUString aPath;
     191             : 
     192         205 :     if (aPath.isEmpty())
     193             :     {
     194         205 :         OUStringBuffer aPathBuffer( 512 );
     195             : 
     196         410 :         OUString aConfigPath( getOfficePath( psp::ConfigPath ) );
     197         410 :         OUString aInstallationRootPath( getOfficePath( psp::InstallationRootPath ) );
     198         410 :         OUString aUserPath( getOfficePath( psp::UserPath ) );
     199         205 :         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 existence 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.clear();
     210             :             else
     211             :             {
     212           0 :                 aPathBuffer.append(aConfigPath);
     213           0 :                 aPathBuffer.appendAscii("/" LIBO_SHARE_FOLDER "/fonts");
     214             :             }
     215             :         }
     216         205 :         if( aConfigPath.isEmpty() )
     217             :         {
     218         205 :             if( !aInstallationRootPath.isEmpty() )
     219             :             {
     220         205 :                 aPathBuffer.append( aInstallationRootPath );
     221         205 :                 aPathBuffer.appendAscii( "/" LIBO_SHARE_FOLDER "/fonts/truetype;");
     222         205 :                 aPathBuffer.append( aInstallationRootPath );
     223         205 :                 aPathBuffer.appendAscii( "/" LIBO_SHARE_FOLDER "/fonts/type1;" );
     224             :             }
     225         205 :             if( !aUserPath.isEmpty() )
     226             :             {
     227         205 :                 aPathBuffer.append( aUserPath );
     228         205 :                 aPathBuffer.appendAscii( "/user/fonts" );
     229             :             }
     230             :         }
     231             : 
     232         410 :         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         205 :     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           0 :     sal_uInt64 nSize(0);
     252           0 :     rInFile.getSize(nSize);
     253             : 
     254           0 :     while( bSuccess && ! bEof )
     255             :     {
     256             :         sal_uInt64 nRead;
     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 might be a pfa font already
     266           0 :             if( ! rInFile.read( buffer+6, 9, nRead ) && nRead == 9 &&
     267           0 :                 ( ! std::strncmp( reinterpret_cast<char*>(buffer), "%!FontType1-", 12 ) ||
     268           0 :                   ! std::strncmp( reinterpret_cast<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 :             sal_uInt64 nOrgPos(0);
     289           0 :             rInFile.getPos(nOrgPos);
     290           0 :             nBytesToRead = std::min<sal_uInt64>(nBytesToRead, nSize - nOrgPos);
     291             : 
     292           0 :             boost::scoped_array<unsigned char> pBuffer(new unsigned char[nBytesToRead+1]);
     293           0 :             pBuffer[nBytesToRead] = 0;
     294             : 
     295           0 :             if( ! rInFile.read( pBuffer.get(), nBytesToRead, nRead ) && nRead == nBytesToRead )
     296             :             {
     297           0 :                 if( nType == 1 )
     298             :                 {
     299             :                     // ascii data, convert dos lineends( \r\n ) and
     300             :                     // m_ac lineends( \r ) to \n
     301           0 :                     boost::scoped_array<unsigned char> pWriteBuffer(new unsigned char[ nBytesToRead ]);
     302           0 :                     unsigned int nBytesToWrite = 0;
     303           0 :                     for( unsigned int i = 0; i < nBytesToRead; i++ )
     304             :                     {
     305           0 :                         if( pBuffer[i] != '\r' )
     306           0 :                             pWriteBuffer[ nBytesToWrite++ ] = pBuffer[i];
     307           0 :                         else if( pBuffer[ i+1 ] == '\n' )
     308             :                         {
     309           0 :                             i++;
     310           0 :                             pWriteBuffer[ nBytesToWrite++ ] = '\n';
     311             :                         }
     312             :                         else
     313           0 :                             pWriteBuffer[ nBytesToWrite++ ] = '\n';
     314             :                     }
     315           0 :                     if( rOutFile.write( pWriteBuffer.get(), nBytesToWrite, nRead ) || nRead != nBytesToWrite )
     316           0 :                         bSuccess = false;
     317             :                 }
     318             :                 else
     319             :                 {
     320             :                     // binary data
     321           0 :                     unsigned int nBuffer = 0;
     322           0 :                     for( unsigned int i = 0; i < nBytesToRead && bSuccess; i++ )
     323             :                     {
     324           0 :                         buffer[ nBuffer++ ] = hexDigits[ pBuffer[ i ] >> 4 ];
     325           0 :                         buffer[ nBuffer++ ] = hexDigits[ pBuffer[ i ] & 15 ];
     326           0 :                         if( nBuffer >= 80 )
     327             :                         {
     328           0 :                             buffer[ nBuffer++ ] = '\n';
     329           0 :                             if( rOutFile.write( buffer, nBuffer, nRead ) || nRead != nBuffer )
     330           0 :                                 bSuccess = false;
     331           0 :                             nBuffer = 0;
     332             :                         }
     333             :                     }
     334           0 :                     if( nBuffer > 0 && bSuccess )
     335             :                     {
     336           0 :                         buffer[ nBuffer++ ] = '\n';
     337           0 :                         if( rOutFile.write( buffer, nBuffer, nRead ) || nRead != nBuffer )
     338           0 :                             bSuccess = false;
     339             :                     }
     340             :                 }
     341             :             }
     342             :             else
     343           0 :                 bSuccess = false;
     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       60325 : 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       60325 :     OString aPath = rPath.replaceAll("//", "/");
     362             : 
     363       60325 :     if( aPath.endsWith("/") )
     364           0 :         aPath = aPath.copy(0, aPath.getLength()-1);
     365             : 
     366      180741 :     if( ( aPath.indexOf("./") != -1 ||
     367       60091 :           aPath.indexOf( '~' ) != -1 )
     368       60559 :         && realpath( aPath.getStr(), buf ) )
     369             :     {
     370         117 :         rPath = buf;
     371             :     }
     372             :     else
     373             :     {
     374       60208 :         rPath = aPath;
     375       60325 :     }
     376       60325 : }
     377             : 
     378       59710 : void psp::splitPath( OString& rPath, OString& rDir, OString& rBase )
     379             : {
     380       59710 :     normPath( rPath );
     381       59710 :     sal_Int32 nIndex = rPath.lastIndexOf( '/' );
     382       59710 :     if( nIndex > 0 )
     383       59710 :         rDir = rPath.copy( 0, nIndex );
     384           0 :     else if( nIndex == 0 ) // root dir
     385           0 :         rDir = rPath.copy( 0, 1 );
     386       59710 :     if( rPath.getLength() > nIndex+1 )
     387       59710 :         rBase = rPath.copy( nIndex+1 );
     388       59710 : }
     389             : 
     390             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.11