Added ttf converter script, and started converting renderer to use the ttf atlas(only 1d for now)

main
noah metz 2024-10-14 13:33:14 -06:00
parent a06fbe8b1c
commit 683c071878
7 changed files with 7667 additions and 26 deletions

@ -1,12 +1,12 @@
ROOT_DIR:=$(shell dirname $(realpath $(firstword $(MAKEFILE_LIST))))
CFLAGS = -I $(ROOT_DIR)/include -I/usr/local/include -O0 -g -Wall -Wextra
LDFLAGS = -L/opt/homebrew/opt/llvm/lib -L/opt/homebrew/opt/llvm/lib/c++ -L/opt/homebrew/lib -lglfw -lvulkan -ldl -Xlinker -rpath -Xlinker /opt/homebrew/lib
LDFLAGS = -L/opt/homebrew/opt/llvm/lib -L/opt/homebrew/opt/llvm/lib/c++ -L/opt/homebrew/lib -lz -lglfw -lvulkan -ldl -Xlinker -rpath -Xlinker /opt/homebrew/lib
CC = /opt/homebrew/opt/llvm/bin/clang
CPP = /opt/homebrew/opt/llvm/bin/clang++
DSYM = /opt/homebrew/opt/llvm/bin/dsymutil
GDB = /opt/homebrew/opt/llvm/bin/lldb
SOURCES = src/main.c src/render.c src/vma.cpp src/pipeline.c src/command.c
SOURCES = src/main.c src/render.c src/vma.cpp src/pipeline.c src/command.c src/spng.c
OBJECTS = $(addsuffix .o, $(basename $(SOURCES)))
VERT_SPV = $(addsuffix .vert.spv, $(basename $(wildcard shader_src/*.vert)))
FRAG_SPV = $(addsuffix .frag.spv, $(basename $(wildcard shader_src/*.frag)))

@ -29,14 +29,21 @@ typedef struct CharStruct {
} Char;
typedef struct FontUniformStruct {
vec2 size;
uint32_t cols;
uint32_t rows;
uint32_t start;
uint32_t num_symbols;
uint32_t width;
uint32_t height;
} FontUniform;
typedef struct SymbolInfoStruct {
uint32_t x;
uint32_t top;
uint32_t width;
} SymbolInfo;
typedef struct FontDataStruct {
FontUniform info;
SymbolInfo* symbols;
uint32_t* codes;
uint32_t* data;
} FontData;

@ -0,0 +1,538 @@
/* SPDX-License-Identifier: BSD-2-Clause */
#ifndef SPNG_H
#define SPNG_H
#ifdef __cplusplus
extern "C" {
#endif
#if (defined(_WIN32) || defined(__CYGWIN__)) && !defined(SPNG_STATIC)
#if defined(SPNG__BUILD)
#define SPNG_API __declspec(dllexport)
#else
#define SPNG_API __declspec(dllimport)
#endif
#else
#define SPNG_API
#endif
#if defined(_MSC_VER)
#define SPNG_CDECL __cdecl
#else
#define SPNG_CDECL
#endif
#include <stdlib.h>
#include <stdint.h>
#include <stdio.h>
#define SPNG_VERSION_MAJOR 0
#define SPNG_VERSION_MINOR 7
#define SPNG_VERSION_PATCH 4
enum spng_errno
{
SPNG_IO_ERROR = -2,
SPNG_IO_EOF = -1,
SPNG_OK = 0,
SPNG_EINVAL,
SPNG_EMEM,
SPNG_EOVERFLOW,
SPNG_ESIGNATURE,
SPNG_EWIDTH,
SPNG_EHEIGHT,
SPNG_EUSER_WIDTH,
SPNG_EUSER_HEIGHT,
SPNG_EBIT_DEPTH,
SPNG_ECOLOR_TYPE,
SPNG_ECOMPRESSION_METHOD,
SPNG_EFILTER_METHOD,
SPNG_EINTERLACE_METHOD,
SPNG_EIHDR_SIZE,
SPNG_ENOIHDR,
SPNG_ECHUNK_POS,
SPNG_ECHUNK_SIZE,
SPNG_ECHUNK_CRC,
SPNG_ECHUNK_TYPE,
SPNG_ECHUNK_UNKNOWN_CRITICAL,
SPNG_EDUP_PLTE,
SPNG_EDUP_CHRM,
SPNG_EDUP_GAMA,
SPNG_EDUP_ICCP,
SPNG_EDUP_SBIT,
SPNG_EDUP_SRGB,
SPNG_EDUP_BKGD,
SPNG_EDUP_HIST,
SPNG_EDUP_TRNS,
SPNG_EDUP_PHYS,
SPNG_EDUP_TIME,
SPNG_EDUP_OFFS,
SPNG_EDUP_EXIF,
SPNG_ECHRM,
SPNG_EPLTE_IDX,
SPNG_ETRNS_COLOR_TYPE,
SPNG_ETRNS_NO_PLTE,
SPNG_EGAMA,
SPNG_EICCP_NAME,
SPNG_EICCP_COMPRESSION_METHOD,
SPNG_ESBIT,
SPNG_ESRGB,
SPNG_ETEXT,
SPNG_ETEXT_KEYWORD,
SPNG_EZTXT,
SPNG_EZTXT_COMPRESSION_METHOD,
SPNG_EITXT,
SPNG_EITXT_COMPRESSION_FLAG,
SPNG_EITXT_COMPRESSION_METHOD,
SPNG_EITXT_LANG_TAG,
SPNG_EITXT_TRANSLATED_KEY,
SPNG_EBKGD_NO_PLTE,
SPNG_EBKGD_PLTE_IDX,
SPNG_EHIST_NO_PLTE,
SPNG_EPHYS,
SPNG_ESPLT_NAME,
SPNG_ESPLT_DUP_NAME,
SPNG_ESPLT_DEPTH,
SPNG_ETIME,
SPNG_EOFFS,
SPNG_EEXIF,
SPNG_EIDAT_TOO_SHORT,
SPNG_EIDAT_STREAM,
SPNG_EZLIB,
SPNG_EFILTER,
SPNG_EBUFSIZ,
SPNG_EIO,
SPNG_EOF,
SPNG_EBUF_SET,
SPNG_EBADSTATE,
SPNG_EFMT,
SPNG_EFLAGS,
SPNG_ECHUNKAVAIL,
SPNG_ENCODE_ONLY,
SPNG_EOI,
SPNG_ENOPLTE,
SPNG_ECHUNK_LIMITS,
SPNG_EZLIB_INIT,
SPNG_ECHUNK_STDLEN,
SPNG_EINTERNAL,
SPNG_ECTXTYPE,
SPNG_ENOSRC,
SPNG_ENODST,
SPNG_EOPSTATE,
SPNG_ENOTFINAL,
};
enum spng_text_type
{
SPNG_TEXT = 1,
SPNG_ZTXT = 2,
SPNG_ITXT = 3
};
enum spng_color_type
{
SPNG_COLOR_TYPE_GRAYSCALE = 0,
SPNG_COLOR_TYPE_TRUECOLOR = 2,
SPNG_COLOR_TYPE_INDEXED = 3,
SPNG_COLOR_TYPE_GRAYSCALE_ALPHA = 4,
SPNG_COLOR_TYPE_TRUECOLOR_ALPHA = 6
};
enum spng_filter
{
SPNG_FILTER_NONE = 0,
SPNG_FILTER_SUB = 1,
SPNG_FILTER_UP = 2,
SPNG_FILTER_AVERAGE = 3,
SPNG_FILTER_PAETH = 4
};
enum spng_filter_choice
{
SPNG_DISABLE_FILTERING = 0,
SPNG_FILTER_CHOICE_NONE = 8,
SPNG_FILTER_CHOICE_SUB = 16,
SPNG_FILTER_CHOICE_UP = 32,
SPNG_FILTER_CHOICE_AVG = 64,
SPNG_FILTER_CHOICE_PAETH = 128,
SPNG_FILTER_CHOICE_ALL = (8|16|32|64|128)
};
enum spng_interlace_method
{
SPNG_INTERLACE_NONE = 0,
SPNG_INTERLACE_ADAM7 = 1
};
/* Channels are always in byte-order */
enum spng_format
{
SPNG_FMT_RGBA8 = 1,
SPNG_FMT_RGBA16 = 2,
SPNG_FMT_RGB8 = 4,
/* Partially implemented, see documentation */
SPNG_FMT_GA8 = 16,
SPNG_FMT_GA16 = 32,
SPNG_FMT_G8 = 64,
/* No conversion or scaling */
SPNG_FMT_PNG = 256,
SPNG_FMT_RAW = 512 /* big-endian (everything else is host-endian) */
};
enum spng_ctx_flags
{
SPNG_CTX_IGNORE_ADLER32 = 1, /* Ignore checksum in DEFLATE streams */
SPNG_CTX_ENCODER = 2 /* Create an encoder context */
};
enum spng_decode_flags
{
SPNG_DECODE_USE_TRNS = 1, /* Deprecated */
SPNG_DECODE_USE_GAMA = 2, /* Deprecated */
SPNG_DECODE_USE_SBIT = 8, /* Undocumented */
SPNG_DECODE_TRNS = 1, /* Apply transparency */
SPNG_DECODE_GAMMA = 2, /* Apply gamma correction */
SPNG_DECODE_PROGRESSIVE = 256 /* Initialize for progressive reads */
};
enum spng_crc_action
{
/* Default for critical chunks */
SPNG_CRC_ERROR = 0,
/* Discard chunk, invalid for critical chunks.
Since v0.6.2: default for ancillary chunks */
SPNG_CRC_DISCARD = 1,
/* Ignore and don't calculate checksum.
Since v0.6.2: also ignores checksums in DEFLATE streams */
SPNG_CRC_USE = 2
};
enum spng_encode_flags
{
SPNG_ENCODE_PROGRESSIVE = 1, /* Initialize for progressive writes */
SPNG_ENCODE_FINALIZE = 2, /* Finalize PNG after encoding image */
};
struct spng_ihdr
{
uint32_t width;
uint32_t height;
uint8_t bit_depth;
uint8_t color_type;
uint8_t compression_method;
uint8_t filter_method;
uint8_t interlace_method;
};
struct spng_plte_entry
{
uint8_t red;
uint8_t green;
uint8_t blue;
uint8_t alpha; /* Reserved for internal use */
};
struct spng_plte
{
uint32_t n_entries;
struct spng_plte_entry entries[256];
};
struct spng_trns
{
uint16_t gray;
uint16_t red;
uint16_t green;
uint16_t blue;
uint32_t n_type3_entries;
uint8_t type3_alpha[256];
};
struct spng_chrm_int
{
uint32_t white_point_x;
uint32_t white_point_y;
uint32_t red_x;
uint32_t red_y;
uint32_t green_x;
uint32_t green_y;
uint32_t blue_x;
uint32_t blue_y;
};
struct spng_chrm
{
double white_point_x;
double white_point_y;
double red_x;
double red_y;
double green_x;
double green_y;
double blue_x;
double blue_y;
};
struct spng_iccp
{
char profile_name[80];
size_t profile_len;
char *profile;
};
struct spng_sbit
{
uint8_t grayscale_bits;
uint8_t red_bits;
uint8_t green_bits;
uint8_t blue_bits;
uint8_t alpha_bits;
};
struct spng_text
{
char keyword[80];
int type;
size_t length;
char *text;
uint8_t compression_flag; /* iTXt only */
uint8_t compression_method; /* iTXt, ztXt only */
char *language_tag; /* iTXt only */
char *translated_keyword; /* iTXt only */
};
struct spng_bkgd
{
uint16_t gray; /* Only for gray/gray alpha */
uint16_t red;
uint16_t green;
uint16_t blue;
uint16_t plte_index; /* Only for indexed color */
};
struct spng_hist
{
uint16_t frequency[256];
};
struct spng_phys
{
uint32_t ppu_x, ppu_y;
uint8_t unit_specifier;
};
struct spng_splt_entry
{
uint16_t red;
uint16_t green;
uint16_t blue;
uint16_t alpha;
uint16_t frequency;
};
struct spng_splt
{
char name[80];
uint8_t sample_depth;
uint32_t n_entries;
struct spng_splt_entry *entries;
};
struct spng_time
{
uint16_t year;
uint8_t month;
uint8_t day;
uint8_t hour;
uint8_t minute;
uint8_t second;
};
struct spng_offs
{
int32_t x, y;
uint8_t unit_specifier;
};
struct spng_exif
{
size_t length;
char *data;
};
struct spng_chunk
{
size_t offset;
uint32_t length;
uint8_t type[4];
uint32_t crc;
};
enum spng_location
{
SPNG_AFTER_IHDR = 1,
SPNG_AFTER_PLTE = 2,
SPNG_AFTER_IDAT = 8,
};
struct spng_unknown_chunk
{
uint8_t type[4];
size_t length;
void *data;
enum spng_location location;
};
enum spng_option
{
SPNG_KEEP_UNKNOWN_CHUNKS = 1,
SPNG_IMG_COMPRESSION_LEVEL,
SPNG_IMG_WINDOW_BITS,
SPNG_IMG_MEM_LEVEL,
SPNG_IMG_COMPRESSION_STRATEGY,
SPNG_TEXT_COMPRESSION_LEVEL,
SPNG_TEXT_WINDOW_BITS,
SPNG_TEXT_MEM_LEVEL,
SPNG_TEXT_COMPRESSION_STRATEGY,
SPNG_FILTER_CHOICE,
SPNG_CHUNK_COUNT_LIMIT,
SPNG_ENCODE_TO_BUFFER,
};
typedef void* SPNG_CDECL spng_malloc_fn(size_t size);
typedef void* SPNG_CDECL spng_realloc_fn(void* ptr, size_t size);
typedef void* SPNG_CDECL spng_calloc_fn(size_t count, size_t size);
typedef void SPNG_CDECL spng_free_fn(void* ptr);
struct spng_alloc
{
spng_malloc_fn *malloc_fn;
spng_realloc_fn *realloc_fn;
spng_calloc_fn *calloc_fn;
spng_free_fn *free_fn;
};
struct spng_row_info
{
uint32_t scanline_idx;
uint32_t row_num; /* deinterlaced row index */
int pass;
uint8_t filter;
};
typedef struct spng_ctx spng_ctx;
typedef int spng_read_fn(spng_ctx *ctx, void *user, void *dest, size_t length);
typedef int spng_write_fn(spng_ctx *ctx, void *user, void *src, size_t length);
typedef int spng_rw_fn(spng_ctx *ctx, void *user, void *dst_src, size_t length);
SPNG_API spng_ctx *spng_ctx_new(int flags);
SPNG_API spng_ctx *spng_ctx_new2(struct spng_alloc *alloc, int flags);
SPNG_API void spng_ctx_free(spng_ctx *ctx);
SPNG_API int spng_set_png_buffer(spng_ctx *ctx, const void *buf, size_t size);
SPNG_API int spng_set_png_stream(spng_ctx *ctx, spng_rw_fn *rw_func, void *user);
SPNG_API int spng_set_png_file(spng_ctx *ctx, FILE *file);
SPNG_API void *spng_get_png_buffer(spng_ctx *ctx, size_t *len, int *error);
SPNG_API int spng_set_image_limits(spng_ctx *ctx, uint32_t width, uint32_t height);
SPNG_API int spng_get_image_limits(spng_ctx *ctx, uint32_t *width, uint32_t *height);
SPNG_API int spng_set_chunk_limits(spng_ctx *ctx, size_t chunk_size, size_t cache_size);
SPNG_API int spng_get_chunk_limits(spng_ctx *ctx, size_t *chunk_size, size_t *cache_size);
SPNG_API int spng_set_crc_action(spng_ctx *ctx, int critical, int ancillary);
SPNG_API int spng_set_option(spng_ctx *ctx, enum spng_option option, int value);
SPNG_API int spng_get_option(spng_ctx *ctx, enum spng_option option, int *value);
SPNG_API int spng_decoded_image_size(spng_ctx *ctx, int fmt, size_t *len);
/* Decode */
SPNG_API int spng_decode_image(spng_ctx *ctx, void *out, size_t len, int fmt, int flags);
/* Progressive decode */
SPNG_API int spng_decode_scanline(spng_ctx *ctx, void *out, size_t len);
SPNG_API int spng_decode_row(spng_ctx *ctx, void *out, size_t len);
SPNG_API int spng_decode_chunks(spng_ctx *ctx);
/* Encode/decode */
SPNG_API int spng_get_row_info(spng_ctx *ctx, struct spng_row_info *row_info);
/* Encode */
SPNG_API int spng_encode_image(spng_ctx *ctx, const void *img, size_t len, int fmt, int flags);
/* Progressive encode */
SPNG_API int spng_encode_scanline(spng_ctx *ctx, const void *scanline, size_t len);
SPNG_API int spng_encode_row(spng_ctx *ctx, const void *row, size_t len);
SPNG_API int spng_encode_chunks(spng_ctx *ctx);
SPNG_API int spng_get_ihdr(spng_ctx *ctx, struct spng_ihdr *ihdr);
SPNG_API int spng_get_plte(spng_ctx *ctx, struct spng_plte *plte);
SPNG_API int spng_get_trns(spng_ctx *ctx, struct spng_trns *trns);
SPNG_API int spng_get_chrm(spng_ctx *ctx, struct spng_chrm *chrm);
SPNG_API int spng_get_chrm_int(spng_ctx *ctx, struct spng_chrm_int *chrm_int);
SPNG_API int spng_get_gama(spng_ctx *ctx, double *gamma);
SPNG_API int spng_get_gama_int(spng_ctx *ctx, uint32_t *gama_int);
SPNG_API int spng_get_iccp(spng_ctx *ctx, struct spng_iccp *iccp);
SPNG_API int spng_get_sbit(spng_ctx *ctx, struct spng_sbit *sbit);
SPNG_API int spng_get_srgb(spng_ctx *ctx, uint8_t *rendering_intent);
SPNG_API int spng_get_text(spng_ctx *ctx, struct spng_text *text, uint32_t *n_text);
SPNG_API int spng_get_bkgd(spng_ctx *ctx, struct spng_bkgd *bkgd);
SPNG_API int spng_get_hist(spng_ctx *ctx, struct spng_hist *hist);
SPNG_API int spng_get_phys(spng_ctx *ctx, struct spng_phys *phys);
SPNG_API int spng_get_splt(spng_ctx *ctx, struct spng_splt *splt, uint32_t *n_splt);
SPNG_API int spng_get_time(spng_ctx *ctx, struct spng_time *time);
SPNG_API int spng_get_unknown_chunks(spng_ctx *ctx, struct spng_unknown_chunk *chunks, uint32_t *n_chunks);
/* Official extensions */
SPNG_API int spng_get_offs(spng_ctx *ctx, struct spng_offs *offs);
SPNG_API int spng_get_exif(spng_ctx *ctx, struct spng_exif *exif);
SPNG_API int spng_set_ihdr(spng_ctx *ctx, struct spng_ihdr *ihdr);
SPNG_API int spng_set_plte(spng_ctx *ctx, struct spng_plte *plte);
SPNG_API int spng_set_trns(spng_ctx *ctx, struct spng_trns *trns);
SPNG_API int spng_set_chrm(spng_ctx *ctx, struct spng_chrm *chrm);
SPNG_API int spng_set_chrm_int(spng_ctx *ctx, struct spng_chrm_int *chrm_int);
SPNG_API int spng_set_gama(spng_ctx *ctx, double gamma);
SPNG_API int spng_set_gama_int(spng_ctx *ctx, uint32_t gamma);
SPNG_API int spng_set_iccp(spng_ctx *ctx, struct spng_iccp *iccp);
SPNG_API int spng_set_sbit(spng_ctx *ctx, struct spng_sbit *sbit);
SPNG_API int spng_set_srgb(spng_ctx *ctx, uint8_t rendering_intent);
SPNG_API int spng_set_text(spng_ctx *ctx, struct spng_text *text, uint32_t n_text);
SPNG_API int spng_set_bkgd(spng_ctx *ctx, struct spng_bkgd *bkgd);
SPNG_API int spng_set_hist(spng_ctx *ctx, struct spng_hist *hist);
SPNG_API int spng_set_phys(spng_ctx *ctx, struct spng_phys *phys);
SPNG_API int spng_set_splt(spng_ctx *ctx, struct spng_splt *splt, uint32_t n_splt);
SPNG_API int spng_set_time(spng_ctx *ctx, struct spng_time *time);
SPNG_API int spng_set_unknown_chunks(spng_ctx *ctx, struct spng_unknown_chunk *chunks, uint32_t n_chunks);
/* Official extensions */
SPNG_API int spng_set_offs(spng_ctx *ctx, struct spng_offs *offs);
SPNG_API int spng_set_exif(spng_ctx *ctx, struct spng_exif *exif);
SPNG_API const char *spng_strerror(int err);
SPNG_API const char *spng_version_string(void);
#ifdef __cplusplus
}
#endif
#endif /* SPNG_H */

@ -2,6 +2,8 @@
#include "pipeline.h"
#include "vk_mem_alloc.h"
#include "vulkan/vk_enum_string_helper.h"
#include "vulkan/vulkan_core.h"
#include "spng.h"
ColoredRect colored_rect(float width, float height, float r, float g, float b, float a, float x, float y, float z) {
ColoredRect rect = {
@ -12,12 +14,62 @@ ColoredRect colored_rect(float width, float height, float r, float g, float b, f
return rect;
}
const uint32_t WHITE = 0xFFFFFFFF;
const uint32_t CLEAR = 0x00000000;
uint32_t test_font_data[] = {
WHITE, WHITE, CLEAR, WHITE,
CLEAR, CLEAR, WHITE, CLEAR,
};
VkResult load_font(const char* atlas_file, const char* metadata_file, FontData* font) {
FILE* atlas = fopen(atlas_file, "rb");
if(atlas == NULL) {
return VK_ERROR_UNKNOWN;
}
fseek(atlas, 0L, SEEK_END);
size_t buf_size = ftell(atlas);
void* buf = malloc(buf_size);
fseek(atlas, 0L, SEEK_SET);
size_t read = fread(buf, buf_size, 1, atlas);
if(read != 1) {
return VK_ERROR_UNKNOWN;
}
fclose(atlas);
size_t out_size = 0;
spng_ctx *ctx = spng_ctx_new(0);
int result = 0;
result = spng_set_png_buffer(ctx, buf, buf_size);
if(result != SPNG_OK) {
return VK_ERROR_UNKNOWN;
}
result = spng_decoded_image_size(ctx, SPNG_FMT_RGBA8, &out_size);
if(result != SPNG_OK) {
return VK_ERROR_UNKNOWN;
}
font->data = malloc(out_size);
result = spng_decode_image(ctx, font->data, out_size, SPNG_FMT_RGBA8, 0);
if(result != SPNG_OK) {
return VK_ERROR_UNKNOWN;
}
struct spng_ihdr ihdr;
result = spng_get_ihdr(ctx, &ihdr);
if(result != SPNG_OK) {
return VK_ERROR_UNKNOWN;
}
font->info.height = ihdr.height;
font->info.width = ihdr.width;
spng_ctx_free(ctx);
free(buf);
FILE* metadata = fopen(metadata_file, "rb");
if(atlas == NULL) {
return VK_ERROR_UNKNOWN;
}
fclose(metadata);
return VK_SUCCESS;
}
VkResult render_thread(GLFWwindow* window, RenderContext* render_context) {
VkResult result;
@ -32,15 +84,11 @@ VkResult render_thread(GLFWwindow* window, RenderContext* render_context) {
return result;
}
FontData test_font = {
.info = {
.size = {2, 2},
.start = 0,
.cols = 2,
.rows = 1,
},
.data = test_font_data,
};
FontData test_font = {};
result = load_font("tools/test.png", "tools/test.meta", &test_font);
if(result != VK_SUCCESS) {
return result;
}
FontDescriptor test_font_descriptor;
result = create_text_descriptor(render_context->device, render_context->allocator, ui_context.font_layout, ui_context.font_pool, &test_font, render_context->transfer_pool, render_context->transfer_queue, &test_font_descriptor);

@ -296,8 +296,8 @@ VkResult create_ui_text_pipeline(VkDevice device, VkRenderPass render_pass, VkDe
}
// TODO: add a compute stage before the shader stages that sets up the draw buffer and commands for the characters based off of strings + positions
// 1. Reserve a buffer for array of draw command params + CharStruct on the GPU
// 2. Reserve a buffer for StringStruct
// 1. Reserve a buffer for array of draw command params + Char on the GPU
// 2. Reserve a buffer for Text on the GPU
VkPipelineShaderStageCreateInfo shader_stages[] = {
{
.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
@ -473,8 +473,8 @@ VkResult create_text_descriptor(VkDevice device, VmaAllocator allocator, VkDescr
.sharingMode = VK_SHARING_MODE_EXCLUSIVE,
.usage = VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT,
.extent.depth = 1,
.extent.width = font->info.size[0]*font->info.cols,
.extent.height = font->info.size[1]*font->info.rows,
.extent.width = font->info.width,
.extent.height = font->info.width,
.mipLevels = 1,
.arrayLayers = 1,
.format = VK_FORMAT_R8G8B8A8_SRGB,
@ -492,7 +492,7 @@ VkResult create_text_descriptor(VkDevice device, VmaAllocator allocator, VkDescr
return result;
}
uint32_t image_size = sizeof(uint32_t)*font->info.rows*font->info.size[0]*font->info.cols*font->info.size[1];
uint32_t image_size = sizeof(uint32_t)*font->info.width*font->info.height;
VkBufferCreateInfo staging_info = {
.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT,

File diff suppressed because it is too large Load Diff

@ -0,0 +1,67 @@
#!/usr/bin/env python3
from fontTools.ttLib import TTFont
from fontTools.unicode import Unicode
from PIL import ImageDraw, Image, ImageFont
from os import mkdir
from argparse import ArgumentParser
from struct import pack
parser = ArgumentParser()
parser.add_argument("ttf_file")
parser.add_argument("atlas")
parser.add_argument("metadata")
args = parser.parse_args()
# Add control characters, keep 0x00 for "unknown"
blacklist = set([
0x08,
0x09,
0x0D,
0x1D,
0x20,
])
# Add other control characters
blacklist.update(set(range(0x80, 0xA0)))
ttfont = TTFont(args.ttf_file)
keycodes = set()
for table in ttfont['cmap'].tables:
for keycode in table.cmap.keys():
keycodes.add(keycode)
keycodes = keycodes.difference(blacklist)
font = ImageFont.truetype(args.ttf_file, size=16)
(ascent, descent) = font.getmetrics()
widths = dict()
tops = dict()
for keycode in keycodes:
(left, top, right, bottom) = font.getbbox(chr(keycode))
widths[keycode] = right-left
tops[keycode] = top
height = ascent - descent
image = Image.new(mode="RGBA", size=(sum(widths.values()), height))
draw = ImageDraw.Draw(image)
x = 0
keycode_list = list(keycodes)
keycode_list.sort()
for keycode in keycode_list:
draw.text((x, -tops[keycode]), chr(keycode), font=font)
x += widths[keycode]
image.save(args.atlas)
metadata = bytearray(pack("!HBB", len(keycode_list), ascent, descent))
idx = 0
x = 0
for keycode in keycode_list:
metadata += pack("!HIBB", keycode, x, widths[keycode], tops[keycode])
x += widths[keycode]
with open(args.metadata, "wb") as metadata_file:
metadata_file.write(metadata)