From f15c59c621401693370cc96635e8e8ebb9377e88 Mon Sep 17 00:00:00 2001 From: Allen Webster Date: Sun, 19 Nov 2017 19:47:55 -0500 Subject: [PATCH] Lots of progress towards new font face system --- 4ed_app_target.cpp | 2 +- 4ed_file_view.cpp | 188 +++++++++++++++++++++++++++++++-- 4ed_font.h | 10 +- 4ed_font_provider_freetype.cpp | 67 ++++++++++++ 4ed_font_provider_freetype.h | 3 + 4ed_linked_node_macros.h | 1 + 4ed_render_fill.cpp | 1 - 4ed_render_format.h | 16 ++- 4ed_render_target.cpp | 7 -- 4ed_render_target.h | 8 ++ 4ed_view.cpp | 5 +- opengl/4ed_opengl_render.cpp | 7 ++ platform_linux/linux_4ed.cpp | 3 +- platform_mac/mac_4ed.cpp | 3 +- platform_win32/win32_4ed.cpp | 3 +- 15 files changed, 298 insertions(+), 26 deletions(-) diff --git a/4ed_app_target.cpp b/4ed_app_target.cpp index cb9299e8..08fc33ff 100644 --- a/4ed_app_target.cpp +++ b/4ed_app_target.cpp @@ -33,8 +33,8 @@ # include "4ed_debug_mem.h" #endif -#include "4ed_render_format.h" #include "4ed_render_target.h" +#include "4ed_render_format.h" #include "4ed.h" #include "4ed_buffer_model.h" diff --git a/4ed_file_view.cpp b/4ed_file_view.cpp index abe181c6..54366893 100644 --- a/4ed_file_view.cpp +++ b/4ed_file_view.cpp @@ -3537,8 +3537,8 @@ style_get_color(Style *style, Cpp_Token token){ } internal void -file_set_font(System_Functions *system, Models *models, Editing_File *file, Font_ID font_id){ - file->settings.font_id = font_id; +file_full_remeasure(System_Functions *system, Models *models, Editing_File *file){ + Font_ID font_id = file->settings.font_id; Font_Pointers font = system->font.get_pointers_by_id(font_id); file_measure_wraps_and_fix_cursor(system, models, file, font); @@ -3550,6 +3550,12 @@ file_set_font(System_Functions *system, Models *models, Editing_File *file, Font } } +internal void +file_set_font(System_Functions *system, Models *models, Editing_File *file, Font_ID font_id){ + file->settings.font_id = font_id; + file_full_remeasure(system, models, file); +} + internal void global_set_font(System_Functions *system, Models *models, Font_ID font_id){ File_Node *node = 0; @@ -3561,6 +3567,20 @@ global_set_font(System_Functions *system, Models *models, Font_ID font_id){ models->global_font_id = font_id; } +internal void +alter_font(System_Functions *system, Models *models, Font_ID font_id, Font_Settings *new_settings){ + if (system->font.change_settings(font_id, new_settings)){ + File_Node *node = 0; + File_Node *sentinel = &models->working_set.used_sentinel; + for (dll_items(node, sentinel)){ + Editing_File *file = (Editing_File*)node; + if (file->settings.font_id == font_id){ + file_full_remeasure(system, models, file); + } + } + } +} + inline void view_show_GUI(View *view, Models *models, View_UI ui){ view->map = mapid_ui; @@ -4511,18 +4531,83 @@ step_file_view(System_Functions *system, View *view, Models *models, View *activ Editing_File *file = view->file_data.file; Assert(file != 0); - message = make_lit_string("Back"); - id.id[0] = 0; - if (gui_do_button(target, id, message)){ + if (gui_do_button(target, id, make_lit_string("Back"))){ view->color_mode = CV_Mode_Library; } gui_begin_scrollable(target, scroll_context, view->gui_scroll, 9*view->line_height, show_scrollbar); Font_ID font_id = file->settings.font_id; - Font_ID new_font_id = 0; + +#if 1 + + // NEW + Font_ID largest_id = system->font.get_largest_id(); + for (Font_ID i = 1; i <= largest_id; ++i){ + Font_Pointers font = system->font.get_pointers_by_id(i); + if (font.valid){ + Font_Settings *settings = font.settings; + Font_Metrics *metrics = font.metrics; + + char space[512]; + String m = make_fixed_width_string(space); + if (i == font_id){ + append(&m, "* "); + } + + append(&m, "family:\""); + append(&m, make_string(metrics->name, metrics->name_len)); + append(&m, "\" size:"); + append_int_to_str(&m, settings->pt_size); + append(&m, " hint:"); + append(&m, (settings->use_hinting)?"ON ":"OFF"); + + if (i == font_id){ + append(&m, " *"); + } + + id.id[0] = i; + id.id[1] = 0; + if (gui_do_button(target, id, m)){ + if (new_font_id == 0){ + new_font_id = i; + } + } + + id.id[0] = i; + id.id[1] = 1; + if (gui_do_button(target, id, make_lit_string("edit"))){ + view->font_edit_id = i; + if (view->color_mode == CV_Mode_Font){ + view->color_mode = CV_Mode_Font_Editing; + } + else{ + view->color_mode = CV_Mode_Global_Font_Editing; + } + } + } + } + + id.id[0] = 0; + id.id[1] = 2; + if (gui_do_button(target, id, make_lit_string("new face"))){ + if (new_font_id == 0){ + Font_Pointers font = system->font.get_pointers_by_id(font_id); + view->font_edit_id = system->font.load_new_font(&font.settings->stub); + if (view->color_mode == CV_Mode_Font){ + view->color_mode = CV_Mode_Font_Editing; + } + else{ + view->color_mode = CV_Mode_Global_Font_Editing; + } + } + } + +#else + + // OLD i32 total_count = system->font.get_loadable_count(); for (i32 i = 0; i < total_count; ++i){ Font_Loadable_Description loadable = {0}; @@ -4542,11 +4627,13 @@ step_file_view(System_Functions *system, View *view, Models *models, View *activ } } - if (new_font_id != 0 && new_font_id != font_id){ - if (view->color_mode == CV_Mode_Font){ +#endif + + if (new_font_id != 0){ + if (view->color_mode == CV_Mode_Font && new_font_id != font_id){ file_set_font(system, models, file, new_font_id); } - else{ + else if (new_font_id != font_id || new_font_id != models->global_font_id){ global_set_font(system, models, new_font_id); } } @@ -4554,6 +4641,89 @@ step_file_view(System_Functions *system, View *view, Models *models, View *activ gui_end_scrollable(target); }break; + case CV_Mode_Font_Editing: + case CV_Mode_Global_Font_Editing: + { + id.id[0] = 0; + if (gui_do_button(target, id, make_lit_string("Back"))){ + if (view->color_mode == CV_Mode_Font_Editing){ + view->color_mode = CV_Mode_Font; + } + else{ + view->color_mode = CV_Mode_Global_Font; + } + } + + Font_ID font_edit_id = view->font_edit_id; + Font_Pointers font = system->font.get_pointers_by_id(font_edit_id); + Font_Settings *settings = font.settings; + Font_Metrics *metrics = font.metrics; + Font_Settings new_settings = *settings; + b32 has_new_settings = false; + + char space[128]; + String m = make_fixed_width_string(space); + copy(&m, "Size Up ("); + append_int_to_str(&m, settings->pt_size); + append(&m, ")"); + ++id.id[0]; + if (gui_do_button(target, id, m)){ + if (!has_new_settings){ + has_new_settings = true; + ++new_settings.pt_size; + } + } + + copy(&m, "Size Down ("); + append_int_to_str(&m, settings->pt_size); + append(&m, ")"); + ++id.id[0]; + if (gui_do_button(target, id, m)){ + if (!has_new_settings){ + has_new_settings = true; + --new_settings.pt_size; + } + } + + copy(&m, "Turn Hinting "); + append(&m, settings->use_hinting?"Off":"On"); + append(&m, " (it is currently "); + append(&m, settings->use_hinting?"On":"Off"); + append(&m, ")"); + ++id.id[0]; + if (gui_do_button(target, id, m)){ + if (!has_new_settings){ + has_new_settings = true; + new_settings.use_hinting = !new_settings.use_hinting; + } + } + + copy(&m, "Current Family: "); + append(&m, make_string(metrics->name, metrics->name_len)); + ++id.id[0]; + gui_do_button(target, id, m); + + i32 total_count = system->font.get_loadable_count(); + for (i32 i = 0; i < total_count; ++i){ + Font_Loadable_Description loadable = {0}; + system->font.get_loadable(i, &loadable); + + if (loadable.valid){ + String name = make_string(loadable.display_name, loadable.display_len); + if (gui_do_button(target, id, name)){ + if (!has_new_settings){ + has_new_settings = true; + memcpy(&new_settings.stub, &loadable.stub, sizeof(loadable.stub)); + } + } + } + } + + if (has_new_settings){ + alter_font(system, models, font_edit_id, &new_settings); + } + }break; + case CV_Mode_Adjusting: { Style *style = main_style(models); diff --git a/4ed_font.h b/4ed_font.h index 4a760028..2b21baee 100644 --- a/4ed_font.h +++ b/4ed_font.h @@ -109,13 +109,19 @@ typedef Sys_Font_Get_Loadable_Sig(Font_Get_Loadable_Function, index, out); #define Sys_Font_Load_New_Font_Sig(n,s) Font_ID (n)(Font_Loadable_Stub *s) typedef Sys_Font_Load_New_Font_Sig(Font_Load_New_Font_Function, stub); +#define Sys_Font_Change_Settings_Sig(n,id,s) b32 (n)(Font_ID id, Font_Settings *s) +typedef Sys_Font_Change_Settings_Sig(Font_Change_Settings_Function, font_id, new_settings); + +#define Sys_Font_Get_Largest_ID_Sig(n) Font_ID (n)(void) +typedef Sys_Font_Get_Largest_ID_Sig(Font_Get_Largest_ID_Function); + #define Sys_Font_Get_Count_Sig(n) i32 (n)(void) typedef Sys_Font_Get_Count_Sig(Font_Get_Count_Function); #define Sys_Font_Get_Name_By_ID_Sig(n, font_id, out, cap) i32 (n)(Font_ID font_id, char *out, u32 cap) typedef Sys_Font_Get_Name_By_ID_Sig(Font_Get_Name_By_ID_Function, font_id, out, cap); -#define Sys_Font_Get_Pointers_By_ID_Sig(n,font_id) Font_Pointers (n)(Font_ID font_id) +#define Sys_Font_Get_Pointers_By_ID_Sig(n, font_id) Font_Pointers (n)(Font_ID font_id) typedef Sys_Font_Get_Pointers_By_ID_Sig(Font_Get_Pointers_By_ID_Function, font_id); #define Sys_Font_Load_Page_Sig(n,s,m,p,pn) void (n)(Font_Settings *s, Font_Metrics *m, Glyph_Page *p, u32 pn) @@ -131,6 +137,8 @@ struct Font_Functions{ Font_Get_Loadable_Count_Function *get_loadable_count; Font_Get_Loadable_Function *get_loadable; Font_Load_New_Font_Function *load_new_font; + Font_Change_Settings_Function *change_settings; + Font_Get_Largest_ID_Function *get_largest_id; Font_Get_Count_Function *get_count; Font_Get_Name_By_ID_Function *get_name_by_id; Font_Get_Pointers_By_ID_Function *get_pointers_by_id; diff --git a/4ed_font_provider_freetype.cpp b/4ed_font_provider_freetype.cpp index 35b505bc..d28bf815 100644 --- a/4ed_font_provider_freetype.cpp +++ b/4ed_font_provider_freetype.cpp @@ -261,6 +261,28 @@ font_load_page_pixels(Partition *part, Font_Settings *settings, Glyph_Page *page return(pixels); } +internal void +font_release_pages(System_Functions *system, Font_Page_Storage *storage){ + u32 old_max = storage->page_max; + Glyph_Page **old_pages = storage->pages; + + for (u32 i = 0; i < old_max; ++i){ + Glyph_Page *this_page = old_pages[i]; + if (this_page != FONT_PAGE_EMPTY && this_page != FONT_PAGE_DELETED){ + if (this_page->has_gpu_setup){ + Assert(sizeof(Render_Pseudo_Command_Free_Texture)%8 == 0); + Render_Pseudo_Command_Free_Texture *c = push_array(&target.buffer, Render_Pseudo_Command_Free_Texture, 1); + c->header.size = sizeof(*c); + c->free_texture_node.tex_id = this_page->gpu_tex; + sll_push(target.free_texture_first, target.free_texture_last, &c->free_texture_node); + } + system->font.free(this_page); + } + } + + system->font.free(old_pages); +} + internal b32 font_load(System_Functions *system, Font_Settings *settings, Font_Metrics *metrics, Font_Page_Storage *pages){ i32 pt_size = settings->pt_size; @@ -519,9 +541,18 @@ Sys_Font_Load_New_Font_Sig(system_font_load_new_font, stub){ new_id = 0; } + if (new_id > fontvars.largest_font_id){ + fontvars.largest_font_id = new_id; + } + return(new_id); } +internal +Sys_Font_Get_Largest_ID_Sig(system_font_get_largest_id){ + return(fontvars.largest_font_id); +} + internal Sys_Font_Get_Count_Sig(system_font_get_count){ return(fontvars.used_slot_count); @@ -548,6 +579,40 @@ system_font_get_active_location(Font_ID font_id){ return(result); } +internal +Sys_Font_Change_Settings_Sig(system_font_change_settings, font_id, new_settings){ + if (font_id == 0){ + return(false); + } + + Font_Slot_Page_And_Index page_and_index = system_font_get_active_location(font_id); + if (page_and_index.page == 0){ + return(false); + } + + Font_Settings *old_settings = &page_and_index.page->settings[page_and_index.index]; + if (memcmp(new_settings, old_settings, sizeof(*new_settings)) == 0){ + return(false); + } + + b32 made_change = false; + + Font_Metrics temp_metrics = {0}; + Font_Page_Storage temp_pages = {0}; + + if (font_load(&sysfunc, new_settings, &temp_metrics, &temp_pages)){ + Font_Metrics *metrics_ptr = &page_and_index.page->metrics[page_and_index.index]; + Font_Page_Storage *pages_ptr = &page_and_index.page->pages[page_and_index.index]; + font_release_pages(&sysfunc, pages_ptr); + memcpy(old_settings, new_settings, sizeof(*old_settings)); + memcpy(metrics_ptr, &temp_metrics, sizeof(*metrics_ptr)); + memcpy(pages_ptr, &temp_pages, sizeof(*pages_ptr)); + made_change = true; + } + + return(made_change); +} + internal Sys_Font_Get_Name_By_ID_Sig(system_font_get_name_by_id, font_id, str_out, capacity){ i32 length = 0; @@ -643,6 +708,8 @@ system_font_init(Font_Functions *font_links, u32 pt_size, b32 use_hinting, Font_ font_links->get_loadable_count = system_font_get_loadable_count; font_links->get_loadable = system_font_get_loadable; font_links->load_new_font = system_font_load_new_font; + font_links->change_settings = system_font_change_settings; + font_links->get_largest_id = system_font_get_largest_id; font_links->get_count = system_font_get_count; font_links->get_name_by_id = system_font_get_name_by_id; font_links->get_pointers_by_id = system_font_get_pointers_by_id; diff --git a/4ed_font_provider_freetype.h b/4ed_font_provider_freetype.h index 99cde6e5..ef1a60b8 100644 --- a/4ed_font_provider_freetype.h +++ b/4ed_font_provider_freetype.h @@ -48,7 +48,10 @@ struct Font_Vars{ Font_Slot_Page slot_pages_sentinel; i32 used_slot_count; i32 max_slot_count; + Font_ID largest_font_id; + // HACK(allen): // HACK(allen): // HACK(allen): + // TODO(allen): Upgrade this to have "unlimited" resizable memory. Font_Loadable_Description loadables[4096]; i32 loadable_count; diff --git a/4ed_linked_node_macros.h b/4ed_linked_node_macros.h index abb6bc74..6fef18cc 100644 --- a/4ed_linked_node_macros.h +++ b/4ed_linked_node_macros.h @@ -25,6 +25,7 @@ // NOTE(allen): These macros work on structs with a next // pointer to the saem type as the containing struct. +#define sll_clear(f,l) (f)=(l)=0 #define sll_push(f,l,n) if((f)==0&&(l)==0){(f)=(l)=(n);}else{(l)->next=(n);(l)=(n);}(l)->next=0 #define sll_pop(f,l) if((f)!=(l)){(f)=(f)->next;}else{(f)=(l)=0;} diff --git a/4ed_render_fill.cpp b/4ed_render_fill.cpp index fa439880..4c86881b 100644 --- a/4ed_render_fill.cpp +++ b/4ed_render_fill.cpp @@ -27,7 +27,6 @@ draw_change_clip(Render_Target *target, i32_Rect clip_box){ internal void begin_render_section(Render_Target *target, System_Functions *system){ - target->buffer.pos = 0; target->clip_top = -1; i32_Rect clip; diff --git a/4ed_render_format.h b/4ed_render_format.h index ba00e712..4615c4ca 100644 --- a/4ed_render_format.h +++ b/4ed_render_format.h @@ -13,12 +13,17 @@ enum Render_Command_Type{ RenCom_Rectangle, RenCom_Outline, RenCom_Glyph, - RenCom_ChangeClip + RenCom_ChangeClip, }; struct Render_Command_Header{ - i32 size; - i32 type; + union{ + struct{ + i32 size; + i32 type; + }; + u64 force_8_byte_align_; + }; }; struct Render_Command_Rectangle{ @@ -47,5 +52,10 @@ struct Render_Command_Change_Clip{ i32_Rect box; }; +struct Render_Pseudo_Command_Free_Texture{ + Render_Command_Header header; + Render_Free_Texture free_texture_node; +}; + // BOTTOM diff --git a/4ed_render_target.cpp b/4ed_render_target.cpp index 59d1131b..d0bd0978 100644 --- a/4ed_render_target.cpp +++ b/4ed_render_target.cpp @@ -23,13 +23,6 @@ Render_Begin_Push_Sig(render_internal_begin_push, t, ptr, size){ if (out != 0){ memcpy(out, ptr, size); } - - // TODO(allen): Application side logging. -#if 0 - else{ - LOG("Render command buffer out of memory!\n"); - } -#endif return(out); } diff --git a/4ed_render_target.h b/4ed_render_target.h index 0df2e289..215e6106 100644 --- a/4ed_render_target.h +++ b/4ed_render_target.h @@ -12,6 +12,11 @@ #if !defined(FRED_RENDER_TARGET_H) #define FRED_RENDER_TARGET_H +struct Render_Free_Texture{ + Render_Free_Texture *next; + u32 tex_id; +}; + struct Render_Target{ i32_Rect clip_boxes[5]; i32 clip_top; @@ -20,6 +25,9 @@ struct Render_Target{ i32 bound_texture; u32 color; + Render_Free_Texture *free_texture_first; + Render_Free_Texture *free_texture_last; + Partition buffer; }; diff --git a/4ed_view.cpp b/4ed_view.cpp index 3a661217..a14f2272 100644 --- a/4ed_view.cpp +++ b/4ed_view.cpp @@ -65,7 +65,9 @@ enum Color_View_Mode{ CV_Mode_Library, CV_Mode_Font, CV_Mode_Global_Font, - CV_Mode_Adjusting + CV_Mode_Font_Editing, + CV_Mode_Global_Font_Editing, + CV_Mode_Adjusting, }; struct Scroll_Context{ @@ -132,6 +134,7 @@ struct View{ View *hot_file_view; u32 *palette; Color_View_Mode color_mode; + Font_ID font_edit_id; Super_Color color; b32 p4c_only; Style_Library inspecting_styles; diff --git a/opengl/4ed_opengl_render.cpp b/opengl/4ed_opengl_render.cpp index a0559748..765161c2 100644 --- a/opengl/4ed_opengl_render.cpp +++ b/opengl/4ed_opengl_render.cpp @@ -105,6 +105,13 @@ interpret_render_buffer(Render_Target *t){ glColor4f(0.f, 0.f, 0.f, 0.f); t->color = 0; + for (Render_Free_Texture *free_texture = t->free_texture_first; + free_texture != 0; + free_texture = free_texture->next){ + glDeleteTextures(1, &free_texture->tex_id); + } + sll_clear(t->free_texture_first, t->free_texture_last); + u8 *start = (u8*)t->buffer.base; u8 *end = (u8*)t->buffer.base + t->buffer.pos; Render_Command_Header *header = 0; diff --git a/platform_linux/linux_4ed.cpp b/platform_linux/linux_4ed.cpp index a4df6009..9d9a32a2 100644 --- a/platform_linux/linux_4ed.cpp +++ b/platform_linux/linux_4ed.cpp @@ -39,8 +39,8 @@ #include "4ed_font.h" #include "4ed_system.h" #include "4ed_log.h" -#include "4ed_render_format.h" #include "4ed_render_target.h" +#include "4ed_render_format.h" #include "4ed.h" #include "4ed_linked_node_macros.h" @@ -1809,6 +1809,7 @@ main(int argc, char **argv){ b32 keep_running = linuxvars.keep_running; // NOTE(allen): Application Core Update + target.buffer.pos = 0; if (app.step != 0){ app.step(&sysfunc, &target, &memory_vars, &linuxvars.input, &result); } diff --git a/platform_mac/mac_4ed.cpp b/platform_mac/mac_4ed.cpp index 57d1643e..de21c2cb 100644 --- a/platform_mac/mac_4ed.cpp +++ b/platform_mac/mac_4ed.cpp @@ -38,8 +38,8 @@ #include "4ed_font.h" #include "4ed_system.h" #include "4ed_log.h" -#include "4ed_render_format.h" #include "4ed_render_target.h" +#include "4ed_render_format.h" #include "4ed.h" #include "4ed_linked_node_macros.h" @@ -588,6 +588,7 @@ osx_step(void){ b32 keep_running = osxvars.keep_running; // NOTE(allen): Application Core Update + target.buffer.pos = 0; if (app.step != 0){ app.step(&sysfunc, &target, &memory_vars, &frame_input, &result); } diff --git a/platform_win32/win32_4ed.cpp b/platform_win32/win32_4ed.cpp index 49fc67d9..d7983fca 100644 --- a/platform_win32/win32_4ed.cpp +++ b/platform_win32/win32_4ed.cpp @@ -49,8 +49,8 @@ #include "4ed_font.h" #include "4ed_system.h" #include "4ed_log.h" -#include "4ed_render_format.h" #include "4ed_render_target.h" +#include "4ed_render_format.h" #include "4ed.h" #include "4ed_linked_node_macros.h" @@ -1518,6 +1518,7 @@ WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdS } // NOTE(allen): Application Core Update + target.buffer.pos = 0; if (app.step != 0){ app.step(&sysfunc, &target, &memory_vars, &input, &result); }