main.c revision 825c30bc
1/* $NetBSD: main.c,v 1.5 2025/03/25 03:15:32 macallan Exp $ */ 2 3/* 4 * Copyright (c) 2011 Michael Lorenz 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 17 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 18 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 19 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 21 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 22 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 23 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 25 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 */ 27 28#include <stdio.h> 29#include <ctype.h> 30#include <fcntl.h> 31#include <unistd.h> 32#include <sys/stat.h> 33#include <dev/wscons/wsconsio.h> 34 35#include <ft2build.h> 36#include FT_FREETYPE_H 37 38char cvr[] = " .-+oaOX"; 39FT_Library library; 40FT_Face face; 41int baseline, above = 0, below = 0, advance = 0; 42 43int push_size(int); 44 45int 46push_size(int letter) 47{ 48 int glyph_index, error; 49 int new_above, new_below, new_advance; 50 51 glyph_index = FT_Get_Char_Index(face, letter); 52 printf("idx: %d\n", glyph_index); 53 error = FT_Load_Glyph(face, glyph_index, FT_LOAD_DEFAULT); 54 if (error) { 55 printf("wtf?!\n"); 56 return -1; 57 } 58 FT_Render_Glyph(face->glyph, FT_RENDER_MODE_NORMAL); 59 printf("%d x %d\n", face->glyph->bitmap.width, face->glyph->bitmap.rows); 60 printf("offset: %d %d\n", face->glyph->bitmap_left, face->glyph->bitmap_top); 61 new_advance = (int)(face->glyph->advance.x >> 6); 62 if (face->glyph->bitmap.width >= new_advance) 63 new_advance = face->glyph->bitmap.width + 1; 64 printf("advance: %d\n", new_advance); 65 new_above = face->glyph->bitmap_top; 66 new_below = face->glyph->bitmap.rows - face->glyph->bitmap_top; 67 if (new_above > above) above = new_above; 68 if (new_below > below) below = new_below; 69 if (new_advance > advance) advance = new_advance; 70 return 0; 71} 72 73int 74main(int argc, char *argv[]) 75{ 76 int error, glyph_index; 77 int x, y, idx, width_in_bytes, height = 22, cell_height; 78 int width, datalen, didx, i, start, end, out; 79 FILE *output; 80 uint8_t *fontdata; 81 char fontname[128], filename[sizeof(fontname) + 4 /* .wsf */]; 82 83 if (argc != 3) { 84 printf("usage: ttf2wsfont some_font.ttf height\n"); 85 return 0; 86 } 87 88 sscanf(argv[2], "%d", &height); 89 90 error = FT_Init_FreeType( &library ); 91 if (error) { 92 printf("Failed to initialize freefont2\n"); 93 return -1; 94 } 95 error = FT_New_Face(library, argv[1], 0, &face ); 96 if ( error == FT_Err_Unknown_File_Format ) { 97 printf("unsupported font format\n"); 98 return -1; 99 } 100 error = FT_Set_Pixel_Sizes(face, /* handle to face object */ 101 0, /* pixel_width */ 102 height - (height / 10) ); /* pixel_height */ 103 if (error) { 104 printf("couldn't set character cell size\n"); 105 } 106 107 push_size('W'); 108 push_size('g'); 109 push_size(']'); 110 push_size('['); 111 push_size('^'); 112 push_size(192); 113 printf("above: %d below: %d advance: %d\n", above, below, advance); 114 width = advance; 115 baseline = above; 116 cell_height = above + below; 117 datalen = 256 * width * cell_height; 118 fontdata = malloc(datalen); 119 120 121 for (i = 0; i < 256; i++) { 122 glyph_index = FT_Get_Char_Index(face, i); 123 FT_Load_Glyph(face, glyph_index, FT_LOAD_DEFAULT); 124 FT_Render_Glyph(face->glyph, FT_RENDER_MODE_NORMAL); 125 width_in_bytes = face->glyph->bitmap.width; 126 start = baseline - face->glyph->bitmap_top; 127 end = start + face->glyph->bitmap.rows; 128 if (end > cell_height) 129 end = cell_height; 130 idx = 0; 131 if (start < 0) { 132 idx += (0 - start) * width_in_bytes; 133 start = 0; 134 } 135 didx = i * width * cell_height + /* character cell */ 136 start * width + /* pixels above baseline */ 137 face->glyph->bitmap_left; /* pixels left from border */ 138 memset(&fontdata[i * width * cell_height], 0, width * cell_height); 139 for (y = start; y < end; y++) { 140 for (x = 0; x < width_in_bytes; x++) { 141 fontdata[didx + x] = face->glyph->bitmap.buffer[idx + x]; 142 } 143 idx += width_in_bytes; 144 didx += width; 145 } 146 } 147 148 /* now output as a header file */ 149 snprintf(fontname, sizeof(fontname), "%s_%dx%d", face->family_name, 150 width, cell_height); 151 for (i = 0; i < strlen(fontname); i++) { 152 if (isblank((int)fontname[i])) 153 fontname[i]='_'; 154 } 155 snprintf(filename, sizeof(filename), "%s.h", fontname); 156 if ((output = fopen(filename, "w")) == NULL) { 157 fprintf(stderr, "Can't open output file %s\n", filename); 158 return -1; 159 } 160 fprintf(output, "static u_char %s_data[];\n", fontname); 161 fprintf(output, "\n"); 162 fprintf(output, "static struct wsdisplay_font %s = {\n", fontname); 163 fprintf(output, "\t\"%s\",\t\t\t/* typeface name */\n", face->family_name); 164 fprintf(output, "\t32,\t\t\t\t/* firstchar */\n"); 165 fprintf(output, "\t256 - 32,\t\t\t/* numchar */\n"); 166 fprintf(output, "\tWSDISPLAY_FONTENC_ISO,\t\t/* encoding */\n"); 167 fprintf(output, "\t%d,\t\t\t\t/* width */\n", width); 168 fprintf(output, "\t%d,\t\t\t\t/* height */\n", cell_height); 169 fprintf(output, "\t%d,\t\t\t\t/* stride */\n", width); 170 fprintf(output, "\tWSDISPLAY_FONTORDER_L2R,\t/* bit order */\n"); 171 fprintf(output, "\tWSDISPLAY_FONTORDER_L2R,\t/* byte order */\n"); 172 fprintf(output, "\t%s_data\t\t/* data */\n", fontname); 173 fprintf(output, "};\n\n"); 174 fprintf(output, "static u_char %s_data[] = {\n", fontname); 175 for (i = 32; i < 256; i++) { 176 fprintf(output, "\t/* %d */\n", i); 177 idx = i * width * cell_height; 178 for (y = 0; y < cell_height; y++) { 179 for (x = 0; x < width; x++) { 180 fprintf(output, "0x%02x, ",fontdata[idx + x]); 181 } 182 fprintf(output, "/* "); 183 for (x = 0; x < width; x++) { 184 fprintf(output, "%c",cvr[fontdata[idx + x] >> 5]); 185 } 186 fprintf(output, " */\n"); 187 188 idx += width; 189 } 190 } 191 fprintf(output, "};\n"); 192 fclose(output); 193 /* dump as binary */ 194 snprintf(filename, sizeof(filename), "%s.wsf", fontname); 195 if ((out = open(filename, O_RDWR | O_CREAT | O_TRUNC, DEFFILEMODE)) > 0) { 196 char nbuf[64]; 197 uint32_t foo; 198 write(out, "WSFT", 4); 199 memset(nbuf, 0, sizeof(nbuf)); 200 strlcpy(nbuf, face->family_name, sizeof(nbuf)); 201 write(out, nbuf, sizeof(nbuf)); 202 /* firstchar */ 203 foo = htole32(32); 204 write(out, &foo, 4); 205 /* numchar */ 206 foo = htole32(256 - 32); 207 write(out, &foo, 4); 208 /* encoding */ 209 foo = htole32(WSDISPLAY_FONTENC_ISO); 210 write(out, &foo, 4); 211 /* fontwidth */ 212 foo = htole32(width); 213 write(out, &foo, 4); 214 /* fontheight */ 215 foo = htole32(cell_height); 216 write(out, &foo, 4); 217 /* stride */ 218 foo = htole32(width); 219 write(out, &foo, 4); 220 /* bitorder */ 221 foo = htole32(WSDISPLAY_FONTORDER_L2R); 222 write(out, &foo, 4); 223 /* byteorder */ 224 foo = htole32(WSDISPLAY_FONTORDER_L2R); 225 write(out, &foo, 4); 226 /* now the font data */ 227 write(out, fontdata + (32 * width * cell_height), 228 (256 - 32) * width * cell_height); 229 close(out); 230 } 231 free(fontdata); 232 FT_Done_Face(face); 233 FT_Done_FreeType(library); 234} 235