Skip to content

Instantly share code, notes, and snippets.

@aolo2
Created July 25, 2020 21:18
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save aolo2/f57ca834fefba8049b501801f0a0b050 to your computer and use it in GitHub Desktop.
Save aolo2/f57ca834fefba8049b501801f0a0b050 to your computer and use it in GitHub Desktop.
read ttf font_directory
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <assert.h>
#include <arpa/inet.h>
#define READ_BE32(buf) htonl(*(u32 *)(buf->data + buf->offset)); buf->offset += 4
#define READ_BE16(buf) htons(*(u16 *)(buf->data + buf->offset)); buf->offset += 2
typedef uint64_t u64;
typedef uint32_t u32;
typedef uint16_t u16;
typedef uint8_t u8;
typedef int64_t s64;
typedef int32_t s32;
typedef int16_t s16;
typedef int8_t s8;
typedef float f32;
typedef double f64;
typedef struct buffer { u8 *data; u64 offset; u64 size; } buffer;
typedef struct offset_subtable {
u32 scaler_type;
u16 num_tables;
u16 search_range;
u16 entry_selector;
u16 range_shift;
} offset_subtable;
typedef struct table_directory {
union { char tag_c[4]; u32 tag; };
u32 checksum;
u32 offset;
u32 length;
} table_directory;
typedef struct font_directory {
offset_subtable off_sub;
table_directory *tbl_dir;
} font_directory;
static buffer
read_file(char *filename)
{
FILE *file = fopen(filename, "rb");
buffer result = { 0 };
if (file) {
fseek(file, 0, SEEK_END);
result.size = ftell(file);
result.data = malloc(result.size);
fseek(file, 0, SEEK_SET);
fread(result.data, result.size, 1, file);
fclose(file);
}
return(result);
}
static offset_subtable
read_offset_table(buffer *file)
{
offset_subtable result;
result.scaler_type = READ_BE32(file);
result.num_tables = READ_BE16(file);
result.search_range = READ_BE16(file);
result.entry_selector = READ_BE16(file);
result.range_shift = READ_BE16(file);
return(result);
}
static table_directory *
read_table_directory(buffer *file, u16 table_count)
{
table_directory *result = calloc(1, sizeof(table_directory) * table_count);
for (int i = 0; i < table_count; ++i) {
table_directory *td = result + i;
td->tag = READ_BE32(file);
td->checksum = READ_BE32(file);
td->offset = READ_BE32(file);
td->length = READ_BE32(file);
}
return(result);
}
static font_directory
read_font_directory(buffer *file)
{
font_directory result;
result.off_sub = read_offset_table(file);
result.tbl_dir = read_table_directory(file, result.off_sub.num_tables);
return(result);
}
int
main(int argc, char **argv)
{
if (argc != 2) {
fprintf(stderr, "[ERROR] Usage: %s filename\n", argv[0]);
return(1);
}
buffer font_file = read_file(argv[1]);
font_directory font_dir = read_font_directory(&font_file);
return(0);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment