#!/usr/bin/perl push @ARGV, ""; if ($ARGV[0] eq "--help") { print STDERR < 0 || die("$0: -o requires an argument\n"); $output = $ARGV[0]; shift @ARGV; } elsif ($ARGV[0] =~ /^-o(.*)$/) { $output = $1; shift @ARGV; } if ($ARGV[0] eq "--") { shift @ARGV; } elsif ($ARGV[0] =~ /^([-+][0-9a-z])$/) { print STDERR "$0: suspicuous $1, use -- to terminate the option list\n"; } pop @ARGV; if ($#ARGV < 0) { $ARGV[0] = "-"; } open(BDF, "<$ARGV[0]") || die("$0: $ARGV[0]: $!\n"); while () { if (/^FONTBOUNDINGBOX\s+([0-9]+)\s+([0-9]+).*$/) { $width = $1; $height = $2; } elsif (/^CHARS\s+([0-9]+)$/) { $chars = $1; last; } } (defined($width) && defined($chars)) || die("$0: $ARGV[0]: missing width/height or CHARS\n"); # psf2 can handle almost anything, but there must be some reasonable limits ($width > 0 && $width <= 128) || die("$0: $ARGV[0]: width $width out of range\n"); ($height > 0 && $height <= 256) || die("$0: $ARGV[0]: height $height out of range\n"); ($chars > 0 && $chars <= 65536) || die("$0: $ARGV[0]: CHARS $chars out of range\n"); $minimal = $width != 8 || $height >= 256 || ($chars != 256 && $chars != 512); $header != 0 || $minimal == 0 || die("$0: $ARGV[0]: RAW format: invalid width $width, height $height or CHARS $chars\n"); $chars == 256 || $reject == 0 || die("$0: $ARGV[0]: RAW format: CHARS $chars rejected, use -r to accept\n", $chars); if (!defined($unicode)) { $unicode = $chars > 256; } if (!defined($version)) { $version = $minimal; } else { $version >= $minimal || die("$0: $ARGV[0]: requested version ", $version + 1, ", required ", $minimal + 1, "\n"); } if (!defined($output)) { $output = "-"; } elsif ($output eq "") { if ($ARGV[0] =~ /^(.*).bdf$/) { $output = "$1$suffix" ; } else { $output = "$ARGV[0]$suffix"; } } $linesize = ($width + 7) >> 3; $charsize = $linesize * $height; sub int { $int = $!; } sub bye { close OUT; $output ne "-" && unlink($output) != 1 && print STDERR "$0: $output: $!\n"; die("@_"); } open(OUT, ">$output") || die("$0: $output: $!\n"); $SIG{INT} = 'int'; binmode(OUT) || bye("$0: $output: $!\n"); if ($header != 0) { if ($version == 0) { printf OUT "%c%c%c%c", 0x36, 0x04, ($chars == 512) + $unicode * 2, $height; } else { printf OUT "%c%c%c%c", 0x72, 0xB5, 0x4A, 0x86; printf OUT "%c%c%c%c", 0x00, 0x00, 0x00, 0x00; printf OUT "%c%c%c%c", 0x20, 0x00, 0x00, 0x00; printf OUT "%c%c%c%c", $unicode, 0x00, 0x00, 0x00; printf OUT "%c%c%c%c", $chars & 0xFF, $chars >> 8, 0x00, 0x00; printf OUT "%c%c%c%c", $charsize & 0xFF, ($charsize >> 8) & 0xFF, $charsize >> 16, 0x00; printf OUT "%c%c%c%c", $height & 0xFF, $height >> 8, 0x00, 0x00; printf OUT "%c%c%c%c", $width & 0xFF, $width >> 8, 0x00, 0x00; } } $lines = 0; while () { $bytes = 0; while (/^([0-9a-fA-F]{2})(([0-9a-fA-F]{2})*)$/) { printf OUT "%c", hex($1); $bytes++; $_ = $2; } if ($bytes != 0) { $lines++; $bytes == $linesize || bye("$0: $ARGV[0]: invalid number of bytes $bytes on data line $lines\n"); } else { if (/^ENCODING\s+([0-9]+)$/) { push @unimap, $1; if ($1 != 65535) { $unidup{$1}[0] = $1; } } elsif (/^ENDFONT$/) { last; } } } close BDF; if ($#ARGV > 0) { if ($unicode) { do { shift @ARGV; open(DUP, "<$ARGV[0]") || bye("$0: $ARGV[0]: $!\n"); while () { next if /^\s*$/; /^([0-9a-fA-F]{1,4})\s+([0-9a-fA-F]{1,4})$/ || bye("$0: $ARGV[0]: invalid unicode(s) $_\n"); $duplicate = hex($2); hex($1) != $duplicate || bye("$0: $ARGV[0]: invalid duplicate entry $_\n"); foreach (@{$unidup{hex($1)}}) { if ($_ == $duplicate) { $duplicate = 65535; last; } } if ($duplicate != 65535) { push @{$unidup{hex($1)}}, $duplicate; } } close DUP; } while ($#ARGV > 0); } else { bye("$0: invalid number of arguments\n"); } } @unimap == $chars || bye("$0: $output: invalid number of chars @unimap\n"); @unimap * $charsize == $lines * $linesize || bye("$0: $output: invalid number of data lines $lines\n"); if ($unicode) { foreach (@unimap) { foreach (@{$unidup{$_}}) { if ($version == 0) { printf OUT "%c%c", $_ & 0xFF, $_ >> 8; } elsif ($_ <= 0x7F) { printf OUT "%c", $_; } else { if ($_ <= 0x7FF) { printf OUT "%c", 0xC0 + ($_ >> 6); } else { printf OUT "%c%c", 0xE0 + ($_ >> 12), 0x80 + (($_ >> 6) & 0x3F); } printf OUT "%c", 0x80 + ($_ & 0x3F); } } printf OUT "%c", 0xFF; if ($version == 0) { printf OUT "%c", 0xFF; } } } close OUT || bye("$0: $output: $!\n"); defined($int) && bye("$0: $int\n");