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
|
*.gch
|
||||||
scramble
|
scramble
|
||||||
cdi4dc
|
cdi4dc
|
||||||
|
tools/ttf_outline
|
Binary file not shown.
@ -29,60 +29,6 @@ struct vertex {
|
|||||||
float v;
|
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] = {
|
const struct vertex strip_vertices[4] = {
|
||||||
// [ position ] [ uv coordinates ]
|
// [ position ] [ uv coordinates ]
|
||||||
{ 0.f, 1.f, 0.f, 0.f, 1.f, },
|
{ 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));
|
constexpr uint32_t strip_length = (sizeof (strip_vertices)) / (sizeof (struct vertex));
|
||||||
|
|
||||||
uint32_t transform(ta_parameter_writer& parameter,
|
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 char * s, const uint32_t len,
|
||||||
const uint32_t y_offset)
|
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
|
uint32_t advance = 0; // in 26.6 fixed-point
|
||||||
|
|
||||||
for (uint32_t string_ix = 0; string_ix < len; string_ix++) {
|
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);
|
auto polygon = global_polygon_type_0(texture_address);
|
||||||
polygon.parameter_control_word = para_control::para_type::polygon_or_modifier_volume
|
polygon.parameter_control_word = para_control::para_type::polygon_or_modifier_volume
|
||||||
| para_control::list_type::opaque
|
| 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
|
polygon.tsp_instruction_word = tsp_instruction_word::src_alpha_instr::one
|
||||||
| tsp_instruction_word::dst_alpha_instr::zero
|
| tsp_instruction_word::dst_alpha_instr::zero
|
||||||
| tsp_instruction_word::fog_control::no_fog
|
| tsp_instruction_word::fog_control::no_fog
|
||||||
| tsp_instruction_word::texture_u_size::_128
|
| tsp_instruction_word::texture_u_size::from_int(texture_width)
|
||||||
| tsp_instruction_word::texture_v_size::_256;
|
| tsp_instruction_word::texture_v_size::from_int(texture_height);
|
||||||
|
|
||||||
polygon.texture_control_word = texture_control_word::pixel_format::_8bpp_palette
|
polygon.texture_control_word = texture_control_word::pixel_format::_8bpp_palette
|
||||||
| texture_control_word::scan_order::twiddled
|
| texture_control_word::scan_order::twiddled
|
||||||
| texture_control_word::texture_address(texture_address / 8);
|
| texture_control_word::texture_address(texture_address / 8);
|
||||||
parameter.append<global_polygon_type_0>() = polygon;
|
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++) {
|
for (uint32_t i = 0; i < strip_length; i++) {
|
||||||
bool end_of_strip = i == strip_length - 1;
|
bool end_of_strip = i == strip_length - 1;
|
||||||
|
|
||||||
@ -142,8 +94,8 @@ uint32_t transform(ta_parameter_writer& parameter,
|
|||||||
v *= glyph.bitmap.height;
|
v *= glyph.bitmap.height;
|
||||||
u += glyph.bitmap.x;
|
u += glyph.bitmap.x;
|
||||||
v += glyph.bitmap.y;
|
v += glyph.bitmap.y;
|
||||||
u = u / 128.f;
|
u = u / static_cast<float>(texture_width);
|
||||||
v = v / 256.f;
|
v = v / static_cast<float>(texture_height);
|
||||||
|
|
||||||
parameter.append<vertex_polygon_type_3>() =
|
parameter.append<vertex_polygon_type_3>() =
|
||||||
vertex_polygon_type_3(x, y, z,
|
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()
|
void palette_data()
|
||||||
{
|
{
|
||||||
|
static_assert(C >= 2);
|
||||||
|
constexpr int increment = 256 / C;
|
||||||
|
|
||||||
holly.PAL_RAM_CTRL = pal_ram_ctrl::pixel_format::rgb565;
|
holly.PAL_RAM_CTRL = pal_ram_ctrl::pixel_format::rgb565;
|
||||||
|
|
||||||
// palette of 256 greys
|
// generate a palette with `C` shades of grey,
|
||||||
for (int i = 0; i < 256; i++) {
|
// ranging in intensity from rgb565(0, 0, 0) to rgb565(31, 63, 31)
|
||||||
holly.PALETTE_RAM[i] = ((i >> 3) << 11)
|
for (int i = 0; i < 256; i += increment) {
|
||||||
|
holly.PALETTE_RAM[i / increment] = ((i >> 3) << 11)
|
||||||
| ((i >> 2) << 5)
|
| ((i >> 2) << 5)
|
||||||
| ((i >> 3) << 0);
|
| ((i >> 3) << 0);
|
||||||
}
|
}
|
||||||
|
holly.PALETTE_RAM[255] = 0xffff;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t _ta_parameter_buf[((32 * 10 * 17) + 32) / 4];
|
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 glyphs = reinterpret_cast<const struct glyph *>(&font[1]);
|
||||||
auto texture = reinterpret_cast<const uint32_t *>(&glyphs[font->glyph_count]);
|
auto texture = reinterpret_cast<const uint32_t *>(&glyphs[font->glyph_count]);
|
||||||
|
|
||||||
|
/*
|
||||||
serial::integer<uint32_t>(font->first_char_code);
|
serial::integer<uint32_t>(font->first_char_code);
|
||||||
serial::integer<uint32_t>(font->glyph_count);
|
serial::integer<uint32_t>(font->glyph_count);
|
||||||
serial::integer<uint32_t>(font->glyph_height);
|
serial::integer<uint32_t>(font->glyph_height);
|
||||||
@ -213,10 +172,11 @@ void main()
|
|||||||
serial::character('\n');
|
serial::character('\n');
|
||||||
serial::integer<uint32_t>(((uint32_t)glyphs) - ((uint32_t)font));
|
serial::integer<uint32_t>(((uint32_t)glyphs) - ((uint32_t)font));
|
||||||
serial::integer<uint32_t>(((uint32_t)texture) - ((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);
|
inflate_font(texture, texture_size);
|
||||||
palette_data();
|
palette_data<256>();
|
||||||
|
|
||||||
// The address of `ta_parameter_buf` must be a multiple of 32 bytes.
|
// 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.
|
// 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);
|
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,
|
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,
|
cabal, 26,
|
||||||
font->glyph_height);
|
font->glyph_height * 1);
|
||||||
|
|
||||||
parameter.append<global_end_of_list>() = global_end_of_list();
|
parameter.append<global_end_of_list>() = global_end_of_list();
|
||||||
|
|
||||||
|
@ -34,6 +34,7 @@ struct font {
|
|||||||
uint16_t glyph_height;
|
uint16_t glyph_height;
|
||||||
uint16_t texture_width;
|
uint16_t texture_width;
|
||||||
uint16_t texture_height;
|
uint16_t texture_height;
|
||||||
|
uint32_t max_z_curve_ix;
|
||||||
} __attribute__ ((packed));
|
} __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 _256 = 5 << 3;
|
||||||
constexpr uint32_t _512 = 6 << 3;
|
constexpr uint32_t _512 = 6 << 3;
|
||||||
constexpr uint32_t _1024 = 7 << 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 {
|
namespace texture_v_size {
|
||||||
@ -120,6 +134,20 @@ namespace tsp_instruction_word {
|
|||||||
constexpr uint32_t _256 = 5 << 0;
|
constexpr uint32_t _256 = 5 << 0;
|
||||||
constexpr uint32_t _512 = 6 << 0;
|
constexpr uint32_t _512 = 6 << 0;
|
||||||
constexpr uint32_t _1024 = 7 << 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 <cassert>
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <compare>
|
#include <compare>
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
#include "insertion_sort.hpp"
|
#include "insertion_sort.hpp"
|
||||||
#include "rect.hpp"
|
#include "rect.hpp"
|
||||||
#include "../twiddle.hpp"
|
#include "../twiddle.hpp"
|
||||||
#include <iostream>
|
#include "2d_pack.hpp"
|
||||||
|
|
||||||
struct size {
|
struct size {
|
||||||
uint32_t width;
|
uint16_t width;
|
||||||
uint32_t height;
|
uint16_t height;
|
||||||
};
|
};
|
||||||
|
|
||||||
constexpr struct size max_texture = {1024, 1024};
|
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;
|
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 size& window,
|
||||||
struct rect& rect)
|
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);
|
auto [x_offset, y_offset] = twiddle::from_ix(z_curve_ix);
|
||||||
|
|
||||||
if (x_offset >= window.width and y_offset >= window.height) {
|
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);
|
assert(window.width < max_texture.width || window.height < max_texture.height);
|
||||||
if (window.width == window.height) { window.height *= 2; }
|
if (window.width == window.height) { window.height *= 2; }
|
||||||
else { window.width *= 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.x = x_offset;
|
||||||
rect.y = y_offset;
|
rect.y = y_offset;
|
||||||
|
|
||||||
return true;
|
return twiddle::from_xy(rect.x + rect.width - 1,
|
||||||
|
rect.y + rect.height - 1);
|
||||||
} else {
|
} else {
|
||||||
z_curve_ix += 1;
|
z_curve_ix += 1;
|
||||||
continue;
|
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 };
|
uint8_t texture[max_texture.height][max_texture.width] = { 0 };
|
||||||
size window = {1, 1};
|
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
|
// sort all rectangles by size
|
||||||
insertion_sort(rects, num_rects);
|
insertion_sort(rects, num_rects);
|
||||||
|
|
||||||
uint32_t max_x = 0;
|
uint32_t max_z_curve_ix = 0;
|
||||||
uint32_t max_y = 0;
|
|
||||||
|
|
||||||
for (uint32_t i = 0; i < num_rects; i++) {
|
for (uint32_t i = 0; i < num_rects; i++) {
|
||||||
std::cerr << "pack " << i << '\n';
|
uint32_t z_curve_ix = pack_into(texture, window, rects[i]);
|
||||||
bool packed = pack_into(texture, window, rects[i]);
|
//std::cerr << "z_curve_ix " << z_curve_ix << '\n';
|
||||||
if (packed) {
|
if (z_curve_ix > max_z_curve_ix)
|
||||||
const uint32_t x = rects[i].x + rects[i].width - 1;
|
max_z_curve_ix = z_curve_ix;
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const uint32_t curve_ix = twiddle::from_xy(max_x, max_y);
|
std::cerr << "window size: " << window.width << ' ' << window.height << '\n';
|
||||||
std::cerr << "max xy " << max_x << ' ' << max_y << '\n';
|
std::cerr << "max_z_curve_ix: " << max_z_curve_ix << '\n';
|
||||||
std::cerr << "curve_ix " << curve_ix << '\n';
|
return {window.width, window.height, max_z_curve_ix};
|
||||||
return 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)
|
CFLAGS += $(shell pkg-config --cflags freetype2)
|
||||||
LDFLAGS = $(shell pkg-config --libs freetype2)
|
LDFLAGS = $(shell pkg-config --libs freetype2)
|
||||||
|
|
||||||
all: ttf-outline
|
all: ttf_outline
|
||||||
|
|
||||||
%.o: %.cpp
|
%.o: %.cpp
|
||||||
$(CXX) $(CFLAGS) $(CXXFLAGS) -c $< -o $@
|
$(CXX) $(CFLAGS) $(CXXFLAGS) -c $< -o $@
|
||||||
@ -12,10 +12,10 @@ all: ttf-outline
|
|||||||
%: %.o
|
%: %.o
|
||||||
$(CXX) $(LDFLAGS) $^ -o $@
|
$(CXX) $(LDFLAGS) $^ -o $@
|
||||||
|
|
||||||
ttf-outline: ttf-outline.o 2d-pack.o
|
ttf_outline: ttf_outline.o 2d_pack.o
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
rm -f *.o ttf-convert ttf-bitmap
|
rm -f *.o ttf_outline
|
||||||
|
|
||||||
.SUFFIXES:
|
.SUFFIXES:
|
||||||
.INTERMEDIATE:
|
.INTERMEDIATE:
|
||||||
|
@ -10,11 +10,14 @@
|
|||||||
|
|
||||||
#include "../font/font.hpp"
|
#include "../font/font.hpp"
|
||||||
#include "rect.hpp"
|
#include "rect.hpp"
|
||||||
#include "2d-pack.hpp"
|
#include "2d_pack.hpp"
|
||||||
#include "../twiddle.hpp"
|
#include "../twiddle.hpp"
|
||||||
|
|
||||||
std::endian _target_endian;
|
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)
|
uint32_t byteswap(const uint32_t n)
|
||||||
{
|
{
|
||||||
if (std::endian::native != _target_endian) {
|
if (std::endian::native != _target_endian) {
|
||||||
@ -63,7 +66,7 @@ load_outline_char(const FT_Face face,
|
|||||||
return -1;
|
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);
|
//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.width == rect.width);
|
||||||
assert(face->glyph->bitmap.rows == rect.height);
|
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) {
|
switch (face->glyph->bitmap.num_grays) {
|
||||||
case 2:
|
case 2:
|
||||||
assert(false);
|
assert(false);
|
||||||
break;
|
break;
|
||||||
case 256:
|
case 256:
|
||||||
std::cerr << "rxy " << rect.x << ' ' << rect.y << '\n';
|
//std::cerr << "rxy " << rect.x << ' ' << rect.y << '\n';
|
||||||
std::cerr << "rwh " << rect.width << ' ' << rect.height << '\n';
|
//std::cerr << "rwh " << rect.width << ' ' << rect.height << '\n';
|
||||||
|
|
||||||
for (uint32_t y = 0; y < rect.height; y++) {
|
for (uint32_t y = 0; y < rect.height; y++) {
|
||||||
for (uint32_t x = 0; x < rect.width; x++) {
|
for (uint32_t x = 0; x < rect.width; x++) {
|
||||||
uint32_t texture_ix = (rect.y + y) * 1024 + (rect.x + x);
|
uint32_t texture_ix = (rect.y + y) * max_texture_dim + (rect.x + x);
|
||||||
assert(texture_ix < 1024 * 1024);
|
assert(texture_ix < max_texture_size);
|
||||||
texture[texture_ix] = face->glyph->bitmap.buffer[y * face->glyph->bitmap.pitch + x];
|
texture[texture_ix] = face->glyph->bitmap.buffer[y * face->glyph->bitmap.pitch + x];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -127,7 +130,8 @@ enum {
|
|||||||
argv_length = 7
|
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 start,
|
||||||
const uint32_t end,
|
const uint32_t end,
|
||||||
glyph * glyphs,
|
glyph * glyphs,
|
||||||
@ -137,7 +141,7 @@ void load_all_positions(const FT_Face face,
|
|||||||
const uint32_t num_glyphs = (end - start) + 1;
|
const uint32_t num_glyphs = (end - start) + 1;
|
||||||
struct rect rects[num_glyphs];
|
struct rect rects[num_glyphs];
|
||||||
|
|
||||||
uint8_t temp[1024 * 1024];
|
uint8_t temp[max_texture_size];
|
||||||
|
|
||||||
// first, load all rectangles
|
// first, load all rectangles
|
||||||
for (uint32_t char_code = start; char_code <= end; char_code++) {
|
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
|
// calculate a 2-dimensional packing for the rectangles
|
||||||
pack_all(rects, num_glyphs);
|
auto window_curve_ix = pack_all(rects, num_glyphs);
|
||||||
|
|
||||||
// asdf
|
// asdf
|
||||||
for (uint32_t i = 0; i < num_glyphs; i++) {
|
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,
|
twiddle::texture2<8>(texture, temp,
|
||||||
128, 256,
|
window_curve_ix.window.width,
|
||||||
1024);
|
window_curve_ix.window.height,
|
||||||
|
max_texture_dim);
|
||||||
|
|
||||||
|
return window_curve_ix;
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
@ -210,8 +217,6 @@ int main(int argc, char *argv[])
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::cerr << "here\n";
|
|
||||||
|
|
||||||
uint32_t start;
|
uint32_t start;
|
||||||
uint32_t end;
|
uint32_t end;
|
||||||
|
|
||||||
@ -224,20 +229,24 @@ int main(int argc, char *argv[])
|
|||||||
|
|
||||||
uint32_t num_glyphs = (end - start) + 1;
|
uint32_t num_glyphs = (end - start) + 1;
|
||||||
glyph glyphs[num_glyphs];
|
glyph glyphs[num_glyphs];
|
||||||
uint32_t texture[(1024 * 1024) / 4];
|
uint32_t texture[max_texture_size / 4];
|
||||||
memset(texture, 0x00, 1024 * 1024);
|
memset(texture, 0x00, max_texture_size);
|
||||||
|
|
||||||
|
auto window_curve_ix = load_all_positions(face, start, end, glyphs, texture);
|
||||||
|
|
||||||
font font;
|
font font;
|
||||||
font.first_char_code = byteswap(start);
|
font.first_char_code = byteswap(start);
|
||||||
font.glyph_count = byteswap(num_glyphs);
|
font.glyph_count = byteswap(num_glyphs);
|
||||||
font.glyph_height = byteswap(face->size->metrics.height);
|
font.glyph_height = byteswap(face->size->metrics.height);
|
||||||
font.texture_width = 128;
|
font.texture_width = byteswap(window_curve_ix.window.width);
|
||||||
font.texture_height = 256;
|
font.texture_height = byteswap(window_curve_ix.window.height);
|
||||||
|
font.max_z_curve_ix = byteswap(window_curve_ix.max_z_curve_ix);
|
||||||
load_all_positions(face, start, end, glyphs, texture);
|
|
||||||
|
|
||||||
std::cerr << "start: 0x" << std::hex << start << '\n';
|
std::cerr << "start: 0x" << std::hex << start << '\n';
|
||||||
std::cerr << "end: 0x" << std::hex << end << '\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");
|
FILE * out = fopen(argv[output_file_path], "w");
|
||||||
if (out == NULL) {
|
if (out == NULL) {
|
||||||
@ -245,10 +254,9 @@ int main(int argc, char *argv[])
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t texture_size = 128 * 256;
|
|
||||||
fwrite(reinterpret_cast<void*>(&font), (sizeof (font)), 1, out);
|
fwrite(reinterpret_cast<void*>(&font), (sizeof (font)), 1, out);
|
||||||
fwrite(reinterpret_cast<void*>(&glyphs[0]), (sizeof (glyph)), num_glyphs, 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);
|
fclose(out);
|
||||||
}
|
}
|
Loading…
x
Reference in New Issue
Block a user