font_outline: remove all 1024/256/128 magic numbers
This fully threads both the real minimum size of the texture and the dimensions of the texture through to the TA parameters. This also removes spurious zero-area drawing commands (space characters).
This commit is contained in:
parent
3b7e1eaef8
commit
8f0afc2868
1
.gitignore
vendored
1
.gitignore
vendored
@ -12,3 +12,4 @@ __pycache__
|
||||
*.gch
|
||||
scramble
|
||||
cdi4dc
|
||||
tools/ttf_outline
|
Binary file not shown.
@ -29,60 +29,6 @@ struct vertex {
|
||||
float v;
|
||||
};
|
||||
|
||||
/*
|
||||
// screen space coordinates
|
||||
const struct vertex quad_verticies[4] = {
|
||||
{ 0.f, 64.f, 0.01f, 0.f, 1.f },
|
||||
{ 0.f, 0.f, 0.01f, 0.f, 0.f },
|
||||
{ 64.f, 0.f, 0.01f, 1.f, 0.f },
|
||||
{ 64.f, 64.f, 0.01f, 1.f, 1.f, },
|
||||
};
|
||||
|
||||
uint32_t transform(uint32_t * ta_parameter_buf)
|
||||
{
|
||||
auto parameter = ta_parameter_writer(ta_parameter_buf);
|
||||
uint32_t texture_address = (offsetof (struct texture_memory_alloc, texture));
|
||||
constexpr uint32_t base_color = 0xffffffff;
|
||||
auto sprite = global_sprite(base_color);
|
||||
sprite.parameter_control_word = para_control::para_type::sprite
|
||||
| para_control::list_type::opaque
|
||||
| obj_control::col_type::packed_color
|
||||
| obj_control::texture
|
||||
| obj_control::_16bit_uv;
|
||||
sprite.tsp_instruction_word = tsp_instruction_word::src_alpha_instr::one
|
||||
| tsp_instruction_word::dst_alpha_instr::zero
|
||||
| tsp_instruction_word::fog_control::no_fog
|
||||
| tsp_instruction_word::texture_u_size::_8 // 8px
|
||||
| tsp_instruction_word::texture_v_size::_8; // 8px
|
||||
sprite.texture_control_word = texture_control_word::pixel_format::_565
|
||||
| texture_control_word::scan_order::twiddled
|
||||
| texture_control_word::texture_address(texture_address / 8);
|
||||
parameter.append<global_sprite>() = sprite;
|
||||
|
||||
parameter.append<vertex_sprite_type_1>() =
|
||||
vertex_sprite_type_1(quad_verticies[0].x,
|
||||
quad_verticies[0].y,
|
||||
quad_verticies[0].z,
|
||||
quad_verticies[1].x,
|
||||
quad_verticies[1].y,
|
||||
quad_verticies[1].z,
|
||||
quad_verticies[2].x,
|
||||
quad_verticies[2].y,
|
||||
quad_verticies[2].z,
|
||||
quad_verticies[3].x,
|
||||
quad_verticies[3].y,
|
||||
uv_16bit(quad_verticies[0].u, quad_verticies[0].v),
|
||||
uv_16bit(quad_verticies[1].u, quad_verticies[1].v),
|
||||
uv_16bit(quad_verticies[2].u, quad_verticies[2].v));
|
||||
// curiously, there is no `dz` in vertex_sprite_type_1
|
||||
// curiously, there is no `du_dv` in vertex_sprite_type_1
|
||||
|
||||
parameter.append<global_end_of_list>() = global_end_of_list();
|
||||
|
||||
return parameter.offset;
|
||||
}
|
||||
*/
|
||||
|
||||
const struct vertex strip_vertices[4] = {
|
||||
// [ position ] [ uv coordinates ]
|
||||
{ 0.f, 1.f, 0.f, 0.f, 1.f, },
|
||||
@ -93,7 +39,9 @@ const struct vertex strip_vertices[4] = {
|
||||
constexpr uint32_t strip_length = (sizeof (strip_vertices)) / (sizeof (struct vertex));
|
||||
|
||||
uint32_t transform(ta_parameter_writer& parameter,
|
||||
const uint32_t first_char_code, const glyph * glyphs,
|
||||
const uint32_t first_char_code,
|
||||
const uint32_t texture_width, uint32_t texture_height,
|
||||
const glyph * glyphs,
|
||||
const char * s, const uint32_t len,
|
||||
const uint32_t y_offset)
|
||||
{
|
||||
@ -102,6 +50,13 @@ uint32_t transform(ta_parameter_writer& parameter,
|
||||
uint32_t advance = 0; // in 26.6 fixed-point
|
||||
|
||||
for (uint32_t string_ix = 0; string_ix < len; string_ix++) {
|
||||
char c = s[string_ix];
|
||||
auto& glyph = glyphs[c - first_char_code];
|
||||
if (glyph.bitmap.width == 0 || glyph.bitmap.height == 0) {
|
||||
advance += glyph.metrics.horiAdvance;
|
||||
continue;
|
||||
}
|
||||
|
||||
auto polygon = global_polygon_type_0(texture_address);
|
||||
polygon.parameter_control_word = para_control::para_type::polygon_or_modifier_volume
|
||||
| para_control::list_type::opaque
|
||||
@ -111,17 +66,14 @@ uint32_t transform(ta_parameter_writer& parameter,
|
||||
polygon.tsp_instruction_word = tsp_instruction_word::src_alpha_instr::one
|
||||
| tsp_instruction_word::dst_alpha_instr::zero
|
||||
| tsp_instruction_word::fog_control::no_fog
|
||||
| tsp_instruction_word::texture_u_size::_128
|
||||
| tsp_instruction_word::texture_v_size::_256;
|
||||
| tsp_instruction_word::texture_u_size::from_int(texture_width)
|
||||
| tsp_instruction_word::texture_v_size::from_int(texture_height);
|
||||
|
||||
polygon.texture_control_word = texture_control_word::pixel_format::_8bpp_palette
|
||||
| texture_control_word::scan_order::twiddled
|
||||
| texture_control_word::texture_address(texture_address / 8);
|
||||
parameter.append<global_polygon_type_0>() = polygon;
|
||||
|
||||
char c = s[string_ix];
|
||||
auto& glyph = glyphs[c - first_char_code];
|
||||
|
||||
for (uint32_t i = 0; i < strip_length; i++) {
|
||||
bool end_of_strip = i == strip_length - 1;
|
||||
|
||||
@ -142,8 +94,8 @@ uint32_t transform(ta_parameter_writer& parameter,
|
||||
v *= glyph.bitmap.height;
|
||||
u += glyph.bitmap.x;
|
||||
v += glyph.bitmap.y;
|
||||
u = u / 128.f;
|
||||
v = v / 256.f;
|
||||
u = u / static_cast<float>(texture_width);
|
||||
v = v / static_cast<float>(texture_height);
|
||||
|
||||
parameter.append<vertex_polygon_type_3>() =
|
||||
vertex_polygon_type_3(x, y, z,
|
||||
@ -183,16 +135,22 @@ void inflate_font(const uint32_t * src, const uint32_t size)
|
||||
}
|
||||
}
|
||||
|
||||
template <int C>
|
||||
void palette_data()
|
||||
{
|
||||
static_assert(C >= 2);
|
||||
constexpr int increment = 256 / C;
|
||||
|
||||
holly.PAL_RAM_CTRL = pal_ram_ctrl::pixel_format::rgb565;
|
||||
|
||||
// palette of 256 greys
|
||||
for (int i = 0; i < 256; i++) {
|
||||
holly.PALETTE_RAM[i] = ((i >> 3) << 11)
|
||||
// generate a palette with `C` shades of grey,
|
||||
// ranging in intensity from rgb565(0, 0, 0) to rgb565(31, 63, 31)
|
||||
for (int i = 0; i < 256; i += increment) {
|
||||
holly.PALETTE_RAM[i / increment] = ((i >> 3) << 11)
|
||||
| ((i >> 2) << 5)
|
||||
| ((i >> 3) << 0);
|
||||
}
|
||||
holly.PALETTE_RAM[255] = 0xffff;
|
||||
}
|
||||
|
||||
uint32_t _ta_parameter_buf[((32 * 10 * 17) + 32) / 4];
|
||||
@ -205,6 +163,7 @@ void main()
|
||||
auto glyphs = reinterpret_cast<const struct glyph *>(&font[1]);
|
||||
auto texture = reinterpret_cast<const uint32_t *>(&glyphs[font->glyph_count]);
|
||||
|
||||
/*
|
||||
serial::integer<uint32_t>(font->first_char_code);
|
||||
serial::integer<uint32_t>(font->glyph_count);
|
||||
serial::integer<uint32_t>(font->glyph_height);
|
||||
@ -213,10 +172,11 @@ void main()
|
||||
serial::character('\n');
|
||||
serial::integer<uint32_t>(((uint32_t)glyphs) - ((uint32_t)font));
|
||||
serial::integer<uint32_t>(((uint32_t)texture) - ((uint32_t)font));
|
||||
*/
|
||||
|
||||
uint32_t texture_size = font->texture_width * font->texture_height;
|
||||
uint32_t texture_size = font->max_z_curve_ix + 1;
|
||||
inflate_font(texture, texture_size);
|
||||
palette_data();
|
||||
palette_data<256>();
|
||||
|
||||
// The address of `ta_parameter_buf` must be a multiple of 32 bytes.
|
||||
// This is mandatory for ch2-dma to the ta fifo polygon converter.
|
||||
@ -256,13 +216,19 @@ void main()
|
||||
|
||||
auto parameter = ta_parameter_writer(ta_parameter_buf);
|
||||
|
||||
transform(parameter, font->first_char_code, glyphs,
|
||||
transform(parameter,
|
||||
font->first_char_code,
|
||||
font->texture_width, font->texture_height,
|
||||
glyphs,
|
||||
ana, 17,
|
||||
0);
|
||||
font->glyph_height * 0);
|
||||
|
||||
transform(parameter, font->first_char_code, glyphs,
|
||||
transform(parameter,
|
||||
font->first_char_code,
|
||||
font->texture_width, font->texture_height,
|
||||
glyphs,
|
||||
cabal, 26,
|
||||
font->glyph_height);
|
||||
font->glyph_height * 1);
|
||||
|
||||
parameter.append<global_end_of_list>() = global_end_of_list();
|
||||
|
||||
|
@ -34,6 +34,7 @@ struct font {
|
||||
uint16_t glyph_height;
|
||||
uint16_t texture_width;
|
||||
uint16_t texture_height;
|
||||
uint32_t max_z_curve_ix;
|
||||
} __attribute__ ((packed));
|
||||
|
||||
static_assert((sizeof (font)) == ((sizeof (uint32_t)) * 3));
|
||||
static_assert((sizeof (font)) == ((sizeof (uint32_t)) * 4));
|
||||
|
@ -109,6 +109,20 @@ namespace tsp_instruction_word {
|
||||
constexpr uint32_t _256 = 5 << 3;
|
||||
constexpr uint32_t _512 = 6 << 3;
|
||||
constexpr uint32_t _1024 = 7 << 3;
|
||||
|
||||
constexpr uint32_t from_int(uint32_t n) {
|
||||
switch (n) {
|
||||
default: [[fallthrough]];
|
||||
case 8: return _8;
|
||||
case 16: return _16;
|
||||
case 32: return _32;
|
||||
case 64: return _64;
|
||||
case 128: return _128;
|
||||
case 256: return _256;
|
||||
case 512: return _512;
|
||||
case 1024: return _1024;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
namespace texture_v_size {
|
||||
@ -120,6 +134,20 @@ namespace tsp_instruction_word {
|
||||
constexpr uint32_t _256 = 5 << 0;
|
||||
constexpr uint32_t _512 = 6 << 0;
|
||||
constexpr uint32_t _1024 = 7 << 0;
|
||||
|
||||
constexpr uint32_t from_int(uint32_t n) {
|
||||
switch (n) {
|
||||
default: [[fallthrough]];
|
||||
case 8: return _8;
|
||||
case 16: return _16;
|
||||
case 32: return _32;
|
||||
case 64: return _64;
|
||||
case 128: return _128;
|
||||
case 256: return _256;
|
||||
case 512: return _512;
|
||||
case 1024: return _1024;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,5 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
uint32_t pack_all(struct rect * rects, const uint32_t num_rects);
|
@ -1,15 +1,16 @@
|
||||
#include <cassert>
|
||||
#include <cstdint>
|
||||
#include <compare>
|
||||
#include <iostream>
|
||||
|
||||
#include "insertion_sort.hpp"
|
||||
#include "rect.hpp"
|
||||
#include "../twiddle.hpp"
|
||||
#include <iostream>
|
||||
#include "2d_pack.hpp"
|
||||
|
||||
struct size {
|
||||
uint32_t width;
|
||||
uint32_t height;
|
||||
uint16_t width;
|
||||
uint16_t height;
|
||||
};
|
||||
|
||||
constexpr struct size max_texture = {1024, 1024};
|
||||
@ -36,7 +37,7 @@ inline bool area_valid(const uint8_t texture[max_texture.height][max_texture.wid
|
||||
return true;
|
||||
}
|
||||
|
||||
bool pack_into(uint8_t texture[max_texture.height][max_texture.width],
|
||||
uint32_t pack_into(uint8_t texture[max_texture.height][max_texture.width],
|
||||
struct size& window,
|
||||
struct rect& rect)
|
||||
{
|
||||
@ -52,7 +53,7 @@ bool pack_into(uint8_t texture[max_texture.height][max_texture.width],
|
||||
auto [x_offset, y_offset] = twiddle::from_ix(z_curve_ix);
|
||||
|
||||
if (x_offset >= window.width and y_offset >= window.height) {
|
||||
std::cerr << z_curve_ix << ' ' << window.width << ' ' << window.height << '\n';
|
||||
//std::cerr << z_curve_ix << ' ' << window.width << ' ' << window.height << '\n';
|
||||
assert(window.width < max_texture.width || window.height < max_texture.height);
|
||||
if (window.width == window.height) { window.height *= 2; }
|
||||
else { window.width *= 2; }
|
||||
@ -76,15 +77,19 @@ bool pack_into(uint8_t texture[max_texture.height][max_texture.width],
|
||||
rect.x = x_offset;
|
||||
rect.y = y_offset;
|
||||
|
||||
return true;
|
||||
return twiddle::from_xy(rect.x + rect.width - 1,
|
||||
rect.y + rect.height - 1);
|
||||
} else {
|
||||
z_curve_ix += 1;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
assert(false);
|
||||
}
|
||||
|
||||
uint32_t pack_all(struct rect * rects, const uint32_t num_rects)
|
||||
struct window_curve_ix
|
||||
pack_all(struct rect * rects, const uint32_t num_rects)
|
||||
{
|
||||
uint8_t texture[max_texture.height][max_texture.width] = { 0 };
|
||||
size window = {1, 1};
|
||||
@ -92,22 +97,16 @@ uint32_t pack_all(struct rect * rects, const uint32_t num_rects)
|
||||
// sort all rectangles by size
|
||||
insertion_sort(rects, num_rects);
|
||||
|
||||
uint32_t max_x = 0;
|
||||
uint32_t max_y = 0;
|
||||
uint32_t max_z_curve_ix = 0;
|
||||
|
||||
for (uint32_t i = 0; i < num_rects; i++) {
|
||||
std::cerr << "pack " << i << '\n';
|
||||
bool packed = pack_into(texture, window, rects[i]);
|
||||
if (packed) {
|
||||
const uint32_t x = rects[i].x + rects[i].width - 1;
|
||||
const uint32_t y = rects[i].y + rects[i].height - 1;
|
||||
if (x > max_x) max_x = x;
|
||||
if (y > max_y) max_y = y;
|
||||
}
|
||||
uint32_t z_curve_ix = pack_into(texture, window, rects[i]);
|
||||
//std::cerr << "z_curve_ix " << z_curve_ix << '\n';
|
||||
if (z_curve_ix > max_z_curve_ix)
|
||||
max_z_curve_ix = z_curve_ix;
|
||||
}
|
||||
|
||||
const uint32_t curve_ix = twiddle::from_xy(max_x, max_y);
|
||||
std::cerr << "max xy " << max_x << ' ' << max_y << '\n';
|
||||
std::cerr << "curve_ix " << curve_ix << '\n';
|
||||
return curve_ix;
|
||||
std::cerr << "window size: " << window.width << ' ' << window.height << '\n';
|
||||
std::cerr << "max_z_curve_ix: " << max_z_curve_ix << '\n';
|
||||
return {window.width, window.height, max_z_curve_ix};
|
||||
}
|
14
tools/2d_pack.hpp
Normal file
14
tools/2d_pack.hpp
Normal file
@ -0,0 +1,14 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
struct window_curve_ix {
|
||||
struct {
|
||||
uint16_t width;
|
||||
uint16_t height;
|
||||
} window;
|
||||
uint32_t max_z_curve_ix;
|
||||
};
|
||||
|
||||
struct window_curve_ix
|
||||
pack_all(struct rect * rects, const uint32_t num_rects);
|
@ -4,7 +4,7 @@ CXXFLAGS = -std=c++23
|
||||
CFLAGS += $(shell pkg-config --cflags freetype2)
|
||||
LDFLAGS = $(shell pkg-config --libs freetype2)
|
||||
|
||||
all: ttf-outline
|
||||
all: ttf_outline
|
||||
|
||||
%.o: %.cpp
|
||||
$(CXX) $(CFLAGS) $(CXXFLAGS) -c $< -o $@
|
||||
@ -12,10 +12,10 @@ all: ttf-outline
|
||||
%: %.o
|
||||
$(CXX) $(LDFLAGS) $^ -o $@
|
||||
|
||||
ttf-outline: ttf-outline.o 2d-pack.o
|
||||
ttf_outline: ttf_outline.o 2d_pack.o
|
||||
|
||||
clean:
|
||||
rm -f *.o ttf-convert ttf-bitmap
|
||||
rm -f *.o ttf_outline
|
||||
|
||||
.SUFFIXES:
|
||||
.INTERMEDIATE:
|
||||
|
@ -10,11 +10,14 @@
|
||||
|
||||
#include "../font/font.hpp"
|
||||
#include "rect.hpp"
|
||||
#include "2d-pack.hpp"
|
||||
#include "2d_pack.hpp"
|
||||
#include "../twiddle.hpp"
|
||||
|
||||
std::endian _target_endian;
|
||||
|
||||
constexpr uint32_t max_texture_dim = 1024;
|
||||
constexpr uint32_t max_texture_size = max_texture_dim * max_texture_dim;
|
||||
|
||||
uint32_t byteswap(const uint32_t n)
|
||||
{
|
||||
if (std::endian::native != _target_endian) {
|
||||
@ -63,7 +66,7 @@ load_outline_char(const FT_Face face,
|
||||
return -1;
|
||||
}
|
||||
|
||||
std::cerr << "size " << face->glyph->bitmap.rows << ' ' << face->glyph->bitmap.width << '\n';
|
||||
//std::cerr << "size " << face->glyph->bitmap.rows << ' ' << face->glyph->bitmap.width << '\n';
|
||||
|
||||
//assert(face->glyph->format == FT_GLYPH_FORMAT_OUTLINE);
|
||||
|
||||
@ -81,19 +84,19 @@ load_outline_char(const FT_Face face,
|
||||
assert(face->glyph->bitmap.width == rect.width);
|
||||
assert(face->glyph->bitmap.rows == rect.height);
|
||||
|
||||
std::cerr << "num_grays " << face->glyph->bitmap.num_grays << '\n';
|
||||
//std::cerr << "num_grays " << face->glyph->bitmap.num_grays << '\n';
|
||||
switch (face->glyph->bitmap.num_grays) {
|
||||
case 2:
|
||||
assert(false);
|
||||
break;
|
||||
case 256:
|
||||
std::cerr << "rxy " << rect.x << ' ' << rect.y << '\n';
|
||||
std::cerr << "rwh " << rect.width << ' ' << rect.height << '\n';
|
||||
//std::cerr << "rxy " << rect.x << ' ' << rect.y << '\n';
|
||||
//std::cerr << "rwh " << rect.width << ' ' << rect.height << '\n';
|
||||
|
||||
for (uint32_t y = 0; y < rect.height; y++) {
|
||||
for (uint32_t x = 0; x < rect.width; x++) {
|
||||
uint32_t texture_ix = (rect.y + y) * 1024 + (rect.x + x);
|
||||
assert(texture_ix < 1024 * 1024);
|
||||
uint32_t texture_ix = (rect.y + y) * max_texture_dim + (rect.x + x);
|
||||
assert(texture_ix < max_texture_size);
|
||||
texture[texture_ix] = face->glyph->bitmap.buffer[y * face->glyph->bitmap.pitch + x];
|
||||
}
|
||||
}
|
||||
@ -127,7 +130,8 @@ enum {
|
||||
argv_length = 7
|
||||
};
|
||||
|
||||
void load_all_positions(const FT_Face face,
|
||||
struct window_curve_ix
|
||||
load_all_positions(const FT_Face face,
|
||||
const uint32_t start,
|
||||
const uint32_t end,
|
||||
glyph * glyphs,
|
||||
@ -137,7 +141,7 @@ void load_all_positions(const FT_Face face,
|
||||
const uint32_t num_glyphs = (end - start) + 1;
|
||||
struct rect rects[num_glyphs];
|
||||
|
||||
uint8_t temp[1024 * 1024];
|
||||
uint8_t temp[max_texture_size];
|
||||
|
||||
// first, load all rectangles
|
||||
for (uint32_t char_code = start; char_code <= end; char_code++) {
|
||||
@ -145,7 +149,7 @@ void load_all_positions(const FT_Face face,
|
||||
}
|
||||
|
||||
// calculate a 2-dimensional packing for the rectangles
|
||||
pack_all(rects, num_glyphs);
|
||||
auto window_curve_ix = pack_all(rects, num_glyphs);
|
||||
|
||||
// asdf
|
||||
for (uint32_t i = 0; i < num_glyphs; i++) {
|
||||
@ -159,8 +163,11 @@ void load_all_positions(const FT_Face face,
|
||||
}
|
||||
|
||||
twiddle::texture2<8>(texture, temp,
|
||||
128, 256,
|
||||
1024);
|
||||
window_curve_ix.window.width,
|
||||
window_curve_ix.window.height,
|
||||
max_texture_dim);
|
||||
|
||||
return window_curve_ix;
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
@ -210,8 +217,6 @@ int main(int argc, char *argv[])
|
||||
return -1;
|
||||
}
|
||||
|
||||
std::cerr << "here\n";
|
||||
|
||||
uint32_t start;
|
||||
uint32_t end;
|
||||
|
||||
@ -224,20 +229,24 @@ int main(int argc, char *argv[])
|
||||
|
||||
uint32_t num_glyphs = (end - start) + 1;
|
||||
glyph glyphs[num_glyphs];
|
||||
uint32_t texture[(1024 * 1024) / 4];
|
||||
memset(texture, 0x00, 1024 * 1024);
|
||||
uint32_t texture[max_texture_size / 4];
|
||||
memset(texture, 0x00, max_texture_size);
|
||||
|
||||
auto window_curve_ix = load_all_positions(face, start, end, glyphs, texture);
|
||||
|
||||
font font;
|
||||
font.first_char_code = byteswap(start);
|
||||
font.glyph_count = byteswap(num_glyphs);
|
||||
font.glyph_height = byteswap(face->size->metrics.height);
|
||||
font.texture_width = 128;
|
||||
font.texture_height = 256;
|
||||
|
||||
load_all_positions(face, start, end, glyphs, texture);
|
||||
font.texture_width = byteswap(window_curve_ix.window.width);
|
||||
font.texture_height = byteswap(window_curve_ix.window.height);
|
||||
font.max_z_curve_ix = byteswap(window_curve_ix.max_z_curve_ix);
|
||||
|
||||
std::cerr << "start: 0x" << std::hex << start << '\n';
|
||||
std::cerr << "end: 0x" << std::hex << end << '\n';
|
||||
std::cerr << "texture_width: " << std::dec << window_curve_ix.window.width << '\n';
|
||||
std::cerr << "texture_height: " << std::dec << window_curve_ix.window.height << '\n';
|
||||
std::cerr << "max_z_curve_ix: " << std::dec << window_curve_ix.max_z_curve_ix << '\n';
|
||||
|
||||
FILE * out = fopen(argv[output_file_path], "w");
|
||||
if (out == NULL) {
|
||||
@ -245,10 +254,9 @@ int main(int argc, char *argv[])
|
||||
return -1;
|
||||
}
|
||||
|
||||
uint32_t texture_size = 128 * 256;
|
||||
fwrite(reinterpret_cast<void*>(&font), (sizeof (font)), 1, out);
|
||||
fwrite(reinterpret_cast<void*>(&glyphs[0]), (sizeof (glyph)), num_glyphs, out);
|
||||
fwrite(reinterpret_cast<void*>(&texture[0]), (sizeof (uint8_t)), texture_size, out);
|
||||
fwrite(reinterpret_cast<void*>(&texture[0]), (sizeof (uint8_t)), window_curve_ix.max_z_curve_ix + 1, out);
|
||||
|
||||
fclose(out);
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user