Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
openSUSE:12.1
fonts-config
fonts-config
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File fonts-config of Package fonts-config
#! /usr/bin/perl -w # -*- perl -*- # # Copyright (c) 2000-2004 SuSE Linux AG, Nuernberg, Germany. # All rights reserved. # ######################################################################## # create a man-page with: # # pod2man --section 1 --center=" " fonts-config | gzip -9 -c > fonts-config.1.gz # cp fonts-config.1.gz /usr/share/man/man1/fonts-config.1.gz =head1 NAME fonts-config - configures installed X11 fonts. =head1 SYNOPSIS fonts-config [B<OPTION>]... =head1 OPTIONS =over 4 =item B<-f>, B<--force> Force the update of all generated files even if it appears to be unnecessary according to the time stamps. =item B<-q>, B<--quiet> Work silently, unless an error occurs. =item B<-v>, B<--verbose> Print some progress messages to standard output. =item B<-d>, B<--debug> Print a lot of debugging messages to standard output. =item B<--(no)gs-fontmap> Generate (or don't generate) a Fontmap for Ghostscript. Can only work if the 'ftdump' binary which is in the 'ft2demos' packages is available. =item B<--(no)ttcap> Generate (or don't generate) TTCap entries. TTCap entries can be used with the xtt module and with recent versions of the freetype module. =item B<--(no)ooo> Generate (or don't generate) font setup for OpenOffice =item B<--(no)java> Generate (or don't generate) font setup for Java 1.4.x and Java 1.5.x. =item B<--bcbwmax> size Maximum pixel size to use the byte code interpreter with black and white rendering. =item B<--version> Display version and exit. =item B<-h>, B<--help> Display a short help message and exit. =back =head1 DESCRIPTION Configures installed X11 fonts. Basically it does the following things: =over 4 =item B<call cidfont-x11-config> cidfont-x11-config is another little perl script which configures CID-keyed fonts for use with X11, see L<cidfont-x11-config(1)>. =item B<creates fonts.scale and fonts.dir files> To find the list of directories currently used for server side fonts, B</etc/X11/xorg.conf> is parsed and merged with a hardcoded list of directories. If the font server xfs is running, B</etc/X11/fs/config> is also parsed and the list of directories found there is merged as well. For each directory from this list, the time stamps of the directory, the B<fonts.scale> file, the B<fonts.dir> file and an extra time stamp file B<.fonts-config-timestamp> are checked. If not all the time stamps are equal or any of these files is missing, the B<fonts.scale> and B<fonts.dir> files will be updated as follows: First of all a B<fonts.scale> file is created by calling B<mkfontscale>. Then, the entries found in the B<fonts.scale> file are merged with the entries from all B<fonts.scale.*> files. B<fonts.scale.*> files may be supplied by rpm-packages or manually added by the user to override or amend the entries created automatically by B<mkfontscale>. Entries in a B<fonts.scale.*> file have higher priority than entries automatically created by B<mkfontscale>. All entries generated automatically by B<mkfontscale> for a certain font file are discarded if any B<fonts.scale.*> file contains an entry for the same font file. If the B<xtt> module is configured to load in B</etc/X11/xorg.conf>, additional entries may be created to make use of the artificial bold and italic features of B<xtt>. The time stamp of B</etc/X11/xorg.conf> is not checked, i.e. you have to use B<fonts-config --force> after editing B</etc/X11/xorg.conf> to switch between the B<xtt> and B<freetype> modules. After the final list of entries has been written back to B<fonts.scale>, B<mkfontdir> is called. Finally, the time stamps of the directory, B<fonts.scale>, B<fonts.dir>, and B<.fonts-config-timestamp> are set to the time when B<fonts-config> started. If any B<fonts.scale> file in the directory list needed an update and the option B<--gs-fontmap> is set, a Ghostcript Fontmap is also generated for all scalable fonts in the directory list and the result is written to B</usr/share/ghostscript/*/lib/Fontmap.X11-auto>. =item B<call fc-cache> creates cache files for fonts to use with client side font rendering via fontconfig/libXft, for details see L<fc-cache(1)>. B<fonts.cache-2> cache files are generated in B</var/cache/fontconfig> for all directories which are configured in B</etc/fonts/fonts.conf> and all their subdirectories. =back Usually B<fonts-config> is called automatically via SuSEconfig (B<SuSEconfig --module fonts>), which is usually automatically called by YaST2. But you can also execute B<fonts-config> directly, which is mainly useful to debug it. =head1 FILES =over 4 =item B</etc/sysconfig/fonts-config> Default values for some command line options of fonts-config are read from this file if it exists. The options currently supported in this file are: =over 4 =item GENERATE_TTCAP_ENTRIES can be set to "yes" or "no" and sets the default for the option B<--(no)ttcap>. =item GENERATE_GHOSTSCRIPT_FONTMAPS can be set to "yes" or "no" and sets the default for the option B<--(no)gs-fontmap>. This can only work if the 'ftdump' binary which is in the 'ft2demos' packages is available. =item GENERATE_OOO_FONT_SETUP can be set to "yes" or "no" and sets the default for the option B<--(no)ooo>. =item GENERATE_JAVA_FONT_SETUP can be set to "yes" or "no" and sets the default for the option B<--(no)java>. =item BYTECODE_BW_MAX_PIXEL can be set to any integer value and sets the default for the option B<--bcbwmax>. =back =back =head1 SEE ALSO L<fc-cache(1)>, L<cidfont-x11-config(1)>, L<mkfontdir(1)>, L<mkfontscale(1)> =head1 AUTHOR Mike FABIAN <I<mfabian@suse.de>>, 2003. =cut ######################################################################## use utf8; use English; use Getopt::Long; use strict; my $script_start_time = time(); my $cvs_id = '$Id: fonts-config,v 1.73 2009/01/28 16:23:08 mfabian Exp $'; my $cvs_date = '$Date: 2009/01/28 16:23:08 $'; $cvs_date =~ /^\$[[:alpha:]]+: (.*) \$$/; my $version = $1; sub usage { print "Usage: fonts-config [option] ...\n"; print "-f, --force Force the update of all generated files even\n"; print " if it appears unnecessary according to the time stamps\n"; print "-q, --quiet Work silently, unless an error occurs.\n"; print "-v, --verbose Print some progress messages to standard output.\n"; print "-d, --debug Print a lot of debugging messages to standard output.\n"; print " --(no)gs-fontmap generate a Fontmap file for Ghostscript.\n"; print " --(no)ttcap generate TTCap entries for xtt and recent freetype modules.\n"; print " --(no)ooo generate font setup for OpenOffice.\n"; print " --(no)java generate font setup for Java 1.4.x and Java 1.5.x.\n"; print " --bcbwmax size maximum pixel size to use the byte code interpreter with\n"; print " black and white rendering.\n"; print " --(no)ebitmap whether to use embedded bitmaps or not.\n"; print " --ebitmaplang string the argument is a string which contains a list of colon\n"; print " separated languages, for example \"ja:ko:zh-CN\" \n"; print " which means \"use embedded bitmaps only for\n"; print " fonts supporting Japanese, Korean, or simplified Chinese.\n"; print " --version Display version and exit.\n"; print "-h, --help Display this help and exit.\n"; exit 1; } my $OPT_FORCE = 0; my $OPT_QUIET = 0; my $OPT_VERBOSE = 1; my $OPT_DEBUG = 0; my $OPT_TTCAP = 0; my $OPT_GS_FONTMAP = 1; my $OPT_OOO = 1; my $OPT_JAVA = 1; my $OPT_BCBWMAX = 0; my $OPT_EBITMAP = 1; my $OPT_EBITMAP_LANG = "ja:ko:zh-CN:zh-TW:zh-HK:zh-SG"; my $OPT_VERSION = 0; my $OPT_HELP = 0; my %sysconfig_options = ( "GENERATE_TTCAP_ENTRIES" , "OPT_TTCAP", "GENERATE_GHOSTSCRIPT_FONTMAPS" , "OPT_GS_FONTMAP", "GENERATE_OOO_FONT_SETUP" , "OPT_OOO", "GENERATE_JAVA_FONT_SETUP" , "OPT_JAVA", "BYTECODE_BW_MAX_PIXEL" , "OPT_BCBWMAX", "USE_EMBEDDED_BITMAPS" , "OPT_EBITMAP", "EMBEDDED_BITMAPS_LANGUAGES" , "OPT_EBITMAP_LANG" ); my $sysconfig_file = "/etc/sysconfig/fonts-config"; sub get_option_defaults_from_sysconfig { if (open (SYSCONFIG, "$sysconfig_file")) { no strict "vars"; # print "reading defaults from $sysconfig.\n"; while (<SYSCONFIG>) { chomp ($ARG); if ($ARG =~ /([^#]*)#?.*/) { # strip comments $ARG = $1; } eval ("\$$ARG;"); } close (SYSCONFIG); for my $i (keys %sysconfig_options) { if (eval ("\$$i") =~ /yes/i) { eval("\$$sysconfig_options{$i}=1"); } elsif (eval ("\$$i") =~ /no/i) { eval("\$$sysconfig_options{$i}=0"); } elsif (eval ("\$$i") =~ /[0-9]+/) { # Type integer eval("\$$sysconfig_options{$i}=\$$i"); } elsif (eval ("\$$i") =~ /[-:a-zA-Z0-9]+/) { # Type string eval("\$$sysconfig_options{$i}=\$$i"); } else { # this case also occurs when the variable is the empty string! eval("\$$sysconfig_options{$i}=0"); } } return (0); } else { # print "$sysconfig doesn't exist, using builtin defaults.\n"; return (1); } } get_option_defaults_from_sysconfig(); # Process command line options my %opt; unless (GetOptions(\%opt, 'force|f', \$OPT_FORCE, 'quiet|q', \$OPT_QUIET, 'verbose|v', \$OPT_VERBOSE, 'debug|d', \$OPT_DEBUG, 'gs-fontmap!', \$OPT_GS_FONTMAP, 'ttcap!', \$OPT_TTCAP, 'ooo!', \$OPT_OOO, 'java!', \$OPT_JAVA, 'bcbwmax=i', \$OPT_BCBWMAX, 'ebitmap!', \$OPT_EBITMAP, 'ebitmaplang=s', \$OPT_EBITMAP_LANG, 'version', \$OPT_VERSION, 'help|h', \$OPT_HELP, )) { &usage (); exit 1; } if ($OPT_VERSION) { print "fonts-config $version\n"; exit 0; } if ($OPT_HELP) { &usage (); exit 0; } my $VERBOSITY_QUIET = 0; my $VERBOSITY_VERBOSE = 1; my $VERBOSITY_DEBUG = 256; my $VERBOSITY = $VERBOSITY_VERBOSE; # default if ($OPT_DEBUG) { $VERBOSITY = $VERBOSITY_DEBUG; } elsif ($OPT_VERBOSE) { $VERBOSITY = $VERBOSITY_VERBOSE; } elsif ($OPT_QUIET) { $VERBOSITY = $VERBOSITY_QUIET; } no strict "vars"; no warnings; if ($VERBOSITY >= $VERBOSITY_DEBUG) { print "The following options were read from $sysconfig_file:\n"; for my $i (keys %sysconfig_options) { if (defined eval ("\$$i")) { printf "$i=%s\n", eval("\$$i"); } } print "--- end of options froom $sysconfig_file ---\n"; } use warnings; use strict; # check if we are started as root # only one of UID and USER must be set correctly if ($UID != 0 && $ENV{USER} !~ /root/) { print "*** Error: You must be root to start $0\n"; usage(); exit 1; } # external binaries: my $fc_cache_bin = search_executable ("/usr/bin/fc-cache", "/usr/X11R6/bin/fc-cache"); my $fc_cache32_bin = search_executable ("/usr/bin/fc-cache32", "/usr/bin/fc-cache-x86"); my $fc_cache64_bin = search_executable ("/usr/bin/fc-cache64"); my $fc_match_bin = search_executable ("/usr/bin/fc-match"); my $cidfont_x11_config_bin = search_executable ("/usr/sbin/cidfont-x11-config"); my $xset_bin = search_executable ("/usr/bin/xset", "/usr/X11R6/bin/xset"); my $xfs_bin = search_executable ("/usr/bin/xfs", "/usr/X11R6/bin/xfs"); my $checkproc_bin = search_executable ("/sbin/checkproc"); my $killproc_bin = search_executable ("/sbin/killproc"); my $XFree86_bin = search_executable ("/usr/bin/Xorg", "/usr/X11R6/bin/Xorg", "/usr/X11R6/bin/XFree86"); my $mkfontscale_bin = search_executable ("/usr/bin/mkfontscale", "/usr/X11R6/bin/mkfontscale"); my $mkfontdir_bin = search_executable ("/usr/bin/mkfontdir", "/usr/X11R6/bin/mkfontdir"); my $ftdump_bin = search_executable ("/usr/bin/ftdump"); my $xtt_module_used = 0; my $freetype_module_used = 0; my $have_file_mmagic = 0; eval { require File::MMagic; }; unless ($EVAL_ERROR) { $have_file_mmagic = 1; import File::MMagic; } my $command = ""; # search whether true CID-keyed fonts are available # in /usr/share/ghostscript/Resource and if yes make them # available to X11 as well: if ($cidfont_x11_config_bin) { $command = $cidfont_x11_config_bin; if ($VERBOSITY >= $VERBOSITY_VERBOSE) { print "Configure X11 to use available CID-keyed fonts ...\n"; } if ($VERBOSITY >= $VERBOSITY_DEBUG) { $command .= " --verbose "; } if ($OPT_FORCE) { $command .= " --force "; } my_system ($command); } my @x11_font_dirs = x11_font_dirs(); my $gs_fontmap_needs_update = 0; if ($VERBOSITY >= $VERBOSITY_VERBOSE) { print "Creating fonts.{scale,dir} files "; } for my $dir (@x11_font_dirs) { make_fonts_scale_and_fonts_dir ($dir); if ($VERBOSITY >= $VERBOSITY_VERBOSE) { print "."; # "progress bar" } } if ($VERBOSITY >= $VERBOSITY_VERBOSE) { print "\n"; } # The following three lines may change files in /etc/fonts, therefore # they have to be called *before* fc-cache. If anything is # changed in /etc/fonts after calling fc-cache, fontconfig # will think that the cache files are out of date again. font_dirs_setup (); hinting_setup (); embedded_bitmap_setup (); my $fc_cache_exit_status = 256; if ($fc_cache_bin) { $command = "$fc_cache_bin"; if ($VERBOSITY >= $VERBOSITY_VERBOSE) { print "Creating cache files for fontconfig "; } if ($OPT_FORCE) { $command .= " --really-force "; } if ($VERBOSITY >= $VERBOSITY_VERBOSE) { $command .= " --verbose "; } if ($VERBOSITY >= $VERBOSITY_VERBOSE) { # with "progress bar" open (FC_CACHE, "$command |"); select (STDOUT); $OUTPUT_AUTOFLUSH = 1; while(<FC_CACHE>) { print "."; } print "\n"; close (FC_CACHE); } else { # without "progress bar" my_system($command); } } $fc_cache_exit_status = $CHILD_ERROR; if ($VERBOSITY >= $VERBOSITY_DEBUG) { print "exit status of fc-cache: $fc_cache_exit_status\n"; } my $fc_cache32_exit_status = 256; if ($fc_cache32_bin) { $command = "$fc_cache32_bin"; if ($VERBOSITY >= $VERBOSITY_VERBOSE) { print "Creating 32bit cache files for fontconfig "; } if ($VERBOSITY >= $VERBOSITY_VERBOSE) { $command .= " --verbose "; } if ($VERBOSITY >= $VERBOSITY_VERBOSE) { # with "progress bar" open (FC_CACHE, "$command |"); select (STDOUT); $OUTPUT_AUTOFLUSH = 1; while(<FC_CACHE>) { print "."; } print "\n"; close (FC_CACHE); } else { # without "progress bar" my_system($command); } } $fc_cache32_exit_status = $CHILD_ERROR; if ($VERBOSITY >= $VERBOSITY_DEBUG) { print "exit status of fc-cache: $fc_cache32_exit_status\n"; } my $fc_cache64_exit_status = 256; if ($fc_cache64_bin) { $command = "$fc_cache64_bin"; if ($VERBOSITY >= $VERBOSITY_VERBOSE) { print "Creating 64bit cache files for fontconfig "; } if ($VERBOSITY >= $VERBOSITY_VERBOSE) { $command .= " --verbose "; } if ($VERBOSITY >= $VERBOSITY_VERBOSE) { # with "progress bar" open (FC_CACHE, "$command |"); select (STDOUT); $OUTPUT_AUTOFLUSH = 1; while(<FC_CACHE>) { print "."; } print "\n"; close (FC_CACHE); } else { # without "progress bar" my_system($command); } } $fc_cache64_exit_status = $CHILD_ERROR; if ($VERBOSITY >= $VERBOSITY_DEBUG) { print "exit status of fc-cache: $fc_cache64_exit_status\n"; } # make_gs_fontmap uses fontconfig, # therefore it has to be called *after* fc-cache if ($OPT_GS_FONTMAP) { if ($OPT_FORCE || $gs_fontmap_needs_update ) { make_gs_fontmap (@x11_font_dirs); } } # generate_ooo_font_setup uses fontconfig, # therefore it has to be called *after* fc-cache if ($OPT_OOO) { generate_ooo_font_setup (); } # generate_java_font_setup uses fontconfig, # therefore it has to be called *after* fc-cache if ($OPT_JAVA) { generate_java_font_setup (); } # source all shell scripts from the directory /usr/lib/fonts-config/conf.d # which start with at least one digit (sorted in POSIX sort order because this # perl script does *not* use "use locale"): if (opendir (DIR, "/usr/lib/fonts-config/conf.d")) { my @entries = readdir (DIR); for my $entry (sort (@entries)) { if ("$entry" =~ /\./ || "$entry" =~ /\.\./ || "$entry" !~ /^[0-9]+/ || ! -f "/usr/lib/fonts-config/conf.d/$entry") { next; } my_system ("sh /usr/lib/fonts-config/conf.d/$entry"); } closedir DIR; } if ($xset_bin) { if ($ENV{DISPLAY} && $ENV{DISPLAY} =~ /^:[0-9].*/) { # it's a local display $command = "$xset_bin fp rehash "; unless ($VERBOSITY >= $VERBOSITY_DEBUG) { $command .= " > /dev/null 2>&1 "; } my_system ($command); } } if ($xfs_bin && my_system ("$checkproc_bin $xfs_bin") == 0) { if ($VERBOSITY >= $VERBOSITY_DEBUG) { print "Reloading config file of X Font Server ...\n"; } my_system ("$killproc_bin $xfs_bin -USR1"); } elsif ($VERBOSITY >= $VERBOSITY_DEBUG) { print "X Font Server not used.\n"; } exit 0; ######################################################################## sub version_compare { my ($version_string_1, $version_string_2) = @_; # compare two version numbers consisting only of digits and dots # returns an integer less than, equal to, or greater than zero # if $version_string_1 is found, respectively, to be a smaller version, # equal version, or greater version than $version_string_2. my @v1 = split (/\./, $version_string_1); my @v2 = split (/\./, $version_string_2); for (my $i = 0 ; $i <= $#v1 && $i <= $#v2; $i++) { if ($v1[$i] < $v2[$i]) { return -1; } elsif ($v1[$i] > $v2[$i]) { return 1; } } if ($#v1 < $#v2) { return -1; } elsif ($#v1 > $#v2) { return 1; } return 0; } sub fontconfig_version { if ($fc_cache_bin) { open (VERSION, "$fc_cache_bin -V 2>&1 |"); binmode VERSION, ":bytes"; while (<VERSION>) { if ($ARG =~ /fontconfig\s+version\s+([.[:digit:]]+)\s*/) { close (VERSION); return "$1"; } } close (VERSION); } # don't know the version return ""; } sub xfree86_version { if ($XFree86_bin) { open (VERSION, "$XFree86_bin -version 2>&1 |"); binmode VERSION, ":bytes"; while (<VERSION>) { if ($ARG =~ /Version\s+([.[:digit:]]+)\s*/) { close (VERSION); return "$1"; } } close (VERSION); } # don't know the version return ""; } sub freetype_module_supports_ttcap { my ($v1, $v2, $v3, $v4) = xfree86_version(); if (version_compare(xfree86_version(), "4.3.99") >= 0) { if ($VERBOSITY >= $VERBOSITY_DEBUG) { print "freetype module supports TTCap.\n"; } return 1; } else { if ($VERBOSITY >= $VERBOSITY_DEBUG) { print "freetype module does not support TTCap.\n"; } return 0; } } sub x11_font_dirs { my @dirs = (); my @standard_dirs = ( "/usr/share/fonts/local", "/usr/share/fonts/misc", "/usr/share/fonts/75dpi", "/usr/share/fonts/100dpi", "/usr/share/fonts/Type1", "/usr/share/fonts/URW", "/usr/share/fonts/Speedo", "/usr/share/fonts/PEX", "/usr/share/fonts/cyrillic", "/usr/share/fonts/latin2/misc", "/usr/share/fonts/latin2/75dpi", "/usr/share/fonts/latin2/100dpi", "/usr/share/fonts/latin2/Type1", "/usr/share/fonts/latin7/75dpi", "/usr/share/fonts/baekmuk", "/usr/share/fonts/japanese", "/usr/share/fonts/kwintv", "/usr/share/fonts/truetype", "/usr/share/fonts/uni", "/usr/share/fonts/CID", "/usr/share/fonts/ucs/misc", "/usr/share/fonts/ucs/75dpi", "/usr/share/fonts/ucs/100dpi", "/usr/share/fonts/hellas/misc", "/usr/share/fonts/hellas/75dpi", "/usr/share/fonts/hellas/100dpi", "/usr/share/fonts/hellas/Type1", "/usr/share/fonts/misc/sgi", "/usr/share/fonts/xtest", "/usr/X11R6/lib/X11/fonts/local", "/usr/X11R6/lib/X11/fonts/misc", "/usr/X11R6/lib/X11/fonts/75dpi", "/usr/X11R6/lib/X11/fonts/100dpi", "/usr/X11R6/lib/X11/fonts/Type1", "/usr/X11R6/lib/X11/fonts/URW", "/usr/X11R6/lib/X11/fonts/Speedo", "/usr/X11R6/lib/X11/fonts/PEX", "/usr/X11R6/lib/X11/fonts/cyrillic", "/usr/X11R6/lib/X11/fonts/latin2/misc", "/usr/X11R6/lib/X11/fonts/latin2/75dpi", "/usr/X11R6/lib/X11/fonts/latin2/100dpi", "/usr/X11R6/lib/X11/fonts/latin2/Type1", "/usr/X11R6/lib/X11/fonts/latin7/75dpi", "/usr/X11R6/lib/X11/fonts/baekmuk", "/usr/X11R6/lib/X11/fonts/japanese", "/usr/X11R6/lib/X11/fonts/kwintv", "/usr/X11R6/lib/X11/fonts/truetype", "/usr/X11R6/lib/X11/fonts/uni", "/usr/X11R6/lib/X11/fonts/CID", "/usr/X11R6/lib/X11/fonts/ucs/misc", "/usr/X11R6/lib/X11/fonts/ucs/75dpi", "/usr/X11R6/lib/X11/fonts/ucs/100dpi", "/usr/X11R6/lib/X11/fonts/hellas/misc", "/usr/X11R6/lib/X11/fonts/hellas/75dpi", "/usr/X11R6/lib/X11/fonts/hellas/100dpi", "/usr/X11R6/lib/X11/fonts/hellas/Type1", "/usr/X11R6/lib/X11/fonts/misc/sgi", "/usr/X11R6/lib/X11/fonts/xtest", "/opt/kde3/share/fonts" ); push (@dirs, @standard_dirs); push (@dirs, xorg_config_font_dirs()); push (@dirs, xfs_font_dirs()); # Attention!: # /usr/X11R6/lib/X11/fonts/encodings usually doesn't contain any fonts. # Neverthelesss a valid encodings.dir file must exist in that directory # because some applications, e.g. luit, read encodings.dir from there # (See for example "LANG=ja_JP strace -eopen luit -c"). # The easiest way to make sure that the encodings.dir in that directory # is correct and up to date is to add the "encodings" directory to the # list of font directories. # Then mkfontdir will be called on that directory as well and a correct # encodings.dir will be generated. if (-d "/usr/share/fonts/encodings") { push (@dirs, ("/usr/share/fonts/encodings")); } else { push (@dirs, ("/usr/X11R6/lib/X11/fonts/encodings")); } # remove non existing directories and duplicates: my %dirs = (); for my $dir (@dirs) { if (-d $dir) { $dirs{$dir} = ""; } } return (keys %dirs); } # gets font paths configured in /etc/X11/xorg.conf # and check wether the "xtt" and/or "freetype" modules are loaded: sub xorg_config_font_dirs { my @dirs = (); my $file = "/etc/X11/xorg.conf"; if (-e $file) { open (CONFIGFILE, $file) || die "can't open file $file: $!"; while (<CONFIGFILE>) { chomp ($ARG); if ($ARG =~ /([^#]*)#?.*/) { # strip comments $ARG = $1; } if ($ARG =~ /\s*FontPath\s+"(.+?)(:unscaled|:scaled)?"\s*/i) { push (@dirs, $1); } if ($ARG =~ /\s*Load\s+"xtt"/) { if ($VERBOSITY >= $VERBOSITY_DEBUG) { print "xtt module is used.\n"; } $xtt_module_used = 1; } if ($ARG =~ /\s*Load\s+"freetype"/) { if ($VERBOSITY >= $VERBOSITY_DEBUG) { print "freetype module is used.\n"; } $freetype_module_used = 1; } } close (CONFIGFILE); } if ($VERBOSITY >= $VERBOSITY_DEBUG) { print "font paths found in $file:\n"; for my $dir (@dirs) { print "$dir\n"; } } return @dirs; } # gets font paths configured for xfs if xfs exists and is running: sub xfs_font_dirs { my @dirs = (); my $file = "/etc/X11/fs/config"; if ($xfs_bin && my_system ("$checkproc_bin $xfs_bin") == 0) { if (-e $file) { my $config_file_contents = ""; open (CONFIGFILE, $file) || die "can't open file $file: $!"; while (<CONFIGFILE>) { $ARG =~ /([^#]*)#?.*/; # strip comments $config_file_contents .= $1; } close (CONFIGFILE); $config_file_contents =~ /catalogue[^=]*=([^=]*?)\n[^\n]*=/si; my $catalogue = $1; @dirs = split(/[\s,\\]+/, $catalogue); for my $index (0 .. $#dirs) { if ($dirs[$index] =~ /(.+?)(:unscaled|:scaled)/) { $dirs[$index] = $1; } } } } if ($VERBOSITY >= $VERBOSITY_DEBUG) { print "font paths found in $file:\n"; for my $dir (@dirs) { print "$dir\n"; } } return @dirs; } sub create_symbolic_links { my ($dir) = @_; my $cwd; chomp ($cwd = `pwd`); chdir $dir ||die "Can't cd to $dir: $!\n"; # create symbolic links for PostScript fonts in pfa format # which have no extension: # (seems like all such fonts are gone now, I can't find # such fonts any more on my system 2005.09.01) if ($have_file_mmagic) { my $mm = new File::MMagic; # use internal magic file # $mm = File::MMagic::new('/etc/magic'); # use external magic file my $type; for my $file (glob ("*")) { unless ($file =~ /\./i) { $type = $mm->checktype_filename($file); if ($VERBOSITY >= $VERBOSITY_DEBUG) { print "File::MMagic $file: $type\n"; } if ($type =~ /application\/postscript/) { # it's probably a PostScript font in pfa format # create a symbolic link unless it has the .pfa extension already # or is a .gsf file (File::MMagic detects .gsf files also as # "application/postscript", but it makes no sense to link these # to .pfa) unless ($file =~ /\.pfa|\.gsf/i) { if ($VERBOSITY >= $VERBOSITY_DEBUG) { printf "symlink ($file, \"${file}.pfa\")\n"; } symlink ($file, "${file}.pfa"); } } } } } # create symbolic links for files which have characters in # their name which are impossible to use in the file name in # fonts.dir: my @forbidden_characters = (" ", ":"); for my $file (glob ("*.*")) { for my $forbidden_character (@forbidden_characters) { if ($file =~ /$forbidden_character/) { my $file_new; ($file_new = $file) =~ s/$forbidden_character/_/g; if ($VERBOSITY >= $VERBOSITY_DEBUG) { printf "symlink ($file, $file_new)\n"; } symlink ($file, $file_new); } } } chdir $cwd ||die "Can't cd to $cwd: $!\n"; } sub make_fonts_scale_and_fonts_dir { my ($dir) = @_; my $timestamp = "$dir/.fonts-config-timestamp"; my $try_again = 0; # workaround for a bug in older versions of /usr/sbin/Check which # gzips the timestamp files: if (-e "${timestamp}.gz") { unlink ("${timestamp}.gz"); } if ($OPT_FORCE || mtime_differs_or_missing ("$timestamp","$dir") || mtime_differs_or_missing ("$timestamp","$dir/fonts.scale") || mtime_differs_or_missing ("$timestamp","$dir/fonts.dir")) { # Touch and delete fonts.scale and fonts.dir just to make sure # we are starting from scratch and the directory is writeable: my_system ("touch $dir/fonts.scale $dir/fonts.dir > /dev/null 2>&1"); if (!unlink ("$dir/fonts.scale", "$dir/fonts.dir")) { if ($VERBOSITY >= $VERBOSITY_DEBUG) { print "Cannot write in $dir. Readonly filesystem?\n"; } return; } $gs_fontmap_needs_update = 1; create_symbolic_links($dir); if ($VERBOSITY >= $VERBOSITY_DEBUG) { print "creating $dir/fonts.{scale,dir} ...\n"; } if ($mkfontscale_bin) { $command = "$mkfontscale_bin $dir"; unless ($VERBOSITY >= $VERBOSITY_DEBUG) { $command .= " > /dev/null 2>&1 "; } my_system ($command); } if (! -e "$dir/fonts.scale" ) { if ($VERBOSITY >= $VERBOSITY_DEBUG) { print "mkfontscale is not available or it failed. "; print "-> Create an empty fonts.scale file.\n"; } $try_again = 1; my_system ("echo 0 > $dir/fonts.scale"); } fix_fonts_scale ($dir); if ($mkfontdir_bin) { $command = "$mkfontdir_bin "; if (-d "/usr/X11R6/lib/X11/fonts/encodings") { $command .= " -e /usr/X11R6/lib/X11/fonts/encodings"; } if (-d "/usr/X11R6/lib/X11/fonts/encodings/large") { $command .= " -e /usr/X11R6/lib/X11/fonts/encodings/large"; } if (-d "/usr/share/fonts/encodings") { $command .= " -e /usr/share/fonts/encodings"; } if (-d "/usr/share/fonts/encodings/large") { $command .= " -e /usr/share/fonts/encodings/large"; } $command .= " $dir"; my_system ($command); } if (! -e "$dir/fonts.dir" ) { if ($VERBOSITY >= $VERBOSITY_DEBUG) { print "mkfontdir is not available or it failed. "; } $try_again = 1; if (-f "$dir/fonts.scale" ){ if ($VERBOSITY >= $VERBOSITY_DEBUG) { print "A fonts.scale file exists, copy it to fonts.dir."; } my_system ("cp $dir/fonts.scale $dir/fonts.dir"); } else { if ($VERBOSITY >= $VERBOSITY_DEBUG) { print "No fonts.scale file exists either, create an empty fonts.dir."; } my_system ("echo 0 > $dir/fonts.dir"); } } # Directory done. Now update time stamps: if ($try_again) { # mkfontscale and/or mkfontdir failed or didn't exist. Remove the # timestamp to make sure this script tries again next time # when the problem with mkfontscale and/or mkfontdir is fixed: unlink ("$timestamp"); } else { # fonts.cache-* files are now generated in /var/cache/fontconfig, # remove old cache files in the individual directories # (fc-cache does this as well when the cache files are out of date # but it can't hurt to remove them here as well just to make sure). for my $file (glob ("$dir/fonts.cache-*")) { if (-e "$file") { unlink ("$file"); } } if (! -e $timestamp) { my_system ("touch $timestamp"); } utime ($script_start_time, $script_start_time, ("$dir/fonts.dir", "$dir/fonts.scale", $timestamp, $dir)); } } } sub fix_fonts_scale { my ($dir) = @_; my ($file, $options, $font, $xlfd); my %fonts_scale_entries = (); my %blacklist = (); if ($VERBOSITY >= $VERBOSITY_DEBUG) { print "----------------------------------------------------------------------\n"; print "fix fonts.scale in $dir:\n"; } ###################################################################### # first parse the "handmade" fonts.scale.* files: for $file (glob ("$dir/fonts.scale.*")) { if (-e $file) { if ($file =~ /~$|\.swp$|\.bak$|\.sav$|\.save$|\.rpmsave$|\.rpmorig|\.rpmnew$/) { if ($VERBOSITY >= $VERBOSITY_DEBUG) { print "$file is considered a backup file, ignored.\n"; } next; } open (FONTS_SCALE, $file) || die "can't open file $file: $!"; if ($VERBOSITY >= $VERBOSITY_DEBUG) { print "reading $dir/$file ...\n"; } while (<FONTS_SCALE>) { if ($ARG =~ /^(.*?)([^:\s]+)\s+(-.+?)\s*$/) { # font name and xlfd found $options = $1; $font = $2; $xlfd = $3; if ($VERBOSITY >= $VERBOSITY_DEBUG) { print "handmade entry found: options=$options font=$font xlfd=$xlfd\n"; } if (( $OPT_TTCAP ) && $options =~ /:([0-9]):/) { if ($VERBOSITY >= $VERBOSITY_DEBUG) { print "--ttcap option is set: convert face number to TTCap syntax: fn=$1:\n"; } $options = "fn=$1:"; } if ($freetype_module_used && ! $OPT_TTCAP ) { if ($options =~ /fn=([0-9]):/) { if ($VERBOSITY >= $VERBOSITY_DEBUG) { print "freetype module used and --ttcap option is not set: convert face number to freetype syntax: :$1:\n"; } $options = ":$1:"; } elsif ($options =~ /[a-z=]/i) { # there's more then just a face number, better ignore it if ($VERBOSITY >= $VERBOSITY_DEBUG) { print "xtt module not used: discard xtt only entry $ARG\n"; } next; } } unless ( $font =~ /\.cid$/) { # For font file name entries ending with ".cid", such a file # usually doesn't exist and it doesn't need to. The backend which # renders CID-keyed fonts just parses this name to find the real # font files and mapping tables # # For other entries, we check whether the file exists. if (! -e "$dir/$font") { if ($VERBOSITY >= $VERBOSITY_DEBUG) { print "file $dir/$font doesn't exist, discard entry $ARG\n"; } next; } } if ($VERBOSITY >= $VERBOSITY_DEBUG) { print "adding handmade entry $ARG\n"; } $fonts_scale_entries{$xlfd} = "${options}${font}"; # This font has "handmade" fonts.scale entries. # Add it to the blacklist to discard any entries for this font # which which might have been automatically created # by mkfontscale: $blacklist{$font} = "yes"; } } close (FONTS_SCALE); } } ###################################################################### # blacklist globs to avoid fonts known to be broken: # # (broken fonts may still be included in manually edited fonts.scale.* # files. He who edits these files manually should know what he is doing ...) my @blacklist_globs = (); # push (@blacklist_globs, ("totally-broken*.ttf", "fubar*.ttc")); # the Hershey-Fonts from ghostscript-fonts-other.rpm have broken outlines # and don't work with X11, neither with the freetype module nor via libXft. push (@blacklist_globs, ("hrger.pfa", "hrgrr.pfa", "hritr.pfa", "hrpld.pfa", "hrpldi.pfa", "hrplt.pfa", "hrplti.pfa", "hrscc.pfa", "hrscs.pfa", "u003043t.gsf", "u004006t.gsf", # .bdf fonts currently don't work with Xft2: "*.bdf" )); my @blacklist_fonts_cache = (); for my $glob (@blacklist_globs) { if ($VERBOSITY >= $VERBOSITY_DEBUG) { print "expanding blacklist glob: $dir/$glob\n"; } for my $font (glob ("$dir/$glob")) { if (-e $font) { $font =~ /\/([^\/]+)$/; # basename (strip directory) $font = $1; if ($VERBOSITY >= $VERBOSITY_DEBUG) { print "$dir/$font matched by blacklist glob, adding $font to blacklist.\n"; } $blacklist{$font} = "yes"; push (@blacklist_fonts_cache, ($font)); } } } ###################################################################### # remove broken entries from fonts.cache-1: if (@blacklist_fonts_cache) { my @entries = (); $file = "$dir/fonts.cache-1"; if (-e $file) { if ($VERBOSITY >= $VERBOSITY_DEBUG) { print "removing blacklisted fonts @blacklist_fonts_cache from $file\n"; } open (FONTS_CACHE, $file) || die "can't open file $file: $!"; while (<FONTS_CACHE>) { $ARG =~ /^"([^"]+)" /; if (! grep /$1/, @blacklist_fonts_cache) { push (@entries, ($ARG)); } } close (FONTS_CACHE); open (FONTS_CACHE, ">$file") || die "can't open file $file: $!"; for my $entry (@entries) { print FONTS_CACHE "$entry"; } close (FONTS_CACHE); } } ###################################################################### # Now parse the fonts.scale file automatically created by mkfontscale: $file = "$dir/fonts.scale"; open (FONTS_SCALE, $file) || die "can't open file $file: $!"; if ($VERBOSITY >= $VERBOSITY_DEBUG) { print "reading $dir/$file ...\n"; } while (<FONTS_SCALE>) { if ($ARG =~ /^(.*?)([^:\s]+)\s+(-.+?)\s*$/) { # font name and xlfd found $options = $1; $font = $2; $xlfd = $3; if ($VERBOSITY >= $VERBOSITY_DEBUG) { print "mkfontscale entry found: options=$options font=$font xlfd=$xlfd\n"; } # mkfontscale apparently doesn't yet generate the special options for # the freetype module to use different face numbers in .ttc files. # But this might change, therefore it is probably better to check this as well: if ( ( $OPT_TTCAP ) && $options =~ /:([0-9]):/) { if ($VERBOSITY >= $VERBOSITY_DEBUG) { print "--ttcap option is set: convert face number to TTCap syntax: fn=$1:\n"; } $options = "fn=$1:"; } if ($blacklist{$font}) { if ($VERBOSITY >= $VERBOSITY_DEBUG) { print "$dir/$font is blacklisted, ignored.\n"; } next; } $fonts_scale_entries{$xlfd} = "${options}${font}"; } } close (FONTS_SCALE); ###################################################################### # generate an oblique entry if only italic is there and vice versa: for my $old_xlfd (keys %fonts_scale_entries) { if ($old_xlfd =~ /(-[^-]+-[^-]+-[^-]+)(-[io]-)([^-]+-[^-]*-\d+-\d+-\d+-\d+-[pmc]-\d+-[^-]+-[^-]+)/i) { my $new_xlfd = ""; if ("$2" eq "-i-") { $new_xlfd = "${1}-o-${3}"; } else { $new_xlfd = "${1}-i-${3}"; } unless ($fonts_scale_entries{$new_xlfd}) { $fonts_scale_entries{$new_xlfd} = $fonts_scale_entries{$old_xlfd}; if ($VERBOSITY >= $VERBOSITY_DEBUG) { print "generated o/i: $fonts_scale_entries{$new_xlfd} $new_xlfd\n"; } } } } ###################################################################### # generate TTCap options for xtt: if ($OPT_TTCAP) { if ($VERBOSITY >= $VERBOSITY_DEBUG) { print "generating TTCap options for use with xtt or recent freetype modules ...\n"; } my ($italic, $oblique, $bold, $bold_italic, $bold_oblique); my $artificial_italic = "ai=0.2:"; my $doublestrike = "ds=y:"; for my $medium (sort (keys %fonts_scale_entries)) { if ($medium !~ /-medium-r-/) { next; } if ($fonts_scale_entries{$medium} !~ /^(.*?)([^:]+)$/) { next; # should not happen ... } $options = $1; $font = $2; if ( $xtt_module_used && $font !~ /\.ttf$|\.ttc$/i ) { next; # xtt can only handle TrueType fonts. } elsif ( $freetype_module_used && $font !~ /\.ttf$|\.ttc$|\.otf|\.otc|\.pfa|\.pfb/i ) { next; # the freetype module handles TrueType, OpenType, and Type1 fonts. } elsif ( !$freetype_module_used && !$xtt_module_used) { # neither the xtt module nor the freetype module is used, generating TTCap # options makes no sense. next; } if ($options) { next; # there are already some TTCap options, better don't touch this } ($italic = $medium) =~ s/-medium-r-/-medium-i-/; ($oblique = $medium) =~ s/-medium-r-/-medium-o-/; ($bold = $medium) =~ s/-medium-r-/-bold-r-/; ($bold_italic = $medium) =~ s/-medium-r-/-bold-i-/; ($bold_oblique = $medium) =~ s/-medium-r-/-bold-o-/; unless ($fonts_scale_entries{$italic} || $fonts_scale_entries{$oblique}) { $fonts_scale_entries{$italic} = "${artificial_italic}${font}"; $fonts_scale_entries{$oblique} = "${artificial_italic}${font}"; if ($VERBOSITY >= $VERBOSITY_DEBUG) { print "generated TTCap entry: $fonts_scale_entries{$italic} $italic\n"; print "generated TTCap entry: $fonts_scale_entries{$oblique} $oblique\n"; } } unless ($fonts_scale_entries{$bold}) { $fonts_scale_entries{$bold} = "${doublestrike}${font}"; if ($VERBOSITY >= $VERBOSITY_DEBUG) { print "generated TTCap entry: $fonts_scale_entries{$bold} $bold\n"; } } unless ($fonts_scale_entries{$bold_italic} || $fonts_scale_entries{$bold_oblique}) { $fonts_scale_entries{$bold_italic} = "${doublestrike}${artificial_italic}${font}"; $fonts_scale_entries{$bold_oblique} = "${doublestrike}${artificial_italic}${font}"; if ($VERBOSITY >= $VERBOSITY_DEBUG) { print "generated TTCap entry: $fonts_scale_entries{$bold_italic} $bold_italic\n"; print "generated TTCap entry: $fonts_scale_entries{$bold_oblique} $bold_oblique\n"; } } } # add bw=0.5 option when necessary: for my $xlfd (sort (keys %fonts_scale_entries)) { if ($fonts_scale_entries{$xlfd} !~ /^(.*?)([^:]+)$/) { next; # should not happen ... } $options = $1; $font = $2; if ( $xtt_module_used && $font !~ /\.ttf$|\.ttc$/i ) { next; # xtt can only handle TrueType fonts. } elsif ( $freetype_module_used && $font !~ /\.ttf$|\.ttc$|\.otf|\.otc|\.pfa|\.pfb/i ) { next; # the new freetype module handles TrueType, OpenType, and Type1 fonts. } elsif ( !$freetype_module_used && !$xtt_module_used) { # neither the xtt module nor the freetype module is used, generating TTCap # options makes no sense. next; } if ($options =~ /bw=/) { next; # there is already a bw=<something> TTCap option, better don't touch this } if ($xlfd =~ /c-0-jisx0201.1976-0/) { $fonts_scale_entries{$xlfd} = "${options}bw=0.5:${font}"; if ($VERBOSITY >= $VERBOSITY_DEBUG) { print "added bw=0.5 option: $fonts_scale_entries{$xlfd} $xlfd\n"; } } } } ###################################################################### # weed out entries which certainly cannot work: for my $xlfd (keys %fonts_scale_entries) { if ($fonts_scale_entries{$xlfd} !~ /\.([[:alnum:]]+)(\.gz)?$/i) { if ($VERBOSITY >= $VERBOSITY_DEBUG) { print "file has no extension, discarding $fonts_scale_entries{$xlfd} $xlfd\n"; } delete $fonts_scale_entries{$xlfd}; next; } else { my $extension = $1 ; # Currently only the freetype module can handle .otf fonts. # # If both xtt and freetype are used at the same time, xtt will only register # for .ttf and .ttc fonts and freetype will still be able to handle # the .otf fonts. # But if freetype is not used, .otf fonts won't work at all and # directories containing entries for .otf fonts in fonts.dir will be # removed from the font path. # This is not nice because there may be other fonts in that directory which # could be used, for example .ttf or .ttc. # Therefore it is better to throw away all entries for .otf fonts if # the freetype module is not used: if ($extension =~ /otf/i && ! $freetype_module_used) { if ($VERBOSITY >= $VERBOSITY_DEBUG) { print ".otf won't work without freetype module, discarding $fonts_scale_entries{$xlfd} $xlfd\n"; } delete $fonts_scale_entries{$xlfd}; } if ($extension =~ /gsf/i) { if ($VERBOSITY >= $VERBOSITY_DEBUG) { print ".gsf fonts won't work with X11, discarding $fonts_scale_entries{$xlfd} $xlfd\n"; } delete $fonts_scale_entries{$xlfd}; } } } ###################################################################### # write final result to fonts.scale: $file = "$dir/fonts.scale"; open (FONTS_SCALE, ">$file") || die "can't open file $file: $!"; if ($VERBOSITY >= $VERBOSITY_DEBUG) { print "writing $dir/$file ...\n"; } printf FONTS_SCALE "%d\n", scalar(keys %fonts_scale_entries); for my $xlfd (sort (keys %fonts_scale_entries)) { print FONTS_SCALE "$fonts_scale_entries{$xlfd} $xlfd\n"; } close (FONTS_SCALE); } ###################################################################### sub get_font_name_entries { my ($font) = @_; # quote " in font names: $font =~ s/\"/\\\"/g; open (FONT, "ftdump \"$font\" 2>/dev/null |"); # Apparently there are some fonts which have non-ASCII PostScript names. # If we are running in a UTF-8 locale, Perl will complain # "Malformed UTF-8 character" # when reading the ftdump output of such a font. # Avoid that error by using the layer ":bytes" for this file handle. binmode FONT, ":bytes"; my $postscript = ""; my $family = ""; my $style = ""; my $face_number = 0; while (<FONT>) { if ($ARG =~ /face.*number.*:\s*([0-9]+)\s*/i) { $face_number = $1; } if ($face_number > 0) { if ($VERBOSITY >= $VERBOSITY_DEBUG) { print "face_number=$face_number found. All faces with number > 0 ignored.\n"; } last; } # the following regexp should work with ftdump from either Freetype-1 or Freetype-2 if ($ARG =~ /postscript.*:\s+([[:alnum:]\-]+?)\s*$/i) { $postscript = $1; if ($postscript eq "UNAVAILABLE") { $postscript = ""; } } if ($ARG =~ /family.*:\s+([[:alnum:]].*[[:alnum:]])\s*$/i) { $family = $1; } if ($ARG =~ /style.*:\s+([[:alnum:]].*[[:alnum:]])\s*$/i) { $style = $1; } } close (FONT); if ($VERBOSITY >= $VERBOSITY_DEBUG) { print "ftdump: font=$font postscript=$postscript family=$family style=$style\n"; } return ($postscript, $family, $style); } sub gs_fontmap_aliases_add { my ($aliases, $alias) = @_; my $alias_case_normalized = $alias; $alias_case_normalized =~ s/\b(\w)(\w*)/ uc($1) . lc($2) /eg; $alias_case_normalized =~ s/ //g; $alias =~ s/ //g; $aliases->{$alias} = ""; $aliases->{$alias_case_normalized} = ""; } sub gs_fontmap_aliases { my ($postscript, $family, $style, $xlfd) = @_; my $xlfd_fmly = ""; my $xlfd_wght = ""; my $xlfd_slant = ""; my %aliases = (); if ($xlfd && $xlfd =~ /-[^-]+-([^-]+)-([^-]+)-([^-])-[^-]+-[^-]*-\d+-\d+-\d+-\d+-[pmc]-\d+-[^-]+-[^-]+/i) { $xlfd_fmly = $1; $xlfd_wght = $2; $xlfd_slant = $3; # Some aliases for applications which don't use the correct PostScript # names but rather some combination of family, weight, and slant from the XLFD. # Probably because there is no way to get the PostScript name without # direct access to the font file. When X11 core fonts are used instead of # fontconfig/libXft, the application may only see the XLFD and can only # try to "guess" the PostScript name from the XLFD. # (For example Qt3 does something like this ...) if ($xlfd_fmly) { if ($xlfd_wght !~ /bold/i && $xlfd_slant ne "i" && $xlfd_slant ne "o") { gs_fontmap_aliases_add(\%aliases, "$xlfd_fmly"); } if ($xlfd_wght !~ /bold/i && ($xlfd_slant eq "i" || $xlfd_slant eq "o")) { gs_fontmap_aliases_add(\%aliases, "$xlfd_fmly-Italic"); } if ($xlfd_wght =~ /bold/i && $xlfd_slant ne "i" && $xlfd_slant ne "o") { gs_fontmap_aliases_add(\%aliases, "$xlfd_fmly-Bold"); } if ($xlfd_wght =~ /bold/i && ($xlfd_slant eq "i" || $xlfd_slant eq "o")) { gs_fontmap_aliases_add(\%aliases, "$xlfd_fmly-Bold Italic"); } } } # an alias to the PostScript name would make no sense, delete it if # it was accidentally created: delete $aliases{$postscript}; return (sort (keys %aliases)); } sub make_gs_fontmap { my (@font_dirs) = @_; if (!$ftdump_bin) { print "Warning: Creation of a Fontmap for Ghostmap has been requested\n"; print " (either the the option --gs-fontmap has been used or the variable\n"; print" GENERATE_GHOSTSCRIPT_FONTMAPS in /etc/sysconfig/fonts-config\n"; print" has been set to \"yes\").\n"; print " But the 'ftdump' program which is needed to do this is\n"; print " apparently not installed. 'ftdump' is in the 'ft2demos'\n"; print " package. Please install this package if you want a Fontmap\n"; print " for Ghostscript to be created.\n"; } else { if ($VERBOSITY >= $VERBOSITY_VERBOSE) { print "Creating Fontmap entries for Ghostscript "; } for my $fontmap_dir (glob ("/usr/share/ghostscript/[0-9]*/lib")) { if (-e $fontmap_dir) { my $file = "$fontmap_dir/Fontmap.X11-auto"; open (FONTMAP, ">$file") || die "can't open file $file: $!"; if ($VERBOSITY >= $VERBOSITY_DEBUG) { printf "writing $file ...\n"; } print FONTMAP "% Fontmap for scalable fonts found in the X11 font paths\n"; print FONTMAP "%\n"; print FONTMAP "% This file is automatically generated by\n"; print FONTMAP "% \"fonts-config\" (version $version) and will be\n"; print FONTMAP "% overwritten during the next run of this script.\n"; print FONTMAP "%\n"; print FONTMAP "% Don't edit this file. If you want to create your own\n"; print FONTMAP "% manual Fontmap entries, put them elsewhere.\n"; print FONTMAP "%\n"; my %fontmap_entries = (); for my $dir (@font_dirs) { open (FONTS_SCALE, "$dir/fonts.scale") || die "can't open file $dir/fonts.scale: $!"; if ($VERBOSITY >= $VERBOSITY_DEBUG) { print "creating hashtable of xlfds from $dir/fonts.scale ...\n"; } my %xlfds; while (<FONTS_SCALE>) { my ($options, $font, $xlfd); if ($ARG =~ /^(.*?)([^:\s]+)\s+(-.+?)\s*$/) { # font name and xlfd found $options = $1; $font = $2; $xlfd = $3; unless ($options) { # ignore face numbers > 0 and other options $xlfds{"$dir/$font"} = $xlfd; } } } close (FONTS_SCALE); for my $font (glob ("$dir/*.{ttf,ttc,pfa,pfb}")) { if (-e $font) { my ($postscript, $family, $style) = get_font_name_entries($font); if ($postscript) { print FONTMAP "%----------------------------------------------------------------------\n"; print FONTMAP "% postscript=\"$postscript\" family=\"$family\" style=\"$style\"\n"; if ($xlfds{$font}) { print FONTMAP "% xlfd=\"$xlfds{$font}\"\n"; } else { print FONTMAP "% xlfd=\"\"\n"; } if ($fontmap_entries{$postscript}) { print FONTMAP "% /$postscript ($font) ; % warning: duplicate!\n"; } else { print FONTMAP "/$postscript ($font) ;\n"; $fontmap_entries{$postscript} = "true"; } for my $alias (gs_fontmap_aliases($postscript, $family, $style, $xlfds{$font})) { if ($fontmap_entries{$alias}) { print FONTMAP "% /$alias /$postscript ; % warning: duplicate!\n"; } else { print FONTMAP "/$alias /$postscript ;\n"; $fontmap_entries{$alias} = "true"; } } } } } if ($VERBOSITY >= $VERBOSITY_VERBOSE) { print "."; # "progress bar" } } close (FONTMAP); } } if ($VERBOSITY >= $VERBOSITY_VERBOSE) { print "\n"; } } } ######################################################################## sub generate_ooo_font_setup { my $common_xcu_file = "/usr/lib/ooo-1.1/share/registry/data/org/openoffice/Office/Common.xcu"; my $common_xcu_template_file = "/usr/share/fonts-config/Common.xcu.template"; my $common_xcu = ""; my $common_xcu_template = ""; my $within_font_node_depth = 0; my $ooo_truetype_font_dir = "/usr/lib/ooo-1.1/share/fonts/truetype"; if ($VERBOSITY >= $VERBOSITY_DEBUG) { printf "generating OpenOffice font setup\n"; } if (! -f "$common_xcu_file") { if ($VERBOSITY >= $VERBOSITY_DEBUG) { printf "Nothing to do for this version of OpenOffice.\n"; } return; } if (! -f "$common_xcu_template_file") { printf "File $common_xcu_template_file missing. This should not happen.\n"; printf "Skipping OpenOffice font setup\n"; return; } my @msgothic_list = ("MS Gothic", "HGGothicB", "HG\\-GothicB\\-Sun", "TLGothic", "IPAGothic", "Sazanami Gothic", "Kochi Gothic"); my @mspgothic_list = ("MS PGothic", "HGPGothicB", "HG\\-PGothicB\\-Sun", "TLPGothic", "IPAPGothic", "Sazanami Gothic", "Kochi Gothic"); my @msmincho_list = ("MS Mincho", "HGMinchoL", "HG\\-MinchoL\\-Sun", "TLMincho", "IPAMincho", "Sazanami Mincho", "Kochi Mincho"); my @mspmincho_list = ("MS PMincho", "HGPMinchoL", "HG\\-PMinchoL\\-Sun", "TLPMincho", "IPAPMincho", "Sazanami Mincho", "Kochi Mincho"); my $msgothic = "Sazanami Gothic"; my $mspgothic = "Sazanami Gothic"; my $msmincho = "Sazanami Mincho"; my $mspmincho = "Sazanami Mincho"; for my $font (@msgothic_list) { if (`fc-list "$font"`) { $msgothic = $font; last; } } for my $font (@mspgothic_list) { if (`fc-list "$font"`) { $mspgothic = $font; last; } } for my $font (@msmincho_list) { if (`fc-list "$font"`) { $msmincho = $font; last; } } for my $font (@mspmincho_list) { if (`fc-list "$font"`) { $mspmincho = $font; last; } } open (TEMPLATE, "$common_xcu_template_file") || die "can't open file $common_xcu_template_file: $!"; binmode TEMPLATE, ":utf8"; while (<TEMPLATE>) { $ARG =~ s/_MSGOTHIC_/$msgothic/; $ARG =~ s/_MSPGOTHIC_/$mspgothic/; $ARG =~ s/_MSMINCHO_/$msmincho/; $ARG =~ s/_MSPMINCHO_/$mspmincho/; $common_xcu_template .= $ARG; } close (TEMPLATE); if (-f "$common_xcu_file" ) { open (XCU, "$common_xcu_file") || die "can't open file $common_xcu_file: $!"; binmode XCU, ":utf8"; while (<XCU>) { if ($ARG =~ /<node oor:name="Font">/) { $within_font_node_depth = 1; next; } if ($within_font_node_depth > 0) { if ($ARG =~ /<node.*>/) { $within_font_node_depth++; } if ($ARG =~ /<\/node>/) { $within_font_node_depth--; } next; } unless ($ARG =~ /<\/oor:component-data>/) { $common_xcu .= $ARG; } } close (XCU); open (XCU, ">$common_xcu_file") || die "can't open file $common_xcu_file: $!"; binmode XCU, ":utf8"; print XCU $common_xcu; print XCU $common_xcu_template; print XCU '</oor:component-data>'; print XCU "\n"; close (XCU); } if ( -d "$ooo_truetype_font_dir" ) { for my $font (`fc-list :lang=ja:outline=true file`) { my $basename; chomp ($font); $font =~ s/:.*$//; ($basename = $font ) =~ s/.*\/([^\/]+)/$1/; if ($VERBOSITY >= $VERBOSITY_DEBUG) { printf "symlink (\"$font\", \"$ooo_truetype_font_dir/$basename\")\n"; } symlink ("$font", "$ooo_truetype_font_dir/$basename"); } # remove dead links: for my $file (glob ("$ooo_truetype_font_dir/*")) { if (! -f "$file") { unlink("$file"); } } } } ######################################################################## sub generate_java_font_setup { my @font_properties_ja_globs = ("/usr/lib*/jvm/java-1[._]4[._]?-sun-*/jre/lib/font.properties.ja"); my $font_properties_ja_template_file = "/usr/share/fonts-config/font.properties.ja.template"; my $font_properties_ja_template = ""; my @fontconfig_SuSE_properties_globs = "/usr/lib*/jvm/jre/lib/fontconfig.SuSE.properties"; my $fontconfig_SuSE_properties_template_file = "/usr/share/fonts-config/fontconfig.SuSE.properties.template"; my $fontconfig_SuSE_properties_template = ""; if ($VERBOSITY >= $VERBOSITY_QUIET) { printf "generating java font setup\n"; } my @sans_japanese_priority = ("MS Gothic", "HGGothicB", "IPAPGothic", "Sazanami Gothic"); my @mono_japanese_priority = ("MS Gothic", "HGGothicB", "IPAGothic", "Sazanami Gothic"); my @serif_japanese_priority = ("MS Mincho", "HGMinchoL", "IPAPMincho", "Sazanami Mincho"); my @sans_simplified_chinese_priority = ("FZSongTi", "AR PL ShanHeiSun Uni", "AR PL SungtiL GB"); my @serif_simplified_chinese_priority = ("FZSongTi", "AR PL ShanHeiSun Uni", "AR PL SungtiL GB"); my @sans_traditional_chinese_priority = ("AR PL ShanHeiSun Uni", "FZMingTiB", "AR PL Mingti2L Big5"); my @serif_traditional_chinese_priority = ("AR PL ShanHeiSun Uni", "FZMingTiB", "AR PL Mingti2L Big5"); my @sans_korean_priority = ("UnDotum", "Baekmuk Gulim", "Baekmuk Dotum"); my @serif_korean_priority = ("UnBatang", "Baekmuk Batang"); my %cjk_xlfds = ( "MS Gothic" , "-ricoh-ms gothic-", "HGGothicB" , "-ricoh-hggothicb-", "IPAGothic" , "-misc-ipagothic-", "IPAPGothic" , "-misc-ipapgothic-", "Sazanami Gothic" , "-misc-sazanami gothic-", "MS Mincho" , "-ricoh-ms mincho-", "HGMinchoL" , "-ricoh-hgminchol-", "IPAPMincho" , "-misc-ipapmincho-", "Sazanami Mincho" , "-misc-sazanami mincho-", "FZSongTi" , "-*-SongTi-", "FZMingTiB" , "-*-MingTiB-", "AR PL ShanHeiSun Uni" , "-*-ar pl shanheisun uni-", "AR PL SungtiL GB" , "-arphic-ar pl sungtil gb-", "AR PL Mingti2L Big5" , "-arphic-ar pl mingti2l big5-", "UnDotum" , "-misc-undotum-", "Baekmuk Gulim" , "-baekmukttf-gulim-", "Baekmuk Dotum" , "-baekmukttf-dotum-", "UnBatang" , "-misc-unbatang-", "Baekmuk Batang" , "-baekmukttf-batang-" ); my $sans_japanese_xlfd = "-misc-sazanami gothic-"; my $sans_japanese_file = "/usr/share/fonts/truetype/sazanami-gothic.ttf"; my $mono_japanese_xlfd = "-misc-sazanami gothic-"; my $mono_japanese_file = "/usr/share/fonts/truetype/sazanami-gothic.ttf"; my $serif_japanese_xlfd = "-misc-sazanami mincho-"; my $serif_japanese_file = "/usr/share/fonts/truetype/sazanami-mincho.ttf"; my $sans_simplified_chinese_xlfd = "-arphic-ar pl sungtil gb-"; my $sans_simplified_chinese_file = "/usr/share/fonts/truetype/gbsn00lp.ttf"; my $serif_simplified_chinese_xlfd = "-arphic-ar pl sungtil gb-"; my $serif_simplified_chinese_file = "/usr/share/fonts/truetype/gbsn00lp.ttf"; my $sans_traditional_chinese_xlfd = "-arphic-ar pl mingti2l big5-"; my $sans_traditional_chinese_file = "/usr/share/fonts/truetype/bsmi00lp.ttf"; my $serif_traditional_chinese_xlfd = "-arphic-ar pl mingti2l big5-"; my $serif_traditional_chinese_file = "/usr/share/fonts/truetype/bsmi00lp.ttf"; my $sans_korean_xlfd = "-baekmukttf-dotum-"; my $sans_korean_file = "/usr/share/fonts/truetype/dotum.ttf"; my $serif_korean_xlfd = "-baekmukttf-batang-"; my $serif_korean_file = "/usr/share/fonts/truetype/batang.ttf"; for my $font (@sans_japanese_priority) { if (`fc-list "$font"`) { open (NAMES, "fc-list \"$font\" file |"); binmode NAMES, ":bytes"; while (<NAMES>) { chomp $ARG; $ARG =~ s/:.*$//; if ($ARG =~ /\.ttf|\.ttc/ && -f "$ARG" && ! -l "$ARG") { $sans_japanese_file = $ARG; $sans_japanese_xlfd = $cjk_xlfds{"$font"}; } } close (NAMES); last; } } if ( ! -f $sans_japanese_file ) { print "Warning: cannot find a sans serif Japanese font. Japanese in Java might not work.\n"; } for my $font (@mono_japanese_priority) { if (`fc-list "$font"`) { open (NAMES, "fc-list \"$font\" file |"); binmode NAMES, ":bytes"; while (<NAMES>) { chomp $ARG; $ARG =~ s/:.*$//; if ($ARG =~ /\.ttf|\.ttc/ && -f "$ARG" && ! -l "$ARG") { $mono_japanese_file = $ARG; $mono_japanese_xlfd = $cjk_xlfds{"$font"}; } } close (NAMES); last; } } if ( ! -f $mono_japanese_file ) { print "Warning: cannot find a monospaced Japanese font. Japanese in Java might not work.\n"; } for my $font (@serif_japanese_priority) { if (`fc-list "$font"`) { open (NAMES, "fc-list \"$font\" file |"); binmode NAMES, ":bytes"; while (<NAMES>) { chomp $ARG; $ARG =~ s/:.*$//; if ($ARG =~ /\.ttf|\.ttc/ && -f "$ARG" && ! -l "$ARG") { $serif_japanese_file = $ARG; $serif_japanese_xlfd = $cjk_xlfds{"$font"}; } } close (NAMES); last; } } if ( ! -f $serif_japanese_file ) { print "Warning: cannot find a serif Japanese font. Japanese in Java might not work.\n"; } for my $font (@sans_simplified_chinese_priority) { if (`fc-list "$font"`) { open (NAMES, "fc-list \"$font\" file |"); binmode NAMES, ":bytes"; while (<NAMES>) { chomp $ARG; $ARG =~ s/:.*$//; if ($ARG =~ /\.ttf|\.ttc/ && -f "$ARG" && ! -l "$ARG") { $sans_simplified_chinese_file = $ARG; $sans_simplified_chinese_xlfd = $cjk_xlfds{"$font"}; } } close (NAMES); last; } } if ( ! -f $sans_simplified_chinese_file ) { print "Warning: cannot find a sans serif simplified Chinese font. Simplified Chinese in Java might not work.\n"; } for my $font (@serif_simplified_chinese_priority) { if (`fc-list "$font"`) { open (NAMES, "fc-list \"$font\" file |"); binmode NAMES, ":bytes"; while (<NAMES>) { chomp $ARG; $ARG =~ s/:.*$//; if ($ARG =~ /\.ttf|\.ttc/ && -f "$ARG" && ! -l "$ARG") { $serif_simplified_chinese_file = $ARG; $serif_simplified_chinese_xlfd = $cjk_xlfds{"$font"}; } } close (NAMES); last; } } if ( ! -f $serif_simplified_chinese_file ) { print "Warning: cannot find a serif simplified Chinese font. Simplified Chinese in Java might not work.\n"; } for my $font (@sans_traditional_chinese_priority) { if (`fc-list "$font"`) { open (NAMES, "fc-list \"$font\" file |"); binmode NAMES, ":bytes"; while (<NAMES>) { chomp $ARG; $ARG =~ s/:.*$//; if ($ARG =~ /\.ttf|\.ttc/ && -f "$ARG" && ! -l "$ARG") { $sans_traditional_chinese_file = $ARG; $sans_traditional_chinese_xlfd = $cjk_xlfds{"$font"}; } } close (NAMES); last; } } if ( ! -f $sans_traditional_chinese_file ) { print "Warning: cannot find a sans serif traditional Chinese font. Traditional Chinese in Java might not work.\n"; } for my $font (@serif_traditional_chinese_priority) { if (`fc-list "$font"`) { open (NAMES, "fc-list \"$font\" file |"); binmode NAMES, ":bytes"; while (<NAMES>) { chomp $ARG; $ARG =~ s/:.*$//; if ($ARG =~ /\.ttf|\.ttc/ && -f "$ARG" && ! -l "$ARG") { $serif_traditional_chinese_file = $ARG; $serif_traditional_chinese_xlfd = $cjk_xlfds{"$font"}; } } close (NAMES); last; } } if ( ! -f $serif_traditional_chinese_file ) { print "Warning: cannot find a serif traditional Chinese font. Traditional Chinese in Java might not work.\n"; } for my $font (@sans_korean_priority) { if (`fc-list "$font"`) { open (NAMES, "fc-list \"$font\" file |"); binmode NAMES, ":bytes"; while (<NAMES>) { chomp $ARG; $ARG =~ s/:.*$//; if ($ARG =~ /\.ttf|\.ttc/ && -f "$ARG" && ! -l "$ARG") { $sans_korean_file = $ARG; $sans_korean_xlfd = $cjk_xlfds{"$font"}; } } close (NAMES); last; } } if ( ! -f $sans_korean_file ) { print "Warning: cannot find a sans serif Korean font. Korean in Java might not work.\n"; } for my $font (@serif_korean_priority) { if (`fc-list "$font"`) { open (NAMES, "fc-list \"$font\" file |"); binmode NAMES, ":bytes"; while (<NAMES>) { chomp $ARG; $ARG =~ s/:.*$//; if ($ARG =~ /\.ttf|\.ttc/ && -f "$ARG" && ! -l "$ARG") { $serif_korean_file = $ARG; $serif_korean_xlfd = $cjk_xlfds{"$font"}; } } close (NAMES); last; } } if ( ! -f $serif_korean_file ) { print "Warning: cannot find a serif Korean font. Korean in Java might not work.\n"; } (my $sans_japanese_xlfd_no_space = $sans_japanese_xlfd) =~ s/ /_/g; (my $mono_japanese_xlfd_no_space = $mono_japanese_xlfd) =~ s/ /_/g; (my $serif_japanese_xlfd_no_space = $serif_japanese_xlfd) =~ s/ /_/g; (my $sans_simplified_chinese_xlfd_no_space = $sans_simplified_chinese_xlfd) =~ s/ /_/g; (my $serif_simplified_chinese_xlfd_no_space = $serif_simplified_chinese_xlfd) =~ s/ /_/g; (my $sans_traditional_chinese_xlfd_no_space = $sans_traditional_chinese_xlfd) =~ s/ /_/g; (my $serif_traditional_chinese_xlfd_no_space = $serif_traditional_chinese_xlfd) =~ s/ /_/g; (my $sans_korean_xlfd_no_space = $sans_korean_xlfd) =~ s/ /_/g; (my $serif_korean_xlfd_no_space = $serif_korean_xlfd) =~ s/ /_/g; if ($VERBOSITY >= $VERBOSITY_DEBUG) { printf ("sans_japanese_file=%s\n", $sans_japanese_file); printf ("sans_japanese_xlfd=%s\n", $sans_japanese_xlfd); printf ("sans_japanese_xlfd_no_space=%s\n", $sans_japanese_xlfd_no_space); printf ("sans_simplified_chinese_file=%s\n", $sans_simplified_chinese_file); printf ("sans_simplified_chinese_xlfd=%s\n", $sans_simplified_chinese_xlfd); printf ("sans_simplified_chinese_xlfd_no_space=%s\n", $sans_simplified_chinese_xlfd_no_space); printf ("sans_traditional_chinese_file=%s\n", $sans_traditional_chinese_file); printf ("sans_traditional_chinese_xlfd=%s\n", $sans_traditional_chinese_xlfd); printf ("sans_traditional_chinese_xlfd_no_space=%s\n", $sans_traditional_chinese_xlfd_no_space); printf ("sans_korean_file=%s\n", $sans_korean_file); printf ("sans_korean_xlfd=%s\n", $sans_korean_xlfd); printf ("sans_korean_xlfd_no_space=%s\n", $sans_korean_xlfd_no_space); } # setup for Java 1.4 (only for Japanese at the moment): if (-f "$font_properties_ja_template_file") { open (TEMPLATE, "$font_properties_ja_template_file") || die "can't open file $font_properties_ja_template_file: $!"; binmode TEMPLATE, ":utf8"; while (<TEMPLATE>) { $ARG =~ s/_SANS_JAPANESE_XLFD_NO_SPACE_/$sans_japanese_xlfd_no_space/g; $ARG =~ s/_SANS_JAPANESE_FILE_/$sans_japanese_file/g; $ARG =~ s/_SANS_JAPANESE_XLFD_/$sans_japanese_xlfd/g; $ARG =~ s/_SERIF_JAPANESE_XLFD_NO_SPACE_/$serif_japanese_xlfd_no_space/g; $ARG =~ s/_SERIF_JAPANESE_FILE_/$serif_japanese_file/g; $ARG =~ s/_SERIF_JAPANESE_XLFD_/$serif_japanese_xlfd/g; $font_properties_ja_template .= $ARG; } close (TEMPLATE); for my $globpattern (@font_properties_ja_globs) { for my $file (glob ("$globpattern")) { if (-f "$file") { if ($VERBOSITY >= $VERBOSITY_QUIET) { printf "writing $file\n"; } open (FONTPROP, ">$file") || die "can't open file $file: $!"; binmode FONTPROP, ":utf8"; print FONTPROP $font_properties_ja_template; close (FONTPROP); } } } } # setup for Java 1.5 (for Japanese, Chinese, and Korean): # I hope it is good enough to get the font directory from the full # path of the Japanese sans serif file. # Probably all fonts are in the same directory: (my $x11fontdir = $sans_japanese_file) =~ s/\/[^\/]+$//; if (-f "$fontconfig_SuSE_properties_template_file") { open (TEMPLATE, "$fontconfig_SuSE_properties_template_file") || die "can't open file $fontconfig_SuSE_properties_template_file: $!"; binmode TEMPLATE, ":utf8"; while (<TEMPLATE>) { $ARG =~ s/_SANS_JAPANESE_XLFD_NO_SPACE_/$sans_japanese_xlfd_no_space/g; $ARG =~ s/_SANS_JAPANESE_FILE_/$sans_japanese_file/g; $ARG =~ s/_SANS_JAPANESE_XLFD_/$sans_japanese_xlfd/g; $ARG =~ s/_MONO_JAPANESE_XLFD_NO_SPACE_/$mono_japanese_xlfd_no_space/g; $ARG =~ s/_MONO_JAPANESE_FILE_/$mono_japanese_file/g; $ARG =~ s/_MONO_JAPANESE_XLFD_/$mono_japanese_xlfd/g; $ARG =~ s/_SERIF_JAPANESE_XLFD_NO_SPACE_/$serif_japanese_xlfd_no_space/g; $ARG =~ s/_SERIF_JAPANESE_FILE_/$serif_japanese_file/g; $ARG =~ s/_SERIF_JAPANESE_XLFD_/$serif_japanese_xlfd/g; $ARG =~ s/_SANS_SIMPLIFIED_CHINESE_XLFD_NO_SPACE_/$sans_simplified_chinese_xlfd_no_space/g; $ARG =~ s/_SANS_SIMPLIFIED_CHINESE_FILE_/$sans_simplified_chinese_file/g; $ARG =~ s/_SANS_SIMPLIFIED_CHINESE_XLFD_/$sans_simplified_chinese_xlfd/g; $ARG =~ s/_SERIF_SIMPLIFIED_CHINESE_XLFD_NO_SPACE_/$serif_simplified_chinese_xlfd_no_space/g; $ARG =~ s/_SERIF_SIMPLIFIED_CHINESE_FILE_/$serif_simplified_chinese_file/g; $ARG =~ s/_SERIF_SIMPLIFIED_CHINESE_XLFD_/$serif_simplified_chinese_xlfd/g; $ARG =~ s/_SANS_TRADITIONAL_CHINESE_XLFD_NO_SPACE_/$sans_traditional_chinese_xlfd_no_space/g; $ARG =~ s/_SANS_TRADITIONAL_CHINESE_FILE_/$sans_traditional_chinese_file/g; $ARG =~ s/_SANS_TRADITIONAL_CHINESE_XLFD_/$sans_traditional_chinese_xlfd/g; $ARG =~ s/_SERIF_TRADITIONAL_CHINESE_XLFD_NO_SPACE_/$serif_traditional_chinese_xlfd_no_space/g; $ARG =~ s/_SERIF_TRADITIONAL_CHINESE_FILE_/$serif_traditional_chinese_file/g; $ARG =~ s/_SERIF_TRADITIONAL_CHINESE_XLFD_/$serif_traditional_chinese_xlfd/g; $ARG =~ s/_SANS_KOREAN_XLFD_NO_SPACE_/$sans_korean_xlfd_no_space/g; $ARG =~ s/_SANS_KOREAN_FILE_/$sans_korean_file/g; $ARG =~ s/_SANS_KOREAN_XLFD_/$sans_korean_xlfd/g; $ARG =~ s/_SERIF_KOREAN_XLFD_NO_SPACE_/$serif_korean_xlfd_no_space/g; $ARG =~ s/_SERIF_KOREAN_FILE_/$serif_korean_file/g; $ARG =~ s/_SERIF_KOREAN_XLFD_/$serif_korean_xlfd/g; $ARG =~ s/_X11FONTDIR_/$x11fontdir/; $fontconfig_SuSE_properties_template .= $ARG; } close (TEMPLATE); for my $globpattern (@fontconfig_SuSE_properties_globs) { for my $file (glob ("$globpattern")) { if (-f "$file") { if ($VERBOSITY >= $VERBOSITY_QUIET) { printf "writing $file\n"; } open (FONTPROP, ">$file") || die "can't open file $file: $!"; binmode FONTPROP, ":utf8"; print FONTPROP $fontconfig_SuSE_properties_template; close (FONTPROP); } } } } } ######################################################################## my @font_dirs = (); sub font_dirs_setup_add_font_dir { my ($dir) = @_; while (-l "$dir") { $dir = readlink ("$dir"); } if (! -d "$dir") { return; } if (grep (/$dir/, @font_dirs)) { return; } push (@font_dirs, ("$dir")); my $dir_handle; if (opendir ($dir_handle, $dir)) { my @entries = readdir ($dir_handle); for my $entry (@entries) { if ("$entry" =~ /\./ || "$entry" =~ /\.\./ || ! -d "$dir/$entry") { next; } font_dirs_setup_add_font_dir("$dir/$entry"); } closedir $dir_handle; } } sub font_dirs_setup { my $suse_font_dirs_file = "/etc/fonts/suse-font-dirs.conf"; my $suse_font_dirs_template_file = "/usr/share/fonts-config/suse-font-dirs.conf.template"; my $suse_font_dirs = ""; my $suse_font_dirs_template = ""; if (-f "$suse_font_dirs_template_file") { open (TEMPLATE, "$suse_font_dirs_template_file") || die "can't open file $suse_font_dirs_template_file: $!"; binmode TEMPLATE, ":utf8"; while (<TEMPLATE>) { if ($ARG =~ /<dir>(.*)<\/dir>/) { for my $dir (glob ("$1")) { if (-d "$dir") { font_dirs_setup_add_font_dir ("$dir"); } } } elsif ($ARG =~ /<\/fontconfig>/) { for my $dir (@font_dirs) { $suse_font_dirs_template .= " <dir>$dir</dir>\n"; } $suse_font_dirs_template .= "\n</fontconfig>\n"; } else { $suse_font_dirs_template .= $ARG; } } close (TEMPLATE); if (open (CONF, "$suse_font_dirs_file")) { while (<CONF>) { $suse_font_dirs .= $ARG; } close (CONF); } if ("$suse_font_dirs_template" eq "$suse_font_dirs") { if ($VERBOSITY >= $VERBOSITY_QUIET) { printf "$suse_font_dirs_file unchanged\n"; } } else { if ($VERBOSITY >= $VERBOSITY_QUIET) { printf "writing $suse_font_dirs_file\n"; } open (CONF, ">$suse_font_dirs_file") || die "can't open file $suse_font_dirs_file: $!"; print CONF $suse_font_dirs_template; close (CONF); } } } ######################################################################## sub hinting_setup { my $suse_hinting_file = "/etc/fonts/suse-hinting.conf"; my $suse_hinting_template_file = "/usr/share/fonts-config/suse-hinting.conf.template"; my $suse_hinting = ""; my $suse_hinting_template = ""; if (-f "$suse_hinting_template_file") { open (TEMPLATE, "$suse_hinting_template_file") || die "can't open file $suse_hinting_template_file: $!"; binmode TEMPLATE, ":utf8"; while (<TEMPLATE>) { $ARG =~ s/_BYTECODE_BW_MAX_PIXEL_/$OPT_BCBWMAX/; $suse_hinting_template .= $ARG; } close (TEMPLATE); if (open (CONF, "$suse_hinting_file")) { while (<CONF>) { $suse_hinting .= $ARG; } close (CONF); } if ("$suse_hinting_template" eq "$suse_hinting") { if ($VERBOSITY >= $VERBOSITY_QUIET) { printf "$suse_hinting_file unchanged\n"; } } else { if ($VERBOSITY >= $VERBOSITY_QUIET) { printf "writing $suse_hinting_file\n"; } open (CONF, ">$suse_hinting_file") || die "can't open file $suse_hinting_file: $!"; print CONF $suse_hinting_template; close (CONF); } } } ######################################################################## sub embedded_bitmap_setup { my $suse_bitmaps_file = "/etc/fonts/suse-bitmaps.conf"; my $suse_bitmaps_template_file = "/usr/share/fonts-config/suse-bitmaps.conf.template"; my $suse_bitmaps = ""; my $suse_bitmaps_template = ""; if (-f "$suse_bitmaps_template_file") { open (TEMPLATE, "$suse_bitmaps_template_file") || die "can't open file $suse_bitmaps_template_file: $!"; binmode TEMPLATE, ":utf8"; while (<TEMPLATE>) { if ($ARG !~ /_USE_EMBEDDED_BITMAPS_PLACEHOLDER_/) { $suse_bitmaps_template .= $ARG; } else { if (! $OPT_EBITMAP) { $suse_bitmaps_template .= " <match target=\"font\">\n"; $suse_bitmaps_template .= " <edit name=\"embeddedbitmap\" mode=\"assign\">\n"; $suse_bitmaps_template .= " <bool>false</bool>\n"; $suse_bitmaps_template .= " </edit>\n"; $suse_bitmaps_template .= " </match>\n"; } elsif ($OPT_EBITMAP && $OPT_EBITMAP_LANG =~ /0/) { $suse_bitmaps_template .= " <match target=\"font\">\n"; $suse_bitmaps_template .= " <edit name=\"embeddedbitmap\" mode=\"assign\">\n"; $suse_bitmaps_template .= " <bool>true</bool>\n"; $suse_bitmaps_template .= " </edit>\n"; $suse_bitmaps_template .= " </match>\n"; } else { $suse_bitmaps_template .= " <match target=\"font\">\n"; $suse_bitmaps_template .= " <edit name=\"embeddedbitmap\" mode=\"assign\">\n"; $suse_bitmaps_template .= " <bool>false</bool>\n"; $suse_bitmaps_template .= " </edit>\n"; $suse_bitmaps_template .= " </match>\n"; $suse_bitmaps_template .= " <match target=\"font\">\n"; $suse_bitmaps_template .= " <test name=\"lang\" compare=\"contains\">\n"; my @languages = split (":", "$OPT_EBITMAP_LANG"); for my $i (@languages) { $suse_bitmaps_template .= " <string>$i</string>\n"; } $suse_bitmaps_template .= " </test>\n"; $suse_bitmaps_template .= " <edit name=\"embeddedbitmap\" mode=\"assign\">\n"; $suse_bitmaps_template .= " <bool>true</bool>\n"; $suse_bitmaps_template .= " </edit>\n"; $suse_bitmaps_template .= " </match>\n"; } } } close (TEMPLATE); if (open (CONF, "$suse_bitmaps_file")) { while (<CONF>) { $suse_bitmaps .= $ARG; } close (CONF); } if ("$suse_bitmaps_template" eq "$suse_bitmaps") { if ($VERBOSITY >= $VERBOSITY_QUIET) { printf "$suse_bitmaps_file unchanged\n"; } } else { if ($VERBOSITY >= $VERBOSITY_QUIET) { printf "writing $suse_bitmaps_file\n"; } open (CONF, ">$suse_bitmaps_file") || die "can't open file $suse_bitmaps_file: $!"; print CONF $suse_bitmaps_template; close (CONF); } } } ######################################################################## # Returns true if the modification time of $f1 differs from # the modification time of $f2 sub mtime_differs { my ($f1,$f2) = @_; if ( -e $f1 && -e $f2) { my @f1s = stat ($f1); my @f2s = stat ($f2); return ($f1s[9] != $f2s[9]); } else { return 0; } } # Returns true if the modification time of $f1 differs from # the modification time of $f2 or if one of the files is missing sub mtime_differs_or_missing { my ($f1,$f2) = @_; if (! -e $f1 || ! -e $f2 || mtime_differs ($f1,$f2)) { return 1; } else { return 0; } } # Returns true if $f1 is newer than $f2 sub newer { my ($f1,$f2) = @_; if ( -e $f1 && -e $f2) { my @f1s = stat ($f1); my @f2s = stat ($f2); return ($f1s[9] > $f2s[9]); } else { return 0; } } # Returns true if $f1 is newer than $f2 or if one of the files is missing sub newer_or_missing { my ($f1,$f2) = @_; if (! -e $f1 || ! -e $f2 || newer ($f1,$f2)) { return 1; } else { return 0; } } sub my_system { my ($command) = @_; if ($VERBOSITY >= $VERBOSITY_DEBUG) { print "executing: $command\n"; } return system ($command); } sub search_executable { for my $file (@_) { if (-x $file) { return $file; } } return ""; }
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor