almost ready to implement fonts on windows

master
Allen Webster 2017-03-12 19:24:18 -04:00
parent 6c8930d6f8
commit 2be3b6bdae
10 changed files with 265 additions and 154 deletions

View File

@ -876,10 +876,7 @@ DOC_SEE(Buffer_Setting_ID)
new_value = 48;
}
if (new_value != file->settings.display_width){
//i16 font_id = file->settings.font_id;
//Font_Info *font_info = get_font_info(models->font_set, font_id);
//Render_Font *font = font_info->font;
Render_Font *font = 0;
Render_Font *font = system->font.get_render_data_by_id(file->settings.font_id);
file_set_width(system, models, file, new_value, font);
}
}break;
@ -891,9 +888,7 @@ DOC_SEE(Buffer_Setting_ID)
new_value = 0;
}
if (new_value != file->settings.minimum_base_display_width){
//i16 font_id = file->settings.font_id;
//Render_Font *font = get_font_info(models->font_set, font_id)->font;
Render_Font *font = 0;
Render_Font *font = system->font.get_render_data_by_id(file->settings.font_id);
file_set_min_base_width(system, models, file, new_value, font);
}
}break;
@ -978,13 +973,11 @@ DOC_SEE(Buffer_Setting_ID)
}
if (full_remeasure){
//i16 font_id = file->settings.font_id;
//Render_Font *font = get_font_info(models->font_set, font_id)->font;
Render_Font *font = 0;
Render_Font *font = system->font.get_render_data_by_id(file->settings.font_id);
file_allocate_character_starts_as_needed(&models->mem.general, file);
buffer_measure_character_starts(&file->state.buffer, file->state.character_starts, 0, file->settings.virtual_white);
file_measure_wraps(models, file, font);
buffer_measure_character_starts(system, font, &file->state.buffer, file->state.character_starts, 0, file->settings.virtual_white);
file_measure_wraps(system, models, file, font);
file_update_cursor_positions(system, models, file);
}
}break;

View File

@ -952,6 +952,7 @@ file_allocate_character_starts_as_needed(General_Memory *general, Editing_File *
internal void
file_measure_character_starts(System_Functions *system, Models *models, Editing_File *file){
file_allocate_character_starts_as_needed(&models->mem.general, file);
Render_Font *font = system->font.get_render_data_by_id(file->settings.font_id);
buffer_measure_character_starts(system, font, &file->state.buffer, file->state.character_starts, 0, file->settings.virtual_white);
file_update_cursor_positions(system, models, file);
}
@ -1067,7 +1068,7 @@ struct Code_Wrap_Step{
};
internal Code_Wrap_Step
wrap_state_consume_token(Code_Wrap_State *state, i32 fixed_end_point){
wrap_state_consume_token(System_Functions *system, Render_Font *font, Code_Wrap_State *state, i32 fixed_end_point){
Code_Wrap_Step result = {0};
i32 i = state->i;
@ -1132,7 +1133,6 @@ wrap_state_consume_token(Code_Wrap_State *state, i32 fixed_end_point){
}
u8 ch = (u8)state->stream.data[i];
translating_fully_process_byte(system, font, &state->tran, ch, i, state->size, &state->emits);
for (TRANSLATION_OUTPUT(state->J, state->emits)){
@ -1737,7 +1737,7 @@ file_measure_wraps(System_Functions *system, Models *models, Editing_File *file,
}
if (!emit_comment_position){
step = wrap_state_consume_token(&wrap_state, next_line_start-1);
step = wrap_state_consume_token(system, font, &wrap_state, next_line_start-1);
}
b32 need_to_choose_a_wrap = 0;
@ -1855,7 +1855,7 @@ file_measure_wraps(System_Functions *system, Models *models, Editing_File *file,
wrap_state = original_wrap_state;
for (;;){
step = wrap_state_consume_token(&wrap_state, wrap_position);
step = wrap_state_consume_token(system, font, &wrap_state, wrap_position);
if (step.position_end >= wrap_position){
break;
}
@ -1881,7 +1881,7 @@ file_measure_wraps(System_Functions *system, Models *models, Editing_File *file,
++real_count;
for (i32 l = 0; wrap_state.i < next_line_start && l < 3; ++l){
wrap_state_consume_token(&wrap_state, next_line_start);
wrap_state_consume_token(system, font, &wrap_state, next_line_start);
}
}
@ -1925,7 +1925,7 @@ file_measure_wraps(System_Functions *system, Models *models, Editing_File *file,
internal void
file_measure_wraps_and_fix_cursor(System_Functions *system, Models *models, Editing_File *file, Render_Font *font){
file_measure_wraps(models, file, font);
file_measure_wraps(system, models, file, font);
file_update_cursor_positions(system, models, file);
}
@ -1976,19 +1976,16 @@ file_create_from_string(System_Functions *system, Models *models, Editing_File *
}
file_synchronize_times(system, file);
// TODO(allen): batch some of these together so we can avoid
// making so many passes over the buffer?
Font_ID font_id = models->global_font_id;
file->settings.font_id = font_id;
Render_Font *font = 0;
file_measure_starts(general, &file->state.buffer);
file_allocate_character_starts_as_needed(general, file);
buffer_measure_character_starts(&file->state.buffer, file->state.character_starts, 0, file->settings.virtual_white);
buffer_measure_character_starts(system, font, &file->state.buffer, file->state.character_starts, 0, file->settings.virtual_white);
Font_ID font_id = models->global_font_id;
file->settings.font_id = font_id;
//Render_Font *font = get_font_info(font_set, font_id)->font;
Render_Font *font = 0;
file_measure_wraps(models, file, font);
file_measure_wraps(system, models, file, font);
file->settings.read_only = read_only;
if (!read_only){
@ -3282,7 +3279,7 @@ file_do_single_edit(System_Functions *system, Models *models, Editing_File *file
buffer_remeasure_starts(buffer, line_start, line_end, line_shift, shift_amount);
file_allocate_character_starts_as_needed(general, file);
buffer_remeasure_character_starts(buffer, line_start, line_end, line_shift, file->state.character_starts, 0, file->settings.virtual_white);
buffer_remeasure_character_starts(system, font, buffer, line_start, line_end, line_shift, file->state.character_starts, 0, file->settings.virtual_white);
// TODO(allen): Redo this as some sort of dialogical API
#if 0
@ -3290,7 +3287,7 @@ file_do_single_edit(System_Functions *system, Models *models, Editing_File *file
buffer_remeasure_wrap_y(buffer, line_start, line_end, line_shift, file->state.wraps, (f32)font->height, font->advance_data, (f32)file->settings.display_width);
#endif
file_measure_wraps(models, file, font);
file_measure_wraps(system, models, file, font);
// NOTE(allen): cursor fixing
Cursor_Fix_Descriptor desc = {0};
@ -3399,13 +3396,14 @@ file_do_batch_edit(System_Functions *system, Models *models, Editing_File *file,
Buffer_Measure_Starts measure_state = {};
buffer_measure_starts(&measure_state, &file->state.buffer);
// TODO(allen): write the remeasurement version
file_allocate_character_starts_as_needed(&models->mem.general, file);
buffer_measure_character_starts(&file->state.buffer, file->state.character_starts, 0, file->settings.virtual_white);
//Render_Font *font = get_font_info(models->font_set, file->settings.font_id)->font;
Render_Font *font = 0;
file_measure_wraps(models, file, font);
// TODO(allen): write the remeasurement version
file_allocate_character_starts_as_needed(&models->mem.general, file);
buffer_measure_character_starts(system, font, &file->state.buffer, file->state.character_starts, 0, file->settings.virtual_white);
file_measure_wraps(system, models, file, font);
// NOTE(allen): cursor fixing
Cursor_Fix_Descriptor desc = {0};

Binary file not shown.

View File

@ -560,12 +560,10 @@ launch_rendering(Render_Target *target){
#define internal static
internal void
font_load_freetype_page_inner(Partition *part, Render_Font *font, FT_Library ft, FT_Face face, b32 use_hinting, Layout_Page *layout_page, u32 page_number, i32 tab_width){
font_load_page_inner(Partition *part, Render_Font *font, FT_Library ft, FT_Face face, b32 use_hinting, Glyph_Page *page, u32 page_number, i32 tab_width){
Temp_Memory temp = begin_temp_memory(part);
Assert(layout_page != 0);
layout_page->page_number = page_number;
Glyph_Page *glyph_page = (Glyph_Page*)(layout_page + 1);
Assert(page != 0);
page->page_number = page_number;
// prepare to read glyphs into a temporary texture buffer
i32 max_glyph_w = face->size->metrics.x_ppem;
@ -600,10 +598,10 @@ font_load_freetype_page_inner(Partition *part, Render_Font *font, FT_Library ft,
// fill the texture
u32 base_codepoint = (page_number << 8);
Glyph_Bounds *glyphs = &glyph_page->glyphs[0];
Glyph_Bounds *glyphs = &page->glyphs[0];
Glyph_Bounds *glyph_ptr = glyphs;
f32 *advances = &layout_page->advance[0];
f32 *advances = &page->advance[0];
f32 *advance_ptr = advances;
for(u32 i = 0; i < ITEM_PER_FONT_PAGE; ++i, ++glyph_ptr, ++advance_ptr){
u32 codepoint = i + base_codepoint;
@ -652,12 +650,11 @@ font_load_freetype_page_inner(Partition *part, Render_Font *font, FT_Library ft,
// upload texture
tex_height = round_up_pot_u32(pen_y + max_glyph_h + 2);
glyph_page->tex_width = tex_width;
glyph_page->tex_height = tex_height;
page->tex_width = tex_width;
page->tex_height = tex_height;
u32 tex;
glGenTextures(1, &tex);
glBindTexture(GL_TEXTURE_2D, tex);
glGenTextures(1, &page->tex);
glBindTexture(GL_TEXTURE_2D, page->tex);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
@ -668,7 +665,6 @@ font_load_freetype_page_inner(Partition *part, Render_Font *font, FT_Library ft,
glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, tex_width, tex_height, 0, GL_ALPHA, GL_UNSIGNED_INT, pixels);
glBindTexture(GL_TEXTURE_2D, 0);
glyph_page->tex = tex;
end_temp_memory(temp);
@ -685,11 +681,29 @@ font_load_freetype_page_inner(Partition *part, Render_Font *font, FT_Library ft,
}
internal b32
font_load_freetype(Partition *part, Render_Font *font, char *filename, i32 pt_size, i32 tab_width, b32 use_hinting){
font_load_page(System_Functions *system, Partition *part, Render_Font *font, char *filename, i32 pt_size, i32 tab_width, b32 use_hinting, u32 page_number){
// TODO(allen): Stop redoing all this init for each call.
FT_Library ft;
FT_Init_FreeType(&ft);
FT_Face face;
FT_New_Face(ft, filename, 0, &face);
// NOTE(allen): set texture and glyph data.
Glyph_Page *page = font_get_or_make_page(system, font, page_number);
font_load_page_inner(part, font, ft, face, use_hinting, page, page_number, tab_width);
FT_Done_FreeType(ft);
return(true);
}
internal b32
font_load(System_Functions *system, Partition *part, Render_Font *font, char *filename, i32 pt_size, i32 tab_width, b32 use_hinting){
memset(font, 0, sizeof(*font));
#if 0
// TODO(allen): Stop redoing all this init for each call.
FT_Library ft;
FT_Init_FreeType(&ft);
@ -703,7 +717,6 @@ font_load_freetype(Partition *part, Render_Font *font, char *filename, i32 pt_si
size.height = pt_size << 6;
FT_Request_Size(face, &size);
font->loaded = true;
font->ascent = ceil32 (face->size->metrics.ascender / 64.0f);
font->descent = floor32 (face->size->metrics.descender / 64.0f);
font->advance = ceil32 (face->size->metrics.max_advance / 64.0f);
@ -714,46 +727,31 @@ font_load_freetype(Partition *part, Render_Font *font, char *filename, i32 pt_si
font->line_skip = 0;
// NOTE(allen): set texture and glyph data.
Glyph_Page *page = font_get_or_make_page(font, 0);
Glyph_Page *page = font_get_or_make_page(system, font, 0);
font_load_freetype_page_inner(part, font, ft, face, use_hinting, page, 0, tab_width);
// NOTE(allen): Setup some basic spacing stuff.
f32 backslash_adv = get_codepoint_advance(font, '\\');
f32 backslash_adv = page->advance['\\'];
f32 max_hex_advance = 0.f;
for (u32 i = '0'; i <= '9'; ++i){
f32 adv = get_codepoint_advance(font, i);
f32 adv = page->advance[i];
max_hex_advance = Max(max_hex_advance, adv);
}
for (u32 i = 'a'; i <= 'f'; ++i){
f32 adv = get_codepoint_advance(font, i);
f32 adv = page->advance[i];
max_hex_advance = Max(max_hex_advance, adv);
}
for (u32 i = 'A'; i <= 'F'; ++i){
f32 adv = get_codepoint_advance(font, i);
f32 adv = page->advance[i];
max_hex_advance = Max(max_hex_advance, adv);
}
font->byte_advance = backslash_adv + max_hex_advance*2;
FT_Done_FreeType(ft);
#endif
return(true);
}
#if 0
internal
Release_Font_Sig(draw_release_font){
for (u32 i = 0; i < ArrayCount(font->pages); ++i){
Glyph_Page *page = font->pages[i];
if (IS_REAL_FONT_PAGE(page)){
glDeleteTextures(1, &page->tex);
FREE(page);
}
FREE(font->pages);
}
}
#endif
// BOTTOM

View File

@ -14,18 +14,6 @@
#define ITEM_PER_FONT_PAGE 256
struct Layout_Page{
u32 page_number;
f32 advance[ITEM_PER_FONT_PAGE];
};
struct Render_Font{
Layout_Page **_layout_pages;
u32 page_count, page_max;
f32 byte_advance;
i32 height, ascent, descent, line_skip, advance;
};
struct Glyph_Bounds{
f32 x0, x1;
f32 y0, y1;
@ -34,16 +22,34 @@ struct Glyph_Bounds{
};
global_const Glyph_Bounds null_glyph_bounds = {0};
struct Glyph_Data{
Glyph_Bounds bounds;
struct Glyph_Page{
u32 page_number;
f32 advance[ITEM_PER_FONT_PAGE];
Glyph_Bounds glyphs[ITEM_PER_FONT_PAGE];
u32 tex;
i32 tex_width, tex_height;
};
struct Glyph_Page{
#define FONT_PAGE_EMPTY ((Glyph_Page*)0)
#define FONT_PAGE_DELETED ((Glyph_Page*)(1))
#define FONT_PAGE_MAX 0x1100
struct Render_Font{
Glyph_Page **pages;
u32 page_count, page_max;
f32 byte_advance;
i32 height, ascent, descent, line_skip, advance;
char filename[256];
char name[256];
u32 filename_len;
u32 name_len;
};
struct Glyph_Data{
Glyph_Bounds bounds;
u32 tex;
i32 tex_width, tex_height;
Glyph_Bounds glyphs[ITEM_PER_FONT_PAGE];
};
#endif

View File

@ -15,6 +15,7 @@
typedef u32 Font_ID;
struct Render_Font;
struct Glyph_Page;
#define Sys_Font_Get_Count_Sig(name_) u32 (name_)(void)
typedef Sys_Font_Get_Count_Sig(Font_Get_Count_Function);
@ -31,12 +32,21 @@ typedef Sys_Font_Get_Name_By_ID_Sig(Font_Get_Name_By_ID_Function);
#define Sys_Font_Get_Render_Data_By_ID_Sig(name_) Render_Font* (name_)(u32 font_id)
typedef Sys_Font_Get_Render_Data_By_ID_Sig(Font_Get_Render_Data_By_ID_Function);
#define Sys_Font_Allocate_Sig(name_) void* (name_)(umem size)
typedef Sys_Font_Allocate_Sig(Font_Allocate_Function);
#define Sys_Font_Free_Sig(name_) void (name_)(void *ptr)
typedef Sys_Font_Free_Sig(Font_Free_Function);
struct Font_Functions{
Font_Get_Count_Function *get_count;
Font_Get_IDs_By_Index_Function *get_ids_by_index;
Font_Get_Name_By_Index_Function *get_name_by_index;
Font_Get_Name_By_ID_Function *get_name_by_id;
Font_Get_Render_Data_By_ID_Function *get_render_data_by_id;
Font_Allocate_Function *allocate;
Font_Free_Function *free;
};
internal f32 font_get_byte_advance(Render_Font *font);
@ -48,6 +58,8 @@ internal i32 font_get_advance(Render_Font *font);
internal b32 font_can_render(struct System_Functions *system, Render_Font *font, u32 codepoint);
internal Glyph_Page *font_get_or_make_page(struct System_Functions *system, Render_Font *font, u32 page_number);
#endif
// BOTTOM

View File

@ -41,6 +41,125 @@ font_get_advance(Render_Font *font){
return(font->advance);
}
internal b32
font_can_render(System_Functions *system, Render_Font *font, u32 codepoint){
b32 result = false;
u32 page_number = (codepoint >> 8);
u32 glyph_index = codepoint & 0xFF;
Glyph_Page *page = font_get_or_make_page(system, font, page_number);
if (page != 0 && page->advance[glyph_index] > 0.f){
result = true;
}
return(result);
}
internal Glyph_Page**
font_page_lookup(Render_Font *font, u32 page_number, b32 get_empty_slot){
Glyph_Page **result = 0;
if (font->page_max > 0){
u32 first_index = page_number % font->page_max;
u32 range_count = 0;
u32 ranges[4];
if (first_index == 0){
ranges[0] = 0;
ranges[1] = font->page_max;
range_count = 2;
}
else{
ranges[0] = first_index;
ranges[1] = font->page_max;
ranges[2] = 0;
ranges[3] = first_index;
range_count = 4;
}
Glyph_Page **pages = font->pages;
if (get_empty_slot){
for (u32 j = 0; j < range_count; j += 2){
u32 stop = ranges[j+1];
for (u32 i = ranges[j]; i < stop; ++i){
if (pages[i] == FONT_PAGE_EMPTY || pages[i] == FONT_PAGE_DELETED){
result = &pages[i];
goto break2;
}
if (pages[i]->page_number == page_number){
goto break2;
}
}
}
}
else{
for (u32 j = 0; j < range_count; j += 2){
u32 stop = ranges[j+1];
for (u32 i = ranges[j]; i < stop; ++i){
if (pages[i] == FONT_PAGE_EMPTY){
goto break2;
}
if (pages[i] != FONT_PAGE_DELETED && pages[i]->page_number == page_number){
result = &pages[i];
goto break2;
}
}
}
}
break2:;
}
return(result);
}
internal Glyph_Page*
font_get_or_make_page(System_Functions *system, Render_Font *font, u32 page_number){
Glyph_Page *result = 0;
if (page_number <= 0x10FF){
Glyph_Page **page_get_result = font_page_lookup(font, page_number, false);
if (page_get_result == 0){
b32 has_space = true;
u32 new_page_count = 1;
u32 new_max = (font->page_count+new_page_count)*3;
if (font->page_max < FONT_PAGE_MAX && new_max > font->page_max*2){
Glyph_Page **pages = (Glyph_Page**)system->font.allocate(sizeof(Glyph_Page*)*new_max);
has_space = false;
if (pages != 0){
memset(pages, 0, sizeof(*pages)*new_max);
u32 old_max = font->page_max;
for (u32 i = 0; i < old_max; ++i){
Glyph_Page *this_page = pages[i];
if (this_page != FONT_PAGE_EMPTY && this_page != FONT_PAGE_DELETED){
u32 this_page_number = this_page->page_number;
Glyph_Page **dest = font_page_lookup(font, this_page_number, true);
Assert(dest != 0);
*dest = this_page;
}
}
system->font.free(font->pages);
font->pages = pages;
font->page_max = new_max;
has_space = true;
}
}
if (has_space){
Glyph_Page *new_page = (Glyph_Page*)system->font.allocate(sizeof(Glyph_Page));
if (new_page != 0){
Glyph_Page **dest = font_page_lookup(font, page_number, true);
Assert(dest != 0);
*dest = new_page;
font->page_count += new_page_count;
result = new_page;
}
}
}
}
return(result);
}
// BOTTOM

View File

@ -1391,45 +1391,6 @@ Sys_Send_Exit_Signal_Sig(system_send_exit_signal){
#include "4ed_system_shared.cpp"
#include "win32_ft_font.cpp"
internal f32
size_change(i32 dpi_x, i32 dpi_y){
// TODO(allen): We're just hoping dpi_x == dpi_y for now I guess.
f32 size_x = dpi_x / 96.f;
f32 size_y = dpi_y / 96.f;
f32 size_max = Max(size_x, size_y);
return(size_max);
}
#if 0
internal
Font_Load_Sig(font_load){
if (win32vars.font_part.base == 0){
win32vars.font_part = Win32ScratchPartition(MB(8));
}
#if SUPPORT_DPI
pt_size = round32(pt_size * size_change(win32vars.dpi_x, win32vars.dpi_y));
#endif
// TODO(allen): Make the growable partition something that can just be passed directly to font load and let it be grown there.
b32 success = false;
for (u32 R = 0; R < 3; ++R){
success = win32_ft_font_load(&win32vars.font_part, font_out, filename, pt_size, tab_width,win32vars.settings.use_hinting);
if (success){
break;
}
else{
Win32ScratchPartitionDouble(&win32vars.font_part);
}
}
return(success);
}
#endif
//
// Linkage to Custom and Application
//

53
win32_4ed_fonts.cpp Normal file
View File

@ -0,0 +1,53 @@
/*
* Mr. 4th Dimention - Allen Webster
*
* 09.02.2016
*
* Shared system functions
*
*/
// TOP
#include "4ed_system_shared.cpp"
#include "font/4coder_font_interface.h"
internal
Sys_Font_Get_Count_Sig(system_font_get_count){
}
internal
Sys_Font_Get_IDs_By_Index_Sig(system_font_get_ids_by_index){
}
internal
Sys_Font_Get_Name_By_Index_Sig(system_font_get_name_by_index){
}
internal
Sys_Font_Get_Name_By_ID_Sig(system_font_get_name_by_id){
}
internal
Sys_Font_Get_Render_Data_By_ID_Sig(system_font_get_render_data_by_id){
}
internal
Sys_Font_Allocate_Sig(system_font_allocate){
}
internal
Sys_Font_Free_Sig(system_font_free){
}
// BOTTOM

View File

@ -1,29 +0,0 @@
/*
* Mr. 4th Dimention - Allen Webster
*
* ??.??.2016
*
* For getting the font files on Linux.
*
*/
// TOP
// TODO(allen): Get system fonts
internal b32
win32_ft_font_load(Partition *part, Render_Font *rf, char *name, i32 pt_size, i32 tab_width, b32 use_hinting){
Temp_Memory temp = begin_temp_memory(part);
char* filename = push_array(part, char, 256);
b32 result = false;
if (filename != 0){
String str = make_string_cap(filename, 0, 256);
sysshared_to_binary_path(&str, name);
result = font_load_freetype(part, rf, filename, pt_size, tab_width, use_hinting);
}
end_temp_memory(temp);
return(result);
}
// BOTTOM