main.c revision 43b3da5d
1/* $NetBSD: main.c,v 1.4 2020/06/08 15:01:59 rin 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 printf("advance: %d\n", new_advance); 63 new_above = face->glyph->bitmap_top; 64 new_below = face->glyph->bitmap.rows - face->glyph->bitmap_top; 65 if (new_above > above) above = new_above; 66 if (new_below > below) below = new_below; 67 if (new_advance > advance) advance = new_advance; 68 return 0; 69} 70 71int 72main(int argc, char *argv[]) 73{ 74 int error, glyph_index; 75 int x, y, idx, width_in_bytes, height = 22, cell_height; 76 int width, datalen, didx, i, start, end, out; 77 FILE *output; 78 uint8_t *fontdata; 79 char fontname[128], filename[sizeof(fontname) + 4 /* .wsf */]; 80 81 if (argc != 3) { 82 printf("usage: ttf2wsfont some_font.ttf height\n"); 83 return 0; 84 } 85 86 sscanf(argv[2], "%d", &height); 87 88 error = FT_Init_FreeType( &library ); 89 if (error) { 90 printf("Failed to initialize freefont2\n"); 91 return -1; 92 } 93 error = FT_New_Face(library, argv[1], 0, &face ); 94 if ( error == FT_Err_Unknown_File_Format ) { 95 printf("unsupported font format\n"); 96 return -1; 97 } 98 error = FT_Set_Pixel_Sizes(face, /* handle to face object */ 99 0, /* pixel_width */ 100 height - (height / 10) ); /* pixel_height */ 101 if (error) { 102 printf("couldn't set character cell size\n"); 103 } 104 105 push_size('W'); 106 push_size('g'); 107 push_size(192); 108 printf("above: %d below: %d advance: %d\n", above, below, advance); 109 width = advance; 110 baseline = above; 111 cell_height = above + below; 112 datalen = 256 * width * cell_height; 113 fontdata = malloc(datalen); 114 115 116 for (i = 0; i < 256; i++) { 117 glyph_index = FT_Get_Char_Index(face, i); 118 FT_Load_Glyph(face, glyph_index, FT_LOAD_DEFAULT); 119 FT_Render_Glyph(face->glyph, FT_RENDER_MODE_NORMAL); 120 width_in_bytes = face->glyph->bitmap.width; 121 start = baseline - face->glyph->bitmap_top; 122 end = start + face->glyph->bitmap.rows; 123 if (end > cell_height) 124 end = cell_height; 125 idx = 0; 126 if (start < 0) { 127 idx += (0 - start) * width_in_bytes; 128 start = 0; 129 } 130 didx = i * width * cell_height + /* character cell */ 131 start * width + /* pixels above baseline */ 132 face->glyph->bitmap_left; /* pixels left from border */ 133 memset(&fontdata[i * width * cell_height], 0, width * cell_height); 134 for (y = start; y < end; y++) { 135 for (x = 0; x < width_in_bytes; x++) { 136 fontdata[didx + x] = face->glyph->bitmap.buffer[idx + x]; 137 } 138 idx += width_in_bytes; 139 didx += width; 140 } 141 } 142 143 /* now output as a header file */ 144 snprintf(fontname, sizeof(fontname), "%s_%dx%d", face->family_name, 145 width, cell_height); 146 for (i = 0; i < strlen(fontname); i++) { 147 if (isblank((int)fontname[i])) 148 fontname[i]='_'; 149 } 150 snprintf(filename, sizeof(filename), "%s.h", fontname); 151 if ((output = fopen(filename, "w")) == NULL) { 152 fprintf(stderr, "Can't open output file %s\n", filename); 153 return -1; 154 } 155 fprintf(output, "static u_char %s_data[];\n", fontname); 156 fprintf(output, "\n"); 157 fprintf(output, "static struct wsdisplay_font %s = {\n", fontname); 158 fprintf(output, "\t\"%s\",\t\t\t/* typeface name */\n", face->family_name); 159 fprintf(output, "\t32,\t\t\t\t/* firstchar */\n"); 160 fprintf(output, "\t256 - 32,\t\t\t/* numchar */\n"); 161 fprintf(output, "\tWSDISPLAY_FONTENC_ISO,\t\t/* encoding */\n"); 162 fprintf(output, "\t%d,\t\t\t\t/* width */\n", width); 163 fprintf(output, "\t%d,\t\t\t\t/* height */\n", cell_height); 164 fprintf(output, "\t%d,\t\t\t\t/* stride */\n", width); 165 fprintf(output, "\tWSDISPLAY_FONTORDER_L2R,\t/* bit order */\n"); 166 fprintf(output, "\tWSDISPLAY_FONTORDER_L2R,\t/* byte order */\n"); 167 fprintf(output, "\t%s_data\t\t/* data */\n", fontname); 168 fprintf(output, "};\n\n"); 169 fprintf(output, "static u_char %s_data[] = {\n", fontname); 170 for (i = 32; i < 256; i++) { 171 fprintf(output, "\t/* %d */\n", i); 172 idx = i * width * cell_height; 173 for (y = 0; y < cell_height; y++) { 174 for (x = 0; x < width; x++) { 175 fprintf(output, "0x%02x, ",fontdata[idx + x]); 176 } 177 fprintf(output, "/* "); 178 for (x = 0; x < width; x++) { 179 fprintf(output, "%c",cvr[fontdata[idx + x] >> 5]); 180 } 181 fprintf(output, " */\n"); 182 183 idx += width; 184 } 185 } 186 fprintf(output, "};\n"); 187 fclose(output); 188 /* dump as binary */ 189 snprintf(filename, sizeof(filename), "%s.wsf", fontname); 190 if ((out = open(filename, O_RDWR | O_CREAT | O_TRUNC, DEFFILEMODE)) > 0) { 191 char nbuf[64]; 192 uint32_t foo; 193 write(out, "WSFT", 4); 194 memset(nbuf, 0, sizeof(nbuf)); 195 strlcpy(nbuf, face->family_name, sizeof(nbuf)); 196 write(out, nbuf, sizeof(nbuf)); 197 /* firstchar */ 198 foo = htole32(32); 199 write(out, &foo, 4); 200 /* numchar */ 201 foo = htole32(256 - 32); 202 write(out, &foo, 4); 203 /* encoding */ 204 foo = htole32(WSDISPLAY_FONTENC_ISO); 205 write(out, &foo, 4); 206 /* fontwidth */ 207 foo = htole32(width); 208 write(out, &foo, 4); 209 /* fontheight */ 210 foo = htole32(cell_height); 211 write(out, &foo, 4); 212 /* stride */ 213 foo = htole32(width); 214 write(out, &foo, 4); 215 /* bitorder */ 216 foo = htole32(WSDISPLAY_FONTORDER_L2R); 217 write(out, &foo, 4); 218 /* byteorder */ 219 foo = htole32(WSDISPLAY_FONTORDER_L2R); 220 write(out, &foo, 4); 221 /* now the font data */ 222 write(out, fontdata + (32 * width * cell_height), 223 (256 - 32) * width * cell_height); 224 close(out); 225 } 226 free(fontdata); 227 FT_Done_Face(face); 228 FT_Done_FreeType(library); 229} 230