combined font-info-load and font-load

This commit is contained in:
Allen Webster 2016-06-03 14:45:51 -04:00
parent 9bd09d1da2
commit 91386e62d0
7 changed files with 395 additions and 553 deletions

522
4ed.cpp

File diff suppressed because it is too large Load Diff

View File

@ -1,11 +1,11 @@
/* /*
* Mr. 4th Dimention - Allen Webster * Mr. 4th Dimention - Allen Webster
* *
* 18.12.2015 * 18.12.2015
* *
* Font set for 4coder * Font set for 4coder
* *
*/ */
// TOP // TOP
@ -40,9 +40,9 @@ font__remove(Font_Slot *slot){
n->prev = p; n->prev = p;
} }
internal Font_Slot inline Font_Slot
font_slot_zero(){ font_slot_zero(){
Font_Slot slot = {}; Font_Slot slot = {0};
return(slot); return(slot);
} }
@ -57,10 +57,10 @@ font_set_init(Font_Set *set, Partition *partition, i32 max, i16 live_max){
partition_align(partition, 8); partition_align(partition, 8);
set->font_block = push_block(partition, live_max*(sizeof(Render_Font) + sizeof(Font_Slot))); set->font_block = push_block(partition, live_max*(sizeof(Render_Font) + sizeof(Font_Slot)));
set->free_slots = font_slot_zero(); set->free_slots = font_slot_zero();
set->used_slots = font_slot_zero(); set->used_slots = font_slot_zero();
dll_init_sentinel(&set->free_slots); dll_init_sentinel(&set->free_slots);
dll_init_sentinel(&set->used_slots); dll_init_sentinel(&set->used_slots);
@ -69,7 +69,7 @@ font_set_init(Font_Set *set, Partition *partition, i32 max, i16 live_max){
dll_insert(&set->free_slots, (Font_Slot*)ptr); dll_insert(&set->free_slots, (Font_Slot*)ptr);
ptr += sizeof(Font_Slot) + sizeof(Render_Font); ptr += sizeof(Font_Slot) + sizeof(Render_Font);
} }
set->font_used_flags = push_array(partition, b8, max); set->font_used_flags = push_array(partition, b8, max);
set->live_max = live_max; set->live_max = live_max;
} }
@ -87,12 +87,12 @@ font_set_add_hash(Font_Set *set, String name, i16 font_id){
entry.hash = font_hash(name); entry.hash = font_hash(name);
entry.name = name; entry.name = name;
entry.font_id = font_id; entry.font_id = font_id;
u32 i, j; u32 i, j;
i = entry.hash % set->max; i = entry.hash % set->max;
j = i - 1; j = i - 1;
if (i <= 1) j += set->max; if (i <= 1) j += set->max;
for (; i != j; ++i){ for (; i != j; ++i){
if (i == set->max) i = 0; if (i == set->max) i = 0;
if (set->entries[i].font_id == 0){ if (set->entries[i].font_id == 0){
@ -100,7 +100,7 @@ font_set_add_hash(Font_Set *set, String name, i16 font_id){
break; break;
} }
} }
Assert(i != j); Assert(i != j);
} }
@ -119,7 +119,7 @@ font_set_load(Partition *partition, Font_Set *set, i16 font_id){
font__insert(&set->used_slots, slot); font__insert(&set->used_slots, slot);
Render_Font *font = (Render_Font*)(slot + 1); Render_Font *font = (Render_Font*)(slot + 1);
set->font_load(font, info->filename.str, info->pt_size, 4); set->font_load(font, info->filename.str, info->pt_size, 4, 1);
info->font = font; info->font = font;
slot->font_id = font_id; slot->font_id = font_id;
} }
@ -145,7 +145,7 @@ internal void
font_set_use(Partition *partition, Font_Set *set, i16 font_id){ font_set_use(Partition *partition, Font_Set *set, i16 font_id){
b8 already_used; b8 already_used;
already_used = set->font_used_flags[font_id-1]; already_used = set->font_used_flags[font_id-1];
if (!already_used){ if (!already_used){
if (set->used_this_frame < set->live_max){ if (set->used_this_frame < set->live_max){
++set->used_this_frame; ++set->used_this_frame;
@ -153,7 +153,7 @@ font_set_use(Partition *partition, Font_Set *set, i16 font_id){
already_used = 1; already_used = 1;
} }
} }
if (already_used){ if (already_used){
// TODO(allen): optimize if you don't mind!!!! // TODO(allen): optimize if you don't mind!!!!
Font_Info *info = get_font_info(set, font_id); Font_Info *info = get_font_info(set, font_id);
@ -165,7 +165,7 @@ font_set_use(Partition *partition, Font_Set *set, i16 font_id){
font_set_load(partition, set, font_id); font_set_load(partition, set, font_id);
} }
slot = ((Font_Slot*)info->font) - 1; slot = ((Font_Slot*)info->font) - 1;
font__remove(slot); font__remove(slot);
font__insert(&set->used_slots, slot); font__insert(&set->used_slots, slot);
} }
@ -176,12 +176,16 @@ font_set_add(Partition *partition, Font_Set *set,
String filename, String name, i32 pt_size){ String filename, String name, i32 pt_size){
b32 result = 0; b32 result = 0;
if (font_set_can_add(set)){ if (font_set_can_add(set)){
Render_Font dummy_font = {0};
i16 font_id = (i16)(++set->count); i16 font_id = (i16)(++set->count);
Font_Info *info = get_font_info(set, font_id); Font_Info *info = get_font_info(set, font_id);
info->filename = filename; info->filename = filename;
info->name = name; info->name = name;
info->pt_size = pt_size; info->pt_size = pt_size;
set->font_info_load(partition, filename.str, pt_size, &info->height, &info->advance); set->font_load(&dummy_font, info->filename.str, info->pt_size, 4, 0);
info->height = dummy_font.height;
info->advance = dummy_font.advance;
font_set_add_hash(set, name, font_id); font_set_add_hash(set, name, font_id);
if (font_set_can_load(set)){ if (font_set_can_load(set)){
@ -201,7 +205,7 @@ font_set_find_pos(Font_Set *set, String name, u32 *position){
i = hash % set->max; i = hash % set->max;
j = i - 1; j = i - 1;
if (j <= 1) j += set->max; if (j <= 1) j += set->max;
result = 0; result = 0;
Font_Table_Entry *entry; Font_Table_Entry *entry;
for (; i != j; ++i){ for (; i != j; ++i){
@ -215,7 +219,7 @@ font_set_find_pos(Font_Set *set, String name, u32 *position){
} }
} }
} }
return(result); return(result);
} }
@ -228,7 +232,7 @@ font_set_extract(Font_Set *set, String name, i16 *font_id){
if (result){ if (result){
*font_id = set->entries[position].font_id; *font_id = set->entries[position].font_id;
} }
return(result); return(result);
} }

View File

@ -305,101 +305,14 @@ launch_rendering(Render_Target *target){
#undef ExtractStruct #undef ExtractStruct
internal i32
draw_font_info_load(Partition *partition,
char *filename_untranslated,
i32 pt_size, i32 *height, i32 *advance){
char space_[1024];
String filename = make_fixed_width_string(space_);
b32 translate_success = sysshared_to_binary_path(&filename, filename_untranslated);
if (!translate_success) return 0;
i32 result = 1;
File_Data file;
file = sysshared_load_file(filename.str);
Temp_Memory temp = begin_temp_memory(partition);
stbtt_packedchar *chardata = push_array(partition, stbtt_packedchar, 256);
i32 oversample = 2;
i32 tex_width, tex_height;
tex_width = pt_size*128*oversample;
tex_height = pt_size*2*oversample;
void *block = push_block(partition, tex_width * tex_height);
if (!file.data.data){
result = 0;
}
else{
stbtt_fontinfo font;
if (!stbtt_InitFont(&font, (u8*)file.data.data, 0)){
result = 0;
}
else{
i32 ascent, descent, line_gap;
f32 scale;
stbtt_GetFontVMetrics(&font, &ascent, &descent, &line_gap);
scale = stbtt_ScaleForPixelHeight(&font, (f32)pt_size);
f32 scaled_ascent, scaled_descent, scaled_line_gap;
scaled_ascent = scale*ascent;
scaled_descent = scale*descent;
scaled_line_gap = scale*line_gap;
i32 font_height = (i32)(scaled_ascent - scaled_descent + scaled_line_gap);
stbtt_pack_context spc;
if (stbtt_PackBegin(&spc, (u8*)block, tex_width, tex_height, tex_width, 1, partition)){
stbtt_PackSetOversampling(&spc, oversample, oversample);
if (stbtt_PackFontRange(&spc, (u8*)file.data.data, 0,
STBTT_POINT_SIZE((f32)pt_size), 0, 128, chardata)){
// do nothing
}
else{
result = 0;
}
stbtt_PackEnd(&spc);
}
else{
result = 0;
}
if (result){
i32 max_advance = 0;
for (u8 code_point = 0; code_point < 128; ++code_point){
if (stbtt_FindGlyphIndex(&font, code_point) != 0){
i32 adv = CEIL32(chardata[code_point].xadvance);
if (max_advance < adv){
max_advance = adv;
}
}
}
*height = font_height;
*advance = max_advance - 1;
}
}
system_free_memory(file.data.data);
}
end_temp_memory(temp);
return(result);
}
internal i32 internal i32
draw_font_load(Partition *part, draw_font_load(Partition *part,
Render_Font *font_out, Render_Font *font_out,
char *filename_untranslated, char *filename_untranslated,
i32 pt_size, i32 pt_size,
i32 tab_width, i32 tab_width,
i32 oversample){ i32 oversample,
b32 store_texture){
char space_[1024]; char space_[1024];
String filename = make_fixed_width_string(space_); String filename = make_fixed_width_string(space_);
@ -410,12 +323,6 @@ draw_font_load(Partition *part,
stbtt_packedchar *chardata = font_out->chardata; stbtt_packedchar *chardata = font_out->chardata;
Temp_Memory temp = begin_temp_memory(part);
i32 tex_width = pt_size*16*oversample;
i32 tex_height = pt_size*16*oversample;
void *block = sysshared_push_block(part, tex_width * tex_height);
File_Data file = sysshared_load_file(filename.str); File_Data file = sysshared_load_file(filename.str);
if (!file.data.data){ if (!file.data.data){
@ -428,85 +335,89 @@ draw_font_load(Partition *part,
result = 0; result = 0;
} }
else{ else{
memset(font_out, 0, sizeof(*font_out));
i32 ascent, descent, line_gap; i32 ascent, descent, line_gap;
f32 scale;
stbtt_GetFontVMetrics(&font, &ascent, &descent, &line_gap); stbtt_GetFontVMetrics(&font, &ascent, &descent, &line_gap);
scale = stbtt_ScaleForPixelHeight(&font, (f32)pt_size);
f32 scaled_ascent, scaled_descent, scaled_line_gap; f32 scale = stbtt_ScaleForPixelHeight(&font, (f32)pt_size);
scaled_ascent = scale*ascent; f32 scaled_ascent = scale*ascent;
scaled_descent = scale*descent; f32 scaled_descent = scale*descent;
scaled_line_gap = scale*line_gap; f32 scaled_line_gap = scale*line_gap;
font_out->height = (i32)(scaled_ascent - scaled_descent + scaled_line_gap); font_out->height = (i32)(scaled_ascent - scaled_descent + scaled_line_gap);
font_out->ascent = (i32)(scaled_ascent); font_out->ascent = (i32)(scaled_ascent);
font_out->descent = (i32)(scaled_descent); font_out->descent = (i32)(scaled_descent);
font_out->line_skip = (i32)(scaled_line_gap); font_out->line_skip = (i32)(scaled_line_gap);
font_out->tex_width = tex_width; if (store_texture){
font_out->tex_height = tex_height; Temp_Memory temp = begin_temp_memory(part);
stbtt_pack_context spc; i32 tex_width = pt_size*16*oversample;
i32 tex_height = pt_size*16*oversample;
// TODO(allen): If this fails we can just expand the partition here now void *block = sysshared_push_block(part, tex_width * tex_height);
// rather than forcing the user to do it.
if (stbtt_PackBegin(&spc, (u8*)block, tex_width, tex_height, font_out->tex_width = tex_width;
tex_width, 1, part)){ font_out->tex_height = tex_height;
stbtt_PackSetOversampling(&spc, oversample, oversample);
if (!stbtt_PackFontRange(&spc, (u8*)file.data.data, 0, stbtt_pack_context spc;
STBTT_POINT_SIZE((f32)pt_size),
0, 128, chardata)){ if (stbtt_PackBegin(&spc, (u8*)block, tex_width, tex_height,
tex_width, 1, part)){
stbtt_PackSetOversampling(&spc, oversample, oversample);
if (!stbtt_PackFontRange(&spc, (u8*)file.data.data, 0,
STBTT_POINT_SIZE((f32)pt_size),
0, 128, chardata)){
result = 0;
}
stbtt_PackEnd(&spc);
}
else{
result = 0; result = 0;
} }
stbtt_PackEnd(&spc); if (result){
} GLuint font_tex;
else{ glGenTextures(1, &font_tex);
result = 0; glBindTexture(GL_TEXTURE_2D, font_tex);
}
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
if (result){ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
GLuint font_tex; glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glGenTextures(1, &font_tex);
glBindTexture(GL_TEXTURE_2D, font_tex); glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, tex_width, tex_height, 0, GL_ALPHA, GL_UNSIGNED_BYTE, block);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); font_out->tex = font_tex;
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); glBindTexture(GL_TEXTURE_2D, 0);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
font_out->chardata['\r'] = font_out->chardata[' '];
glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, tex_width, tex_height, 0, GL_ALPHA, GL_UNSIGNED_BYTE, block); font_out->chardata['\n'] = font_out->chardata[' '];
font_out->chardata['\t'] = font_out->chardata[' '];
font_out->tex = font_tex; font_out->chardata['\t'].xadvance *= tab_width;
glBindTexture(GL_TEXTURE_2D, 0);
i32 max_advance = 0;
font_out->chardata['\r'] = font_out->chardata[' ']; for (u8 code_point = 0; code_point < 128; ++code_point){
font_out->chardata['\n'] = font_out->chardata[' ']; if (stbtt_FindGlyphIndex(&font, code_point) != 0){
font_out->chardata['\t'] = font_out->chardata[' ']; font_out->glyphs[code_point].exists = 1;
font_out->chardata['\t'].xadvance *= tab_width; i32 advance = CEIL32(font_out->chardata[code_point].xadvance);
if (max_advance < advance) max_advance = advance;
i32 max_advance = 0; font_out->advance_data[code_point] = font_out->chardata[code_point].xadvance;
for (u8 code_point = 0; code_point < 128; ++code_point){ }
if (stbtt_FindGlyphIndex(&font, code_point) != 0){ else if (code_point == '\r' || code_point == '\n' || code_point == '\t'){
font_out->glyphs[code_point].exists = 1; font_out->advance_data[code_point] = font_out->chardata[code_point].xadvance;
i32 advance = CEIL32(font_out->chardata[code_point].xadvance); }
if (max_advance < advance) max_advance = advance;
font_out->advance_data[code_point] = font_out->chardata[code_point].xadvance;
}
else if (code_point == '\r' || code_point == '\n' || code_point == '\t'){
font_out->advance_data[code_point] = font_out->chardata[code_point].xadvance;
} }
font_out->advance = max_advance - 1;
} }
font_out->advance = max_advance - 1;
end_temp_memory(temp);
} }
} }
system_free_memory(file.data.data); system_free_memory(file.data.data);
} }
end_temp_memory(temp);
return(result); return(result);
} }

View File

@ -115,16 +115,11 @@ typedef Draw_Push_Piece_Sig(Draw_Push_Piece);
Render_Font *font_out, \ Render_Font *font_out, \
char *filename, \ char *filename, \
i32 pt_size, \ i32 pt_size, \
i32 tab_width) i32 tab_width, \
b32 store_texture)
typedef Font_Load_Sig(Font_Load); typedef Font_Load_Sig(Font_Load);
#define Font_Info_Load_Sig(name) i32 name( \
Partition *partition, \
char *filename, \
i32 pt_size, \
i32 *height, \
i32 *advance)
typedef Font_Info_Load_Sig(Font_Info_Load);
#define Release_Font_Sig(name) void name(Render_Font *font) #define Release_Font_Sig(name) void name(Render_Font *font)
typedef Release_Font_Sig(Release_Font); typedef Release_Font_Sig(Release_Font);
@ -158,7 +153,7 @@ struct Font_Set{
Font_Slot free_slots; Font_Slot free_slots;
Font_Slot used_slots; Font_Slot used_slots;
Font_Info_Load *font_info_load; //Font_Info_Load *font_info_load;
Font_Load *font_load; Font_Load *font_load;
Release_Font *release_font; Release_Font *release_font;

View File

@ -128,101 +128,6 @@ buffer_reverse_seek_delimiter(Buffer_Type *buffer, int pos, char delim){
return(pos); return(pos);
} }
#if 0
internal_4tech int
buffer_seek_whitespace_down(Buffer_Type *buffer, int pos){
Buffer_Stringify_Type loop;
char *data;
int end;
int size;
int no_hard;
int prev_endline;
size = buffer_size(buffer);
loop = buffer_stringify_loop(buffer, pos, size);
for (;buffer_stringify_good(&loop);
buffer_stringify_next(&loop)){
end = loop.size + loop.absolute_pos;
data = loop.data - loop.absolute_pos;
for (;pos < end; ++pos){
if (!is_whitespace(data[pos])) goto buffer_seek_whitespace_down_mid;
}
}
buffer_seek_whitespace_down_mid:
no_hard = 0;
prev_endline = -1;
for (;buffer_stringify_good(&loop);
buffer_stringify_next(&loop)){
end = loop.size + loop.absolute_pos;
data = loop.data - loop.absolute_pos;
for (; pos < end; ++pos){
if (data[pos] == '\n'){
if (no_hard) goto buffer_seek_whitespace_down_end;
else{
no_hard = 1;
prev_endline = pos;
}
}
else if (!is_whitespace(data[pos])){
no_hard = 0;
}
}
}
buffer_seek_whitespace_down_end:
if (prev_endline == -1 || prev_endline+1 >= size) pos = size;
else pos = prev_endline+1;
return pos;
}
internal_4tech int
buffer_seek_whitespace_up(Buffer_Type *buffer, int pos){
Buffer_Backify_Type loop;
char *data;
int end;
int size;
int no_hard;
size = buffer_size(buffer);
loop = buffer_backify_loop(buffer, pos-1, 1);
for (;buffer_backify_good(&loop);
buffer_backify_next(&loop)){
end = loop.absolute_pos;
data = loop.data - loop.absolute_pos;
for (;pos >= end; --pos){
if (!is_whitespace(data[pos])) goto buffer_seek_whitespace_up_mid;
}
}
buffer_seek_whitespace_up_mid:
no_hard = 0;
for (;buffer_backify_good(&loop);
buffer_backify_next(&loop)){
end = loop.absolute_pos;
data = loop.data - loop.absolute_pos;
for (; pos >= end; --pos){
if (data[pos] == '\n'){
if (no_hard) goto buffer_seek_whitespace_up_end;
else no_hard = 1;
}
else if (!is_whitespace(data[pos])){
no_hard = 0;
}
}
}
buffer_seek_whitespace_up_end:
if (pos != 0) ++pos;
return pos;
}
#endif
internal_4tech int internal_4tech int
buffer_seek_whitespace_right(Buffer_Type *buffer, int pos){ buffer_seek_whitespace_right(Buffer_Type *buffer, int pos){
Buffer_Stringify_Type loop; Buffer_Stringify_Type loop;
@ -948,6 +853,8 @@ buffer_get_line_index_range(Buffer_Type *buffer, int pos, int l_bound, int u_bou
lines = buffer->line_starts; lines = buffer->line_starts;
assert_4tech(lines != 0);
start = l_bound; start = l_bound;
end = u_bound; end = u_bound;
for (;;){ for (;;){
@ -967,8 +874,7 @@ buffer_get_line_index_range(Buffer_Type *buffer, int pos, int l_bound, int u_bou
inline_4tech int inline_4tech int
buffer_get_line_index(Buffer_Type *buffer, int pos){ buffer_get_line_index(Buffer_Type *buffer, int pos){
int result; int result = buffer_get_line_index_range(buffer, pos, 0, buffer->line_count);
result = buffer_get_line_index_range(buffer, pos, 0, buffer->line_count);
return(result); return(result);
} }

View File

@ -29,6 +29,7 @@
#include "system_shared.h" #include "system_shared.h"
#define SUPPORT_DPI 1 #define SUPPORT_DPI 1
#define USE_WIN32_FONTS 1
#define FPS 60 #define FPS 60
#define frame_useconds (1000000 / FPS) #define frame_useconds (1000000 / FPS)
@ -1137,9 +1138,11 @@ Sys_CLI_End_Update_Sig(system_cli_end_update){
return close_me; return close_me;
} }
#include "system_shared.cpp" #include "system_shared.cpp"
#include "4ed_rendering.cpp" #include "4ed_rendering.cpp"
#if USE_WIN32_FONTS
#include "win32_font.cpp"
#endif
internal f32 internal f32
size_change(i32 dpi_x, i32 dpi_y){ size_change(i32 dpi_x, i32 dpi_y){
@ -1168,10 +1171,12 @@ Font_Load_Sig(system_draw_font_load){
filename, filename,
pt_size, pt_size,
tab_width, tab_width,
oversample); oversample,
store_texture);
// TODO(allen): Make the growable partition something that can // TODO(allen): Make the growable partition something
// just be passed directly to font load and let it be grown there. // that can just be passed directly to font load and
// let it be grown there.
if (!success){ if (!success){
Win32ScratchPartitionDouble(&win32vars.font_part); Win32ScratchPartitionDouble(&win32vars.font_part);
} }
@ -1190,13 +1195,15 @@ Win32LoadAppCode(){
App_Get_Functions *get_funcs = 0; App_Get_Functions *get_funcs = 0;
#if UseWinDll #if UseWinDll
win32vars.app_code = LoadLibraryA("4ed_app.dll"); win32vars.app_code = LoadLibraryA("4ed_app.dll");
if (win32vars.app_code){ if (win32vars.app_code){
get_funcs = (App_Get_Functions*) get_funcs = (App_Get_Functions*)
GetProcAddress(win32vars.app_code, "app_get_functions"); GetProcAddress(win32vars.app_code, "app_get_functions");
} }
#else #else
File_Data file = system_load_file("4ed_app.dll"); File_Data file = system_load_file("4ed_app.dll");
if (file.got_file){ if (file.got_file){
@ -1291,7 +1298,7 @@ Win32LoadRenderCode(){
win32vars.target.pop_clip = draw_pop_clip; win32vars.target.pop_clip = draw_pop_clip;
win32vars.target.push_piece = draw_push_piece; win32vars.target.push_piece = draw_push_piece;
win32vars.target.font_set.font_info_load = draw_font_info_load; //win32vars.target.font_set.font_info_load = draw_font_info_load;
win32vars.target.font_set.font_load = system_draw_font_load; win32vars.target.font_set.font_load = system_draw_font_load;
win32vars.target.font_set.release_font = draw_release_font; win32vars.target.font_set.release_font = draw_release_font;
} }

25
win32_font.cpp Normal file
View File

@ -0,0 +1,25 @@
/*
* Mr. 4th Dimention - Allen Webster
*
* 12.12.2014
*
* Win32 font rendering for nicer fonts
*
*/
// TOP
internal i32
win32_draw_font_load(Partition *part,
Render_Font *font_out,
char *filename_untranslated,
i32 pt_size,
i32 tab_width,
i32 oversample){
i32 result = 1;
return(result);
}
// BOTTOM