1#!/usr/local/bin/perl -w
2
3#
4# Simple convertor from bdf to gd font format.
5#
6# Author: Jan Pazdziora, adelton@fi.muni.cz, http://www.fi.muni.cz/~adelton/
7# at Faculty of Informatics, Masaryk University in Brno, Czech Republic.
8#
9# Example of use:
10# fstobdf -s fontserverhost:7100 -fn 8x16 | ./bdftogd FontLarge gdfontl
11#
12
13use strict;
14
15my $VERSION = '0.60';
16my $now = localtime;
17
18if (@ARGV != 2)
19	{ die "usage: bdftogd fontname filename, eg. bdftogd FontLarge gdfontl\n"; }
20
21my $gdname = shift;
22$gdname = 'gd' . $gdname unless $gdname =~ /^gd/i;
23
24my $filename = shift;
25$filename = 'gd' . $filename unless $filename =~ /^gd/i;
26
27my $gdfunc = $gdname;
28$gdfunc =~ s/(.*Font)(.*)/$1Get$2/;
29
30if (-f "$filename.c") { die "File $filename.c already exists, won't overwrite\n"; }
31if (-f "$filename.h") { die "File $filename.h already exists, won't overwrite\n"; }
32
33my ($width, $height);
34my (@data, @left, @bottom);
35my ($globalleft, $globaltop);
36
37my ($minchar, $maxchar);
38
39my ($copyright, $fontdef);
40
41my $currentchar;
42my $gobitmap = 0;
43
44
45while (<>)
46	{
47	chomp;
48	s/\r$//;
49	my ($tag, $value) = split / /, $_, 2;
50	die "Font is not fixed width\n"
51			if $tag eq 'SPACING' and not $value =~ /[CM]/i;
52
53	$currentchar = $value if $tag eq 'ENCODING';
54	$minchar = $currentchar if not defined $minchar
55		or $currentchar < $minchar;
56	$maxchar = $currentchar if not defined $maxchar
57		or $currentchar > $maxchar;
58
59	if ($tag eq 'ENDCHAR')
60		{
61		$gobitmap = 0;
62		my $bottom = $globaltop - $bottom[$currentchar];
63
64
65		if ($bottom > 0)
66			{ $data[$currentchar] = substr $data[$currentchar], 0, length($data[$currentchar]) - $bottom * $width; }
67		else
68			{ $data[$currentchar] .= '0' x (-$bottom * $width); }
69		}
70
71	if ($tag eq 'FONTBOUNDINGBOX')
72		{
73		my ($tag, $wid, $hei, $left, $top) = split / /;
74		if (defined $top)
75			{
76			$globalleft = $left;
77			$globaltop = $top;
78			$height = $hei;
79			$width = $wid;
80			}
81		}
82	if ($tag eq 'FONT' and not defined $fontdef)
83		{ $fontdef = $value; }
84	if ($tag eq 'COPYRIGHT' and not defined $copyright)
85		{ $copyright = $value; }
86
87	if ($tag eq 'BBX')
88		{
89		my ($tag, $wid, $hei, $left, $bottom) = split / /;
90		if (defined $bottom)
91			{
92			$left[$currentchar] = $left;
93			$bottom[$currentchar] = $bottom;
94			}
95		}
96
97	if ($gobitmap)
98		{
99		my $value = pack 'H*', $_;
100		my $bits = unpack 'B*', $value;
101		$bits = ('0' x $left[$currentchar]) . $bits;
102		$bits .= '0' x ($width - length $bits);
103		$bits = substr $bits, 0, $width;
104		$data[$currentchar] .= $bits;
105		}
106
107	if ($tag eq 'BITMAP')
108		{
109		$gobitmap = 1;
110		$data[$currentchar] = '';
111		}
112	}
113
114my $info = <<"EOF";
115/*
116	This is a header file for gd font, generated using
117	bdftogd version $VERSION by Jan Pazdziora, adelton\@fi.muni.cz
118	from bdf font
119	$fontdef
120	at $now.
121EOF
122
123if (defined $copyright)
124	{
125	$info .= <<"EOF";
126	The original bdf was holding following copyright:
127	$copyright
128 */
129EOF
130	}
131else
132	{
133	$info .= <<"EOF";
134	No copyright info was found in the original bdf.
135 */
136EOF
137	}
138
139open FILEC, "> $filename.c" or die "Error writing $filename.c: $!\n";
140open FILEH, "> $filename.h" or die "Error writing $filename.h: $!\n";
141print FILEC <<"EOF";
142
143$info
144
145#ifdef HAVE_CONFIG_H
146#include "config.h"
147#endif
148
149#include "$filename.h"
150
151char ${gdname}Data[] = {
152EOF
153
154$minchar = 0 unless defined $minchar;
155$maxchar = 255 unless defined $maxchar;
156for (my $i = $minchar; $i <= $maxchar; $i++)
157	{
158	$data[$i] = '' unless defined $data[$i];
159	$data[$i] = '0' x ($width * $height - length $data[$i]) . $data[$i];
160
161	print FILEC "/* Char $i */\n";
162	for my $line (0 .. $height - 1)
163		{ print FILEC join ',', split(//, substr($data[$i], $line * $width, $width)), "\n"; }
164
165	print FILEC "\n";
166
167	next;
168
169	for my $line (0 .. $height - 1)
170		{ print substr($data[$i], $line * $width, $width), "\n"; }
171	}
172
173my $capdef = "\U_${filename}_H_";
174
175print FILEC <<"EOF";
176
177};
178
179gdFont ${gdname}Rep = {
180	@{[ $maxchar - $minchar + 1]},
181	$minchar,
182	$width,
183	$height,
184	${gdname}Data
185};
186
187BGD_EXPORT_DATA_PROT gdFontPtr ${gdname} = &${gdname}Rep;
188
189BGD_DECLARE(gdFontPtr)
190$gdfunc (void)
191{
192  return $gdname;
193}
194
195/* This file has not been truncated. */
196EOF
197
198
199close FILEC;
200
201print FILEH <<"EOF";
202#ifndef $capdef
203#define $capdef 1
204
205#ifdef __cplusplus
206extern "C" {
207#endif
208
209$info
210
211#include "gd.h"
212
213extern BGD_EXPORT_DATA_PROT  gdFontPtr $gdname;
214BGD_DECLARE(gdFontPtr) $gdfunc(void);
215
216#ifdef __cplusplus
217}
218#endif
219
220#endif
221EOF
222
2231;
224