1219888Sed/*-
2219888Sed * Copyright (c) 2009 The FreeBSD Foundation
3219888Sed * All rights reserved.
4219888Sed *
5219888Sed * This software was developed by Ed Schouten under sponsorship from the
6219888Sed * FreeBSD Foundation.
7219888Sed *
8219888Sed * Redistribution and use in source and binary forms, with or without
9219888Sed * modification, are permitted provided that the following conditions
10219888Sed * are met:
11219888Sed * 1. Redistributions of source code must retain the above copyright
12219888Sed *    notice, this list of conditions and the following disclaimer.
13219888Sed * 2. Redistributions in binary form must reproduce the above copyright
14219888Sed *    notice, this list of conditions and the following disclaimer in the
15219888Sed *    documentation and/or other materials provided with the distribution.
16219888Sed *
17219888Sed * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
18219888Sed * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19219888Sed * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20219888Sed * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
21219888Sed * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22219888Sed * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23219888Sed * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24219888Sed * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25219888Sed * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26219888Sed * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27219888Sed * SUCH DAMAGE.
28219888Sed */
29219888Sed
30219888Sed#include <sys/cdefs.h>
31219888Sed__FBSDID("$FreeBSD$");
32219888Sed
33219888Sed#include <sys/endian.h>
34219888Sed#include <sys/param.h>
35219888Sed
36219888Sed#include <stdint.h>
37219888Sed#include <stdio.h>
38219888Sed#include <stdlib.h>
39219888Sed#include <string.h>
40219888Sed
41219888Sedstruct file_mapping {
42219888Sed	uint32_t	source;
43219888Sed	uint16_t	destination;
44219888Sed	uint16_t	length;
45219888Sed} __packed;
46219888Sed
47219888Sedstruct file_header {
48219888Sed	uint8_t		magic[8];
49219888Sed	uint8_t		width;
50219888Sed	uint8_t		height;
51259680Semaste	uint16_t	pad;
52259680Semaste	uint32_t	glyph_count;
53259680Semaste	uint32_t	map_count[4];
54219888Sed} __packed;
55219888Sed
56219888Sedstatic int
57219888Sedprint_glyphs(struct file_header *fh)
58219888Sed{
59259680Semaste	unsigned int gbytes, glyph_count, j, k, total;
60219888Sed	uint8_t *gbuf;
61219888Sed
62219888Sed	gbytes = howmany(fh->width, 8) * fh->height;
63259680Semaste	glyph_count = be32toh(fh->glyph_count);
64219888Sed
65259680Semaste	printf("\nstatic uint8_t font_bytes[%u * %u] = {", glyph_count, gbytes);
66259680Semaste	total = glyph_count * gbytes;
67219888Sed	gbuf = malloc(total);
68219888Sed
69219888Sed	if (fread(gbuf, total, 1, stdin) != 1) {
70219888Sed		perror("glyph");
71219888Sed		return (1);
72219888Sed	}
73219888Sed
74219888Sed	for (j = 0; j < total; j += 12) {
75219888Sed		for (k = 0; k < 12 && k < total - j; k++) {
76219888Sed			printf(k == 0 ? "\n\t" : " ");
77219888Sed			printf("0x%02hhx,", gbuf[j + k]);
78219888Sed		}
79219888Sed	}
80219888Sed
81219888Sed	free(gbuf);
82219888Sed	printf("\n};\n");
83219888Sed
84219888Sed	return (0);
85219888Sed}
86219888Sed
87259680Semastestatic const char *map_names[4] = {
88259680Semaste    "normal", "normal_right", "bold", "bold_right" };
89259680Semaste
90219888Sedstatic int
91259680Semasteprint_mappings(struct file_header *fh, int map_index)
92219888Sed{
93219888Sed	struct file_mapping fm;
94219888Sed	unsigned int nmappings, i, col = 0;
95219888Sed
96259680Semaste
97259680Semaste	nmappings = be32toh(fh->map_count[map_index]);
98219888Sed
99219888Sed	if (nmappings == 0)
100219888Sed		return (0);
101219888Sed
102219888Sed	printf("\nstatic struct vt_font_map font_mapping_%s[%u] = {",
103259680Semaste	    map_names[map_index], nmappings);
104219888Sed
105219888Sed	for (i = 0; i < nmappings; i++) {
106219888Sed		if (fread(&fm, sizeof fm, 1, stdin) != 1) {
107219888Sed			perror("mapping");
108219888Sed			return (1);
109219888Sed		}
110219888Sed
111219888Sed		printf(col == 0 ? "\n\t" : " ");
112219888Sed		printf("{ 0x%04x, 0x%04x, 0x%02x },",
113219888Sed		    be32toh(fm.source), be16toh(fm.destination),
114219888Sed		    be16toh(fm.length));
115219888Sed		col = (col + 1) % 2;
116219888Sed	}
117219888Sed
118219888Sed	printf("\n};\n");
119219888Sed
120219888Sed	return (0);
121219888Sed}
122219888Sed
123219888Sedstatic int
124219888Sedprint_info(struct file_header *fh)
125219888Sed{
126259680Semaste	unsigned int i;
127219888Sed
128219888Sed	printf(
129219888Sed	    "\nstruct vt_font vt_font_default = {\n"
130219888Sed	    "\t.vf_width\t\t= %u,\n"
131219888Sed	    "\t.vf_height\t\t= %u,\n"
132219888Sed	    "\t.vf_bytes\t\t= font_bytes,\n",
133219888Sed	    fh->width, fh->height);
134219888Sed
135259680Semaste	printf("\t.vf_map\t\t\t= {\n");
136259680Semaste	for (i = 0; i < 4; i++) {
137259680Semaste		if (fh->map_count[i] > 0)
138259680Semaste			printf("\t\t\t\t    font_mapping_%s,\n", map_names[i]);
139259680Semaste		else
140259680Semaste			printf("\t\t\t\t    NULL,\n");
141259680Semaste	}
142266847Semaste	printf("\t\t\t\t  },\n");
143259680Semaste	printf("\t.vf_map_count\t\t= { %u, %u, %u, %u },\n",
144259680Semaste	    be32toh(fh->map_count[0]),
145259680Semaste	    be32toh(fh->map_count[1]),
146259680Semaste	    be32toh(fh->map_count[2]),
147259680Semaste	    be32toh(fh->map_count[3]));
148219888Sed	printf("\t.vf_refcount\t\t= 1,\n};\n");
149219888Sed
150219888Sed	return (0);
151219888Sed}
152219888Sed
153219888Sedint
154219888Sedmain(int argc __unused, char *argv[] __unused)
155219888Sed{
156219888Sed	struct file_header fh;
157259772Semaste	unsigned int i;
158219888Sed
159219888Sed	if (fread(&fh, sizeof fh, 1, stdin) != 1) {
160219888Sed		perror("file_header");
161219888Sed		return (1);
162219888Sed	}
163219888Sed
164259680Semaste	if (memcmp(fh.magic, "VFNT0002", 8) != 0) {
165219888Sed		fprintf(stderr, "Bad magic\n");
166219888Sed		return (1);
167219888Sed	}
168219888Sed
169219888Sed	printf("#include <dev/vt/vt.h>\n");
170219888Sed
171219888Sed	if (print_glyphs(&fh) != 0)
172219888Sed		return (1);
173259772Semaste	for (i = 0; i < 4; i++)
174259772Semaste		if (print_mappings(&fh, i) != 0)
175259772Semaste			return (1);
176219888Sed	if (print_info(&fh) != 0)
177219888Sed		return (1);
178219888Sed
179219888Sed	return (0);
180219888Sed}
181