tools: add ttf_bitmap2
This commit is contained in:
parent
67823b3d00
commit
0206a5139a
1
.gitignore
vendored
1
.gitignore
vendored
@ -14,6 +14,7 @@ scramble
|
||||
cdi4dc
|
||||
tools/ttf_outline
|
||||
tools/ttf_bitmap
|
||||
tools/ttf_bitmap2
|
||||
tools/ftdi_transfer
|
||||
k_means_vq
|
||||
*.blend1
|
||||
|
BIN
font/tandy1k/BmPlus_Tandy1K-II_225L.otb
Normal file
BIN
font/tandy1k/BmPlus_Tandy1K-II_225L.otb
Normal file
Binary file not shown.
BIN
font/tandy1k/tandy1k.data
Normal file
BIN
font/tandy1k/tandy1k.data
Normal file
Binary file not shown.
@ -1,8 +1,7 @@
|
||||
CFLAGS = -Og -g -gdwarf-4 -Wall -Wextra -Wno-error
|
||||
CFLAGS = -Og -g -gdwarf-4 -Wall -Wextra -Wno-error -Wfatal-errors
|
||||
CFLAGS += -Wno-error=unused-parameter
|
||||
CFLAGS += -Wno-error=unused-variable
|
||||
CFLAGS += -Wno-error=unused-but-set-variable
|
||||
CFLAGS += -Wno-vla-extension
|
||||
CXXFLAGS = -std=c++23
|
||||
|
||||
PREFIX ?= /usr/local
|
||||
|
140
tools/ttf_bitmap2.cpp
Normal file
140
tools/ttf_bitmap2.cpp
Normal file
@ -0,0 +1,140 @@
|
||||
#include <assert.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include <ft2build.h>
|
||||
#include FT_FREETYPE_H
|
||||
|
||||
#include "../twiddle.hpp"
|
||||
|
||||
int
|
||||
load_bitmap_char(FT_Face face,
|
||||
FT_ULong char_code,
|
||||
int buf_stride,
|
||||
uint8_t * buf)
|
||||
{
|
||||
FT_Error error;
|
||||
FT_UInt glyph_index = FT_Get_Char_Index(face, char_code);
|
||||
|
||||
error = FT_Load_Glyph(face, glyph_index, FT_LOAD_DEFAULT);
|
||||
if (error) {
|
||||
fprintf(stderr, "FT_Load_Glyph %s\n", FT_Error_String(error));
|
||||
return -1;
|
||||
}
|
||||
|
||||
assert(face->glyph->format == FT_GLYPH_FORMAT_BITMAP);
|
||||
assert(face->glyph->bitmap.num_grays == 2);
|
||||
|
||||
for (int y = 0; y < (int)face->glyph->bitmap.rows; y++) {
|
||||
uint8_t * row = &face->glyph->bitmap.buffer[y * face->glyph->bitmap.pitch];
|
||||
for (int x = 0; x < (int)face->glyph->bitmap.width; x += 1) {
|
||||
const int bit = (row[x / 8] >> (7 - (x % 8))) & 1;
|
||||
//std::cerr << (bit ? "█" : " ");
|
||||
buf[y * buf_stride + x] = bit;
|
||||
}
|
||||
//std::cerr << "|\n";
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int load_font(FT_Library * library, FT_Face * face, const char * font_file_path)
|
||||
{
|
||||
FT_Error error;
|
||||
|
||||
error = FT_Init_FreeType(library);
|
||||
if (error) {
|
||||
fprintf(stderr, "FT_Init_FreeType\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
error = FT_New_Face(*library, font_file_path, 0, face);
|
||||
if (error) {
|
||||
fprintf(stderr, "FT_New_Face\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
error = FT_Select_Size(*face, 0);
|
||||
if (error) {
|
||||
fprintf(stderr, "FT_Select_Size: %d: %s\n", error, FT_Error_String(error));
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void usage(const char * argv_0)
|
||||
{
|
||||
printf("%s [start-hex] [end-hex] [texture-width] [texture-height] [font-file-path] [output-file-path]\n", argv_0);
|
||||
}
|
||||
|
||||
int main(int argc, const char * argv[])
|
||||
{
|
||||
if (argc != 7) {
|
||||
usage(argv[0]);
|
||||
return -1;
|
||||
}
|
||||
|
||||
char * endptr;
|
||||
|
||||
int start_hex = strtol(argv[1], &endptr, 16);
|
||||
assert(*endptr == 0);
|
||||
int end_hex = strtol(argv[2], &endptr, 16);
|
||||
assert(*endptr == 0);
|
||||
|
||||
int texture_width = strtol(argv[3], &endptr, 10);
|
||||
assert(*endptr == 0);
|
||||
int texture_height = strtol(argv[4], &endptr, 10);
|
||||
assert(*endptr == 0);
|
||||
|
||||
const char * font_file_path = argv[5];
|
||||
const char * output_file_path = argv[6];
|
||||
|
||||
printf("start_hex %x\n", start_hex);
|
||||
printf("end_hex %x\n", start_hex);
|
||||
printf("texture_width %d\n", texture_width);
|
||||
printf("texture_height %d\n", texture_height);
|
||||
printf("font_file_path %s\n", font_file_path);
|
||||
printf("output_file_path %s\n", output_file_path);
|
||||
|
||||
FT_Library library;
|
||||
FT_Face face;
|
||||
int res;
|
||||
res = load_font(&library, &face, font_file_path);
|
||||
if (res < 0)
|
||||
return -1;
|
||||
|
||||
int width = face->size->metrics.max_advance >> 6;
|
||||
int height = face->size->metrics.height >> 6;
|
||||
|
||||
int texture_buf_size = texture_width * texture_height;
|
||||
uint8_t * texture = (uint8_t *)malloc(texture_buf_size);
|
||||
|
||||
int x = 0;
|
||||
int y = 0;
|
||||
|
||||
for (int char_code = start_hex; char_code <= end_hex; char_code++) {
|
||||
res = load_bitmap_char(face,
|
||||
char_code,
|
||||
texture_width,
|
||||
&texture[y * texture_width + x]);
|
||||
x += width;
|
||||
if (x + width > texture_width) {
|
||||
y += height;
|
||||
x = 0;
|
||||
assert(y + height <= texture_height);
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t * twiddle = (uint8_t *)malloc(texture_buf_size / 2);
|
||||
twiddle::texture_4bpp(twiddle, texture, texture_width, texture_height);
|
||||
|
||||
FILE * out = fopen(output_file_path, "w");
|
||||
if (out == NULL) {
|
||||
perror("fopen(w)");
|
||||
return -1;
|
||||
}
|
||||
//fwrite((void *)texture, texture_buf_size, 1, out);
|
||||
fwrite((void *)twiddle, texture_buf_size / 2, 1, out);
|
||||
fclose(out);
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user