Article View: comp.fonts
Article #2882Re: How do I create an SFP (HP LJ) Font?
From: Paul Bijnens
Date: Thu, 11 Feb 1993 14:46
Date: Thu, 11 Feb 1993 14:46
336 lines
9951 bytes
9951 bytes
Archive-name: hpsoftfont
Submitted-by: polleke@cc1.kuleuven.ac.be
> I need to turn a simple logo into a HP Laser Jet downloadable font
>(SFP? format.) I've done this sort of thing with True Type and Adobe
>Type Is. What do I need to create/convert to this font format?
>Fontmonger?
Do I understand that you have the logo in Truetype and you want it
in HP softfont (SFP) format? If so, a few weeks ago, I had the same
problem and came up with these little perl hacks.
Getting started:
Make a document (e.g. in Word for Windows) with all the characters in
the font, choose the right font and the right size and paper orientation.
Then print into a file. Then use the utility "hpfontextr" to extract
the softfonts from that file. Rename the resulting files "font16384"
etc. to a sensible name e.g. "tmsr12p.sfp" (for Times Roman 12 points).
The program "hpfontdesc" shows an ASCII graphics representation of
the font on the screen.
The package "hpfont" contains some useful routines to use these
fonts in an other perl program.
No documentation exists. Read the sources.
#!/bin/sh
# This is a shell archive (produced by shar 3.49)
# To extract the files from this archive, save it to a file, remove
# everything above the "!/bin/sh" line above, and type "sh file_name".
#
# made 02/11/1993 13:09 UTC by polleke@triton
# Source directory /user/home/polleke/src/hpfont
#
# existing files will NOT be overwritten unless -c is specified
#
# This shar contains:
# length mode name
# ------ ---------- ------------------------------------------
# 1636 -rwxrwxr-x hpfont
# 1209 -rwxrwxr-x hpfontextr
# 2939 -rwxrwxr-x hpfontdesc
#
# ============= hpfont ==============
if test -f 'hpfont' -a X"$1" != X"-c"; then
echo 'x - skipping hpfont (File already exists)'
else
echo 'x - extracting hpfont (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'hpfont' &&
X#!/usr/bin/perl
X
X# HP soft font package
X
X# e.g. program to get the widths of the characters in the softfont
X# foreach (@ARGV) {
X# print "FONT $_\n";
X# $font = &hp'readfont($_);
X# @W = &hp'getwidth($font);
X# for ($[ .. $#W) {
X# print "char: ", $_, "\t", "width: ", $W[$_], "\n";
X# }
X# }
X
X
Xpackage hp;
X
X# read HP soft font into scalar variable
Xsub readfont
X{
X local($filename) = shift;
X local($font);
X local($/);
X
X undef $/; # slurp complete file
X open(FONTFILE, "<$filename") || die("open $filename: $!\n");
X $font = <FONTFILE>;
X close(FONTFILE);
X $font;
X}
X
X
X# return array with widths of characters
Xsub getwidth
X{
X local($_) = shift; # the font
X local(@w);
X
X $w[$1] = unpack(n, $2) / 4
X while(/\033\*c(\d+)E\033\(s\d+W[\0-\xff]{14}([\0-\xff][\0-\xff])/g);
X # $w[32] = &min(@w[97..122]); # space: minimum of lowercase letters
X $w[32] = $w[48]; # space as wide as a number
X @w;
X}
X
X
Xsub reset
X{
X print "\033E\033*c0F";
X}
X
X
Xsub loadfont
X{
X local($fontid) = shift;
X local($font) = shift;
X
X print "\033*c", $fontid, "D", $font, "\033*c4F";
X}
X
X
Xsub changefont
X{
X local($fontid) = shift;
X
X print "\033(", $fontid, "X";
X}
X
X
X# Cursor movement (in dots)
X
Xsub movex
X{
X local($xpos) = shift;
X
X print "\033*p", $xpos, "X";
X}
X
X
Xsub movey
X{
X local($ypos) = shift;
X
X print "\033*p", $ypos, "Y";
X}
X
X
Xsub movexy
X{
X local($xpos) = shift;
X local($ypos) = shift;
X
X print "\033*p", $ypos, "x", $ypos, "Y";
X}
X
X
Xsub min { local($v) = pop(@_); grep(($_ < $v) && ($v = $_),@_); $v; }
X# sub max { local($v) = pop(@_); grep(($_ > $v) && ($v = $_),@_); $v; }
X
X
X1;
SHAR_EOF
chmod 0775 hpfont ||
echo 'restore of hpfont failed'
Wc_c="`wc -c < 'hpfont'`"
test 1636 -eq "$Wc_c" ||
echo 'hpfont: original size 1636, current size' "$Wc_c"
fi
# ============= hpfontextr ==============
if test -f 'hpfontextr' -a X"$1" != X"-c"; then
echo 'x - skipping hpfontextr (File already exists)'
else
echo 'x - extracting hpfontextr (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'hpfontextr' &&
X#!/usr/bin/perl
X
X# extract HP soft font definition from a print file
X# e.g. convert truetype to hp-softfont from output generated by
X# printing into a file
X
Xundef($/); # slurp all
X$tt = <>; # read truetype output
X
X$fontid = 0; # just in case the fontid sequence is missing
X$fontid{$fontid}++;
X
Xwhile ($tt =~ /\033/) {
X $n = length($`);
X $tt = substr($tt, $n) if ($n > 0);
X if ($tt =~ /^\033\*c(\d+)D/) {
X $fontid = $1;
X $fontid{$fontid}++;
X $tt = $';
X } elsif ($tt =~ /^\033\)s(\d+)W/) {
X $n = $1;
X $fonthdr{$fontid} = $&;
X $tt = $';
X $fonthdr{$fontid} .= substr($tt, 0, $n);
X $tt = substr($tt, $n);
X } elsif ($tt =~ /^\033\*c(\d+)E/) {
X $chrcode = $1;
X $c{$chrcode, $fontid} = $&;
X $tt = $';
X } elsif ($tt =~ /^\033\(s(\d+)W/) {
X $n = $1;
X $c{$chrcode, $fontid} .= $&;
X $tt = $';
X $c{$chrcode, $fontid} .= substr($tt, 0, $n);
X $tt = substr($tt, $n);
X } else {
X $tt = substr($tt, 1); # advance 1 byte
X }
X}
X
X
Xforeach $fontid (keys %fontid) {
X open(OUT, ">font$fontid");
X print OUT $fonthdr{$fontid};
X foreach $xx (sort {$a <=> $b} (keys %c)) {
X ($chrcode, $ftid) = split($;, $xx);
X next unless ($ftid == $fontid);
X print OUT $c{$chrcode, $fontid};
X }
X close(OUT);
X}
SHAR_EOF
chmod 0775 hpfontextr ||
echo 'restore of hpfontextr failed'
Wc_c="`wc -c < 'hpfontextr'`"
test 1209 -eq "$Wc_c" ||
echo 'hpfontextr: original size 1209, current size' "$Wc_c"
fi
# ============= hpfontdesc ==============
if test -f 'hpfontdesc' -a X"$1" != X"-c"; then
echo 'x - skipping hpfontdesc (File already exists)'
else
echo 'x - extracting hpfontdesc (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'hpfontdesc' &&
X#!/usr/bin/perl
X
X# show hp softfont in human readable form
X
X$show_global = 1;
X
X
Xundef $/;
X$_ = <>;
X
Xwhile ($_) {
X if (/^\033\)s(\d+)W/) {
X # print "Font Header ", $1, " bytes\n";
X $lc = length($&); # length of the code
X $ld = $1; # length of the data
X ($code, $fthdr, $_) = unpack("a${lc}a${ld}a*", $_);
X &decode_fthdr($fthdr);
X } elsif (/^\033\*c(\d+)E/) {
X print "\n", "-" x $fthdr_cellwidth, "\n";
X $code = pack("c", $1);
X print "Character Code: ", $1, " ($code)\n";
X $_ = substr($_, length($&));
X } elsif (/^\033\(s(\d+)W/) {
X $lc = length($&);
X $ld = $1;
X ($code, $chhdr, $_) = unpack("a${lc}a${ld}a*", $_);
X &decode_char($chhdr);
X } else {
X /^[^\033]*/;
X print "\n\n*** GARBAGE :", length($&), " bytes\n\n\n";
X $hex = unpack('H*', $&), "\n";
X $_ = substr($_, length($&));
X $hex =~ s/../$& /g;
X print $hex, "\n";
X }
X}
X
X
Xsub decode_fthdr {
X local($_) = shift;
X ($fthdr_size) = unpack("s", $_);
X # $fthdr_size += 3; # this is needed sometimes...???
X ($fthdr_data, $fthdr_comment) =
X unpack("a${fthdr_size}a*", $fthdr);
X ($fthdr_size, $fthdr_type, $fthdr_zero1, $fthdr_base,
X $fthdr_cellwidth, $fthdr_cellheight, $fthdr_orientation,
X $fthdr_spacing, $fthdr_symbolset, $fthdr_pitch,
X $fthdr_height, $fthdr_zero2, $fthdr_style,
X $fthdr_tickness, $fthdr_typeface
X ) = unpack("s6c2s5c2", $fthdr);
X # print $fthdr; exit;
X# return;
X printf "Fonthdr_size: %d\n", $fthdr_size;
X printf "Fonthdr_type: %d\n", $fthdr_type;
X printf "Fonthdr_base: %d\n", $fthdr_base;
X printf "Fonthdr_cellwidth: %d\n", $fthdr_cellwidth;
X printf "Fonthdr_cellheight: %d\n", $fthdr_cellheight;
X printf "Fonthdr_orientation: %d\n", $fthdr_orientation;
X printf "Fonthdr_symbolset: %d\n", $fthdr_symbolset;
X printf "Fonthdr_pitch: %d\n", $fthdr_pitch;
X print "Font comment: ", $fthdr_comment, "\n";
X # not yet complete... but my manual is silent here
X}
X
X
Xsub decode_char {
X local($_) = shift;
X ($ch_dummy1, $ch_dummy2, $ch_orientation, $ch_dummy3,
X $ch_leftoffset, $ch_topoffset, $ch_width, $ch_height,
X $ch_deltax, $ch_bits
X ) = unpack("s2ccsssssa*", $_);
X print "Orientation: ", $ch_orientation, "\n";
X print "Left offset: ", $ch_leftoffset, "\n";
X print "Top offset: ", $ch_topoffset, "\n";
X print "Width: ", $ch_width, "\n";
X print "Height: ", $ch_height, "\n";
X print "Delta X: ", $ch_deltax, "\n";
X print "Char width: ", $ch_deltax/4, "\n";
X# return;
X print "\n";
X for $i (1 .. $ch_height) {
X ($row, $ch_bits) = unpack("B${ch_width}a*", $ch_bits);
X $row =~ y/01/.@/;
X if ($show_global) {
X $l = $ch_deltax/4 - $ch_leftoffset;
X $row =~ s/^(.{$l})([,.])/$1|/;
X $row = ',' x $ch_leftoffset
X . $row .
X ',' x ($ch_deltax/4 - $ch_width - $ch_leftoffset);
X $row =~ y/.,/__/ if ($i == $ch_topoffset);
X $row =~ s/^(.{$l})([,.])/$1|/
X if (($l = - $ch_leftoffset) > 0);
X }
X print $row, "\n";
X }
X print "\n";
X}
SHAR_EOF
chmod 0775 hpfontdesc ||
echo 'restore of hpfontdesc failed'
Wc_c="`wc -c < 'hpfontdesc'`"
test 2939 -eq "$Wc_c" ||
echo 'hpfontdesc: original size 2939, current size' "$Wc_c"
fi
exit 0
--
Paul Bijnens -- MS-DOS is the world's most widespread virus.
Linguistics dept., K. University Leuven, Belgium
Polleke@cc1.kuleuven.ac.be
Technical Details
Message-ID:
<93042.144615FFAAC09@cc1.kuleuven.ac.be>Path:
arc1-ca.pugleaf.net!wupost!howland.reston.ans.net!usc!rpi!ghost.dsi.unimi.it!univ-lyon1.fr!frmop11!blekul11!ffaac09References:
<93042.013520AHACC@ASUACAD.BITNET>Show Full Headers
Complete Article Headers
Path: arc1-ca.pugleaf.net!wupost!howland.reston.ans.net!usc!rpi!ghost.dsi.unimi.it!univ-lyon1.fr!frmop11!blekul11!ffaac09 Organization: K.U.Leuven - Academic Computing Center Date: Thu, 11 Feb 1993 14:46:15 +01 From: Paul Bijnens <FFAAC09@cc1.kuleuven.ac.be> Message-ID: <93042.144615FFAAC09@cc1.kuleuven.ac.be> Newsgroups: comp.fonts,alt.sources,comp.lang.perl Followup-to: comp.fonts Subject: Re: How do I create an SFP (HP LJ) Font? Summary: HP soft font utilities (convert Truetype to SFP) References: <93042.013520AHACC@ASUACAD.BITNET> Lines: 336