Entire font core system up and running, still need docs and nicer font usage in default framework

This commit is contained in:
Allen Webster 2017-11-20 18:31:57 -05:00
parent a85ddda2a7
commit 6a725838d3
18 changed files with 612 additions and 158 deletions

View File

@ -709,7 +709,7 @@ STRUCT Theme_Color{
};
/*
DOC(Theme lists ever color that makes up a standard color scheme.)
DOC(Theme lists every color that makes up a standard color scheme.)
DOC_SEE(int_color)
*/
STRUCT Theme{
@ -717,6 +717,44 @@ STRUCT Theme{
int_color colors[Stag_COUNT];
};
/*
DOC(Available_Font contains a name for a font was detected at startup either in the local 4coder font folder, or by the system. An available font is not necessarily loaded yet, and may fail to load for various reasons even though it appearsin the available font list.)
DOC_SEE(get_available_font)
*/
STRUCT Available_Font{
char name[64];
bool32 in_local_font_folder;
};
/*
DOC(Every face is assigned a unique and consistent Face_ID for it's life time. This represents a slot in which a face can exist. The face in the slot is always valid once it exists, but the face might be changed or released durring it's lifetime. A Face_ID value of zero is reserved for the meaning "not a valid face".)
*/
TYPEDEF uint32_t Face_ID;
/*
DOC(Face_Description contains all the information unique to a single font face, including the font name, the size, and style of the face.)
DOC_SEE(get_available_font)
*/
STRUCT Face_Description{
/* DOC(Indicates a face's association with an available font. This should be an exact copy of an Available_Font returned by get_available_fonts.) DOC_SEE(get_available_font) */
Available_Font font;
/* DOC(Indicates the size for the face. Valid values must be greater than 0. Different fonts with the same pt_size do not necessarily have the same line height.) */
int32_t pt_size;
/* DOC(Indicates whether the face tries to use a bold style.) */
bool32 bold;
/* DOC(Indicates whether the face tries to use an italic style.) */
bool32 italic;
/* DOC(Indicates whether the face tries to underline text.) */
bool32 underline;
/* DOC(Indicates whether the face tries to apply hinting.) */
bool32 hinting;
};
/* DOC(A Buffer_Batch_Edit_Type is a type of batch operation.) */
ENUM(int32_t, Buffer_Batch_Edit_Type){
/* DOC(The BatchEdit_Normal operation is always correct but does the most work if there are tokens to correct.) */

View File

@ -1114,6 +1114,149 @@ load_themes_folder(Application_Links *app){
}
}
//
// Font Helpers
//
static bool32
descriptions_match(Face_Description *a, Face_Description *b){
bool32 result = false;
if (match(a->font.name, b->font.name) && a->font.in_local_font_folder == b->font.in_local_font_folder){
if (memcmp((&a->pt_size), (&b->pt_size), sizeof(*a) - sizeof(a->font)) == 0){
result = true;
}
}
return(result);
}
static Face_ID
get_existing_face_id_matching_name(Application_Links *app, char *name, int32_t len){
String name_str = make_string(name, len);
Face_ID largest_id = get_largest_face_id(app);
Face_ID result = 0;
for (Face_ID id = 1; id <= largest_id; ++id){
Face_Description compare = get_face_description(app, id);
if (match(compare.font.name, name_str)){
result = id;
break;
}
}
return(result);
}
static Face_ID
get_existing_face_id_matching_description(Application_Links *app, Face_Description *description){
Face_ID largest_id = get_largest_face_id(app);
Face_ID result = 0;
for (Face_ID id = 1; id <= largest_id; ++id){
Face_Description compare = get_face_description(app, id);
if (descriptions_match(&compare, description)){
result = id;
break;
}
}
return(result);
}
static Face_ID
get_face_id_by_name(Application_Links *app, char *name, int32_t len, Face_Description *base_description){
Face_ID new_id = 0;
String str = make_string(name, len);
if (!match(str, base_description->font.name)){
new_id = get_existing_face_id_matching_name(app, name, len);
if (new_id == 0){
Face_Description description = *base_description;
copy_fast_unsafe_cs(description.font.name, str);
description.font.name[str.size] = 0;
description.font.in_local_font_folder = false;
new_id = try_create_new_face(app, &description);
if (new_id == 0){
description.font.in_local_font_folder = true;
new_id = try_create_new_face(app, &description);
}
}
}
return(new_id);
}
static void
change_font(Application_Links *app, char *name, int32_t len, bool32 apply_to_all_buffers){
Face_ID global_face_id = get_face_id(app, 0);
Face_Description description = get_face_description(app, global_face_id);
Face_ID new_id = get_face_id_by_name(app, name, len, &description);
if (new_id != 0){
set_global_face(app, new_id, apply_to_all_buffers);
}
}
static void
buffer_set_font(Application_Links *app, Buffer_Summary *buffer, char *name, int32_t len){
Face_ID current_id = get_face_id(app, buffer);
if (current_id != 0){
Face_Description description = get_face_description(app, current_id);
Face_ID new_id = get_face_id_by_name(app, name, len, &description);
if (new_id != 0){
buffer_set_face(app, buffer, new_id);
}
}
}
static Face_ID
get_face_id_by_description(Application_Links *app, Face_Description *description, Face_Description *base_description){
Face_ID new_id = 0;
if (!descriptions_match(description, base_description)){
new_id = get_existing_face_id_matching_description(app, description);
if (new_id == 0){
new_id = try_create_new_face(app, description);
}
}
return(new_id);
}
static void
change_face_description(Application_Links *app, Face_Description *new_description, bool32 apply_to_all_buffers){
Face_ID global_face_id = get_face_id(app, 0);
Face_Description old_description = get_face_description(app, global_face_id);
Face_ID new_id = get_face_id_by_description(app, new_description, &old_description);
if (new_id != 0){
set_global_face(app, new_id, apply_to_all_buffers);
}
}
static void
buffer_set_face_description(Application_Links *app, Buffer_Summary *buffer, Face_Description *new_description){
Face_ID current_id = get_face_id(app, buffer);
if (current_id != 0){
Face_Description old_description = get_face_description(app, current_id);
Face_ID new_id = get_face_id_by_description(app, new_description, &old_description);
if (new_id != 0){
buffer_set_face(app, buffer, new_id);
}
}
}
static Face_Description
get_buffer_face_description(Application_Links *app, Buffer_Summary *buffer){
Face_ID current_id = get_face_id(app, buffer);
Face_Description description = {0};
if (current_id != 0){
description = get_face_description(app, current_id);
}
return(description);
}
static Face_Description
get_global_face_description(Application_Links *app){
Face_ID current_id = get_face_id(app, 0);
Face_Description description = get_face_description(app, current_id);
return(description);
}
//
// Framework Init Functions
//
@ -1140,7 +1283,7 @@ default_4coder_initialize(Application_Links *app, bool32 use_scrollbars, bool32
String font = get_default_font_name();
change_theme(app, theme.str, theme.size);
change_font(app, font.str, font.size, 1);
change_font(app, font.str, font.size, true);
default_use_scrollbars = use_scrollbars;
default_use_file_bars = use_file_bars;

View File

@ -204,7 +204,7 @@ OPEN_FILE_HOOK_SIG(default_file_settings){
buffer_set_setting(app, &buffer, BufferSetting_LexWithoutStrings, true);
buffer_set_setting(app, &buffer, BufferSetting_VirtualWhitespace, true);
}
else if (treat_as_code && enable_code_wrapping && buffer.size < (1 << 18)){
else if (treat_as_code && enable_code_wrapping && buffer.size < (512 << 10)){
// NOTE(allen|a4.0.12): There is a little bit of grossness going on here.
// If we set BufferSetting_Lex to true, it will launch a lexing job.
// If a lexing job is active when we set BufferSetting_VirtualWhitespace, the call can fail.

View File

@ -56,9 +56,16 @@ struct Application_Links;
#define PRINT_MESSAGE_SIG(n) void n(Application_Links *app, char *str, int32_t len)
#define CREATE_THEME_SIG(n) void n(Application_Links *app, Theme *theme, char *name, int32_t len)
#define CHANGE_THEME_SIG(n) void n(Application_Links *app, char *name, int32_t len)
#define CHANGE_FONT_SIG(n) void n(Application_Links *app, char *name, int32_t len, bool32 apply_to_all_files)
#define BUFFER_SET_FONT_SIG(n) void n(Application_Links *app, Buffer_Summary *buffer, char *name, int32_t len)
#define BUFFER_GET_FONT_SIG(n) bool32 n(Application_Links *app, Buffer_Summary *buffer, char *name_out, int32_t name_max)
#define GET_LARGEST_FACE_ID_SIG(n) Face_ID n(Application_Links *app)
#define SET_GLOBAL_FACE_SIG(n) bool32 n(Application_Links *app, Face_ID id, bool32 apply_to_all_buffers)
#define BUFFER_SET_FACE_SIG(n) bool32 n(Application_Links *app, Buffer_Summary *buffer, Face_ID id)
#define GET_FACE_DESCRIPTION_SIG(n) Face_Description n(Application_Links *app, Face_ID id)
#define GET_FACE_ID_SIG(n) Face_ID n(Application_Links *app, Buffer_Summary *buffer)
#define TRY_CREATE_NEW_FACE_SIG(n) Face_ID n(Application_Links *app, Face_Description *description)
#define TRY_MODIFY_FACE_SIG(n) bool32 n(Application_Links *app, Face_ID id, Face_Description *description)
#define TRY_RELEASE_FACE_SIG(n) bool32 n(Application_Links *app, Face_ID id, Face_ID replacement_id)
#define GET_AVAILABLE_FONT_COUNT_SIG(n) int32_t n(Application_Links *app)
#define GET_AVAILABLE_FONT_SIG(n) Available_Font n(Application_Links *app, int32_t index)
#define SET_THEME_COLORS_SIG(n) void n(Application_Links *app, Theme_Color *colors, int32_t count)
#define GET_THEME_COLORS_SIG(n) void n(Application_Links *app, Theme_Color *colors, int32_t count)
#define DIRECTORY_GET_HOT_SIG(n) int32_t n(Application_Links *app, char *out, int32_t capacity)
@ -133,9 +140,16 @@ typedef END_QUERY_BAR_SIG(End_Query_Bar_Function);
typedef PRINT_MESSAGE_SIG(Print_Message_Function);
typedef CREATE_THEME_SIG(Create_Theme_Function);
typedef CHANGE_THEME_SIG(Change_Theme_Function);
typedef CHANGE_FONT_SIG(Change_Font_Function);
typedef BUFFER_SET_FONT_SIG(Buffer_Set_Font_Function);
typedef BUFFER_GET_FONT_SIG(Buffer_Get_Font_Function);
typedef GET_LARGEST_FACE_ID_SIG(Get_Largest_Face_ID_Function);
typedef SET_GLOBAL_FACE_SIG(Set_Global_Face_Function);
typedef BUFFER_SET_FACE_SIG(Buffer_Set_Face_Function);
typedef GET_FACE_DESCRIPTION_SIG(Get_Face_Description_Function);
typedef GET_FACE_ID_SIG(Get_Face_ID_Function);
typedef TRY_CREATE_NEW_FACE_SIG(Try_Create_New_Face_Function);
typedef TRY_MODIFY_FACE_SIG(Try_Modify_Face_Function);
typedef TRY_RELEASE_FACE_SIG(Try_Release_Face_Function);
typedef GET_AVAILABLE_FONT_COUNT_SIG(Get_Available_Font_Count_Function);
typedef GET_AVAILABLE_FONT_SIG(Get_Available_Font_Function);
typedef SET_THEME_COLORS_SIG(Set_Theme_Colors_Function);
typedef GET_THEME_COLORS_SIG(Get_Theme_Colors_Function);
typedef DIRECTORY_GET_HOT_SIG(Directory_Get_Hot_Function);
@ -212,9 +226,16 @@ End_Query_Bar_Function *end_query_bar;
Print_Message_Function *print_message;
Create_Theme_Function *create_theme;
Change_Theme_Function *change_theme;
Change_Font_Function *change_font;
Buffer_Set_Font_Function *buffer_set_font;
Buffer_Get_Font_Function *buffer_get_font;
Get_Largest_Face_ID_Function *get_largest_face_id;
Set_Global_Face_Function *set_global_face;
Buffer_Set_Face_Function *buffer_set_face;
Get_Face_Description_Function *get_face_description;
Get_Face_ID_Function *get_face_id;
Try_Create_New_Face_Function *try_create_new_face;
Try_Modify_Face_Function *try_modify_face;
Try_Release_Face_Function *try_release_face;
Get_Available_Font_Count_Function *get_available_font_count;
Get_Available_Font_Function *get_available_font;
Set_Theme_Colors_Function *set_theme_colors;
Get_Theme_Colors_Function *get_theme_colors;
Directory_Get_Hot_Function *directory_get_hot;
@ -290,9 +311,16 @@ End_Query_Bar_Function *end_query_bar_;
Print_Message_Function *print_message_;
Create_Theme_Function *create_theme_;
Change_Theme_Function *change_theme_;
Change_Font_Function *change_font_;
Buffer_Set_Font_Function *buffer_set_font_;
Buffer_Get_Font_Function *buffer_get_font_;
Get_Largest_Face_ID_Function *get_largest_face_id_;
Set_Global_Face_Function *set_global_face_;
Buffer_Set_Face_Function *buffer_set_face_;
Get_Face_Description_Function *get_face_description_;
Get_Face_ID_Function *get_face_id_;
Try_Create_New_Face_Function *try_create_new_face_;
Try_Modify_Face_Function *try_modify_face_;
Try_Release_Face_Function *try_release_face_;
Get_Available_Font_Count_Function *get_available_font_count_;
Get_Available_Font_Function *get_available_font_;
Set_Theme_Colors_Function *set_theme_colors_;
Get_Theme_Colors_Function *get_theme_colors_;
Directory_Get_Hot_Function *directory_get_hot_;
@ -376,9 +404,16 @@ app_links->end_query_bar_ = End_Query_Bar;\
app_links->print_message_ = Print_Message;\
app_links->create_theme_ = Create_Theme;\
app_links->change_theme_ = Change_Theme;\
app_links->change_font_ = Change_Font;\
app_links->buffer_set_font_ = Buffer_Set_Font;\
app_links->buffer_get_font_ = Buffer_Get_Font;\
app_links->get_largest_face_id_ = Get_Largest_Face_ID;\
app_links->set_global_face_ = Set_Global_Face;\
app_links->buffer_set_face_ = Buffer_Set_Face;\
app_links->get_face_description_ = Get_Face_Description;\
app_links->get_face_id_ = Get_Face_ID;\
app_links->try_create_new_face_ = Try_Create_New_Face;\
app_links->try_modify_face_ = Try_Modify_Face;\
app_links->try_release_face_ = Try_Release_Face;\
app_links->get_available_font_count_ = Get_Available_Font_Count;\
app_links->get_available_font_ = Get_Available_Font;\
app_links->set_theme_colors_ = Set_Theme_Colors;\
app_links->get_theme_colors_ = Get_Theme_Colors;\
app_links->directory_get_hot_ = Directory_Get_Hot;\
@ -454,9 +489,16 @@ static inline void end_query_bar(Application_Links *app, Query_Bar *bar, uint32_
static inline void print_message(Application_Links *app, char *str, int32_t len){(app->print_message(app, str, len));}
static inline void create_theme(Application_Links *app, Theme *theme, char *name, int32_t len){(app->create_theme(app, theme, name, len));}
static inline void change_theme(Application_Links *app, char *name, int32_t len){(app->change_theme(app, name, len));}
static inline void change_font(Application_Links *app, char *name, int32_t len, bool32 apply_to_all_files){(app->change_font(app, name, len, apply_to_all_files));}
static inline void buffer_set_font(Application_Links *app, Buffer_Summary *buffer, char *name, int32_t len){(app->buffer_set_font(app, buffer, name, len));}
static inline bool32 buffer_get_font(Application_Links *app, Buffer_Summary *buffer, char *name_out, int32_t name_max){return(app->buffer_get_font(app, buffer, name_out, name_max));}
static inline Face_ID get_largest_face_id(Application_Links *app){return(app->get_largest_face_id(app));}
static inline bool32 set_global_face(Application_Links *app, Face_ID id, bool32 apply_to_all_buffers){return(app->set_global_face(app, id, apply_to_all_buffers));}
static inline bool32 buffer_set_face(Application_Links *app, Buffer_Summary *buffer, Face_ID id){return(app->buffer_set_face(app, buffer, id));}
static inline Face_Description get_face_description(Application_Links *app, Face_ID id){return(app->get_face_description(app, id));}
static inline Face_ID get_face_id(Application_Links *app, Buffer_Summary *buffer){return(app->get_face_id(app, buffer));}
static inline Face_ID try_create_new_face(Application_Links *app, Face_Description *description){return(app->try_create_new_face(app, description));}
static inline bool32 try_modify_face(Application_Links *app, Face_ID id, Face_Description *description){return(app->try_modify_face(app, id, description));}
static inline bool32 try_release_face(Application_Links *app, Face_ID id, Face_ID replacement_id){return(app->try_release_face(app, id, replacement_id));}
static inline int32_t get_available_font_count(Application_Links *app){return(app->get_available_font_count(app));}
static inline Available_Font get_available_font(Application_Links *app, int32_t index){return(app->get_available_font(app, index));}
static inline void set_theme_colors(Application_Links *app, Theme_Color *colors, int32_t count){(app->set_theme_colors(app, colors, count));}
static inline void get_theme_colors(Application_Links *app, Theme_Color *colors, int32_t count){(app->get_theme_colors(app, colors, count));}
static inline int32_t directory_get_hot(Application_Links *app, char *out, int32_t capacity){return(app->directory_get_hot(app, out, capacity));}
@ -532,9 +574,16 @@ static inline void end_query_bar(Application_Links *app, Query_Bar *bar, uint32_
static inline void print_message(Application_Links *app, char *str, int32_t len){(app->print_message_(app, str, len));}
static inline void create_theme(Application_Links *app, Theme *theme, char *name, int32_t len){(app->create_theme_(app, theme, name, len));}
static inline void change_theme(Application_Links *app, char *name, int32_t len){(app->change_theme_(app, name, len));}
static inline void change_font(Application_Links *app, char *name, int32_t len, bool32 apply_to_all_files){(app->change_font_(app, name, len, apply_to_all_files));}
static inline void buffer_set_font(Application_Links *app, Buffer_Summary *buffer, char *name, int32_t len){(app->buffer_set_font_(app, buffer, name, len));}
static inline bool32 buffer_get_font(Application_Links *app, Buffer_Summary *buffer, char *name_out, int32_t name_max){return(app->buffer_get_font_(app, buffer, name_out, name_max));}
static inline Face_ID get_largest_face_id(Application_Links *app){return(app->get_largest_face_id_(app));}
static inline bool32 set_global_face(Application_Links *app, Face_ID id, bool32 apply_to_all_buffers){return(app->set_global_face_(app, id, apply_to_all_buffers));}
static inline bool32 buffer_set_face(Application_Links *app, Buffer_Summary *buffer, Face_ID id){return(app->buffer_set_face_(app, buffer, id));}
static inline Face_Description get_face_description(Application_Links *app, Face_ID id){return(app->get_face_description_(app, id));}
static inline Face_ID get_face_id(Application_Links *app, Buffer_Summary *buffer){return(app->get_face_id_(app, buffer));}
static inline Face_ID try_create_new_face(Application_Links *app, Face_Description *description){return(app->try_create_new_face_(app, description));}
static inline bool32 try_modify_face(Application_Links *app, Face_ID id, Face_Description *description){return(app->try_modify_face_(app, id, description));}
static inline bool32 try_release_face(Application_Links *app, Face_ID id, Face_ID replacement_id){return(app->try_release_face_(app, id, replacement_id));}
static inline int32_t get_available_font_count(Application_Links *app){return(app->get_available_font_count_(app));}
static inline Available_Font get_available_font(Application_Links *app, int32_t index){return(app->get_available_font_(app, index));}
static inline void set_theme_colors(Application_Links *app, Theme_Color *colors, int32_t count){(app->set_theme_colors_(app, colors, count));}
static inline void get_theme_colors(Application_Links *app, Theme_Color *colors, int32_t count){(app->get_theme_colors_(app, colors, count));}
static inline int32_t directory_get_hot(Application_Links *app, char *out, int32_t capacity){return(app->directory_get_hot_(app, out, capacity));}

View File

@ -1223,7 +1223,7 @@ init_command_line_settings(App_Settings *settings, Plat_Settings *plat_settings,
{
if (i < argc){
plat_settings->font_size = str_to_int_c(argv[i]);
plat_settings->font_size = plat_settings->font_size;
settings->font_size = plat_settings->font_size;
}
action = CLAct_Nothing;
}break;
@ -1231,6 +1231,7 @@ init_command_line_settings(App_Settings *settings, Plat_Settings *plat_settings,
case CLAct_FontUseHinting:
{
plat_settings->use_hinting = true;
settings->use_hinting = plat_settings->use_hinting;
action = CLAct_Nothing;
}break;

View File

@ -2239,78 +2239,234 @@ DOC(This call changes 4coder's color pallet to one of the built in themes.)
}
}
API_EXPORT void
Change_Font(Application_Links *app, char *name, int32_t len, bool32 apply_to_all_files)
/*
DOC_PARAM(name, The name parameter specifies the name of the font to begin using; it need not be null terminated.)
DOC_PARAM(len, The len parameter specifies the length of the name string.)
DOC_PARAM(apply_to_all_files, If this is set all open files change to this font. Usually this should be true durring the start hook because several files already exist at that time.)
DOC(This call changes 4coder's default font to one of the built in fonts.)
*/{
API_EXPORT Face_ID
Get_Largest_Face_ID(Application_Links *app)
{
Command_Data *cmd = (Command_Data*)app->cmd_context;
Models *models = cmd->models;
System_Functions *system = cmd->system;
String font_name = make_string(name, len);
Font_ID font_id = font_get_id_by_name(system, font_name);
if (font_id != 0){
if (apply_to_all_files){
global_set_font(system, models, font_id);
}
else{
models->global_font_id = font_id;
}
}
}
API_EXPORT void
Buffer_Set_Font(Application_Links *app, Buffer_Summary *buffer, char *name, int32_t len)
/*
DOC_PARAM(buffer, This parameter the buffer that shall have it's font changed)
DOC_PARAM(name, The name parameter specifies the name of the font to begin using; it need not be null terminated.)
DOC_PARAM(len, The len parameter specifies the length of the name string.)
DOC(This call sets the display font of a particular buffer.)
*/{
Command_Data *cmd = (Command_Data*)app->cmd_context;
Models *models = cmd->models;
System_Functions *system = cmd->system;
Editing_File *file = imp_get_file(cmd, buffer);
if (file != 0){
String font_name = make_string(name, len);
Font_ID font_id = font_get_id_by_name(system, font_name);
if (font_id != 0){
file_set_font(system, models, file, font_id);
}
}
Face_ID result = system->font.get_largest_id();
return(result);
}
API_EXPORT bool32
Buffer_Get_Font(Application_Links *app, Buffer_Summary *buffer, char *name_out, int32_t name_max)
/*
DOC_PARAM(buffer, the buffer from which to get the font name)
DOC_PARAM(name_out, a character array in which to write the name of the font)
DOC_PARAM(name_max, the capacity of name_out)
DOC_RETURN(returns non-zero on success)
*/{
Set_Global_Face(Application_Links *app, Face_ID id, bool32 apply_to_all_buffers)
{
Command_Data *cmd = (Command_Data*)app->cmd_context;
System_Functions *system = cmd->system;
bool32 did_change = false;
Font_Pointers font = system->font.get_pointers_by_id(id);
if (font.valid){
did_change = true;
Models *models = cmd->models;
if (apply_to_all_buffers){
global_set_font(system, models, id);
}
else{
models->global_font_id = id;
}
}
return(did_change);
}
API_EXPORT bool32
Buffer_Set_Face(Application_Links *app, Buffer_Summary *buffer, Face_ID id)
{
Command_Data *cmd = (Command_Data*)app->cmd_context;
Editing_File *file = imp_get_file(cmd, buffer);
bool32 result = false;
bool32 did_change = false;
if (file != 0){
String name = make_string_cap(name_out, 0, name_max);
Font_ID font_id = file->settings.font_id;
name.size = system->font.get_name_by_id(font_id, name_out, name_max);
if (name.size > 0){
result = true;
System_Functions *system = cmd->system;
Font_Pointers font = system->font.get_pointers_by_id(id);
if (font.valid){
did_change = true;
Models *models = cmd->models;
file_set_font(system, models, file, id);
}
}
return(result);
return(did_change);
}
internal void
font_pointers_to_face_description(Font_Pointers font, Face_Description *description){
Font_Metrics *metrics = font.metrics;
i32 len = str_size(metrics->name);
memcpy(description->font.name, metrics->name, len);
Font_Settings *settings = font.settings;
description->font.in_local_font_folder = settings->stub.in_font_folder;
description->pt_size = settings->parameters.pt_size;
description->bold = settings->parameters.bold;
description->italic = settings->parameters.italics;
description->underline = settings->parameters.underline;
description->hinting = settings->parameters.use_hinting;
}
internal b32
face_description_to_settings(System_Functions *system, Face_Description description, Font_Settings *settings){
b32 success = false;
if (description.font.in_local_font_folder){
i32 count = system->font.get_loadable_count();
for (i32 i = 0; i < count; ++i){
Font_Loadable_Description loadable = {0};
system->font.get_loadable(i, &loadable);
if (loadable.valid){
if (!loadable.stub.in_font_folder){
break;
}
if (match(make_string(loadable.display_name, loadable.display_len), description.font.name)){
success = true;
memcpy(&settings->stub, &loadable.stub, sizeof(settings->stub));
break;
}
}
}
}
else{
success = true;
settings->stub.load_from_path = false;
settings->stub.in_font_folder = false;
settings->stub.len = str_size(description.font.name);
memcpy(settings->stub.name, description.font.name, settings->stub.len + 1);
}
if (success){
settings->parameters.pt_size = description.pt_size;
settings->parameters.italics = description.italic;
settings->parameters.bold = description.bold;
settings->parameters.underline = description.underline;
settings->parameters.use_hinting = description.hinting;
}
return(success);
}
API_EXPORT Face_Description
Get_Face_Description(Application_Links *app, Face_ID id)
{
Command_Data *cmd = (Command_Data*)app->cmd_context;
System_Functions *system = cmd->system;
Face_Description description = {0};
if (id != 0){
Font_Pointers font = system->font.get_pointers_by_id(id);
if (font.valid){
font_pointers_to_face_description(font, &description);
Assert(description.font.name[0] != 0);
}
}
else{
Models *models = cmd->models;
description.pt_size = models->settings.font_size;
description.hinting = models->settings.use_hinting;
}
return(description);
}
API_EXPORT Face_ID
Get_Face_ID(Application_Links *app, Buffer_Summary *buffer)
{
Command_Data *cmd = (Command_Data*)app->cmd_context;
Face_ID id = 0;
if (buffer != 0){
Editing_File *file = imp_get_file(cmd, buffer);
if (file != 0){
id = file->settings.font_id;
}
}
else{
Models *models = cmd->models;
id = models->global_font_id;
}
return(id);
}
API_EXPORT Face_ID
Try_Create_New_Face(Application_Links *app, Face_Description *description)
{
Command_Data *cmd = (Command_Data*)app->cmd_context;
System_Functions *system = cmd->system;
Face_ID id = 0;
Font_Settings settings;
if (face_description_to_settings(system, *description, &settings)){
id = system->font.face_allocate_and_init(&settings);
}
return(id);
}
API_EXPORT bool32
Try_Modify_Face(Application_Links *app, Face_ID id, Face_Description *description)
{
Command_Data *cmd = (Command_Data*)app->cmd_context;
System_Functions *system = cmd->system;
bool32 success = false;
Font_Settings settings;
if (face_description_to_settings(system, *description, &settings)){
Models *models = cmd->models;
if (alter_font(system, models, id, &settings)){
success = true;
}
}
return(success);
}
API_EXPORT bool32
Try_Release_Face(Application_Links *app, Face_ID id, Face_ID replacement_id)
{
Command_Data *cmd = (Command_Data*)app->cmd_context;
System_Functions *system = cmd->system;
Models *models = cmd->models;
bool32 success = false;
if (release_font(system, models, id, replacement_id)){
success = true;
}
return(success);
}
API_EXPORT int32_t
Get_Available_Font_Count(Application_Links *app)
{
Command_Data *cmd = (Command_Data*)app->cmd_context;
System_Functions *system = cmd->system;
i32 count = system->font.get_loadable_count();
return(count);
}
API_EXPORT Available_Font
Get_Available_Font(Application_Links *app, int32_t index)
{
Command_Data *cmd = (Command_Data*)app->cmd_context;
System_Functions *system = cmd->system;
Available_Font available = {0};
Font_Loadable_Description description = {0};
system->font.get_loadable(index, &description);
if (description.valid){
memcpy(available.name, description.display_name, description.display_len);
available.in_local_font_folder = description.stub.in_font_folder;
}
return(available);
}
API_EXPORT void

View File

@ -20,9 +20,8 @@ struct App_Settings{
i32 initial_line;
b32 lctrl_lalt_is_altgr;
char *custom_font_file;
char *custom_font_name;
i32 custom_font_size;
i32 font_size;
b32 use_hinting;
};
global_const App_Settings null_app_settings = {0};
@ -46,7 +45,7 @@ struct Models{
Mem_Options mem;
App_Settings settings;
Font_ID global_font_id;
Face_ID global_font_id;
Mapping mapping;

View File

@ -96,7 +96,7 @@ struct Editing_File_Settings{
Parse_Context_ID parse_context_id;
b32 dos_write_mode;
b32 virtual_white;
Font_ID font_id;
Face_ID font_id;
b8 unwrapped_lines;
b8 tokens_exist;
b8 tokens_without_strings;

View File

@ -1783,7 +1783,7 @@ file_create_from_string(System_Functions *system, Models *models, Editing_File *
}
file_synchronize_times(system, file);
Font_ID font_id = models->global_font_id;
Face_ID font_id = models->global_font_id;
file->settings.font_id = font_id;
Font_Pointers font = system->font.get_pointers_by_id(font_id);
Assert(font.valid);
@ -2657,7 +2657,7 @@ file_view_nullify_file(View *view){
}
internal void
update_view_line_height(System_Functions *system, Models *models, View *view, Font_ID font_id){
update_view_line_height(System_Functions *system, Models *models, View *view, Face_ID font_id){
Font_Pointers font = system->font.get_pointers_by_id(font_id);
Assert(font.valid);
view->line_height = font.metrics->height;
@ -3538,7 +3538,7 @@ style_get_color(Style *style, Cpp_Token token){
internal void
file_full_remeasure(System_Functions *system, Models *models, Editing_File *file){
Font_ID font_id = file->settings.font_id;
Face_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);
@ -3551,13 +3551,13 @@ file_full_remeasure(System_Functions *system, Models *models, Editing_File *file
}
internal void
file_set_font(System_Functions *system, Models *models, Editing_File *file, Font_ID font_id){
file_set_font(System_Functions *system, Models *models, Editing_File *file, Face_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){
global_set_font(System_Functions *system, Models *models, Face_ID font_id){
File_Node *node = 0;
File_Node *sentinel = &models->working_set.used_sentinel;
for (dll_items(node, sentinel)){
@ -3567,9 +3567,13 @@ 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){
internal b32
alter_font(System_Functions *system, Models *models, Face_ID font_id, Font_Settings *new_settings){
b32 success = false;
if (system->font.face_change_settings(font_id, new_settings)){
success = true;
File_Node *node = 0;
File_Node *sentinel = &models->working_set.used_sentinel;
for (dll_items(node, sentinel)){
@ -3579,6 +3583,39 @@ alter_font(System_Functions *system, Models *models, Font_ID font_id, Font_Setti
}
}
}
return(success);
}
internal b32
release_font(System_Functions *system, Models *models, Face_ID font_id, Face_ID replacement_id){
b32 success = false;
if (system->font.face_release(font_id)){
Font_Pointers font = system->font.get_pointers_by_id(replacement_id);
if (!font.valid){
Face_ID largest_id = system->font.get_largest_id();
for (replacement_id = 1; replacement_id <= largest_id && replacement_id > 0; ++replacement_id){
Font_Pointers font = system->font.get_pointers_by_id(replacement_id);
if (font.valid){
break;
}
}
Assert(replacement_id <= largest_id && replacement_id > 0);
}
success = true;
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_set_font(system, models, file, replacement_id);
}
}
}
return(success);
}
inline void
@ -3945,7 +3982,7 @@ struct File_Bar{
f32 pos_x, pos_y;
f32 text_shift_x, text_shift_y;
i32_Rect rect;
Font_ID font_id;
Face_ID font_id;
};
internal void
@ -4538,11 +4575,11 @@ step_file_view(System_Functions *system, View *view, Models *models, View *activ
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;
Face_ID font_id = file->settings.font_id;
Face_ID new_font_id = 0;
Font_ID largest_id = system->font.get_largest_id();
for (Font_ID i = 1; i <= largest_id; ++i){
Face_ID largest_id = system->font.get_largest_id();
for (Face_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;
@ -4629,7 +4666,7 @@ step_file_view(System_Functions *system, View *view, Models *models, View *activ
gui_begin_scrollable(target, scroll_context, view->gui_scroll, 9*view->line_height, show_scrollbar);
Font_ID font_edit_id = view->font_edit_id;
Face_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;
@ -5872,7 +5909,7 @@ draw_file_loaded(System_Functions *system, View *view, Models *models, i32_Rect
i32 max = partition_remaining(part) / sizeof(Buffer_Render_Item);
Buffer_Render_Item *items = push_array(part, Buffer_Render_Item, max);
Font_ID font_id = file->settings.font_id;
Face_ID font_id = file->settings.font_id;
Font_Pointers font = system->font.get_pointers_by_id(font_id);
f32 scroll_x = view->edit_pos->scroll.scroll_x;
@ -6079,7 +6116,7 @@ draw_file_loaded(System_Functions *system, View *view, Models *models, i32_Rect
}
internal void
draw_text_field(System_Functions *system, Render_Target *target, View *view, Models *models, Font_ID font_id, i32_Rect rect, String p, String t){
draw_text_field(System_Functions *system, Render_Target *target, View *view, Models *models, Face_ID font_id, i32_Rect rect, String p, String t){
Style *style = main_style(models);
u32 back_color = style->main.margin_color;
@ -6097,7 +6134,7 @@ draw_text_field(System_Functions *system, Render_Target *target, View *view, Mod
}
internal void
draw_text_with_cursor(System_Functions *system, Render_Target *target, View *view, Models *models, Font_ID font_id, i32_Rect rect, String s, i32 pos){
draw_text_with_cursor(System_Functions *system, Render_Target *target, View *view, Models *models, Face_ID font_id, i32_Rect rect, String s, i32 pos){
Style *style = main_style(models);
u32 back_color = style->main.margin_color;
@ -6232,7 +6269,7 @@ get_margin_color(i32 active_level, Style *style){
}
internal void
draw_color_button(System_Functions *system, GUI_Target *gui_target, Render_Target *target, View *view, Font_ID font_id, i32_Rect rect, GUI_id id, u32 fore, u32 back, String text){
draw_color_button(System_Functions *system, GUI_Target *gui_target, Render_Target *target, View *view, Face_ID font_id, i32_Rect rect, GUI_id id, u32 fore, u32 back, String text){
i32 active_level = gui_active_level(gui_target, id);
if (active_level > 0){
@ -6244,7 +6281,7 @@ draw_color_button(System_Functions *system, GUI_Target *gui_target, Render_Targe
}
internal void
draw_font_button(System_Functions *system, GUI_Target *gui_target, Render_Target *target, View *view, Models *models, i32_Rect rect, GUI_id id, Font_ID font_id, String text){
draw_font_button(System_Functions *system, GUI_Target *gui_target, Render_Target *target, View *view, Models *models, i32_Rect rect, GUI_id id, Face_ID font_id, String text){
Style *style = main_style(models);
i32 active_level = gui_active_level(gui_target, id);
@ -6259,7 +6296,7 @@ draw_font_button(System_Functions *system, GUI_Target *gui_target, Render_Target
}
internal void
draw_fat_option_block(System_Functions *system, GUI_Target *gui_target, Render_Target *target, View *view, Models *models, Font_ID font_id, i32_Rect rect, GUI_id id, String text, String pop, i8 checkbox = -1){
draw_fat_option_block(System_Functions *system, GUI_Target *gui_target, Render_Target *target, View *view, Models *models, Face_ID font_id, i32_Rect rect, GUI_id id, String text, String pop, i8 checkbox = -1){
Style *style = main_style(models);
i32 active_level = gui_active_level(gui_target, id);
@ -6298,7 +6335,7 @@ draw_fat_option_block(System_Functions *system, GUI_Target *gui_target, Render_T
}
internal void
draw_button(System_Functions *system, GUI_Target *gui_target, Render_Target *target, View *view, Models *models, Font_ID font_id, i32_Rect rect, GUI_id id, String text){
draw_button(System_Functions *system, GUI_Target *gui_target, Render_Target *target, View *view, Models *models, Face_ID font_id, i32_Rect rect, GUI_id id, String text){
Style *style = main_style(models);
i32 active_level = gui_active_level(gui_target, id);
@ -6322,7 +6359,7 @@ draw_button(System_Functions *system, GUI_Target *gui_target, Render_Target *tar
}
internal void
draw_style_preview(System_Functions *system, GUI_Target *gui_target, Render_Target *target, View *view, Models *models, Font_ID font_id, i32_Rect rect, GUI_id id, Style *style){
draw_style_preview(System_Functions *system, GUI_Target *gui_target, Render_Target *target, View *view, Models *models, Face_ID font_id, i32_Rect rect, GUI_id id, Style *style){
i32 active_level = gui_active_level(gui_target, id);
char font_name_space[256];
String font_name = make_fixed_width_string(font_name_space);
@ -6381,7 +6418,7 @@ do_render_file_view(System_Functions *system, View *view, Models *models, GUI_Sc
Assert(file != 0);
Font_ID font_id = file->settings.font_id;
Face_ID font_id = file->settings.font_id;
if (gui_target->push.pos > 0){
gui_session_init(&gui_session, gui_target, rect, view->line_height);
@ -6447,7 +6484,7 @@ do_render_file_view(System_Functions *system, View *view, Models *models, GUI_Sc
{
GUI_Interactive *b = (GUI_Interactive*)h;
void *ptr = (b + 1);
Font_ID this_font_id = (Font_ID)gui_read_integer(&ptr);
Face_ID this_font_id = (Face_ID)gui_read_integer(&ptr);
String t = gui_read_string(&ptr);
draw_font_button(system, gui_target, target, view, models, gui_session.rect, b->id, this_font_id, t);

View File

@ -9,11 +9,11 @@
// TOP
internal Font_ID
internal Face_ID
font_get_id_by_name(System_Functions *system, String name){
Font_ID id = 0;
Face_ID id = 0;
u32 count = system->font.get_count();
for (Font_ID id_it = 1; id_it <= count; ++id_it){
for (Face_ID id_it = 1; id_it <= count; ++id_it){
char str[256];
i32 str_len = system->font.get_name_by_id(id_it, str, sizeof(str));
if (str_len > 0){

View File

@ -52,6 +52,9 @@ struct Font_Metrics{
i32 line_skip;
i32 advance;
f32 underline_yoff1;
f32 underline_yoff2;
f32 byte_advance;
f32 sub_advances[3];
};
@ -105,8 +108,6 @@ struct Font_Pointers{
Font_Page_Storage *pages;
};
typedef u32 Font_ID;
// NOTE(allen): Platform layer calls - implemented in a "font provider"
#define Sys_Font_Get_Loadable_Count_Sig(n) i32 (n)(void)
typedef Sys_Font_Get_Loadable_Count_Sig(Font_Get_Loadable_Count_Function);
@ -114,25 +115,25 @@ typedef Sys_Font_Get_Loadable_Count_Sig(Font_Get_Loadable_Count_Function);
#define Sys_Font_Get_Loadable_Sig(n,i,o) void (n)(i32 i, Font_Loadable_Description *o)
typedef Sys_Font_Get_Loadable_Sig(Font_Get_Loadable_Function, index, out);
#define Sys_Font_Face_Allocate_And_Init_Sig(n,s) Font_ID (n)(Font_Settings *s)
#define Sys_Font_Face_Allocate_And_Init_Sig(n,s) Face_ID (n)(Font_Settings *s)
typedef Sys_Font_Face_Allocate_And_Init_Sig(Font_Face_Allocate_And_Init_Function, settings);
#define Sys_Font_Face_Change_Settings_Sig(n,id,s) b32 (n)(Font_ID id, Font_Settings *s)
#define Sys_Font_Face_Change_Settings_Sig(n,id,s) b32 (n)(Face_ID id, Font_Settings *s)
typedef Sys_Font_Face_Change_Settings_Sig(Font_Face_Change_Settings_Function, font_id, new_settings);
#define Sys_Font_Face_Release_Sig(n,id) b32 (n)(Font_ID id)
#define Sys_Font_Face_Release_Sig(n,id) b32 (n)(Face_ID id)
typedef Sys_Font_Face_Release_Sig(Font_Face_Release_Function, font_id);
#define Sys_Font_Get_Largest_ID_Sig(n) Font_ID (n)(void)
#define Sys_Font_Get_Largest_ID_Sig(n) Face_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)
#define Sys_Font_Get_Name_By_ID_Sig(n, font_id, out, cap) i32 (n)(Face_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)(Face_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)

View File

@ -64,8 +64,11 @@ font_ft_get_face(FT_Library ft, Font_Loadable_Stub *stub, Font_Parameters *param
if (data.size > 0){
FT_Error error = FT_New_Memory_Face(ft, data.data, data.size, 0, face);
success = (error == 0);
if (success){
success = match((*face)->family_name, stub->name);
do_transform = (success && data.used_base_file);
}
}
else{
success = false;
}
@ -117,15 +120,8 @@ font_load_page_layout(Font_Settings *settings, Font_Metrics *metrics, Glyph_Page
page->has_layout = true;
u32 pt_size = settings->parameters.pt_size;
b32 italics = settings->parameters.italics;
b32 bold = settings->parameters.bold;
b32 underline = settings->parameters.underline;
b32 use_hinting = settings->parameters.use_hinting;
AllowLocal(italics);
AllowLocal(bold);
AllowLocal(underline);
// TODO(allen): Stop redoing all this init for each call.
FT_Library ft;
FT_Init_FreeType(&ft);
@ -217,15 +213,8 @@ font_load_page_pixels(Partition *part, Font_Settings *settings, Glyph_Page *page
Assert(page->page_number == page_number);
u32 pt_size = settings->parameters.pt_size;
b32 italics = settings->parameters.italics;
b32 bold = settings->parameters.bold;
b32 underline = settings->parameters.underline;
b32 use_hinting = settings->parameters.use_hinting;
AllowLocal(italics);
AllowLocal(bold);
AllowLocal(underline);
// TODO(allen): Stop redoing all this init for each call.
FT_Library ft;
FT_Init_FreeType(&ft);
@ -363,14 +352,31 @@ font_load(System_Functions *system, Font_Settings *settings, Font_Metrics *metri
}
}
metrics->ascent = ceil32 (face->size->metrics.ascender / 64.0f);
metrics->descent = floor32 (face->size->metrics.descender / 64.0f);
metrics->advance = ceil32 (face->size->metrics.max_advance / 64.0f);
metrics->height = ceil32 (face->size->metrics.height / 64.0f);
metrics->ascent = ceil32(face->size->metrics.ascender /64.f);
metrics->descent = floor32(face->size->metrics.descender /64.f);
metrics->advance = ceil32(face->size->metrics.max_advance/64.f);
metrics->height = ceil32(face->size->metrics.height /64.f);
metrics->line_skip = metrics->height - (metrics->ascent - metrics->descent);
metrics->height -= metrics->line_skip;
metrics->line_skip = 0;
if (metrics->height > pt_size*4){
if (settings->parameters.underline){
f32 notional_to_real_ratio = (f32)metrics->height/(f32)face->height;
f32 relative_center = -1.f*notional_to_real_ratio*face->underline_position;
f32 relative_thickness = notional_to_real_ratio*face->underline_thickness;
f32 center = (f32)floor32(metrics->ascent + relative_center);
f32 thickness = clamp_bottom(1.f, relative_thickness);
metrics->underline_yoff1 = center - thickness*0.5f;
metrics->underline_yoff2 = center + thickness*0.5f;
}
else{
metrics->underline_yoff1 = 0.f;
metrics->underline_yoff2 = 0.f;
}
if (metrics->height > pt_size*4 || metrics->height < 6){
success = false;
}
else{
@ -558,7 +564,7 @@ Sys_Font_Face_Allocate_And_Init_Sig(system_font_face_allocate_and_init, new_sett
Font_Settings *settings = &page_with_slot->settings[index];
Font_Metrics *metrics = &page_with_slot->metrics[index];
Font_Page_Storage *pages = &page_with_slot->pages[index];
Font_ID new_id = page_with_slot->first_id + index;
Face_ID new_id = page_with_slot->first_id + index;
Assert(((*is_active_flags) & is_active_mask) == 0);
@ -602,7 +608,7 @@ Sys_Font_Get_Count_Sig(system_font_get_count){
}
internal Font_Slot_Page_And_Index
system_font_get_active_location(Font_ID font_id){
system_font_get_active_location(Face_ID font_id){
Font_Slot_Page_And_Index result = {0};
for (Font_Slot_Page *page = fontvars.slot_pages_sentinel.next;
@ -658,6 +664,10 @@ Sys_Font_Face_Change_Settings_Sig(system_font_face_change_settings, font_id, new
internal
Sys_Font_Face_Release_Sig(system_font_face_release, font_id){
if (fontvars.used_slot_count == 1){
return(false);
}
if (font_id == 0){
return(false);
}

View File

@ -31,7 +31,7 @@ struct Font_Slot_Page{
i32 used_count;
i32 fill_count;
i32 max;
Font_ID first_id;
Face_ID first_id;
};
struct Font_Slot_Page_And_Index{
@ -48,7 +48,7 @@ struct Font_Vars{
Font_Slot_Page slot_pages_sentinel;
i32 used_slot_count;
i32 max_slot_count;
Font_ID largest_font_id;
Face_ID largest_font_id;
// HACK(allen): // HACK(allen): // HACK(allen):
// TODO(allen): Upgrade this to have "unlimited" resizable memory.

View File

@ -89,7 +89,7 @@ draw_margin(Render_Target *target, i32_Rect outer, i32 width, u32 color){
}
internal void
draw_font_glyph(Render_Target *target, Font_ID font_id, u32 codepoint, f32 x, f32 y, u32 color){
draw_font_glyph(Render_Target *target, Face_ID font_id, u32 codepoint, f32 x, f32 y, u32 color){
Render_Command_Glyph cmd;
CmdHeader(RenCom_Glyph);
cmd.pos.x = x;
@ -102,7 +102,7 @@ draw_font_glyph(Render_Target *target, Font_ID font_id, u32 codepoint, f32 x, f3
}
internal f32
draw_string_base(System_Functions *system, Render_Target *target, Font_ID font_id, String str_, i32 x_, i32 y_, u32 color){
draw_string_base(System_Functions *system, Render_Target *target, Face_ID font_id, String str_, i32 x_, i32 y_, u32 color){
f32 x = 0;
Font_Pointers font = system->font.get_pointers_by_id(font_id);
@ -155,26 +155,26 @@ draw_string_base(System_Functions *system, Render_Target *target, Font_ID font_i
}
internal f32
draw_string(System_Functions *system, Render_Target *target, Font_ID font_id, String str, i32 x, i32 y, u32 color){
draw_string(System_Functions *system, Render_Target *target, Face_ID font_id, String str, i32 x, i32 y, u32 color){
f32 w = draw_string_base(system, target, font_id, str, x, y, color);
return(w);
}
internal f32
draw_string(System_Functions *system, Render_Target *target, Font_ID font_id, char *str, i32 x, i32 y, u32 color){
draw_string(System_Functions *system, Render_Target *target, Face_ID font_id, char *str, i32 x, i32 y, u32 color){
String string = make_string_slowly(str);
f32 w = draw_string_base(system, target, font_id, string, x, y, color);
return(w);
}
internal f32
font_string_width(System_Functions *system, Render_Target *target, Font_ID font_id, String str){
font_string_width(System_Functions *system, Render_Target *target, Face_ID font_id, String str){
f32 w = draw_string_base(system, target, font_id, str, 0, 0, 0);
return(w);
}
internal f32
font_string_width(System_Functions *system, Render_Target *target, Font_ID font_id, char *str){
font_string_width(System_Functions *system, Render_Target *target, Face_ID font_id, char *str){
String string = make_string_slowly(str);
f32 w = draw_string_base(system, target, font_id, string, 0, 0, 0);
return(w);

View File

@ -43,7 +43,7 @@ struct Render_Command_Glyph{
Render_Command_Header header;
Vec2 pos;
u32 color;
Font_ID font_id;
Face_ID font_id;
u32 codepoint;
};

View File

@ -10,7 +10,7 @@
// TOP
struct Style_Font{
Font_ID font_id;
Face_ID font_id;
};
struct Style{

View File

@ -134,7 +134,7 @@ struct View{
View *hot_file_view;
u32 *palette;
Color_View_Mode color_mode;
Font_ID font_edit_id;
Face_ID font_edit_id;
Super_Color color;
b32 p4c_only;
Style_Library inspecting_styles;

View File

@ -218,6 +218,26 @@ interpret_render_buffer(Render_Target *t){
glTexCoord2f(uv.x0, uv.y0); glVertex2f(xy.x0, xy.y0);
}
glEnd();
if (codepoint != ' ' && font.settings->parameters.underline){
glDisable(GL_TEXTURE_2D);
f32 x0 = x;
f32 x1 = x + page->advance[glyph_index];
f32 yoff1 = y + font.metrics->underline_yoff1;
f32 yoff2 = y + font.metrics->underline_yoff2;
glBegin(GL_QUADS);
{
glVertex2f(x0, yoff1);
glVertex2f(x1, yoff1);
glVertex2f(x1, yoff2);
glVertex2f(x0, yoff2);
}
glEnd();
glEnable(GL_TEXTURE_2D);
}
}break;
case RenCom_ChangeClip: