This commit is contained in:
Allen Webster 2016-01-06 10:39:15 -05:00
parent c2206e5830
commit 0aa1df3da0
38 changed files with 4601 additions and 4778 deletions

View File

@ -2,18 +2,20 @@
* Example use of customization API
*/
#define FCPP_STRING_IMPLEMENTATION
#include "4coder_string.h"
#include "4coder_custom.h"
#include "4coder_helper.h"
#define exec_command_keep_stack app.exec_command_keep_stack
#define clear_parameters app.clear_parameters
#define get_active_buffer app.get_active_buffer
#define exec_command_keep_stack app->exec_command_keep_stack
#define clear_parameters app->clear_parameters
#define get_active_buffer app->get_active_buffer
#define exec_command(cmd_context, id) \
exec_command_keep_stack(cmd_context, id); \
clear_parameters(cmd_context)
#define push_parameter(cmd_context, ...) push_parameter_helper(cmd_context, app, __VA_ARGS__)
#define push_memory(cmd_context, len) app.push_memory(cmd_context, len)
#define push_memory(cmd_context, len) app->push_memory(cmd_context, len)
#define literal(s) s, (sizeof(s)-1)
@ -21,6 +23,7 @@
// I recommend enumerating your own map ids as shown here.
enum My_Maps{
my_code_map = mapid_user_custom,
my_html_map
};
HOOK_SIG(my_start){
@ -64,9 +67,9 @@ HOOK_SIG(my_file_settings){
else if (str_match(extension, extension_len, literal("hpp"))) treat_as_code = 1;
}
push_parameter(cmd_context, par_lex_as_cpp_file, treat_as_code);
push_parameter(cmd_context, par_wrap_lines, !treat_as_code);
push_parameter(cmd_context, par_key_mapid, (treat_as_code)?(my_code_map):(mapid_file));
push_parameter(app, cmd_context, par_lex_as_cpp_file, treat_as_code);
push_parameter(app, cmd_context, par_wrap_lines, !treat_as_code);
push_parameter(app, cmd_context, par_key_mapid, (treat_as_code)?(my_code_map):(mapid_file));
exec_command(cmd_context, cmdid_set_settings);
}
@ -79,7 +82,7 @@ CUSTOM_COMMAND_SIG(open_my_files){
// NOTE(allen|a3.1): The command cmdid_interactive_open can now open
// a file specified on the parameter stack. If the file does not
// exist cmdid_interactive_open behaves as usual.
push_parameter(cmd_context, par_name, literal("w:/4ed/data/test/basic.cpp"));
push_parameter(app, cmd_context, par_name, literal("w:/4ed/data/test/basic.cpp"));
exec_command(cmd_context, cmdid_interactive_open);
exec_command(cmd_context, cmdid_change_active_panel);
@ -93,12 +96,82 @@ CUSTOM_COMMAND_SIG(open_my_files){
}
// NOTE(allen|a3.1): null terminators are not needed for strings.
push_parameter(cmd_context, par_name, my_file, my_file_len);
push_parameter(app, cmd_context, par_name, my_file, my_file_len);
exec_command(cmd_context, cmdid_interactive_open);
exec_command(cmd_context, cmdid_change_active_panel);
}
CUSTOM_COMMAND_SIG(build_at_launch_location){
// NOTE(allen|a3.3): An example of calling build by setting all
// parameters directly. This only works if build.bat can be called
// from the starting directory
push_parameter(app, cmd_context, par_cli_overlap_with_conflict, 1);
push_parameter(app, cmd_context, par_target_buffer_name, literal("*compilation*"));
push_parameter(app, cmd_context, par_cli_path, literal("."));
push_parameter(app, cmd_context, par_cli_command, literal("build"));
exec_command(cmd_context, cmdid_build);
}
CUSTOM_COMMAND_SIG(build_search){
// NOTE(allen|a3.3): An example of traversing the filesystem through parent
// directories looking for a file, in this case a batch file to execute.
//
//
// Step 1: push_directory returns a String containing the current "hot" directory
// (whatever directory you most recently visited in the 4coder file browsing interface)
//
// Step 2: app->directory_has_file queries the file system to see if "build.bat" exists
// If it does exist several parameters are pushed:
// - par_cli_overlap_with_conflict: whether to launch this process if an existing process
// is already being used for output on the same buffer
//
// - par_target_buffer_name: the name of the buffer to fill with the output from the process
//
// - par_cli_path: sets the path from which the command is executed
//
// - par_cli_command: sets the actual command to be executed, this can be almost any command
// that you could execute through a command line interface
//
//
// To set par_cli_path: push_parameter makes a copy of the dir string on the stack
// because the string allocated by push_directory is going to change again
// To set par_cli_command: app->push_parameter does not make a copy of the dir because
// dir isn't going to change again.
//
// Step 3: If the batch file did not exist try to move to the parent directory using
// app->directory_cd. The cd function can also be used to navigate to subdirectories.
// It returns true if it can actually move in the specified direction, and false otherwise.
int keep_going = 1;
String dir = push_directory(app, cmd_context);
while (keep_going){
if (app->directory_has_file(dir, "build.bat")){
push_parameter(app, cmd_context, par_cli_overlap_with_conflict, 0);
push_parameter(app, cmd_context, par_target_buffer_name, literal("*compilation*"));
push_parameter(app, cmd_context, par_cli_path, dir.str, dir.size);
if (append(&dir, "build")){
app->push_parameter(cmd_context,
dynamic_int(par_cli_command),
dynamic_string(dir.str, dir.size));
exec_command(cmd_context, cmdid_build);
}
else{
clear_parameters(cmd_context);
}
return;
}
if (app->directory_cd(&dir, "..") == 0){
keep_going = 0;
}
}
// TODO(allen): feedback message - couldn't find build.bat
}
CUSTOM_COMMAND_SIG(write_and_auto_tab){
exec_command(cmd_context, cmdid_write_character);
exec_command(cmd_context, cmdid_auto_tab_line_at_cursor);
@ -126,9 +199,12 @@ extern "C" GET_BINDING_DATA(get_bindings){
bind(context, 'c', MDFR_ALT, cmdid_open_color_tweaker);
bind(context, 'x', MDFR_ALT, cmdid_open_menu);
bind_me(context, 'o', MDFR_ALT, open_in_other);
// NOTE(allen|a3.1): Go look at open_my_files, that's the only point of this being here,
// it won't actually be useful for you.
// NOTE(allen): These callbacks may not actually be useful to you, but
// go look at them and see what they do.
bind_me(context, 'M', MDFR_ALT | MDFR_CTRL, open_my_files);
bind_me(context, 'M', MDFR_ALT, build_at_launch_location);
bind_me(context, 'm', MDFR_ALT, build_search);
end_map(context);

View File

@ -5,10 +5,7 @@
#define MDFR_SHIFT 4
#define MDFR_NUMPAD 8
// NOTE(allen): These need not be used direct
#define MDFR_EXACT 128
typedef u16 Code;
typedef unsigned char Code;
struct Key_Codes{
Code back;
@ -121,6 +118,7 @@ enum Command_ID{
cmdid_cursor_mark_swap,
cmdid_open_menu,
cmdid_set_settings,
cmdid_build,
//
cmdid_count
};
@ -130,6 +128,10 @@ enum Param_ID{
par_lex_as_cpp_file,
par_wrap_lines,
par_key_mapid,
par_target_buffer_name,
par_cli_path,
par_cli_command,
par_cli_overlap_with_conflict,
// never below this
par_type_count
};
@ -230,10 +232,19 @@ struct Buffer_Summary{
int map_id;
};
#ifndef FRED_STRING_STRUCT
#define FRED_STRING_STRUCT
struct String{
char *str;
int size;
int memory_size;
};
#endif
#define GET_BINDING_DATA(name) int name(void *data, int size, Key_Codes *codes)
#define SET_EXTRA_FONT_SIG(name) void name(Extra_Font *font_out)
#define CUSTOM_COMMAND_SIG(name) void name(void *cmd_context, struct Application_Links app)
#define HOOK_SIG(name) void name(void *cmd_context, struct Application_Links app)
#define CUSTOM_COMMAND_SIG(name) void name(void *cmd_context, struct Application_Links *app)
#define HOOK_SIG(name) void name(void *cmd_context, struct Application_Links *app)
extern "C"{
typedef CUSTOM_COMMAND_SIG(Custom_Command_Function);
@ -247,6 +258,9 @@ extern "C"{
#define EXECUTE_COMMAND_SIG(name) void name(void *cmd_context, int command_id)
#define CLEAR_PARAMETERS_SIG(name) void name(void *cmd_context)
#define GET_ACTIVE_BUFFER_SIG(name) Buffer_Summary name(void *cmd_context)
#define DIRECTORY_GET_HOT_SIG(name) int name(void *cmd_context, char *buffer, int max)
#define DIRECTORY_HAS_FILE_SIG(name) int name(String dir, char *filename)
#define DIRECTORY_CD_SIG(name) int name(String *dir, char *rel_path)
extern "C"{
typedef EXECUTE_COMMAND_SIG(Exec_Command_Function);
@ -254,6 +268,9 @@ extern "C"{
typedef PUSH_MEMORY_SIG(Push_Memory_Function);
typedef CLEAR_PARAMETERS_SIG(Clear_Parameters_Function);
typedef GET_ACTIVE_BUFFER_SIG(Get_Active_Buffer_Function);
typedef DIRECTORY_GET_HOT_SIG(Directory_Get_Hot);
typedef DIRECTORY_HAS_FILE_SIG(Directory_Has_File);
typedef DIRECTORY_CD_SIG(Directory_CD);
}
struct Application_Links{
@ -262,6 +279,9 @@ struct Application_Links{
Push_Memory_Function *push_memory;
Clear_Parameters_Function *clear_parameters;
Get_Active_Buffer_Function *get_active_buffer;
Directory_Get_Hot *directory_get_hot;
Directory_Has_File *directory_has_file;
Directory_CD *directory_cd;
};
struct Config_API{

View File

@ -97,14 +97,6 @@ struct Bind_Target{
unsigned char modifiers;
};
inline Bind_Target
ekey(short code, unsigned char modifiers){
Bind_Target target;
target.code = code;
target.modifiers = modifiers | MDFR_EXACT;
return target;
}
inline Bind_Target
tkey(short code, unsigned char modifiers){
Bind_Target target;
@ -144,14 +136,14 @@ bind_me(Bind_Helper *helper, Bind_Target target, Custom_Command_Function *func){
inline void
bind(Bind_Helper *helper, short code, unsigned char modifiers, int cmdid){
Bind_Target target;
target.code = tkey(code, modifiers);
target = tkey(code, modifiers);
bind(helper, target, cmdid);
}
inline void
bind_me(Bind_Helper *helper, short code, unsigned char modifiers, Custom_Command_Function *func){
Bind_Target target;
target.code = tkey(code, modifiers);
target = tkey(code, modifiers);
bind_me(helper, target, func);
}
@ -207,30 +199,46 @@ end_bind_helper(Bind_Helper *helper){
// NOTE(allen): Useful functions and overloads on app links
inline void
push_parameter_helper(void *cmd_context, Application_Links app, int param, int value){
app.push_parameter(cmd_context, dynamic_int(param), dynamic_int(value));
push_parameter(Application_Links *app, void *cmd_context, int param, int value){
app->push_parameter(cmd_context, dynamic_int(param), dynamic_int(value));
}
inline void
push_parameter_helper(void *cmd_context, Application_Links app, int param, const char *value, int value_len){
char *value_copy = app.push_memory(cmd_context, value_len);
push_parameter(Application_Links *app, void *cmd_context, int param, const char *value, int value_len){
char *value_copy = app->push_memory(cmd_context, value_len+1);
copy(value_copy, value, value_len);
app.push_parameter(cmd_context, dynamic_int(param), dynamic_string(value_copy, value_len));
value_copy[value_len] = 0;
app->push_parameter(cmd_context, dynamic_int(param), dynamic_string(value_copy, value_len));
}
inline void
push_parameter_helper(void *cmd_context, Application_Links app, const char *param, int param_len, int value){
char *param_copy = app.push_memory(cmd_context, param_len);
push_parameter(Application_Links *app, void *cmd_context, const char *param, int param_len, int value){
char *param_copy = app->push_memory(cmd_context, param_len+1);
copy(param_copy, param, param_len);
app.push_parameter(cmd_context, dynamic_string(param_copy, param_len), dynamic_int(value));
param_copy[param_len] = 0;
app->push_parameter(cmd_context, dynamic_string(param_copy, param_len), dynamic_int(value));
}
inline void
push_parameter_helper(void *cmd_context, Application_Links app, const char *param, int param_len, const char *value, int value_len){
char *param_copy = app.push_memory(cmd_context, param_len);
char *value_copy = app.push_memory(cmd_context, value_len);
push_parameter(Application_Links *app, void *cmd_context, const char *param, int param_len, const char *value, int value_len){
char *param_copy = app->push_memory(cmd_context, param_len+1);
char *value_copy = app->push_memory(cmd_context, value_len+1);
copy(param_copy, param, param_len);
copy(value_copy, value, value_len);
app.push_parameter(cmd_context, dynamic_string(param_copy, param_len), dynamic_string(value_copy, value_len));
value_copy[value_len] = 0;
param_copy[param_len] = 0;
app->push_parameter(cmd_context, dynamic_string(param_copy, param_len), dynamic_string(value_copy, value_len));
}
inline String
push_directory(Application_Links *app, void *cmd_context){
String result;
result.memory_size = 512;
result.str = app->push_memory(cmd_context, result.memory_size);
result.size = app->directory_get_hot(cmd_context, result.str, result.memory_size);
return(result);
}
#define dir_string(d) ((d).str), ((d).size)

View File

@ -24,16 +24,19 @@ NOTES ON USE:
// - memcpy / memmove replacements (different file for optimization options?)
//
#include "4cpp_config.h"
#include "4coder_config.h"
#ifndef FCPP_STRING_INC
#define FCPP_STRING_INC
#ifndef FRED_STRING_STRUCT
#define FRED_STRING_STRUCT
struct String{
char *str;
int size;
int memory_size;
};
#endif
inline bool char_not_slash(char c) { return (c != '\\' && c != '/'); }
inline bool char_is_slash(char c) { return (c == '\\' || c == '/'); }
@ -147,12 +150,14 @@ inline int compare(char *a, String b) { return -compare(b,a); }
FCPP_LINK int compare(String a, String b);
FCPP_LINK int reverse_seek_slash(String str);
FCPP_LINK int reverse_seek_slash(String str, int start_pos);
inline bool get_front_of_directory(String *dest, String dir) { return append_checked(dest, substr(dir, reverse_seek_slash(dir) + 1)); }
inline bool get_path_of_directory(String *dest, String dir) { return append_checked(dest, substr(dir, 0, reverse_seek_slash(dir) + 1)); }
FCPP_LINK bool set_last_folder(String *dir, char *folder_name);
FCPP_LINK bool set_last_folder(String *dir, String folder_name);
FCPP_LINK String file_extension(String str);
FCPP_LINK String file_extension_slowly(char *str);
FCPP_LINK bool remove_last_folder(String *str);
inline String make_string(char *str, int size, int mem_size){
String result;
@ -834,14 +839,19 @@ compare(String a, String b){
}
FCPP_LINK int
reverse_seek_slash(String str){
int i = str.size - 1;
reverse_seek_slash(String str, int pos){
int i = str.size - 1 - pos;
while (i >= 0 && char_not_slash(str.str[i])){
--i;
}
return i;
}
FCPP_LINK int
reverse_seek_slash(String str){
return(reverse_seek_slash(str, 0));
}
FCPP_LINK bool
set_last_folder(String *dir, char *folder_name){
bool result = 0;
@ -886,7 +896,7 @@ file_extension(String str){
FCPP_LINK String
file_extension_slowly(char *str){
i32 s, i;
int s, i;
for (s = 0; str[s]; ++s);
for (i = s - 1; i >= 0; --i){
if (str[i] == '.') break;
@ -895,9 +905,24 @@ file_extension_slowly(char *str){
return make_string(str+i, s-i);
}
FCPP_LINK bool
remove_last_folder(String *str){
bool result = 0;
int end = reverse_seek_slash(*str, 1);
if (end >= 0){
result = 1;
str->size = end + 1;
}
return(result);
}
// NOTE(allen): experimental section, things below here are
// not promoted to public API level yet.
#ifndef ArrayCount
#define ArrayCount(a) ((sizeof(a))/sizeof(a))
#endif
struct Absolutes{
String a[8];
int count;

View File

@ -58,7 +58,7 @@ NOTES ON USE:
// - lex in chunks
//
#include "4cpp_config.h"
#include "4coder_config.h"
#ifndef FCPP_LEXER_INC
#define FCPP_LEXER_INC

File diff suppressed because it is too large Load Diff

View File

@ -9,7 +9,7 @@ NOTES ON USE:
// TODO(allen):
// - create non stdint.h version in case someone wants to exclude that header
#include "4cpp_config.h"
#include "4coder_config.h"
#ifndef FCPP_TYPES
#define FCPP_TYPES

937
4ed.cpp

File diff suppressed because it is too large Load Diff

53
4ed.h
View File

@ -31,10 +31,10 @@ enum Key_Control{
};
struct Key_Event_Data{
u16 keycode;
u16 loose_keycode;
u16 character;
u16 character_no_caps_lock;
u8 keycode;
//u8 apply_shift;
u8 character;
u8 character_no_caps_lock;
};
struct Key_Input_Data{
@ -97,14 +97,44 @@ struct Clipboard_Contents{
i32 size;
};
struct Thread_Context;
#define FileNameMax (1 << 9)
struct File_Slot{
File_Slot *next, *prev;
byte *data;
i32 size, max;
char *filename;
i32 filename_len;
u32 flags;
};
enum File_Exchange_Flag{
FEx_Request = 0x1,
FEx_Ready = 0x2,
FEx_Not_Exist = 0x4,
FEx_Save = 0x8,
FEx_Save_Complete = 0x10
};
struct File_Exchange{
File_Slot available, active, free_list;
File_Slot *files;
i32 num_active, max;
};
struct Exchange{
Thread_Exchange thread;
File_Exchange file;
};
#define App_Init_Sig(name) \
b32 name(System_Functions *system, \
Render_Target *target, \
Application_Memory *memory, \
Exchange *exchange, \
Key_Codes *loose_codes, \
Clipboard_Contents clipboard, \
String current_directory, \
Config_API api)
typedef App_Init_Sig(App_Init);
@ -131,16 +161,29 @@ struct Application_Step_Result{
Mouse_State *mouse, \
Render_Target *target, \
Application_Memory *memory, \
Exchange *exchange, \
Clipboard_Contents clipboard, \
b32 time_step, b32 first_step, b32 force_redraw)
typedef App_Step_Sig(App_Step);
#define App_Alloc_Sig(name) void *name(void *handle, i32 size)
typedef App_Alloc_Sig(App_Alloc);
#define App_Free_Sig(name) void name(void *handle, void *block)
typedef App_Free_Sig(App_Free);
struct App_Functions{
App_Init *init;
App_Step *step;
App_Alloc *alloc;
App_Free *free;
};
#define App_Get_Functions_Sig(name) App_Functions name()
typedef App_Get_Functions_Sig(App_Get_Functions);
#endif
// BOTTOM

View File

@ -17,11 +17,11 @@
#include "4cpp_types.h"
#define FCPP_STRING_IMPLEMENTATION
#include "4cpp_string.h"
#include "4coder_string.h"
#include "4ed_mem.cpp"
#include "4ed_math.cpp"
#include "4coder_custom.h"
#include "4ed_system.h"
#include "4ed_rendering.h"
@ -32,6 +32,8 @@
#define FCPP_LEXER_IMPLEMENTATION
#include "4cpp_lexer.h"
#include "4ed_exchange.cpp"
#include "4ed_font_set.cpp"
#include "4ed_rendering_helper.cpp"
#include "4ed_command.cpp"
#include "4ed_layout.cpp"

View File

@ -15,6 +15,7 @@ enum Color_View_Mode{
CV_MODE_EXPORT_FILE,
CV_MODE_IMPORT,
CV_MODE_EXPORT,
CV_MODE_IMPORT_WAIT,
CV_MODE_ADJUSTING
};
@ -104,7 +105,7 @@ struct Color_View{
Style *main_style;
Style_Library *styles;
File_View *hot_file_view;
Font_Set *fonts;
Font_Set *font_set;
u32 *palette;
Working_Set *working_set;
i32 palette_size;
@ -112,9 +113,10 @@ struct Color_View{
UI_State state;
Super_Color color;
Color_Highlight highlight;
bool32 p4c_only;
b32 p4c_only;
Style_Library inspecting_styles;
bool8 import_export_check[64];
b8 import_export_check[64];
i32 import_file_id;
};
inline Color_View*
@ -188,10 +190,11 @@ draw_rgb_slider(Render_Target *target, Vec4 base, i32 channel,
}
internal void
do_label(UI_State *state, UI_Layout *layout, char *text, real32 height = 2.f){
do_label(UI_State *state, UI_Layout *layout, char *text, f32 height = 2.f){
Style *style = state->style;
Render_Font *font = style->font;
i32_Rect label = layout_rect(layout, FLOOR32(font->height * height));
i16 font_id = style->font_id;
i32 line_height = get_font_info(state->font_set, font_id)->height;
i32_Rect label = layout_rect(layout, FLOOR32(line_height * height));
if (!state->input_stage){
Render_Target *target = state->target;
@ -199,8 +202,8 @@ do_label(UI_State *state, UI_Layout *layout, char *text, real32 height = 2.f){
u32 fore = style->main.default_color;
draw_rectangle(target, label, back);
i32 height = label.y1 - label.y0;
draw_string(target, font, text, label.x0,
label.y0 + (height - font->height)/2, fore);
draw_string(target, font_id, text, label.x0,
label.y0 + (height - line_height)/2, fore);
}
}
@ -221,18 +224,18 @@ do_scroll_bar(UI_State *state, i32_Rect rect){
bottom_arrow.y1 = rect.y1;
bottom_arrow.y0 = bottom_arrow.y1 - w;
real32 space_h = (real32)(bottom_arrow.y0 - top_arrow.y1);
f32 space_h = (f32)(bottom_arrow.y0 - top_arrow.y1);
if (space_h <= w) return;
i32 slider_h = w;
real32 view_hmin = 0;
real32 view_hmax = state->height - h;
real32 L = unlerp(view_hmin, state->view_y, view_hmax);
f32 view_hmin = 0;
f32 view_hmax = state->height - h;
f32 L = unlerp(view_hmin, state->view_y, view_hmax);
real32 slider_hmin = (real32)top_arrow.y1;
real32 slider_hmax = (real32)bottom_arrow.y0 - slider_h;
real32 S = lerp(slider_hmin, L, slider_hmax);
f32 slider_hmin = (f32)top_arrow.y1;
f32 slider_hmax = (f32)bottom_arrow.y0 - slider_h;
f32 S = lerp(slider_hmin, L, slider_hmax);
i32_Rect slider;
slider.x0 = rect.x0;
@ -244,16 +247,17 @@ do_scroll_bar(UI_State *state, i32_Rect rect){
if (state->input_stage){
state->view_y =
ui_do_vscroll_input(state, top_arrow, bottom_arrow, slider,
wid, state->view_y, (real32)state->font->height,
ui_do_vscroll_input(state, top_arrow, bottom_arrow, slider, wid, state->view_y,
(f32)(get_font_info(state->font_set, state->font_id)->height),
slider_hmin, slider_hmax, view_hmin, view_hmax);
}
else{
Render_Target *target = state->target;
real32 x0, y0, x1, y1, x2, y2;
real32 w_1_2 = w*.5f;
real32 w_1_3 = w*.333333f;
real32 w_2_3 = w*.666667f;
f32 x0, y0, x1, y1, x2, y2;
f32 w_1_2 = w*.5f;
f32 w_1_3 = w*.333333f;
f32 w_2_3 = w*.666667f;
UI_Style ui_style = get_ui_style(state->style);
@ -403,23 +407,25 @@ fill_buffer_color_channel(char *buffer, u8 x, Channel_Field_Type ftype){
}
}
internal bool32
internal b32
do_channel_field(i32 sub_id, Color_UI *ui, u8 *channel, Channel_Field_Type ftype,
i32 y, u32 color, u32 back, i32 x0, i32 x1){
bool32 result = 0;
Render_Target *target = ui->state.target;
Render_Font *font = ui->state.font;
b32 result = 0;
i16 font_id = ui->state.font_id;
i32 line_height = get_font_info(ui->state.font_set, font_id)->height;
i32_Rect hit_region;
hit_region.x0 = x0;
hit_region.x1 = x1;
hit_region.y0 = y;
hit_region.y1 = y + font->height;
hit_region.y1 = y + line_height;
i32 digit_count;
if (ftype == CF_DEC) digit_count = 3;
else digit_count = 2;
Render_Target *target = ui->state.target;
if (ui->state.input_stage){
i32 indx;
ui_do_subdivided_button_input(&ui->state, hit_region, digit_count,
@ -515,7 +521,7 @@ do_channel_field(i32 sub_id, Color_UI *ui, u8 *channel, Channel_Field_Type ftype
}
if (!ui->state.input_stage)
draw_string_mono(target, font, string_buffer,
draw_string_mono(target, font_id, string_buffer,
(real32)x0 + 1, (real32)y, ui->hex_advance,
color);
@ -688,8 +694,7 @@ do_palette(Color_UI *ui, i32_Rect rect){
if (!ui->state.input_stage){
Render_Target *target = ui->state.target;
Render_Font *font = style->font;
draw_string(target, font, "Global Palette: right click to save color",
draw_string(target, style->font_id, "Global Palette: right click to save color",
layout.x, layout.rect.y0, style->main.default_color);
}
@ -709,15 +714,16 @@ do_palette(Color_UI *ui, i32_Rect rect){
internal void
do_sub_button(i32 id, Color_UI *ui, char *text){
Render_Font *font = ui->state.font;
i32_Rect rect = layout_rect(&ui->layout, font->height + 2);
i16 font_id = ui->state.font_id;
i32 line_height = get_font_info(ui->state.font_set, font_id)->height;
i32_Rect rect = layout_rect(&ui->layout, line_height + 2);
if (ui->state.input_stage){
ui_do_button_input(&ui->state, rect, make_sub0(&ui->state, id), 1);
}
else{
Render_Target *target = ui->state.target;
u32 back_color, text_color;
text_color = 0xFFDDDDDD;
if (ui->state.selected.sub_id0 == id){
@ -731,7 +737,7 @@ do_sub_button(i32 id, Color_UI *ui, char *text){
}
draw_rectangle(target, rect, back_color);
draw_string(target, font, text, rect.x0, rect.y0 + 1,
draw_string(target, font_id, text, rect.x0, rect.y0 + 1,
text_color);
}
}
@ -740,9 +746,8 @@ internal void
do_color_adjuster(Color_UI *ui, u32 *color,
u32 text_color, u32 back_color, char *name){
i32 id = raw_ptr_dif(color, ui->state.style);
Render_Target *target = ui->state.target;
Render_Font *font = ui->state.font;
i32 character_h = font->height;
i16 font_id = ui->state.font_id;
i32 character_h = get_font_info(ui->state.font_set, font_id)->height;
u32 text = 0, back = 0;
i32_Rect bar = layout_rect(&ui->layout, character_h);
@ -755,6 +760,7 @@ do_color_adjuster(Color_UI *ui, u32 *color,
}
else{
Render_Target *target = ui->state.target;
u32 text_hover = 0xFF101010;
u32 back_hover = 0xFF999999;
if (ui->state.selected.id != id && ui->state.hover.id == id){
@ -767,7 +773,7 @@ do_color_adjuster(Color_UI *ui, u32 *color,
}
draw_rectangle(target, bar, back);
i32 end_pos = draw_string(target, font, name, bar.x0, bar.y0, text);
i32 end_pos = draw_string(target, font_id, name, bar.x0, bar.y0, text);
real32 x_spacing = ui->hex_advance;
i32_Rect temp_rect = bar;
@ -780,8 +786,8 @@ do_color_adjuster(Color_UI *ui, u32 *color,
n >>= 4;
full_hex_string[i] = int_to_hexchar(m);
}
draw_string_mono(target, font, full_hex_string,
(real32)temp_rect.x0, (real32)bar.y0,
draw_string_mono(target, font_id, full_hex_string,
(f32)temp_rect.x0, (f32)bar.y0,
x_spacing, text);
}
@ -794,6 +800,7 @@ do_color_adjuster(Color_UI *ui, u32 *color,
}
if (ui->state.selected.id == id){
Render_Target *target = ui->state.target;
i32_Rect expanded = layout_rect(&ui->layout, 115 + (character_h + 2));
UI_Layout_Restore restore = begin_sub_layout(&ui->layout, expanded);
@ -830,12 +837,14 @@ do_color_adjuster(Color_UI *ui, u32 *color,
internal void
do_style_name(Color_UI *ui){
i32 id = -3;
Render_Font *font = ui->state.font;
i32_Rect srect = layout_rect(&ui->layout, font->height);
i16 font_id = ui->state.font_id;
i32 line_height = get_font_info(ui->state.font_set, font_id)->height;
i32_Rect srect = layout_rect(&ui->layout, line_height);
Widget_ID wid = make_id(&ui->state, id);
bool32 selected = is_selected(&ui->state, wid);
b32 selected = is_selected(&ui->state, wid);
if (ui->state.input_stage){
if (!selected){
@ -868,18 +877,20 @@ do_style_name(Color_UI *ui){
draw_rectangle(target, srect, back);
i32 x = srect.x0;
x = draw_string(target, font, "NAME: ",
x = draw_string(target, font_id, "NAME: ",
x, srect.y0, fore_label);
x = draw_string(target, font, style->name.str,
x = draw_string(target, font_id, style->name.str,
x, srect.y0, fore_text);
}
}
internal bool32
do_font_option(Color_UI *ui, Render_Font *font){
bool32 result = 0;
i32 sub_id = (i32)(font);
i32_Rect orect = layout_rect(&ui->layout, font->height);
internal b32
do_font_option(Color_UI *ui, i16 font_id){
b32 result = 0;
Font_Info *info = get_font_info(ui->state.font_set, font_id);
i32 sub_id = (i32)(info);
i32_Rect orect = layout_rect(&ui->layout, info->height);
Widget_ID wid = make_sub0(&ui->state, sub_id);
if (ui->state.input_stage){
@ -900,10 +911,8 @@ do_font_option(Color_UI *ui, Render_Font *font){
}
draw_rectangle(target, orect, back);
i32 x = orect.x0;
x = draw_string(target, font, "->",
x, orect.y0, fore);
x = draw_string(target, font, font->name.str,
x, orect.y0, fore);
x = draw_string(target, font_id, "->", x, orect.y0, fore);
draw_string(target, font_id, info->name.str, x, orect.y0, fore);
}
return result;
@ -913,11 +922,13 @@ internal void
do_font_switch(Color_UI *ui){
i32 id = -2;
Render_Target *target = ui->state.target;
Render_Font *font = ui->state.font;
i32 character_h = font->height;
Font_Set *font_set = ui->state.font_set;
i16 font_id = ui->state.font_id;
Font_Info *info = get_font_info(font_set, font_id);
i32 character_h = info->height;
i32_Rect srect = layout_rect(&ui->layout, character_h);
Widget_ID wid = make_id(&ui->state, id);
if (ui->state.input_stage){
@ -936,24 +947,23 @@ do_font_switch(Color_UI *ui){
}
draw_rectangle(target, srect, back);
i32 x = srect.x0;
x = draw_string(target, font, "FONT: ",
x = draw_string(target, font_id, "FONT: ",
x, srect.y0, fore);
x = draw_string(target, font, font->name.str,
x = draw_string(target, font_id, info->name.str,
x, srect.y0, fore);
}
if (is_selected(&ui->state, wid)){
Font_Set *fonts = ui->fonts;
Render_Font *font_opt = fonts->fonts;
i32 count = fonts->count;
srect = layout_rect(&ui->layout, character_h/2);
if (!ui->state.input_stage)
draw_rectangle(target, srect, 0xFF000000);
for (i32 i = 0; i < count; ++i, ++font_opt){
if (font_opt == font) continue;
if (do_font_option(ui, font_opt)){
ui->state.style->font = font_opt;
i32 count = font_set->count + 1;
for (i16 i = 1; i < count; ++i){
if (i == font_id) continue;
if (do_font_option(ui, i)){
ui->state.style->font_id = i;
ui->state.style->font_changed = 1;
}
}
@ -974,16 +984,17 @@ step_draw_adjusting(Color_View *color_view, i32_Rect rect, View_Message message,
Color_UI ui;
ui.state = ui_state_init(&color_view->state, target, user_input,
style, color_view->working_set, (message == VMSG_STEP));
style, color_view->font_set, color_view->working_set,
(message == VMSG_STEP));
begin_layout(&ui.layout, rect);
ui.fonts = color_view->fonts;
ui.fonts = color_view->font_set;
ui.highlight = color_view->highlight;
ui.color = color_view->color;
ui.has_hover_color = 0;
ui.state.sub_id1_change = 0;
ui.hex_advance = font_get_max_width(ui.state.font, "0123456789abcdefx");
ui.hex_advance = font_get_max_width(ui.fonts, ui.state.font_id, "0123456789abcdefx");
ui.palette = color_view->palette;
ui.palette_size = color_view->palette_size;
@ -1119,15 +1130,15 @@ update_highlighting(Color_View *color_view){
Style *style = color_view->main_style;
Editing_File *file = file_view->file;
i32 pos = view_get_cursor_pos(file_view);
char c = file->buffer.data[pos];
char c = file->state.buffer.data[pos];
if (c == '\r'){
color_view->highlight.ids[0] =
raw_ptr_dif(&style->main.special_character_color, style);
}
else if (file->tokens_complete){
Cpp_Token_Stack *tokens = &file->token_stack;
else if (file->state.tokens_complete){
Cpp_Token_Stack *tokens = &file->state.token_stack;
Cpp_Get_Token_Result result = cpp_get_token(tokens, pos);
Cpp_Token token = tokens->tokens[result.token_index];
if (!result.in_whitespace){
@ -1183,15 +1194,17 @@ update_highlighting(Color_View *color_view){
#endif
}
internal bool32
internal b32
do_style_preview(Library_UI *ui, Style *style, i32 toggle = -1){
bool32 result = 0;
Render_Font *font = style->font;
b32 result = 0;
i32 id;
if (style == ui->state.style) id = 2;
else id = raw_ptr_dif(style, ui->styles->styles) + 100;
i32_Rect prect = layout_rect(&ui->layout, font->height*3 + 6);
i16 font_id = style->font_id;
Font_Info *info = get_font_info(ui->state.font_set, font_id);
i32_Rect prect = layout_rect(&ui->layout, info->height*3 + 6);
Widget_ID wid = make_id(&ui->state, id);
@ -1202,7 +1215,6 @@ do_style_preview(Library_UI *ui, Style *style, i32 toggle = -1){
}
else{
Render_Target *target = ui->state.target;
u32 margin_color = style->main.margin_color;
if (is_hover(&ui->state, wid)){
margin_color = style->main.margin_active_color;
@ -1211,7 +1223,7 @@ do_style_preview(Library_UI *ui, Style *style, i32 toggle = -1){
i32_Rect inner;
if (toggle != -1){
i32_Rect toggle_box = prect;
toggle_box.x1 = toggle_box.x0 + font->height*2 + 6;
toggle_box.x1 = toggle_box.x0 + info->height*2 + 6;
prect.x0 = toggle_box.x1;
inner = get_inner_rect(toggle_box, 3);
@ -1219,12 +1231,12 @@ do_style_preview(Library_UI *ui, Style *style, i32 toggle = -1){
draw_rectangle(target, inner, style->main.back_color);
i32 d;
d = font->height/2;
d = info->height/2;
i32_Rect b;
b.x0 = (inner.x1 + inner.x0)/2 - d;
b.y0 = (inner.y1 + inner.y0)/2 - d;
b.x1 = b.x0 + font->height;
b.y1 = b.y0 + font->height;
b.x1 = b.x0 + info->height;
b.y1 = b.y0 + info->height;
if (toggle) draw_rectangle(target, b, margin_color);
else draw_rectangle_outline(target, b, margin_color);
}
@ -1235,33 +1247,33 @@ do_style_preview(Library_UI *ui, Style *style, i32 toggle = -1){
i32 text_y = inner.y0;
i32 text_x = inner.x0;
text_x = draw_string(target, font, style->name.str,
text_x = draw_string(target, font_id, style->name.str,
text_x, text_y, style->main.default_color);
i32 font_x = (i32)(inner.x1 - font_string_width(font, font->name.str));
i32 font_x = (i32)(inner.x1 - font_string_width(target, font_id, info->name.str));
if (font_x > text_x + 10)
draw_string(target, font, font->name.str,
draw_string(target, font_id, info->name.str,
font_x, text_y, style->main.default_color);
text_x = inner.x0;
text_y += font->height;
text_x = draw_string(target, font, "if ", text_x, text_y,
text_y += info->height;
text_x = draw_string(target, font_id, "if ", text_x, text_y,
style->main.keyword_color);
text_x = draw_string(target, font, "(x < ", text_x, text_y,
text_x = draw_string(target, font_id, "(x < ", text_x, text_y,
style->main.default_color);
text_x = draw_string(target, font, "0", text_x, text_y,
text_x = draw_string(target, font_id, "0", text_x, text_y,
style->main.int_constant_color);
text_x = draw_string(target, font, ") { x = ", text_x, text_y,
text_x = draw_string(target, font_id, ") { x = ", text_x, text_y,
style->main.default_color);
text_x = draw_string(target, font, "0", text_x, text_y,
text_x = draw_string(target, font_id, "0", text_x, text_y,
style->main.int_constant_color);
text_x = draw_string(target, font, "; } ", text_x, text_y,
text_x = draw_string(target, font_id, "; } ", text_x, text_y,
style->main.default_color);
text_x = draw_string(target, font, "// comment", text_x, text_y,
text_x = draw_string(target, font_id, "// comment", text_x, text_y,
style->main.comment_color);
text_x = inner.x0;
text_y += font->height;
text_x = draw_string(target, font, "[] () {}; * -> +-/ <>= ! && || % ^",
text_y += info->height;
text_x = draw_string(target, font_id, "[] () {}; * -> +-/ <>= ! && || % ^",
text_x, text_y, style->main.default_color);
}
@ -1269,14 +1281,16 @@ do_style_preview(Library_UI *ui, Style *style, i32 toggle = -1){
return result;
}
internal bool32
internal b32
do_main_file_box(System_Functions *system, UI_State *state, UI_Layout *layout, Hot_Directory *hot_directory, char *end = 0){
bool32 result = 0;
b32 result = 0;
Style *style = state->style;
Render_Font *font = style->font;
i32_Rect box = layout_rect(layout, font->height + 2);
String *string = &hot_directory->string;
i16 font_id = style->font_id;
i32 line_height = get_font_info(state->font_set, font_id)->height;
i32_Rect box = layout_rect(layout, line_height + 2);
if (state->input_stage){
if (ui_do_file_field_input(system, state, hot_directory)){
result = 1;
@ -1289,8 +1303,8 @@ do_main_file_box(System_Functions *system, UI_State *state, UI_Layout *layout, H
u32 special = style->main.special_character_color;
draw_rectangle(target, box, back);
i32 x = box.x0;
x = draw_string(target, font, string->str, x, box.y0, fore);
if (end) draw_string(target, font, end, x, box.y0, special);
x = draw_string(target, font_id, string->str, x, box.y0, fore);
if (end) draw_string(target, font_id, end, x, box.y0, special);
}
layout->y = box.y1;
@ -1301,8 +1315,10 @@ internal bool32
do_main_string_box(System_Functions *system, UI_State *state, UI_Layout *layout, String *string){
bool32 result = 0;
Style *style = state->style;
Render_Font *font = style->font;
i32_Rect box = layout_rect(layout, font->height + 2);
i16 font_id = style->font_id;
i32 line_height = get_font_info(state->font_set, font_id)->height;
i32_Rect box = layout_rect(layout, line_height + 2);
if (state->input_stage){
if (ui_do_line_field_input(system, state, string)){
@ -1315,7 +1331,7 @@ do_main_string_box(System_Functions *system, UI_State *state, UI_Layout *layout,
u32 fore = style->main.default_color;
draw_rectangle(target, box, back);
i32 x = box.x0;
x = draw_string(target, font, string->str, x, box.y0, fore);
x = draw_string(target, font_id, string->str, x, box.y0, fore);
}
layout->y = box.y1;
@ -1326,10 +1342,11 @@ internal bool32
do_list_option(i32 id, UI_State *state, UI_Layout *layout, String text){
bool32 result = 0;
Style *style = state->style;
Render_Font *font = style->font;
i32 character_h = font->height;
i32_Rect box = layout_rect(layout, font->height*2);
i16 font_id = style->font_id;
i32 character_h = get_font_info(state->font_set, font_id)->height;
i32_Rect box = layout_rect(layout, character_h*2);
Widget_ID wid = make_id(state, id);
if (state->input_stage){
@ -1349,7 +1366,7 @@ do_list_option(i32 id, UI_State *state, UI_Layout *layout, String text){
draw_rectangle(target, inner, back);
i32 x = inner.x0, y = box.y0 + character_h/2;
x = draw_string(target, font, text, x, y, fore);
x = draw_string(target, font_id, text, x, y, fore);
draw_margin(target, box, inner, outline);
}
@ -1359,14 +1376,14 @@ do_list_option(i32 id, UI_State *state, UI_Layout *layout, String text){
#define do_list_option_lit(id,state,layout,str) do_list_option(id, state, layout, make_lit_string(str))
internal bool32
do_file_option(i32 id, UI_State *state, UI_Layout *layout, String filename, bool32 is_folder, String extra){
bool32 result = 0;
internal b32
do_file_option(i32 id, UI_State *state, UI_Layout *layout, String filename, b32 is_folder, String extra){
b32 result = 0;
Style *style = state->style;
Render_Font *font = style->font;
i32 character_h = font->height;
i16 font_id = style->font_id;
i32 character_h = get_font_info(state->font_set, font_id)->height;
i32_Rect box = layout_rect(layout, font->height*2);
i32_Rect box = layout_rect(layout, character_h*2);
Widget_ID wid = make_id(state, id);
if (state->input_stage){
@ -1386,9 +1403,9 @@ do_file_option(i32 id, UI_State *state, UI_Layout *layout, String filename, bool
draw_rectangle(target, inner, back);
i32 x = inner.x0, y = box.y0 + character_h/2;
x = draw_string(target, font, filename, x, y, fore);
if (is_folder) x = draw_string(target, font, "\\", x, y, fore);
draw_string(target, font, extra, x, y, pop);
x = draw_string(target, font_id, filename, x, y, fore);
if (is_folder) x = draw_string(target, font_id, "\\", x, y, fore);
draw_string(target, font_id, extra, x, y, pop);
draw_margin(target, box, inner, outline);
}
@ -1397,10 +1414,10 @@ do_file_option(i32 id, UI_State *state, UI_Layout *layout, String filename, bool
}
internal b32
do_file_list_box(System_Functions *system,
UI_State *state, UI_Layout *layout, Hot_Directory *hot_dir, bool32 has_filter,
bool32 *new_dir, bool32 *selected, char *end){
bool32 result = 0;
do_file_list_box(System_Functions *system, UI_State *state,
UI_Layout *layout, Hot_Directory *hot_dir, b32 has_filter,
b32 *new_dir, b32 *selected, char *end){
b32 result = 0;
File_List *files = &hot_dir->file_list;
if (do_main_file_box(system, state, layout, hot_dir, end)){
@ -1437,10 +1454,10 @@ do_file_list_box(System_Functions *system,
Editing_File *file = working_set_contains(state->working_set, full_path);
full_path.size = restore_size;
bool8 is_folder = (info->folder != 0);
bool8 ext_match = (match(file_extension(filename), p4c_extension) != 0);
bool8 name_match = (filename_match(front_name, &absolutes, filename) != 0);
bool8 is_loaded = (file != 0);
b8 is_folder = (info->folder != 0);
b8 ext_match = (match(file_extension(filename), p4c_extension) != 0);
b8 name_match = (filename_match(front_name, &absolutes, filename) != 0);
b8 is_loaded = (file != 0);
String message = message_nothing;
if (is_loaded){
@ -1494,18 +1511,18 @@ do_live_file_list_box(System_Functions *system, UI_State *state, UI_Layout *layo
for (i32 i = 0; i < count; ++i){
Editing_File *file = files + i;
if (!file->is_dummy){
if (!file->state.is_dummy){
String message = message_nothing;
switch (buffer_get_sync(file)){
case SYNC_BEHIND_OS: message = message_unsynced; break;
case SYNC_UNSAVED: message = message_unsaved; break;
}
if (filename_match(*string, &absolutes, file->live_name)){
if (do_file_option(100+i, state, layout, file->live_name, 0, message)){
if (filename_match(*string, &absolutes, file->state.live_name)){
if (do_file_option(100+i, state, layout, file->state.live_name, 0, message)){
result = 1;
*selected = 1;
copy(string, file->live_name);
copy(string, file->state.live_name);
terminate_with_null(string);
}
}
@ -1517,16 +1534,17 @@ do_live_file_list_box(System_Functions *system, UI_State *state, UI_Layout *layo
}
internal i32
step_draw_library(System_Functions *system,
step_draw_library(System_Functions *system, Exchange *exchange, Mem_Options *mem,
Color_View *color_view, i32_Rect rect, View_Message message,
Render_Target *target, Input_Summary *user_input){
i32 result = 0;
Library_UI ui;
ui.state = ui_state_init(&color_view->state, target, user_input,
color_view->main_style, color_view->working_set, (message == VMSG_STEP));
color_view->main_style, color_view->font_set,
color_view->working_set, (message == VMSG_STEP));
ui.fonts = color_view->fonts;
ui.fonts = color_view->font_set;
ui.hot_directory = color_view->hot_directory;
ui.styles = color_view->styles;
@ -1591,7 +1609,7 @@ step_draw_library(System_Functions *system,
do_label(&ui.state, &ui.layout, "Current Theme");
do_style_preview(&ui, color_view->main_style);
bool32 file_selected = 0;
b32 file_selected = 0;
do_label(&ui.state, &ui.layout, "Import Which File?");
begin_row(&ui.layout, 2);
@ -1602,7 +1620,7 @@ step_draw_library(System_Functions *system,
color_view->mode = CV_MODE_LIBRARY;
}
bool32 new_dir = 0;
b32 new_dir = 0;
if (do_file_list_box(system,
&ui.state, &ui.layout, ui.hot_directory, color_view->p4c_only,
&new_dir, &file_selected, 0)){
@ -1614,19 +1632,40 @@ step_draw_library(System_Functions *system,
}
if (file_selected){
memset(&color_view->inspecting_styles, 0, sizeof(Style_Library));
memset(color_view->import_export_check, 1, sizeof(color_view->import_export_check));
Style *styles = color_view->inspecting_styles.styles;
i32 count, max;
max = ArrayCount(color_view->inspecting_styles.styles);
if (style_library_import(system,
color_view->hot_directory->string.str,
ui.fonts, styles, max, &count)){
color_view->mode = CV_MODE_IMPORT;
memset(color_view->import_export_check, 1,
sizeof(color_view->import_export_check));
color_view->import_file_id =
exchange_request_file(exchange,
color_view->hot_directory->string.str,
color_view->hot_directory->string.size);
color_view->mode = CV_MODE_IMPORT_WAIT;
}
}break;
case CV_MODE_IMPORT_WAIT:
{
Style *styles = color_view->inspecting_styles.styles;
Data file;
i32 file_max;
i32 count, max;
max = ArrayCount(color_view->inspecting_styles.styles);
if (exchange_file_ready(exchange, color_view->import_file_id,
&file.data, &file.size, &file_max)){
if (file.data){
if (style_library_import(file, ui.fonts, styles, max, &count))
color_view->mode = CV_MODE_IMPORT;
else color_view->mode = CV_MODE_LIBRARY;
color_view->inspecting_styles.count = count;
}
else{
color_view->mode = CV_MODE_LIBRARY;
Assert(!"this shouldn't happen!");
}
color_view->inspecting_styles.count = count;
exchange_free_file(exchange, color_view->import_file_id);
}
}break;
@ -1635,7 +1674,7 @@ step_draw_library(System_Functions *system,
do_label(&ui.state, &ui.layout, "Current Theme");
do_style_preview(&ui, color_view->main_style);
bool32 file_selected = 0;
b32 file_selected = 0;
do_label(&ui.state, &ui.layout, "Export File Name?");
begin_row(&ui.layout, 2);
@ -1646,7 +1685,7 @@ step_draw_library(System_Functions *system,
color_view->mode = CV_MODE_LIBRARY;
}
bool32 new_dir = 0;
b32 new_dir = 0;
if (do_file_list_box(system,
&ui.state, &ui.layout, ui.hot_directory, 1,
&new_dir, &file_selected, ".p4c")){
@ -1659,8 +1698,9 @@ step_draw_library(System_Functions *system,
}
if (file_selected){
i32 count = ui.styles->count;
// TODO(allen): pass the transient memory in here
Style **styles = (Style**)system->get_memory(sizeof(Style*)*count);
Temp_Memory temp = begin_temp_memory(&mem->part);
Style **styles = push_array(&mem->part, Style*, sizeof(Style*)*count);
Style *style = ui.styles->styles;
bool8 *export_check = color_view->import_export_check;
i32 export_count = 0;
@ -1669,13 +1709,13 @@ step_draw_library(System_Functions *system,
styles[export_count++] = style;
}
}
char *mem = (char*)system->get_memory(ui.hot_directory->string.size + 5);
String str = make_string(mem, 0, ui.hot_directory->string.size + 5);
char *data = push_array(&mem->part, char, ui.hot_directory->string.size + 5);
String str = make_string(data, 0, ui.hot_directory->string.size + 5);
copy(&str, ui.hot_directory->string);
append(&str, make_lit_string(".p4c"));
style_library_export(system, str.str, styles, export_count);
system->free_memory(mem);
system->free_memory(styles);
style_library_export(system, exchange, mem, &target->font_set, str.str, styles, export_count);
end_temp_memory(temp);
color_view->mode = CV_MODE_LIBRARY;
}
}break;
@ -1757,14 +1797,17 @@ Do_View_Sig(do_color_view){
case CV_MODE_EXPORT_FILE:
case CV_MODE_IMPORT:
case CV_MODE_EXPORT:
case CV_MODE_IMPORT_WAIT:
switch (message){
case VMSG_STEP:
{
result = step_draw_library(system, color_view, rect, message, target, user_input);
result = step_draw_library(system, exchange, view->mem,
color_view, rect, message, target, user_input);
}break;
case VMSG_DRAW:
{
step_draw_library(system, color_view, rect, message, target, user_input);
step_draw_library(system, exchange, view->mem,
color_view, rect, message, target, user_input);
}break;
}break;

View File

@ -38,8 +38,8 @@ map_hash(u16 event_code, u8 modifiers){
}
internal b32
map_add(Command_Map *map, u16 event_code, u8 modifiers, Command_Function function,
Custom_Command_Function *custom = 0){
map_add(Command_Map *map, u16 event_code, u8 modifiers,
Command_Function function, Custom_Command_Function *custom = 0){
Assert(map->count * 8 < map->max * 7);
Command_Binding bind;
bind.function = function;
@ -61,7 +61,8 @@ map_add(Command_Map *map, u16 event_code, u8 modifiers, Command_Function functio
}
internal b32
map_find_entry(Command_Map *map, u16 event_code, u8 modifiers, i32 *index_out){
map_find_entry(Command_Map *map, u16 event_code, u8 modifiers,
i32 *index_out){
i64 hash = map_hash(event_code, modifiers);
i32 max = map->max;
i32 index = hash % map->max;
@ -77,7 +78,8 @@ map_find_entry(Command_Map *map, u16 event_code, u8 modifiers, i32 *index_out){
}
internal b32
map_find(Command_Map *map, u16 event_code, u8 modifiers, Command_Binding *bind_out){
map_find(Command_Map *map, u16 event_code, u8 modifiers,
Command_Binding *bind_out){
b32 result;
i32 index;
result = map_find_entry(map, event_code, modifiers, &index);
@ -100,7 +102,8 @@ map_drop(Command_Map *map, u16 event_code, u8 modifiers){
}
internal void
map_init(Command_Map *commands, Partition *part, i32 max, Command_Map *parent){
map_init(Command_Map *commands, Partition *part, i32 max,
Command_Map *parent){
commands->parent = parent;
commands->commands = push_array(part, Command_Binding, max);
memset(commands->commands, 0, max*sizeof(*commands->commands));
@ -110,31 +113,35 @@ map_init(Command_Map *commands, Partition *part, i32 max, Command_Map *parent){
}
internal void
map_get_vanilla_keyboard_default(Command_Map *map, u8 command, Command_Binding *bind_out){
map_get_vanilla_keyboard_default(Command_Map *map, u8 command,
Command_Binding *bind_out){
if (command == MDFR_NONE){
*bind_out = map->vanilla_keyboard_default;
}
}
inline u8
apply_shift_to_code(u8 keycode){
return !(keycode >= 0x20 && keycode < 0x7F && keycode != ' ');
}
internal Command_Binding
map_extract(Command_Map *map, Key_Single key){
Command_Binding bind = {};
b32 ctrl = key.modifiers[CONTROL_KEY_CONTROL];
b32 alt = key.modifiers[CONTROL_KEY_ALT];
b32 shift = key.modifiers[CONTROL_KEY_SHIFT] && key.key.loose_keycode;
b32 shift = key.modifiers[CONTROL_KEY_SHIFT];
u16 code;
u8 command = MDFR_NONE;
if (key.key.character_no_caps_lock != 0 &&
key.key.character_no_caps_lock != ' ') shift = 0;
if (shift) command |= MDFR_SHIFT;
if (ctrl) command |= MDFR_CTRL;
if (alt) command |= MDFR_ALT;
command |= MDFR_EXACT;
code = key.key.keycode;
map_find(map, code, command, &bind);
command &= ~(MDFR_EXACT);
code = key.key.character_no_caps_lock;
if (code == 0){
code = key.key.keycode;

View File

@ -23,7 +23,7 @@ struct Dbg_Past_Key{
struct Debug_View{
View view_base;
Render_Font *font;
i16 font_id;
Debug_Mode mode;
Dbg_Past_Key past_keys[32];
i32 past_key_count, past_key_pos;
@ -38,8 +38,8 @@ view_to_debug_view(View *view){
internal i32
draw_general_memory(Debug_View *view, i32_Rect rect, Render_Target *target, i32 y){
Render_Font *font = view->font;
i32 y_advance = font->height;
i16 font_id = view->font_id;
i32 y_advance = get_font_info(&target->font_set, font_id)->height;
Bubble *sentinel = &view->view_base.mem->general.sentinel;
for (Bubble *bubble = sentinel->next;
@ -70,7 +70,7 @@ draw_general_memory(Debug_View *view, i32_Rect rect, Render_Target *target, i32
append_int_to_str(bubble->size, &s);
terminate_with_null(&s);
draw_string(target, font, str, rect.x0, y, color);
draw_string(target, font_id, str, rect.x0, y, color);
y += y_advance;
Bubble *next = bubble->next;
@ -83,7 +83,7 @@ draw_general_memory(Debug_View *view, i32_Rect rect, Render_Target *target, i32
append(&s, "discontinuity");
terminate_with_null(&s);
draw_string(target, font, str, rect.x0, y, color);
draw_string(target, font_id, str, rect.x0, y, color);
y += y_advance;
}
}
@ -93,9 +93,10 @@ draw_general_memory(Debug_View *view, i32_Rect rect, Render_Target *target, i32
}
internal i32
draw_system_memory(System_Functions *system, Debug_View *view, i32_Rect rect, Render_Target *target, i32 y){
Render_Font *font = view->font;
i32 y_advance = font->height;
draw_system_memory(System_Functions *system, Debug_View *view, i32_Rect rect,
Render_Target *target, i32 y){
i16 font_id = view->font_id;
i32 y_advance = get_font_info(&target->font_set, font_id)->height;
Bubble *sentinel = system->internal_sentinel();
for (Bubble *bubble = sentinel->next;
@ -114,7 +115,7 @@ draw_system_memory(System_Functions *system, Debug_View *view, i32_Rect rect, Re
append_int_to_str(bubble->size, &s);
terminate_with_null(&s);
draw_string(target, font, str, rect.x0, y, color);
draw_string(target, font_id, str, rect.x0, y, color);
y += y_advance;
}
@ -152,7 +153,7 @@ draw_background_threads(System_Functions *system,
String s = make_fixed_width_string(str);
append_int_to_str(pending, &s);
terminate_with_null(&s);
draw_string(target, view->font, str, trect.x1, trect.y1, light);
draw_string(target, view->font_id, str, trect.x1, trect.y1, light);
}
struct Dbg_Modifier{
@ -174,7 +175,7 @@ draw_modifiers(Debug_View *view, Render_Target *target,
if (modifiers[m.modifier]) color = on_color;
else color = off_color;
*x = draw_string(target, view->font, m.name, *x, y, color);
*x = draw_string(target, view->font_id, m.name, *x, y, color);
*x += 5;
}
}
@ -182,15 +183,17 @@ draw_modifiers(Debug_View *view, Render_Target *target,
internal i32
draw_key_event(Debug_View *view, Render_Target *target,
Dbg_Past_Key *key, i32 x, i32 y, u32 on_color, u32 off_color){
Render_Font *font = view->font;
draw_modifiers(view, target, key->modifiers,
on_color, off_color, &x, y);
if (font->glyphs[key->key.character].exists){
i16 font_id = view->font_id;
Render_Font *font = get_font_info(&target->font_set, font_id)->font;
if (font && font->glyphs[key->key.character].exists){
char c[2];
c[0] = (char)key->key.character;
c[1] = 0;
x = draw_string(target, font, c, x, y, on_color);
x = draw_string(target, font_id, c, x, y, on_color);
}
else{
char c[10] = {};
@ -198,7 +201,7 @@ draw_key_event(Debug_View *view, Render_Target *target,
append(&str, "\\");
append_int_to_str(key->key.keycode, &str);
terminate_with_null(&str);
x = draw_string(target, font, c, x, y, on_color);
x = draw_string(target, font_id, c, x, y, on_color);
}
return x;
@ -213,13 +216,14 @@ draw_os_events(Debug_View *view, i32_Rect rect, Render_Target *target,
x = rect.x0;
y = rect.y0;
Render_Font *font = view->font;
i16 font_id = view->font_id;
i32 line_height = get_font_info(&target->font_set, font_id)->height;
draw_modifiers(view, target, active_input->keys.modifiers,
0xFFFFFFFF, 0xFF444444, &x, y);
max_x = x;
x = rect.x0;
y += font->height;
y += line_height;
for (i32 j = 0; j < view->past_key_count; ++j){
Dbg_Past_Key *key = view->past_keys + j;
@ -236,7 +240,7 @@ draw_os_events(Debug_View *view, i32_Rect rect, Render_Target *target,
if (max_x < x) max_x = x;
x = rect.x0;
y += font->height;
y += line_height;
}
i32_Rect mrect = rect;
@ -250,13 +254,13 @@ draw_os_events(Debug_View *view, i32_Rect rect, Render_Target *target,
u32 color;
if (active_input->mouse.out_of_window){
color = 0xFFFF0000;
draw_string(target, font, "OUT", x, y, color);
draw_string(target, font_id, "OUT", x, y, color);
}
else{
color = 0xFF008800;
draw_string(target, font, "IN", x, y, color);
draw_string(target, font_id, "IN", x, y, color);
}
y += font->height;
y += line_height;
char c[16];
String s = make_fixed_width_string(c);
@ -264,20 +268,20 @@ draw_os_events(Debug_View *view, i32_Rect rect, Render_Target *target,
append(&s, ", ");
append_int_to_str(active_input->mouse.my, &s);
terminate_with_null(&s);
draw_string(target, font, c, x, y, color);
y += font->height;
draw_string(target, font_id, c, x, y, color);
y += line_height;
u32 btn_color;
if (active_input->mouse.l) btn_color = color;
else btn_color = 0xFF444444;
x = draw_string(target, font, "L ", x, y, btn_color);
x = draw_string(target, font_id, "L ", x, y, btn_color);
if (active_input->mouse.r) btn_color = color;
else btn_color = 0xFF444444;
x = draw_string(target, font, "R", x, y, btn_color);
x = draw_string(target, font_id, "R", x, y, btn_color);
x = mrect.x0;
y += font->height;
y += line_height;
s = make_fixed_width_string(c);
append_int_to_str(view->prev_mouse_wheel, &s);
@ -285,9 +289,9 @@ draw_os_events(Debug_View *view, i32_Rect rect, Render_Target *target,
if (active_input->mouse.wheel_used) btn_color = color;
else btn_color = 0xFF444444;
draw_string(target, font, c, x, y, btn_color);
draw_string(target, font_id, c, x, y, btn_color);
y += font->height;
y += line_height;
}
}

217
4ed_exchange.cpp Normal file
View File

@ -0,0 +1,217 @@
/*
* Mr. 4th Dimention - Allen Webster
*
* 9.12.2015
*
* Exchange stuff
*
*/
// TOP
internal void
ex__file_insert(File_Slot *pos, File_Slot *file){
pos->next->prev = file;
file->next = pos->next;
pos->next = file;
file->prev = pos;
}
internal void
ex__file_remove(File_Slot *file){
file->next->prev = file->prev;
file->prev->next = file->next;
}
internal void
ex__check_file(File_Slot *pos){
File_Slot *file = pos;
Assert(pos == pos->next->prev);
for (pos = pos->next;
file != pos;
pos = pos->next){
Assert(pos == pos->next->prev);
}
}
internal void
ex__check(File_Exchange *file_exchange){
ex__check_file(&file_exchange->available);
ex__check_file(&file_exchange->active);
ex__check_file(&file_exchange->free_list);
}
internal void
ex__clear(File_Slot *file){
file->data = 0;
file->size = 0;
file->max = 0;
file->flags = 0;
}
internal File_Slot*
ex__get_file(Exchange *exchange){
File_Exchange *files = &exchange->file;
File_Slot *file;
++files->num_active;
file = files->available.next;
ex__file_remove(file);
ex__clear(file);
ex__file_insert(&files->active, file);
ex__check(files);
return file;
}
internal void
ex__set_filename(File_Slot *file, char *filename, int len){
memcpy(file->filename, filename, len);
file->filename[len] = 0;
file->filename_len = len;
}
internal i32
exchange_request_file(Exchange *exchange, char *filename, int len){
File_Exchange *files = &exchange->file;
i32 result = 0;
if (len+1 < FileNameMax){
if (files->num_active < files->max){
File_Slot *file = ex__get_file(exchange);
ex__set_filename(file, filename, len);
file->flags |= FEx_Request;
result = (int)(file - files->files) + 1;
}
}
return result;
}
internal b32
exchange_file_ready(Exchange *exchange, i32 file_id, byte **data, int *size, int *max){
File_Exchange *files = &exchange->file;
b32 result = 0;
if (file_id > 0 && file_id <= files->max){
File_Slot *file = files->files + file_id - 1;
if (file->flags & FEx_Ready){
*data = file->data;
*size = file->size;
*max = file->max;
result = 1;
}
if (file->flags & FEx_Not_Exist){
*data = 0;
*size = 0;
*max = 0;
result = 1;
}
}
return result;
}
internal i32
exchange_save_file(Exchange *exchange, char *filename, int len,
byte *data, int size, int max){
File_Exchange *files = &exchange->file;
i32 result = 0;
if (len+1 < FileNameMax){
if (files->num_active < files->max){
File_Slot *file = ex__get_file(exchange);
ex__set_filename(file, filename, len);
file->flags |= FEx_Save;
file->data = data;
file->size = size;
file->max = max;
result = (int)(file - files->files) + 1;
}
}
return result;
}
internal b32
exchange_file_save_complete(Exchange *exchange, i32 file_id, byte **data, int *size, int *max){
File_Exchange *files = &exchange->file;
b32 result = 0;
if (file_id > 0 && file_id <= files->max){
File_Slot *file = files->files + file_id - 1;
if (file->flags & FEx_Save_Complete){
*data = file->data;
*size = file->size;
*max = file->max;
result = 1;
}
}
return result;
}
internal char*
exchange_file_filename(Exchange *exchange, i32 file_id, i32 *size = 0){
File_Exchange *files = &exchange->file;
char *result = 0;
if (file_id > 0 && file_id <= files->max){
File_Slot *file = files->files + file_id - 1;
result = file->filename;
if (size) *size = file->filename_len;
}
return result;
}
internal void
exchange_free_file(Exchange *exchange, i32 file_id){
File_Exchange *files = &exchange->file;
if (file_id > 0 && file_id <= files->max){
File_Slot *file = files->files + file_id - 1;
ex__file_remove(file);
ex__file_insert(&files->free_list, file);
ex__check(files);
--files->num_active;
}
}
internal void
exchange_clear_file(Exchange *exchange, i32 file_id){
File_Exchange *files = &exchange->file;
if (file_id > 0 && file_id <= files->max){
File_Slot *file = files->files + file_id - 1;
ex__clear(file);
}
}
internal b32
queue_job_is_pending(Work_Queue *queue, u32 job_id){
b32 result;
u32 job_index;
Full_Job_Data *full_job;
job_index = job_id % QUEUE_WRAP;
full_job = queue->jobs + job_index;
Assert(full_job->id == job_id);
result = 0;
if (full_job->running_thread != 0){
result = 1;
}
return(result);
}
// BOTTOM

File diff suppressed because it is too large Load Diff

232
4ed_font_set.cpp Normal file
View File

@ -0,0 +1,232 @@
/*
* Mr. 4th Dimention - Allen Webster
*
* 18.12.2015
*
* Font set for 4coder
*
*/
// TOP
inline u32
font_hash(String name){
u32 x = 5381;
char *p = name.str;
for (i32 i = 0; i < name.size; ++i, ++p){
x = ((x << 5) + x) ^ (*p);
}
return(x);
}
inline void
font__insert(Font_Slot *pos, Font_Slot *slot){
Font_Slot *nex;
nex = pos->next;
slot->next = nex;
slot->prev = pos;
nex->prev = slot;
pos->next = slot;
}
inline void
font__remove(Font_Slot *slot){
Font_Slot *n, *p;
n = slot->next;
p = slot->prev;
p->next = n;
n->prev = p;
}
internal void
font_set_init(Font_Set *set, Partition *partition, i32 max, i16 live_max){
partition_align(partition, 8);
set->info = push_array(partition, Font_Info, max);
partition_align(partition, 8);
set->entries = push_array(partition, Font_Table_Entry, max);
set->count = 0;
set->max = max;
partition_align(partition, 8);
set->font_block = push_block(partition, live_max*(sizeof(Render_Font) + sizeof(Font_Slot)));
set->free_slots = {};
set->used_slots = {};
set->free_slots.next = &set->free_slots;
set->free_slots.prev = &set->free_slots;
set->used_slots.next = &set->used_slots;
set->used_slots.prev = &set->used_slots;
char *ptr = (char*)set->font_block;
for (i32 i = 0; i < live_max; ++i){
font__insert(&set->free_slots, (Font_Slot*)ptr);
ptr += sizeof(Font_Slot) + sizeof(Render_Font);
}
set->font_used_flags = push_array(partition, b8, max);
set->live_max = live_max;
}
internal b32
font_set_can_add(Font_Set *set){
b32 result = 0;
if (set->count*8 < set->max*7) result = 1;
return(result);
}
internal void
font_set_add_hash(Font_Set *set, String name, i16 font_id){
Font_Table_Entry entry;
entry.hash = font_hash(name);
entry.name = name;
entry.font_id = font_id;
u32 i, j;
i = entry.hash % set->max;
j = i - 1;
if (i <= 1) j += set->max;
for (; i != j; ++i){
if (i == set->max) i = 0;
if (set->entries[i].font_id == 0){
set->entries[i] = entry;
break;
}
}
Assert(i != j);
}
inline b32
font_set_can_load(Font_Set *set){
b32 result = (set->free_slots.next != &set->free_slots);
return(result);
}
internal void
font_set_load(Partition *partition, Font_Set *set, i16 font_id){
Font_Info *info = get_font_info(set, font_id);
Font_Slot *slot = set->free_slots.next;
Assert(slot != &set->free_slots);
font__remove(slot);
font__insert(&set->used_slots, slot);
Render_Font *font = (Render_Font*)(slot + 1);
set->font_load(partition, font, info->filename.str, info->pt_size, 4);
info->font = font;
slot->font_id = font_id;
}
internal void
font_set_evict_lru(Font_Set *set){
Font_Slot *slot = set->used_slots.prev;
Assert(slot != &set->used_slots);
i16 font_id = slot->font_id;
Font_Info *info = get_font_info(set, font_id);
Assert(((Font_Slot*)info->font) - 1 == slot);
set->release_font(info->font);
info->font = 0;
slot->font_id = 0;
font__remove(slot);
font__insert(&set->free_slots, slot);
}
internal void
font_set_use(Partition *partition, Font_Set *set, i16 font_id){
b8 already_used;
already_used = set->font_used_flags[font_id-1];
if (!already_used){
if (set->used_this_frame < set->live_max){
++set->used_this_frame;
set->font_used_flags[font_id-1] = 1;
already_used = 1;
}
}
if (already_used){
// TODO(allen): optimize if you don't mind!!!!
Font_Info *info = get_font_info(set, font_id);
Font_Slot *slot;
if (info->font == 0){
if (!font_set_can_load(set)){
font_set_evict_lru(set);
}
font_set_load(partition, set, font_id);
}
slot = ((Font_Slot*)info->font) - 1;
font__remove(slot);
font__insert(&set->used_slots, slot);
}
}
internal b32
font_set_add(Partition *partition, Font_Set *set,
String filename, String name, i32 pt_size){
b32 result = 0;
if (font_set_can_add(set)){
i16 font_id = (i16)(++set->count);
Font_Info *info = get_font_info(set, font_id);
info->filename = filename;
info->name = name;
info->pt_size = pt_size;
set->font_info_load(partition, filename.str, pt_size, &info->height, &info->advance);
font_set_add_hash(set, name, font_id);
if (font_set_can_load(set)){
font_set_load(partition, set, font_id);
}
result = 1;
}
return(result);
}
internal b32
font_set_find_pos(Font_Set *set, String name, u32 *position){
b32 result;
u32 hash, i, j;
hash = font_hash(name);
i = hash % set->max;
j = i - 1;
if (j <= 1) j += set->max;
result = 0;
Font_Table_Entry *entry;
for (; i != j; ++i){
if (i == set->max) i = 0;
entry = set->entries + i;
if (entry->hash == hash){
if (match(name, entry->name)){
result = 1;
*position = i;
break;
}
}
}
return(result);
}
internal b32
font_set_extract(Font_Set *set, String name, i16 *font_id){
b32 result;
u32 position;
result = font_set_find_pos(set, name, &position);
if (result){
*font_id = set->entries[position].font_id;
}
return(result);
}
// BOTTOM

View File

@ -30,6 +30,7 @@ struct Interactive_View{
Style *style;
Working_Set *working_set;
Delay *delay;
Font_Set *font_set;
UI_State state;
Interactive_View_Interaction interaction;
Interactive_View_Action action;
@ -97,19 +98,20 @@ interactive_view_complete(Interactive_View *view){
}
internal i32
step_draw_int_view(System_Functions *system,
Interactive_View *view, Render_Target *target, i32_Rect rect,
Input_Summary *user_input, bool32 input_stage){
step_draw_int_view(System_Functions *system, Interactive_View *view,
Render_Target *target, i32_Rect rect,
Input_Summary *user_input, b32 input_stage){
i32 result = 0;
UI_State state =
ui_state_init(&view->state, target, user_input, view->style, view->working_set, input_stage);
ui_state_init(&view->state, target, user_input,
view->style, view->font_set, view->working_set, input_stage);
UI_Layout layout;
begin_layout(&layout, rect);
bool32 new_dir = 0;
bool32 complete = 0;
b32 new_dir = 0;
b32 complete = 0;
terminate_with_null(&view->query);
do_label(&state, &layout, view->query.str, 1.f);
@ -202,8 +204,9 @@ Do_View_Sig(do_interactive_view){
}
internal Interactive_View*
interactive_view_init(System_Functions *system, View *view, Hot_Directory *hot_dir, Style *style,
Working_Set *working_set, Delay *delay){
interactive_view_init(System_Functions *system, View *view,
Hot_Directory *hot_dir, Style *style,
Working_Set *working_set, Font_Set *font_set, Delay *delay){
Interactive_View *result = (Interactive_View*)view;
view->type = VIEW_TYPE_INTERACTIVE;
view->do_view = do_interactive_view;
@ -214,6 +217,7 @@ interactive_view_init(System_Functions *system, View *view, Hot_Directory *hot_d
result->dest = make_fixed_width_string(result->dest_);
result->style = style;
result->working_set = working_set;
result->font_set = font_set;
result->delay = delay;
return result;
}

View File

@ -9,85 +9,27 @@
// TOP
globalvar u16 keycode_lookup_table[255];
globalvar u16 loose_keycode_lookup_table[255];
globalvar u8 keycode_lookup_table[255];
internal void
set_dynamic_key_names(Key_Codes *codes){
u16 code = 1;
u16 *codes_array = (u16*)codes;
u8 code = 1;
u8 *codes_array = (u8*)codes;
for (i32 i = 0; i < sizeof(*codes)/sizeof(codes->up);){
switch (code){
case '\n': code++; break;
case '\t': code++; break;
case 0x20: code = 0x7F; break;
default:
codes_array[i++] = code++;
}
codes_array[i++] = code++;
}
}
inline u16
inline u8
keycode_lookup(u8 system_code){
return keycode_lookup_table[system_code];
}
inline u16
loose_keycode_lookup(u8 system_code){
return loose_keycode_lookup_table[system_code];
}
inline b32
keycode_has_ascii(u16 keycode){
return (keycode >= 0x20 && keycode < 0x7F) || keycode == '\n' || keycode == '\t';
}
internal u8
translate_key(u16 keycode,
b32 shift,
b32 caps_lock){
u8 character = 0;
if (keycode >= 'A' && keycode <= 'Z'){
if (caps_lock) shift = !shift;
if (!shift) character = char_to_lower((char)keycode);
else character = (u8)keycode;
}
else if (keycode >= '0' && keycode <= '9'){
persist u8 shift_number_table[10] = {
')', '!', '@', '#', '$', '%', '^', '&', '*', '('
//0 1 2 3 4 5 6 7 8 9
};
if (shift){
character = shift_number_table[keycode - '0'];
}
else{
character = (u8)keycode;
}
}
else{
if (keycode_has_ascii(keycode)){
character = (u8)keycode;
u8 shift_character = character;
switch (keycode){
case '-': character = '-'; shift_character = '_'; break;
case '=': character = '='; shift_character = '+'; break;
case '`': character = '`'; shift_character = '~'; break;
case '\\': character = '\\'; shift_character = '|'; break;
case '[': character = '['; shift_character = '{'; break;
case ']': character = ']'; shift_character = '}'; break;
case '\'': character = '\''; shift_character = '"'; break;
case ';': character = ';'; shift_character = ':'; break;
case '/': character = '/'; shift_character = '?'; break;
case '.': character = '.'; shift_character = '>'; break;
case ',': character = ','; shift_character = '<'; break;
case ' ': character = ' '; shift_character = ' '; break;
case '\n': character = '\n'; shift_character = '\n'; break;
case '\t': character = '\t'; shift_character = '\t'; break;
}
if (shift) character = shift_character;
}
}
return character;
}
// BOTTOM

View File

@ -26,7 +26,7 @@ struct Interactive_Bar{
real32 pos_x, pos_y;
real32 text_shift_x, text_shift_y;
i32_Rect rect;
Render_Font *font;
i16 font_id;
};
enum View_Message{
@ -39,7 +39,7 @@ enum View_Message{
struct View;
#define Do_View_Sig(name) \
i32 (name)(System_Functions *system, \
i32 (name)(System_Functions *system, Exchange *exchange, \
View *view, i32_Rect rect, View *active, \
View_Message message, Render_Target *target, \
Input_Summary *user_input, Input_Summary *active_input)
@ -78,8 +78,8 @@ struct View{
i32 type;
i32 block_size;
Application_Mouse_Cursor mouse_cursor_type;
bool32 is_active;
bool32 is_minor;
b32 is_active;
b32 is_minor;
};
struct Live_Views{
@ -133,31 +133,30 @@ struct Editing_Layout{
};
internal void
intbar_draw_string(Render_Target *target, Interactive_Bar *bar,
u8 *str, u32 char_color){
Render_Font *font = bar->font;
intbar_draw_string(Render_Target *target,
Interactive_Bar *bar, u8 *str, u32 char_color){
i16 font_id = bar->font_id;
for (i32 i = 0; str[i]; ++i){
char c = str[i];
font_draw_glyph(target, font, c,
font_draw_glyph(target, font_id, c,
bar->pos_x + bar->text_shift_x,
bar->pos_y + bar->text_shift_y,
char_color);
bar->pos_x += font_get_glyph_width(font, c);
bar->pos_x += font_get_glyph_width(target, font_id, c);
}
}
internal void
intbar_draw_string(Render_Target *target,
Interactive_Bar *bar, String str,
u32 char_color){
Render_Font *font = bar->font;
intbar_draw_string(Render_Target *target, Interactive_Bar *bar,
String str, u32 char_color){
i16 font_id = bar->font_id;
for (i32 i = 0; i < str.size; ++i){
char c = str.str[i];
font_draw_glyph(target, font, c,
font_draw_glyph(target, font_id, c,
bar->pos_x + bar->text_shift_x,
bar->pos_y + bar->text_shift_y,
char_color);
bar->pos_x += font_get_glyph_width(font, c);
bar->pos_x += font_get_glyph_width(target, font_id, c);
}
}
@ -191,9 +190,9 @@ live_set_alloc_view(Live_Views *live_set, Mem_Options *mem){
}
inline void
live_set_free_view(System_Functions *system, Live_Views *live_set, View *view){
live_set_free_view(System_Functions *system, Exchange *exchange, Live_Views *live_set, View *view){
Assert(live_set->count > 0);
view->do_view(system, view, {}, 0, VMSG_FREE, 0, {}, 0);
view->do_view(system, exchange, view, {}, 0, VMSG_FREE, 0, {}, 0);
view->next_free = live_set->free_view;
live_set->free_view = view;
--live_set->count;
@ -201,13 +200,14 @@ live_set_free_view(System_Functions *system, Live_Views *live_set, View *view){
}
inline void
view_replace_major(System_Functions *system, View *new_view, Panel *panel, Live_Views *live_set){
view_replace_major(System_Functions *system, Exchange *exchange,
View *new_view, Panel *panel, Live_Views *live_set){
View *view = panel->view;
if (view){
if (view->is_minor && view->major){
live_set_free_view(system, live_set, view->major);
live_set_free_view(system, exchange, live_set, view->major);
}
live_set_free_view(system, live_set, view);
live_set_free_view(system, exchange, live_set, view);
}
new_view->panel = panel;
new_view->minor = 0;
@ -215,13 +215,14 @@ view_replace_major(System_Functions *system, View *new_view, Panel *panel, Live_
}
inline void
view_replace_minor(System_Functions *system, View *new_view, Panel *panel, Live_Views *live_set){
view_replace_minor(System_Functions *system, Exchange *exchange,
View *new_view, Panel *panel, Live_Views *live_set){
View *view = panel->view;
new_view->is_minor = 1;
if (view){
if (view->is_minor){
new_view->major = view->major;
live_set_free_view(system, live_set, view);
live_set_free_view(system, exchange, live_set, view);
}
else{
new_view->major = view;
@ -236,40 +237,43 @@ view_replace_minor(System_Functions *system, View *new_view, Panel *panel, Live_
}
inline void
view_remove_major(System_Functions *system, Panel *panel, Live_Views *live_set){
view_remove_major(System_Functions *system, Exchange *exchange,
Panel *panel, Live_Views *live_set){
View *view = panel->view;
if (view){
if (view->is_minor && view->major){
live_set_free_view(system, live_set, view->major);
live_set_free_view(system, exchange, live_set, view->major);
}
live_set_free_view(system, live_set, view);
live_set_free_view(system, exchange, live_set, view);
}
panel->view = 0;
}
inline void
view_remove_major_leave_minor(System_Functions *system, Panel *panel, Live_Views *live_set){
view_remove_major_leave_minor(System_Functions *system, Exchange *exchange,
Panel *panel, Live_Views *live_set){
View *view = panel->view;
if (view){
if (view->is_minor && view->major){
live_set_free_view(system, live_set, view->major);
live_set_free_view(system, exchange, live_set, view->major);
view->major = 0;
}
else{
live_set_free_view(system, live_set, view);
live_set_free_view(system, exchange, live_set, view);
panel->view = 0;
}
}
}
inline void
view_remove_minor(System_Functions *system, Panel *panel, Live_Views *live_set){
view_remove_minor(System_Functions *system, Exchange *exchange,
Panel *panel, Live_Views *live_set){
View *view = panel->view;
View *major = 0;
if (view){
if (view->is_minor){
major = view->major;
live_set_free_view(system, live_set, view);
live_set_free_view(system, exchange, live_set, view);
}
}
panel->view = major;
@ -277,10 +281,11 @@ view_remove_minor(System_Functions *system, Panel *panel, Live_Views *live_set){
}
inline void
view_remove(System_Functions *system, Panel *panel, Live_Views *live_set){
view_remove(System_Functions *system, Exchange *exchange,
Panel *panel, Live_Views *live_set){
View *view = panel->view;
if (view->is_minor) view_remove_minor(system, panel, live_set);
else view_remove_major(system, panel, live_set);
if (view->is_minor) view_remove_minor(system, exchange, panel, live_set);
else view_remove_major(system, exchange, panel, live_set);
}
struct Divider_And_ID{

View File

@ -14,6 +14,36 @@ struct Partition{
i32 pos, max;
};
struct Temp_Memory{
void *handle;
int pos;
};
enum Memory_Bubble_Flag{
MEM_BUBBLE_USED = 0x1,
MEM_BUBBLE_DEBUG = 0xD3000000,
MEM_BUBBLE_SYS_DEBUG = 0x5D000000,
MEM_BUBBLE_DEBUG_MASK = 0xFF000000
};
struct Bubble{
Bubble *prev;
Bubble *next;
u32 flags;
i32 size;
u32 type;
u32 _unused_;
};
struct General_Memory{
Bubble sentinel;
};
struct Mem_Options{
Partition part;
General_Memory general;
};
inline Partition
partition_open(void *memory, i32 size){
Partition partition;
@ -60,26 +90,6 @@ partition_sub_part(Partition *data, i32 size){
#define push_array(part, T, size) (T*)partition_allocate(part, sizeof(T)*(size))
#define push_block(part, size) partition_allocate(part, size)
enum Memory_Bubble_Flag{
MEM_BUBBLE_USED = 0x1,
MEM_BUBBLE_DEBUG = 0xD3000000,
MEM_BUBBLE_SYS_DEBUG = 0x5D000000,
MEM_BUBBLE_DEBUG_MASK = 0xFF000000
};
struct Bubble{
Bubble *prev;
Bubble *next;
u32 flags;
i32 size;
u32 type;
u32 _unused_;
};
struct General_Memory{
Bubble sentinel;
};
inline void
insert_bubble(Bubble *prev, Bubble *bubble){
bubble->prev = prev;
@ -226,28 +236,18 @@ general_memory_reallocate_nocopy(General_Memory *general, void *old, i32 size, u
return general_memory_reallocate(general, old, 0, size, type);
}
struct Temp_Memory{
Partition *part;
i32 pos;
};
internal Temp_Memory
begin_temp_memory(Partition *data){
Temp_Memory result;
result.part = data;
result.handle = data;
result.pos = data->pos;
return result;
}
internal void
end_temp_memory(Temp_Memory temp){
temp.part->pos = temp.pos;
((Partition*)temp.handle)->pos = temp.pos;
}
struct Mem_Options{
Partition part;
General_Memory general;
};
// BOTTOM

View File

@ -33,7 +33,7 @@ step_draw_menu_view(Menu_View *view, Render_Target *target, i32_Rect rect,
UI_State state =
ui_state_init(&view->state, target, user_input,
view->style, view->working_set, input_stage);
view->style, &target->font_set, view->working_set, input_stage);
UI_Layout layout;
begin_layout(&layout, rect);

View File

@ -187,10 +187,10 @@ LargeRoundUp(i32 x, i32 granularity){
#define Byte_7 (0xFFU << 56)
#define bytes(n) (n)
#define Kbytes(n) (bytes(n) * 1024)
#define Mbytes(n) (Kbytes(n) * 1024)
#define Gbytes(n) (Mbytes((u64)n) * 1024)
#define Tbytes(n) (Gbytes((u64)n) * 1024)
#define Kbytes(n) ((n) << 10)
#define Mbytes(n) ((n) << 20)
#define Gbytes(n) (((u64)n) << 30)
#define Tbytes(n) (((u64)n) << 40)
#endif

View File

@ -138,7 +138,7 @@ private_draw_gradient(Render_Target *target, f32_Rect rect,
inline void
private_draw_glyph(Render_Target *target, Render_Font *font,
u16 character, f32 x, f32 y, u32 color){
u8 character, f32 x, f32 y, u32 color){
f32 x_shift, y_shift;
x_shift = 0;
y_shift = (f32)font->ascent;
@ -147,8 +147,8 @@ private_draw_glyph(Render_Target *target, Render_Font *font,
y += y_shift;
stbtt_aligned_quad q;
stbtt_GetBakedQuadUnrounded(font->chardata, font->tex_width, font->tex_height,
character, &x, &y, &q, 1);
stbtt_GetPackedQuad(font->chardata, font->tex_width, font->tex_height,
character, &x, &y, &q, 1);
draw_set_color(target, color);
draw_bind_texture(target, font->tex);
@ -163,7 +163,7 @@ private_draw_glyph(Render_Target *target, Render_Font *font,
}
inline void
private_draw_glyph_mono(Render_Target *target, Render_Font *font, u16 character,
private_draw_glyph_mono(Render_Target *target, Render_Font *font, u8 character,
f32 x, f32 y, f32 advance, u32 color){
f32 x_shift, y_shift;
i32 left = font->chardata[character].x0;
@ -176,7 +176,8 @@ private_draw_glyph_mono(Render_Target *target, Render_Font *font, u16 character,
y += y_shift;
stbtt_aligned_quad q;
stbtt_GetBakedQuadUnrounded(font->chardata, font->tex_width, font->tex_height, character, &x, &y, &q, 1);
stbtt_GetPackedQuad(font->chardata, font->tex_width, font->tex_height,
character, &x, &y, &q, 1);
draw_set_color(target, color);
draw_bind_texture(target, font->tex);
@ -191,7 +192,7 @@ private_draw_glyph_mono(Render_Target *target, Render_Font *font, u16 character,
}
inline void
private_draw_glyph_mono(Render_Target *target, Render_Font *font, u16 character,
private_draw_glyph_mono(Render_Target *target, Render_Font *font, u8 character,
real32 x, real32 y, u32 color){
private_draw_glyph_mono(target, font, character, x, y, (f32)font->advance, color);
}
@ -233,31 +234,34 @@ launch_rendering(Render_Target *target){
{
Render_Piece_Glyph *glyph =
ExtractStruct(Render_Piece_Glyph);
Render_Font *font = glyph->font_id;
private_draw_glyph(target, font, glyph->character,
glyph->pos.x, glyph->pos.y, glyph->color);
Render_Font *font = get_font_info(&target->font_set, glyph->font_id)->font;
if (font)
private_draw_glyph(target, font, glyph->character,
glyph->pos.x, glyph->pos.y, glyph->color);
}break;
case piece_type_mono_glyph:
{
Render_Piece_Glyph *glyph =
ExtractStruct(Render_Piece_Glyph);
Render_Font *font = glyph->font_id;
private_draw_glyph_mono(target, font, glyph->character,
glyph->pos.x, glyph->pos.y, glyph->color);
Render_Font *font = get_font_info(&target->font_set, glyph->font_id)->font;
if (font)
private_draw_glyph_mono(target, font, glyph->character,
glyph->pos.x, glyph->pos.y, glyph->color);
}break;
case piece_type_mono_glyph_advance:
{
Render_Piece_Glyph_Advance *glyph =
ExtractStruct(Render_Piece_Glyph_Advance);
Render_Font *font = glyph->font_id;
private_draw_glyph_mono(target, font, glyph->character,
glyph->pos.x, glyph->pos.y,
glyph->advance, glyph->color);
Render_Font *font = get_font_info(&target->font_set, glyph->font_id)->font;
if (font)
private_draw_glyph_mono(target, font, glyph->character,
glyph->pos.x, glyph->pos.y,
glyph->advance, glyph->color);
}break;
}
}
@ -265,18 +269,99 @@ launch_rendering(Render_Target *target){
#undef ExtractStruct
internal i32
draw_font_load(System_Functions *system,
Render_Font *font_out,
char *filename,
i32 pt_size,
void *font_block,
i32 font_block_size,
i32 *memory_used_out,
i32 tab_width){
internal
Font_Info_Load_Sig(draw_font_info_load){
i32 result = 1;
Data file;
file = system->load_file(filename);
file = system_load_file(filename);
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){
result = 0;
}
else{
stbtt_fontinfo font;
if (!stbtt_InitFont(&font, (u8*)file.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, 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);
}
end_temp_memory(temp);
return(result);
}
internal
Font_Load_Sig(draw_font_load){
i32 result = 1;
Data file;
file = system_load_file(filename);
Temp_Memory temp = begin_temp_memory(partition);
stbtt_packedchar *chardata = font_out->chardata;
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){
result = 0;
@ -289,12 +374,12 @@ draw_font_load(System_Functions *system,
}
else{
i32 ascent, descent, line_gap;
real32 scale;
f32 scale;
stbtt_GetFontVMetrics(&font, &ascent, &descent, &line_gap);
scale = stbtt_ScaleForPixelHeight(&font, (real32)pt_size);
scale = stbtt_ScaleForPixelHeight(&font, (f32)pt_size);
real32 scaled_ascent, scaled_descent, scaled_line_gap;
f32 scaled_ascent, scaled_descent, scaled_line_gap;
scaled_ascent = scale*ascent;
scaled_descent = scale*descent;
@ -305,167 +390,36 @@ draw_font_load(System_Functions *system,
font_out->descent = (i32)(scaled_descent);
font_out->line_skip = (i32)(scaled_line_gap);
u8 *memory_cursor = (u8*)font_block;
Assert(pt_size*pt_size*128 <= font_block_size);
i32 tex_width, tex_height;
tex_width = pt_size*128;
tex_height = pt_size*2;
font_out->tex_width = tex_width;
font_out->tex_height = tex_height;
if (stbtt_BakeFontBitmap((u8*)file.data, 0, (real32)pt_size,
memory_cursor, tex_width, tex_height, 0, 128, font_out->chardata) <= 0){
result = 0;
}
else{
GLuint font_tex;
glGenTextures(1, &font_tex);
glBindTexture(GL_TEXTURE_2D, font_tex);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, tex_width, tex_height, 0, GL_ALPHA, GL_UNSIGNED_BYTE, memory_cursor);
font_out->tex = font_tex;
glBindTexture(GL_TEXTURE_2D, 0);
}
font_out->chardata['\r'] = font_out->chardata[' '];
font_out->chardata['\n'] = font_out->chardata[' '];
font_out->chardata['\t'] = font_out->chardata[' '];
font_out->chardata['\t'].xadvance *= tab_width;
i32 max_advance = 0;
for (u16 code_point = 0; code_point < 128; ++code_point){
if (stbtt_FindGlyphIndex(&font, code_point) != 0){
font_out->glyphs[code_point].exists = 1;
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;
}
}
font_out->advance = max_advance - 1;
}
system->free_file(file);
}
return result;
}
stbtt_pack_context spc;
#if 0
if (stbtt_BakeFontBitmap((u8*)file.data, 0, (f32)pt_size,
memory_cursor, tex_width, tex_height, 0, 128,
font_out->chardata, partition) <= 0){
result = 0;
}
#endif
internal void
draw_rectangle(Render_Target *target, i32_Rect rect, u32 color){
draw_set_color(target, color);
draw_bind_texture(target, 0);
glBegin(GL_QUADS);
{
glVertex2i(rect.x0, rect.y0);
glVertex2i(rect.x0, rect.y1);
glVertex2i(rect.x1, rect.y1);
glVertex2i(rect.x1, rect.y0);
}
glEnd();
}
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, 0,
STBTT_POINT_SIZE((f32)pt_size), 0, 128, chardata)){
// do nothing
}
else{
result = 0;
}
internal void
draw_triangle_3corner(Render_Target *target,
real32 x0, real32 y0,
real32 x1, real32 y1,
real32 x2, real32 y2,
u32 color){
draw_set_color(target, color);
draw_bind_texture(target, 0);
glBegin(GL_TRIANGLES);
{
glVertex2f(x0, y0);
glVertex2f(x1, y1);
glVertex2f(x2, y2);
}
glEnd();
}
inline void
draw_gradient_2corner_clipped(Render_Target *target, real32 l, real32 t, real32 r, real32 b,
Vec4 color_left, Vec4 color_right){
draw_gradient_2corner_clipped(target, f32R(l,t,r,b), color_left, color_right);
}
inline void
draw_rectangle_outline(Render_Target *target, i32_Rect rect, u32 color){
draw_rectangle_outline(target, f32R(rect), color);
}
internal void
draw_margin(Render_Target *target, i32_Rect outer, i32_Rect inner, u32 color){
draw_rectangle(target, i32R(outer.x0, outer.y0, outer.x1, inner.y0), color);
draw_rectangle(target, i32R(outer.x0, inner.y1, outer.x1, outer.y1), color);
draw_rectangle(target, i32R(outer.x0, inner.y0, inner.x0, inner.y1), color);
draw_rectangle(target, i32R(inner.x1, inner.y0, outer.x1, inner.y1), color);
}
inline internal i32
font_predict_size(i32 pt_size){
return pt_size*pt_size*128;
}
internal i32
font_load(System_Functions *system,
Render_Font *font_out, char *filename, i32 pt_size,
void *font_block, i32 font_block_size,
i32 *memory_used_out, i32 tab_width){
i32 result = 1;
File_Data file;
file = system->load_file(filename);
if (!file.data){
result = 0;
}
else{
stbtt_fontinfo font;
if (!stbtt_InitFont(&font, (u8*)file.data, 0)){
result = 0;
}
else{
i32 ascent, descent, line_gap;
real32 scale;
stbtt_GetFontVMetrics(&font, &ascent, &descent, &line_gap);
scale = stbtt_ScaleForPixelHeight(&font, (real32)pt_size);
real32 scaled_ascent, scaled_descent, scaled_line_gap;
scaled_ascent = scale*ascent;
scaled_descent = scale*descent;
scaled_line_gap = scale*line_gap;
font_out->height = (i32)(scaled_ascent - scaled_descent + scaled_line_gap);
font_out->ascent = (i32)(scaled_ascent);
font_out->descent = (i32)(scaled_descent);
font_out->line_skip = (i32)(scaled_line_gap);
u8 *memory_cursor = (u8*)font_block;
Assert(pt_size*pt_size*128 <= font_block_size);
i32 tex_width, tex_height;
tex_width = pt_size*128;
tex_height = pt_size*2;
font_out->tex_width = tex_width;
font_out->tex_height = tex_height;
if (stbtt_BakeFontBitmap((u8*)file.data, 0, (real32)pt_size,
memory_cursor, tex_width, tex_height, 0, 128, font_out->chardata) <= 0){
stbtt_PackEnd(&spc);
}
else{
result = 0;
}
else{
if (result){
GLuint font_tex;
glGenTextures(1, &font_tex);
glBindTexture(GL_TEXTURE_2D, font_tex);
@ -474,120 +428,45 @@ font_load(System_Functions *system,
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, tex_width, tex_height, 0, GL_ALPHA, GL_UNSIGNED_BYTE, memory_cursor);
glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, tex_width, tex_height, 0, GL_ALPHA, GL_UNSIGNED_BYTE, block);
font_out->tex = font_tex;
glBindTexture(GL_TEXTURE_2D, 0);
}
font_out->chardata['\r'] = font_out->chardata[' '];
font_out->chardata['\n'] = font_out->chardata[' '];
font_out->chardata['\t'] = font_out->chardata[' '];
font_out->chardata['\t'].xadvance *= tab_width;
font_out->chardata['\r'] = font_out->chardata[' '];
font_out->chardata['\n'] = font_out->chardata[' '];
font_out->chardata['\t'] = font_out->chardata[' '];
font_out->chardata['\t'].xadvance *= tab_width;
i32 max_advance = 0;
for (u16 code_point = 0; code_point < 128; ++code_point){
if (stbtt_FindGlyphIndex(&font, code_point) != 0){
font_out->glyphs[code_point].exists = 1;
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;
i32 max_advance = 0;
for (u8 code_point = 0; code_point < 128; ++code_point){
if (stbtt_FindGlyphIndex(&font, code_point) != 0){
font_out->glyphs[code_point].exists = 1;
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;
}
system->free_file(file);
system_free_memory(file.data);
}
end_temp_memory(temp);
return result;
}
internal void
font_set_tabwidth(Render_Font *font, i32 tab_width){
font->chardata['\t'].xadvance *= font->chardata[' '].xadvance * tab_width;
internal
Release_Font_Sig(draw_release_font){
glDeleteTextures(1, &font->tex);
font->tex = 0;
}
inline real32
font_get_glyph_width(Render_Font *font, u16 character){
return font->chardata[character].xadvance;
}
internal real32
font_string_width(Render_Font *font, char *str){
real32 x = 0;
for (i32 i = 0; str[i]; ++i){
x += font_get_glyph_width(font, str[i]);
}
return x;
}
internal i32
draw_string(Render_Target *target, Render_Font *font, char *str,
i32 x_, i32 y, u32 color){
real32 x = (real32)x_;
for (i32 i = 0; str[i]; ++i){
char c = str[i];
font_draw_glyph(target, font, c,
x, (real32)y, color);
x += font_get_glyph_width(font, c);
}
return CEIL32(x);
}
internal real32
draw_string_mono(Render_Target *target, Render_Font *font, char *str,
real32 x, real32 y, real32 advance, u32 color){
for (i32 i = 0; str[i]; ++i){
font_draw_glyph_mono(target, font, str[i],
x, y, advance, color);
x += advance;
}
return x;
}
internal i32
draw_string(Render_Target *target, Render_Font *font, String str,
i32 x_, i32 y, u32 color){
real32 x = (real32)x_;
for (i32 i = 0; i < str.size; ++i){
char c = str.str[i];
font_draw_glyph(target, font, c,
x, (real32)y, color);
x += font_get_glyph_width(font, c);
}
return CEIL32(x);
}
internal real32
draw_string_mono(Render_Target *target, Render_Font *font, String str,
real32 x, real32 y, real32 advance, u32 color){
for (i32 i = 0; i < str.size; ++i){
font_draw_glyph_mono(target, font, str.str[i],
x, y, advance, color);
x += advance;
}
return x;
}
internal real32
font_get_max_width(Render_Font *font, char *characters){
stbtt_bakedchar *chardata = font->chardata;
real32 cx, x = 0;
for (i32 i = 0; characters[i]; ++i){
cx = chardata[characters[i]].xadvance;
if (x < cx) x = cx;
}
return x;
}
internal real32
font_get_string_width(Render_Font *font, String string){
real32 result = 0;
for (i32 i = 0; i < string.size; ++i){
font_get_glyph_width(font, string.str[i]);
}
return result;
}
#endif
// BOTTOM

View File

@ -12,6 +12,20 @@
#ifndef FRED_RENDERING_H
#define FRED_RENDERING_H
internal void*
part_alloc(int size, void *context){
Partition *part = (Partition*)context;
void *result = push_block(part, size);
return(result);
}
internal void
part_free(void *ptr, void *context){
}
#define STBTT_malloc part_alloc
#define STBTT_free part_free
#define STB_TRUETYPE_IMPLEMENTATION
#include "stb_truetype.h"
@ -25,7 +39,7 @@ struct Render_Font{
b32 loaded;
Glyph_Data glyphs[256];
stbtt_bakedchar chardata[256];
stbtt_packedchar chardata[256];
float advance_data[256];
i32 height, ascent, descent, line_skip;
i32 advance;
@ -67,16 +81,16 @@ struct Render_Piece_Gradient{
struct Render_Piece_Glyph{
Vec2 pos;
u32 color;
Render_Font *font_id;
u16 character;
i16 font_id;
u8 character;
};
struct Render_Piece_Glyph_Advance{
Vec2 pos;
u32 color;
f32 advance;
Render_Font *font_id;
u16 character;
i16 font_id;
u8 character;
};
struct Render_Piece_Combined{
@ -93,16 +107,62 @@ struct Render_Piece_Combined{
typedef Draw_Push_Piece_Sig(Draw_Push_Piece);
#define Font_Load_Sig(name) i32 name( \
System_Functions *system, \
Partition *partition, \
Render_Font *font_out, \
char *filename, \
i32 pt_size, \
void *font_block, \
i32 font_block_size, \
i32 *memory_used_out, \
i32 tab_width)
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)
typedef Release_Font_Sig(Release_Font);
struct Font_Table_Entry{
u32 hash;
String name;
i16 font_id;
};
struct Font_Info{
Render_Font *font;
String filename;
String name;
i32 height, advance;
i32 pt_size;
};
struct Font_Slot{
Font_Slot *next, *prev;
i16 font_id;
u8 padding[14];
};
struct Font_Set{
Font_Info *info;
Font_Table_Entry *entries;
u32 count, max;
void *font_block;
Font_Slot free_slots;
Font_Slot used_slots;
Font_Info_Load *font_info_load;
Font_Load *font_load;
Release_Font *release_font;
b8 *font_used_flags;
i16 used_this_frame;
i16 live_max;
};
struct Render_Target{
void *handle;
void *context;
@ -115,10 +175,12 @@ struct Render_Target{
byte *push_buffer;
i32 size, max;
Font_Set font_set;
Partition *partition;
Draw_Push_Clip *push_clip;
Draw_Pop_Clip *pop_clip;
Draw_Push_Piece *push_piece;
Font_Load *font_load;
};
inline i32_Rect
@ -126,6 +188,12 @@ rect_from_target(Render_Target *target){
return i32R(0, 0, target->width, target->height);
}
inline Font_Info*
get_font_info(Font_Set *set, i16 font_id){
Font_Info *result = set->info + font_id - 1;
return(result);
}
#endif
// BOTTOM

View File

@ -19,6 +19,18 @@ draw_pop_clip(Render_Target *target){
target->pop_clip(target);
}
internal void
begin_render_section(Render_Target *target){
Font_Set *font_set = &target->font_set;
font_set->used_this_frame = 0;
memset(font_set->font_used_flags, 0, font_set->max);
}
internal void
end_render_section(Render_Target *target){
//Font_Set *font_set = &target->font_set;
}
internal void
draw_rectangle(Render_Target *target, i32_Rect rect, u32 color){
Render_Piece_Combined piece;
@ -81,87 +93,80 @@ font_predict_size(i32 pt_size){
return pt_size*pt_size*128;
}
internal i32
font_load(Render_Target *target, System_Functions *system,
Render_Font *font_out, char *filename, i32 pt_size,
void *font_block, i32 font_block_size,
i32 *memory_used_out, i32 tab_width){
i32 result =
target->font_load(system, font_out, filename, pt_size,
font_block, font_block_size, memory_used_out, tab_width);
return result;
}
internal void
font_set_tabwidth(Render_Font *font, i32 tab_width){
font->chardata['\t'].xadvance *= font->chardata[' '].xadvance * tab_width;
}
// TODO(allen): Abstract Render_Font all the fucking way out of the app side code.
internal void
font_draw_glyph_mono(Render_Target *target, Render_Font *font, u16 character,
f32 x, f32 y, f32 advance, u32 color){
font_draw_glyph_mono(Render_Target *target, i16 font_id,
u8 character, f32 x, f32 y, f32 advance, u32 color){
Render_Piece_Combined piece;
piece.header.type = piece_type_mono_glyph;
piece.glyph.pos.x = x;
piece.glyph.pos.y = y;
piece.glyph.color = color;
piece.glyph.font_id = font;
piece.glyph.font_id = font_id;
piece.glyph.character = character;
target->push_piece(target, piece);
font_set_use(target->partition, &target->font_set, font_id);
}
inline void
font_draw_glyph_mono(Render_Target *target, Render_Font *font, u16 character,
real32 x, real32 y, u32 color){
font_draw_glyph_mono(target, font, character, x, y, (real32)font->advance, color);
font_draw_glyph_mono(Render_Target *target, i16 font_id,
u8 character, f32 x, f32 y, u32 color){
f32 advance = (f32)get_font_info(&target->font_set, font_id)->advance;
font_draw_glyph_mono(target, font_id, character, x, y, advance, color);
}
internal void
font_draw_glyph(Render_Target *target, Render_Font *font, u16 character,
f32 x, f32 y, u32 color){
font_draw_glyph(Render_Target *target, i16 font_id,
u8 character, f32 x, f32 y, u32 color){
Render_Piece_Combined piece;
piece.header.type = piece_type_glyph;
piece.glyph.pos.x = x;
piece.glyph.pos.y = y;
piece.glyph.color = color;
piece.glyph.font_id = font;
piece.glyph.font_id = font_id;
piece.glyph.character = character;
target->push_piece(target, piece);
font_set_use(target->partition, &target->font_set, font_id);
}
inline real32
font_get_glyph_width(Render_Font *font, u16 character){
return font->chardata[character].xadvance;
inline f32
font_get_glyph_width(Render_Target *target, i16 font_id, u16 character){
Render_Font *font = get_font_info(&target->font_set, font_id)->font;
f32 result = 0.f;
if (font) result = font->chardata[character].xadvance;
return (result);
}
internal real32
font_string_width(Render_Font *font, char *str){
real32 x = 0;
internal f32
font_string_width(Render_Target *target, i16 font_id, char *str){
f32 x = 0;
for (i32 i = 0; str[i]; ++i){
x += font_get_glyph_width(font, str[i]);
x += font_get_glyph_width(target, font_id, str[i]);
}
return x;
}
internal i32
draw_string(Render_Target *target, Render_Font *font, char *str,
i32 x_, i32 y, u32 color){
draw_string(Render_Target *target, i16 font_id,
char *str, i32 x_, i32 y, u32 color){
real32 x = (real32)x_;
for (i32 i = 0; str[i]; ++i){
char c = str[i];
font_draw_glyph(target, font, c,
x, (real32)y, color);
x += font_get_glyph_width(font, c);
font_draw_glyph(target, font_id, c, x, (f32)y, color);
x += font_get_glyph_width(target, font_id, c);
}
return CEIL32(x);
}
internal real32
draw_string_mono(Render_Target *target, Render_Font *font, char *str,
real32 x, real32 y, real32 advance, u32 color){
internal f32
draw_string_mono(Render_Target *target, i16 font_id,
char *str, f32 x, f32 y, f32 advance, u32 color){
for (i32 i = 0; str[i]; ++i){
font_draw_glyph_mono(target, font, str[i],
font_draw_glyph_mono(target, font_id, str[i],
x, y, advance, color);
x += advance;
}
@ -169,47 +174,51 @@ draw_string_mono(Render_Target *target, Render_Font *font, char *str,
}
internal i32
draw_string(Render_Target *target, Render_Font *font, String str,
i32 x_, i32 y, u32 color){
real32 x = (real32)x_;
draw_string(Render_Target *target, i16 font_id,
String str, i32 x_, i32 y, u32 color){
f32 x = (f32)x_;
for (i32 i = 0; i < str.size; ++i){
char c = str.str[i];
font_draw_glyph(target, font, c,
x, (real32)y, color);
x += font_get_glyph_width(font, c);
font_draw_glyph(target, font_id, c,
x, (f32)y, color);
x += font_get_glyph_width(target, font_id, c);
}
return CEIL32(x);
}
internal real32
draw_string_mono(Render_Target *target, Render_Font *font, String str,
real32 x, real32 y, real32 advance, u32 color){
internal f32
draw_string_mono(Render_Target *target, i16 font_id,
String str, f32 x, f32 y, f32 advance, u32 color){
for (i32 i = 0; i < str.size; ++i){
font_draw_glyph_mono(target, font, str.str[i],
x, y, advance, color);
font_draw_glyph_mono(target, font_id,
str.str[i], x, y, advance, color);
x += advance;
}
return x;
}
internal real32
font_get_max_width(Render_Font *font, char *characters){
stbtt_bakedchar *chardata = font->chardata;
real32 cx, x = 0;
for (i32 i = 0; characters[i]; ++i){
cx = chardata[characters[i]].xadvance;
if (x < cx) x = cx;
internal f32
font_get_max_width(Font_Set *font_set, i16 font_id, char *characters){
Render_Font *font = get_font_info(font_set, font_id)->font;
f32 cx, x = 0;
if (font){
stbtt_packedchar *chardata = font->chardata;
for (i32 i = 0; characters[i]; ++i){
cx = chardata[characters[i]].xadvance;
if (x < cx) x = cx;
}
}
return x;
}
internal real32
font_get_string_width(Render_Font *font, String string){
real32 result = 0;
internal f32
font_get_string_width(Render_Target *target, i16 font_id, String string){
f32 result = 0;
for (i32 i = 0; i < string.size; ++i){
font_get_glyph_width(font, string.str[i]);
font_get_glyph_width(target, font_id, string.str[i]);
}
return result;
}
// BOTTOM

View File

@ -1,405 +0,0 @@
/*
* Mr. 4th Dimention - Allen Webster
*
* 12.17.2014
*
* Rendering layer for project codename "4ed"
*
*/
// TOP
#if 0
inline void
draw_set_clip(Render_Target *target, i32_Rect clip_box){
glScissor(clip_box.x0,
target->height - clip_box.y1,
clip_box.x1 - clip_box.x0,
clip_box.y1 - clip_box.y0);
}
inline void
draw_push_clip(Render_Target *target, i32_Rect clip_box){
Assert(target->clip_top == -1 ||
fits_inside(clip_box, target->clip_boxes[target->clip_top]));
Assert(target->clip_top+1 < ArrayCount(target->clip_boxes));
target->clip_boxes[++target->clip_top] = clip_box;
draw_set_clip(target, clip_box);
}
inline void
draw_pop_clip(Render_Target *target){
Assert(target->clip_top > 0);
--target->clip_top;
draw_set_clip(target, target->clip_boxes[target->clip_top]);
}
inline void
draw_bind_texture(Render_Target *target, i32 texid){
if (target->bound_texture != texid){
glBindTexture(GL_TEXTURE_2D, texid);
target->bound_texture = texid;
}
}
internal void
draw_set_color(Render_Target *target, u32 color){
if (target->color != color){
target->color = color;
Vec4 c = unpack_color4(color);
glColor4f(c.r, c.g, c.b, c.a);
}
}
internal void
draw_rectangle(Render_Target *target, i32_Rect rect, u32 color){
draw_set_color(target, color);
draw_bind_texture(target, 0);
glBegin(GL_QUADS);
{
glVertex2i(rect.x0, rect.y0);
glVertex2i(rect.x0, rect.y1);
glVertex2i(rect.x1, rect.y1);
glVertex2i(rect.x1, rect.y0);
}
glEnd();
}
internal void
draw_rectangle(Render_Target *target, real32_Rect rect, u32 color){
draw_set_color(target, color);
draw_bind_texture(target, 0);
glBegin(GL_QUADS);
{
glVertex2f(rect.x0, rect.y0);
glVertex2f(rect.x0, rect.y1);
glVertex2f(rect.x1, rect.y1);
glVertex2f(rect.x1, rect.y0);
}
glEnd();
}
internal void
draw_triangle_3corner(Render_Target *target,
real32 x0, real32 y0,
real32 x1, real32 y1,
real32 x2, real32 y2,
u32 color){
draw_set_color(target, color);
draw_bind_texture(target, 0);
glBegin(GL_TRIANGLES);
{
glVertex2f(x0, y0);
glVertex2f(x1, y1);
glVertex2f(x2, y2);
}
glEnd();
}
internal void
draw_gradient_2corner_clipped(Render_Target *target, real32_Rect rect,
Vec4 color_left, Vec4 color_right){
Vec4 cl = color_left;
Vec4 cr = color_right;
draw_bind_texture(target, 0);
glBegin(GL_QUADS);
{
glColor4f(cl.r, cl.g, cl.b, cl.a);
glVertex2f(rect.x0, rect.y0);
glVertex2f(rect.x0, rect.y1);
glColor4f(cr.r, cr.g, cr.b, cr.a);
glVertex2f(rect.x1, rect.y1);
glVertex2f(rect.x1, rect.y0);
}
glEnd();
}
inline void
draw_gradient_2corner_clipped(Render_Target *target, real32 l, real32 t, real32 r, real32 b,
Vec4 color_left, Vec4 color_right){
draw_gradient_2corner_clipped(target, f32R(l,t,r,b), color_left, color_right);
}
internal void
draw_rectangle_outline(Render_Target *target, real32_Rect rect, u32 color){
real32_Rect r;
r.x0 = rect.x0 + .5f;
r.y0 = rect.y0 + .5f;
r.x1 = rect.x1 - .5f;
r.y1 = rect.y1 - .5f;
draw_set_color(target, color);
draw_bind_texture(target, 0);
glBegin(GL_LINE_STRIP);
{
glVertex2f(r.x0, r.y0);
glVertex2f(r.x1, r.y0);
glVertex2f(r.x1, r.y1);
glVertex2f(r.x0, r.y1);
glVertex2f(r.x0, r.y0);
}
glEnd();
}
inline void
draw_rectangle_outline(Render_Target *target, i32_Rect rect, u32 color){
draw_rectangle_outline(target, f32R(rect), color);
}
internal void
draw_margin(Render_Target *target, i32_Rect outer, i32_Rect inner, u32 color){
draw_rectangle(target, i32R(outer.x0, outer.y0, outer.x1, inner.y0), color);
draw_rectangle(target, i32R(outer.x0, inner.y1, outer.x1, outer.y1), color);
draw_rectangle(target, i32R(outer.x0, inner.y0, inner.x0, inner.y1), color);
draw_rectangle(target, i32R(inner.x1, inner.y0, outer.x1, inner.y1), color);
}
// TODO(allen): eliminate this?
internal i32
font_init(){
return 1;
}
inline internal i32
font_predict_size(i32 pt_size){
return pt_size*pt_size*128;
}
internal i32
font_load(System_Functions *system,
Render_Font *font_out, char *filename, i32 pt_size,
void *font_block, i32 font_block_size,
i32 *memory_used_out, i32 tab_width){
i32 result = 1;
File_Data file;
file = system->load_file(filename);
if (!file.data){
result = 0;
}
else{
stbtt_fontinfo font;
if (!stbtt_InitFont(&font, (u8*)file.data, 0)){
result = 0;
}
else{
i32 ascent, descent, line_gap;
real32 scale;
stbtt_GetFontVMetrics(&font, &ascent, &descent, &line_gap);
scale = stbtt_ScaleForPixelHeight(&font, (real32)pt_size);
real32 scaled_ascent, scaled_descent, scaled_line_gap;
scaled_ascent = scale*ascent;
scaled_descent = scale*descent;
scaled_line_gap = scale*line_gap;
font_out->height = (i32)(scaled_ascent - scaled_descent + scaled_line_gap);
font_out->ascent = (i32)(scaled_ascent);
font_out->descent = (i32)(scaled_descent);
font_out->line_skip = (i32)(scaled_line_gap);
u8 *memory_cursor = (u8*)font_block;
Assert(pt_size*pt_size*128 <= font_block_size);
i32 tex_width, tex_height;
tex_width = pt_size*128;
tex_height = pt_size*2;
font_out->tex_width = tex_width;
font_out->tex_height = tex_height;
if (stbtt_BakeFontBitmap((u8*)file.data, 0, (real32)pt_size,
memory_cursor, tex_width, tex_height, 0, 128, font_out->chardata) <= 0){
result = 0;
}
else{
GLuint font_tex;
glGenTextures(1, &font_tex);
glBindTexture(GL_TEXTURE_2D, font_tex);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, tex_width, tex_height, 0, GL_ALPHA, GL_UNSIGNED_BYTE, memory_cursor);
font_out->tex = font_tex;
glBindTexture(GL_TEXTURE_2D, 0);
}
font_out->chardata['\r'] = font_out->chardata[' '];
font_out->chardata['\n'] = font_out->chardata[' '];
font_out->chardata['\t'] = font_out->chardata[' '];
font_out->chardata['\t'].xadvance *= tab_width;
i32 max_advance = 0;
for (u16 code_point = 0; code_point < 128; ++code_point){
if (stbtt_FindGlyphIndex(&font, code_point) != 0){
font_out->glyphs[code_point].exists = 1;
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;
}
}
font_out->advance = max_advance - 1;
}
system->free_file(file);
}
return result;
}
internal void
font_set_tabwidth(Render_Font *font, i32 tab_width){
font->chardata['\t'].xadvance *= font->chardata[' '].xadvance * tab_width;
}
internal void
font_draw_glyph_mono(Render_Target *target, Render_Font *font, u16 character,
real32 x, real32 y, real32 advance, u32 color){
real32 x_shift, y_shift;
i32 left = font->chardata[character].x0;
i32 right = font->chardata[character].x1;
i32 width = (right - left);
x_shift = (real32)(advance - width) * .5f - font->chardata[character].xoff;
y_shift = (real32)font->ascent;
x += x_shift;
y += y_shift;
stbtt_aligned_quad q;
stbtt_GetBakedQuadUnrounded(font->chardata, font->tex_width, font->tex_height, character, &x, &y, &q, 1);
draw_set_color(target, color);
draw_bind_texture(target, font->tex);
glBegin(GL_QUADS);
{
glTexCoord2f(q.s0, q.t1); glVertex2f(q.x0, q.y1);
glTexCoord2f(q.s1, q.t1); glVertex2f(q.x1, q.y1);
glTexCoord2f(q.s1, q.t0); glVertex2f(q.x1, q.y0);
glTexCoord2f(q.s0, q.t0); glVertex2f(q.x0, q.y0);
}
glEnd();
}
inline void
font_draw_glyph_mono(Render_Target *target, Render_Font *font, u16 character,
real32 x, real32 y, u32 color){
font_draw_glyph_mono(target, font, character, x, y, (real32)font->advance, color);
}
internal void
font_draw_glyph(Render_Target *target, Render_Font *font, u16 character,
real32 x, real32 y, u32 color){
real32 x_shift, y_shift;
x_shift = 0;
y_shift = (real32)font->ascent;
x += x_shift;
y += y_shift;
stbtt_aligned_quad q;
stbtt_GetBakedQuadUnrounded(font->chardata, font->tex_width, font->tex_height, character, &x, &y, &q, 1);
draw_set_color(target, color);
draw_bind_texture(target, font->tex);
glBegin(GL_QUADS);
{
glTexCoord2f(q.s0, q.t1); glVertex2f(q.x0, q.y1);
glTexCoord2f(q.s1, q.t1); glVertex2f(q.x1, q.y1);
glTexCoord2f(q.s1, q.t0); glVertex2f(q.x1, q.y0);
glTexCoord2f(q.s0, q.t0); glVertex2f(q.x0, q.y0);
}
glEnd();
}
inline real32
font_get_glyph_width(Render_Font *font, u16 character){
return font->chardata[character].xadvance;
}
internal real32
font_string_width(Render_Font *font, char *str){
real32 x = 0;
for (i32 i = 0; str[i]; ++i){
x += font_get_glyph_width(font, str[i]);
}
return x;
}
internal i32
draw_string(Render_Target *target, Render_Font *font, char *str,
i32 x_, i32 y, u32 color){
real32 x = (real32)x_;
for (i32 i = 0; str[i]; ++i){
char c = str[i];
font_draw_glyph(target, font, c,
x, (real32)y, color);
x += font_get_glyph_width(font, c);
}
return CEIL32(x);
}
internal real32
draw_string_mono(Render_Target *target, Render_Font *font, char *str,
real32 x, real32 y, real32 advance, u32 color){
for (i32 i = 0; str[i]; ++i){
font_draw_glyph_mono(target, font, str[i],
x, y, advance, color);
x += advance;
}
return x;
}
internal i32
draw_string(Render_Target *target, Render_Font *font, String str,
i32 x_, i32 y, u32 color){
real32 x = (real32)x_;
for (i32 i = 0; i < str.size; ++i){
char c = str.str[i];
font_draw_glyph(target, font, c,
x, (real32)y, color);
x += font_get_glyph_width(font, c);
}
return CEIL32(x);
}
internal real32
draw_string_mono(Render_Target *target, Render_Font *font, String str,
real32 x, real32 y, real32 advance, u32 color){
for (i32 i = 0; i < str.size; ++i){
font_draw_glyph_mono(target, font, str.str[i],
x, y, advance, color);
x += advance;
}
return x;
}
internal real32
font_get_max_width(Render_Font *font, char *characters){
stbtt_bakedchar *chardata = font->chardata;
real32 cx, x = 0;
for (i32 i = 0; characters[i]; ++i){
cx = chardata[characters[i]].xadvance;
if (x < cx) x = cx;
}
return x;
}
internal real32
font_get_string_width(Render_Font *font, String string){
real32 result = 0;
for (i32 i = 0; i < string.size; ++i){
font_get_glyph_width(font, string.str[i]);
}
return result;
}
#endif
// BOTTOM

View File

@ -214,9 +214,9 @@ struct Style_File_Format{
struct Style{
char name_[24];
String name;
Render_Font *font;
Style_Main_Data main;
bool32 font_changed;
b32 font_changed;
i16 font_id;
};
struct Style_Library{
@ -224,11 +224,6 @@ struct Style_Library{
i32 count, max;
};
struct Font_Set{
Render_Font *fonts;
i32 count, max;
};
internal void
style_copy(Style *dst, Style *src){
*dst = *src;
@ -243,21 +238,6 @@ style_set_name(Style *style, String name){
copy(&style->name, name);
}
internal Render_Font*
font_set_extract(Font_Set *fonts, char *name, i32 size){
String n = make_string(name, size);
i32 count = fonts->count;
Render_Font *result = 0;
Render_Font *font = fonts->fonts;
for (i32 i = 0; i < count; ++i, ++font){
if (match(n, font->name)){
result = font;
break;
}
}
return result;
}
internal void
style_form_convert(Style_File_Format_v2 *o, Style_File_Format_v1 *i){
o->name_size = i->name_size;
@ -415,7 +395,11 @@ style_format_for_use(Font_Set *fonts, Style *out, Style_File_Format *style){
out->name = make_string(out->name_, 0, ArrayCount(out->name_) - 1);
out->name_[ArrayCount(out->name_) - 1] = 0;
copy(&out->name, style->name);
out->font = font_set_extract(fonts, style->font_name, style->font_name_size);
if (!font_set_extract(fonts,
make_string(style->font_name, style->font_name_size),
&out->font_id)){
out->font_id = 0;
}
i32 spec_count = style->color_specifier_count;
Style_Color_Specifier *spec = (Style_Color_Specifier*)(style + 1);
@ -443,7 +427,11 @@ style_format_for_use(Font_Set *fonts, Style *out, Style_File_Format_v4 *style){
out->name = make_string(out->name_, 0, ArrayCount(out->name_) - 1);
out->name_[ArrayCount(out->name_) - 1] = 0;
copy(&out->name, style->name);
out->font = font_set_extract(fonts, style->font_name, style->font_name_size);
if (!font_set_extract(fonts,
make_string(style->font_name, style->font_name_size),
&out->font_id)){
out->font_id = 0;
}
out->main = style->main;
}
@ -475,11 +463,9 @@ style_format_for_use(Font_Set *fonts, Style *out, Style_File_Format_v3 *style){
}
internal b32
style_library_import(System_Functions *system,
char *filename, Font_Set *fonts, Style *out, i32 max,
style_library_import(Data file, Font_Set *fonts, Style *out, i32 max,
i32 *count_opt, i32 *total_opt = 0){
b32 result = 1;
Data file = system->load_file(filename);
Style_Page_Header *h = 0;
if (!file.data){
@ -540,13 +526,26 @@ style_library_import(System_Functions *system,
default: result = 0; break;
}
early_exit:
system->free_file(file);
early_exit:;
}
return result;
}
#if 0
internal b32
style_library_import(System_Functions *system,
char *filename, Font_Set *fonts, Style *out, i32 max,
i32 *count_opt, i32 *total_opt = 0){
b32 result;
Data file = system->load_file(filename);
result = style_library_import(file, fonts, out, max, count_opt, total_opt);
system->free_file(file);
return result;
}
#endif
internal b32
style_library_add(Style_Library *library, Style *style){
b32 result = 0;
@ -572,12 +571,13 @@ style_library_add(Style_Library *library, Style *style){
}
internal Style_File_Format*
style_format_for_file(Style *style, Style_File_Format *out){
Render_Font *font = style->font;
style_format_for_file(Font_Set *set, Style *style, Style_File_Format *out){
out->name_size = style->name.size;
memcpy(out->name, style->name.str, ArrayCount(out->name));
out->font_name_size = font->name.size;
memcpy(out->font_name, font->name.str, ArrayCount(out->font_name));
String font_name = get_font_info(set, style->font_id)->name;
out->font_name_size = font_name.size;
memcpy(out->font_name, font_name.str, font_name.size);
Style_Color_Specifier *spec = (Style_Color_Specifier*)(out + 1);
i32 count = 0;
@ -597,10 +597,12 @@ style_format_for_file(Style *style, Style_File_Format *out){
}
internal void
style_library_export(System_Functions *system, char *filename, Style **styles, i32 count){
style_library_export(System_Functions *system, Exchange *exchange, Mem_Options *mem,
Font_Set *set, char *filename, Style **styles, i32 count){
i32 size = count*(sizeof(Style_File_Format) + STAG_COUNT*sizeof(Style_Color_Specifier)) +
sizeof(P4C_Page_Header) + sizeof(Style_Page_Header);
void *data = system->get_memory(size);
Temp_Memory temp = begin_temp_memory(&mem->part);
void *data = push_block(&mem->part, size);
void *cursor = data;
{
@ -620,10 +622,17 @@ style_library_export(System_Functions *system, char *filename, Style **styles, i
Style_File_Format *out = (Style_File_Format*)cursor;
Style **in = styles;
for (i32 i = 0; i < count; ++i){
out = style_format_for_file(*in++, out);
out = style_format_for_file(set, *in++, out);
}
int filename_len = str_size(filename);
exchange_save_file(exchange, filename, filename_len,
(byte*)data, size, size);
#if 0
system->save_file(filename, data, size);
system->free_memory(data);
#endif
end_temp_memory(temp);
}
// BOTTOM

View File

@ -9,72 +9,34 @@
// TOP
struct System_Functions;
struct Plat_Handle{
u32 d[4];
};
struct Time_Stamp{
u64 time;
b32 success;
};
#define Sys_Load_File_Sig(name) Data name(char *filename)
typedef Sys_Load_File_Sig(System_Load_File);
#define Sys_Save_File_Sig(name) i32 name(char *filename, void *data, i32 size)
typedef Sys_Save_File_Sig(System_Save_File);
#define Sys_File_Size_Sig(name) i32 name(char *filename)
typedef Sys_File_Size_Sig(System_File_Size);
#define Sys_File_Time_Stamp_Sig(name) Time_Stamp name(char *filename)
typedef Sys_File_Time_Stamp_Sig(System_File_Time_Stamp);
#define Sys_Time_Stamp_Now_Sig(name) u64 name()
typedef Sys_Time_Stamp_Now_Sig(System_Time_Stamp_Now);
#define Sys_Free_File_Sig(name) void name(Data file)
typedef Sys_Free_File_Sig(System_Free_File);
#define Sys_Get_Current_Directory_Sig(name) i32 name(char *out, i32 max)
typedef Sys_Get_Current_Directory_Sig(System_Get_Current_Directory);
#define Sys_Get_Easy_Directory_Sig(name) i32 name(char *destination)
typedef Sys_Get_Easy_Directory_Sig(System_Get_Easy_Directory);
struct File_Info{
String filename;
b32 folder;
};
struct File_List{
File_Info *infos;
void *block;
i32 count;
File_Info *infos;
i32 count, block_size;
};
#define Sys_Get_File_List_Sig(name) File_List name(String directory)
typedef Sys_Get_File_List_Sig(System_Get_File_List);
#define Sys_File_Time_Stamp_Sig(name) u64 name(char *filename)
typedef Sys_File_Time_Stamp_Sig(System_File_Time_Stamp);
#define Sys_Free_File_List_Sig(name) void name(File_List list)
typedef Sys_Free_File_List_Sig(System_Free_File_List);
#define Sys_Get_Memory_Sig(name) void* name(i32 size, i32 line_number, char *filename)
typedef Sys_Get_Memory_Sig(System_Get_Memory);
#define get_memory(size) get_memory_full(size, __LINE__, __FILE__)
#define Sys_Free_Memory_Sig(name) void name(void *block)
typedef Sys_Free_Memory_Sig(System_Free_Memory);
#define Sys_Set_File_List_Sig(name) void name(File_List *file_list, String directory)
typedef Sys_Set_File_List_Sig(System_Set_File_List);
#define Sys_Post_Clipboard_Sig(name) void name(String str)
typedef Sys_Post_Clipboard_Sig(System_Post_Clipboard);
#define Sys_Time_Sig(name) i64 name()
#define Sys_Time_Sig(name) u64 name()
typedef Sys_Time_Sig(System_Time);
// cli
struct CLI_Handles{
Plat_Handle proc;
Plat_Handle out_read;
@ -82,7 +44,7 @@ struct CLI_Handles{
u32 scratch_space[4];
};
#define Sys_CLI_Call_Sig(name) b32 name(char *path, char *script, CLI_Handles *cli)
#define Sys_CLI_Call_Sig(name) b32 name(char *path, char *script_name, CLI_Handles *cli_out)
typedef Sys_CLI_Call_Sig(System_CLI_Call);
#define Sys_CLI_Begin_Update_Sig(name) void name(CLI_Handles *cli)
@ -94,6 +56,7 @@ typedef Sys_CLI_Update_Step_Sig(System_CLI_Update_Step);
#define Sys_CLI_End_Update_Sig(name) b32 name(CLI_Handles *cli)
typedef Sys_CLI_End_Update_Sig(System_CLI_End_Update);
// thread
struct Thread_Context;
enum Lock_ID{
@ -120,8 +83,12 @@ struct Thread_Memory{
i32 id;
};
#define Job_Callback_Sig(name) void name(\
System_Functions *system, Thread_Context *thread, Thread_Memory *memory, void *data[2])
struct Thread_Exchange;
struct System_Functions;
#define Job_Callback_Sig(name) void name( \
System_Functions *system, Thread_Context *thread, Thread_Memory *memory, \
Thread_Exchange *exchange, void *data[2])
typedef Job_Callback_Sig(Job_Callback);
struct Job_Data{
@ -130,21 +97,38 @@ struct Job_Data{
i32 memory_request;
};
#define Sys_Thread_Get_ID_Sig(name) u32 name(Thread_Context *thread)
typedef Sys_Thread_Get_ID_Sig(System_Thread_Get_ID);
struct Full_Job_Data{
Job_Data job;
#define Sys_Thread_Current_Job_ID_Sig(name) u32 name(Thread_Context *thread)
typedef Sys_Thread_Current_Job_ID_Sig(System_Thread_Current_Job_ID);
u32 job_memory_index;
u32 running_thread;
b32 finished;
u32 id;
};
#define Sys_Post_Job_Sig(name) u32 name(Thread_Group_ID id, Job_Data job)
struct Work_Queue{
Full_Job_Data jobs[256];
Plat_Handle semaphore;
volatile u32 write_position;
volatile u32 read_position;
};
#define THREAD_NOT_ASSIGNED 0xFFFFFFFF
#define JOB_ID_WRAP (ArrayCount(queue->jobs) * 4)
#define QUEUE_WRAP (ArrayCount(queue->jobs))
struct Thread_Exchange{
Work_Queue queues[THREAD_GROUP_COUNT];
volatile u32 force_redraw;
};
#define Sys_Post_Job_Sig(name) u32 name(Thread_Group_ID group_id, Job_Data job)
typedef Sys_Post_Job_Sig(System_Post_Job);
#define Sys_Cancel_Job_Sig(name) void name(Thread_Group_ID id, u32 job_id)
#define Sys_Cancel_Job_Sig(name) void name(Thread_Group_ID group_id, u32 job_id)
typedef Sys_Cancel_Job_Sig(System_Cancel_Job);
#define Sys_Job_Is_Pending_Sig(name) b32 name(Thread_Group_ID id, u32 job_id)
typedef Sys_Job_Is_Pending_Sig(System_Job_Is_Pending);
#define Sys_Grow_Thread_Memory_Sig(name) void name(Thread_Memory *memory)
typedef Sys_Grow_Thread_Memory_Sig(System_Grow_Thread_Memory);
@ -154,9 +138,7 @@ typedef Sys_Acquire_Lock_Sig(System_Acquire_Lock);
#define Sys_Release_Lock_Sig(name) void name(i32 id)
typedef Sys_Release_Lock_Sig(System_Release_Lock);
#define Sys_Force_Redraw_Sig(name) void name()
typedef Sys_Force_Redraw_Sig(System_Force_Redraw);
// debug
#define INTERNAL_Sys_Sentinel_Sig(name) Bubble* name()
typedef INTERNAL_Sys_Sentinel_Sig(INTERNAL_System_Sentinel);
@ -167,40 +149,34 @@ typedef INTERNAL_Sys_Get_Thread_States_Sig(INTERNAL_System_Get_Thread_States);
typedef INTERNAL_Sys_Debug_Message_Sig(INTERNAL_System_Debug_Message);
struct System_Functions{
System_Load_File *load_file;
System_Save_File *save_file;
// files: 2
System_File_Time_Stamp *file_time_stamp;
System_Time_Stamp_Now *time_stamp_now;
System_Free_File *free_file;
System_Set_File_List *set_file_list;
System_Get_Current_Directory *get_current_directory;
System_Get_Easy_Directory *get_easy_directory;
System_Get_File_List *get_file_list;
System_Free_File_List *free_file_list;
System_Get_Memory *get_memory_full;
System_Free_Memory *free_memory;
// file system navigation (4coder_custom.h): 2
Directory_Has_File *directory_has_file;
Directory_CD *directory_cd;
// clipboard: 1
System_Post_Clipboard *post_clipboard;
// time: 1
System_Time *time;
// cli: 4
System_CLI_Call *cli_call;
System_CLI_Begin_Update *cli_begin_update;
System_CLI_Update_Step *cli_update_step;
System_CLI_End_Update *cli_end_update;
System_Thread_Get_ID *thread_get_id;
System_Thread_Current_Job_ID *thread_current_job_id;
// threads: 5
System_Post_Job *post_job;
System_Cancel_Job *cancel_job;
System_Job_Is_Pending *job_is_pending;
System_Grow_Thread_Memory *grow_thread_memory;
System_Acquire_Lock *acquire_lock;
System_Release_Lock *release_lock;
System_Force_Redraw *force_redraw;
// debug: 3
INTERNAL_System_Sentinel *internal_sentinel;
INTERNAL_System_Get_Thread_States *internal_get_thread_states;
INTERNAL_System_Debug_Message *internal_debug_message;

360
4ed_ttf.cpp Normal file
View File

@ -0,0 +1,360 @@
/*
* YOUR INFO HERE!
*/
// TOP
typedef unsigned int Fixed16_16;
struct Offset_Table{
Fixed16_16 version;
unsigned short num_tables;
unsigned short search_range;
unsigned short entry_selector;
unsigned short range_shift;
};
struct Table_Directory_Entry{
unsigned long tag;
unsigned long check_sum;
unsigned long offset;
unsigned long length;
};
#include <stdio.h>
#include <stdlib.h>
struct Data{
char *data;
int size;
};
Data
open_file(const char *filename){
Data result = {};
FILE *file;
file = fopen(filename, "rb");
if (file){
fseek(file, 0, SEEK_END);
result.size = ftell(file);
fseek(file, 0, SEEK_SET);
if (result.size > 0){
result.data = (char*)malloc(result.size);
fread(result.data, result.size, 1, file);
}
fclose(file);
}
return(result);
}
void
print(Offset_Table *offset){
printf("version %d\n", offset->version >> 16);
printf("number of tables %d\n", (int)(offset->num_tables));
printf("search range %d\n", (int)(offset->search_range));
printf("entry selector %d\n", (int)(offset->entry_selector));
printf("range shift %d\n", (int)(offset->range_shift));
}
void
print(Table_Directory_Entry *entry){
printf("tag %.4s\n", &entry->tag);
printf("check sum %08x\n", entry->check_sum);
printf("offset %d\n", entry->offset);
printf("length %d\n", entry->length);
}
void
byte_reverse(void *ptr, int len){
char *c;
int i,j;
char t;
c = (char*)ptr;
for (i = 0, j = len-1; i < j; ++i, --j){
t = c[i];
c[i] = c[j];
c[j] = t;
}
}
void
byte_fix(Offset_Table *offset){
byte_reverse(&offset->version, 4);
byte_reverse(&offset->num_tables, 2);
byte_reverse(&offset->search_range, 2);
byte_reverse(&offset->entry_selector, 2);
byte_reverse(&offset->range_shift, 2);
}
void
byte_fix(Table_Directory_Entry *entry){
byte_reverse(&entry->check_sum, 4);
byte_reverse(&entry->offset, 4);
byte_reverse(&entry->length, 4);
}
struct cmap_Header{
unsigned short version;
unsigned short num_subtables;
};
struct cmap_Subtable_Entry{
unsigned short plat_id;
unsigned short plat_encoding_id;
unsigned long offset_from_cmap;
};
void
byte_fix(cmap_Header *header){
byte_reverse(&header->version, 2);
byte_reverse(&header->num_subtables, 2);
}
void
print(cmap_Header *header){
printf("cmap tables:\n");
printf("\tversion %d\n", (int)(header->version));
printf("\tsubtables %d\n", (int)(header->num_subtables));
}
void
byte_fix(cmap_Subtable_Entry *entry){
byte_reverse(&entry->plat_id, 2);
byte_reverse(&entry->plat_encoding_id, 2);
byte_reverse(&entry->offset_from_cmap, 4);
}
struct cmap_Subtable_Format4_Header{
unsigned short format;
unsigned short length;
unsigned short version;
unsigned short segment_count_2;
unsigned short search_range;
unsigned short entry_selector;
unsigned short range_shift;
};
void
print(cmap_Subtable_Entry *entry){
printf("\tplatform id %d\n", (int)(entry->plat_id));
printf("\tencoding id %d\n", (int)(entry->plat_encoding_id));
printf("\toffset from cmap %d\n", (int)(entry->offset_from_cmap));
}
void
byte_fix(cmap_Subtable_Format4_Header *header){
byte_reverse(&header->length, 2);
byte_reverse(&header->version, 2);
byte_reverse(&header->segment_count_2, 2);
byte_reverse(&header->search_range, 2);
byte_reverse(&header->entry_selector, 2);
byte_reverse(&header->range_shift, 2);
}
void
print(cmap_Subtable_Format4_Header *header){
printf("\t\tlength %d\n", header->length);
printf("\t\tversion %d\n", header->version);
printf("\t\tsegment count doubled %d\n", header->segment_count_2);
printf("\t\tsearch range %d\n", header->search_range);
printf("\t\tentry selector %d\n", header->entry_selector);
printf("\t\trange shift %d\n", header->range_shift);
}
struct cmap_Subtable_Format4_Segments{
unsigned short *end_code, *start_code;
unsigned short *id_delta, *id_range_offset;
};
void
byte_fix(cmap_Subtable_Format4_Segments segs, int segment_count){
for (int i = 0; i < segment_count; ++i){
byte_reverse(segs.end_code + i, 2);
}
for (int i = 0; i < segment_count; ++i){
byte_reverse(segs.start_code + i, 2);
}
for (int i = 0; i < segment_count; ++i){
byte_reverse(segs.id_delta + i, 2);
}
for (int i = 0; i < segment_count; ++i){
byte_reverse(segs.id_range_offset + i, 2);
}
}
void
print(cmap_Subtable_Format4_Segments segs, int i){
printf("\t\tsegment %d\n", i);
printf("\t\tend code %d\n", (int)(segs.end_code[i]));
printf("\t\tstart code %d\n", (int)(segs.start_code[i]));
printf("\t\tid delta %d\n", (int)(segs.id_delta[i]));
printf("\t\tid range offset %d\n", (int)(segs.id_range_offset[i]));
}
void
parse_cmap_subtable4(char *start){
char *cursor = start;
cmap_Subtable_Format4_Header *header =
(cmap_Subtable_Format4_Header*)cursor;
cursor = (char*)(header + 1);
byte_fix(header);
print(header);
int segment_count = (header->segment_count_2 >> 1);
cmap_Subtable_Format4_Segments segs;
segs.end_code = (unsigned short*)cursor;
cursor = (char*)(segs.end_code + segment_count);
cursor = cursor + sizeof(unsigned short);
segs.start_code = (unsigned short*)cursor;
cursor = (char*)(segs.start_code + segment_count);
segs.id_delta = (unsigned short*)cursor;
cursor = (char*)(segs.id_delta + segment_count);
segs.id_range_offset = (unsigned short*)cursor;
cursor = (char*)(segs.id_range_offset + segment_count);
byte_fix(segs, segment_count);
for (int i = 0; i < segment_count; ++i){
printf("\n");
print(segs, i);
}
}
void
parse_cmap_subtable(char *start){
char *cursor = start;
short *format = (short*)cursor;
byte_reverse(format, 2);
printf("\t\tformat %d\n", (int)(*format));
switch (*format){
case 4:
parse_cmap_subtable4(start);
break;
}
}
void
parse_cmap(char *start){
char *cursor = start;
cmap_Header *header = (cmap_Header*)cursor;
cursor = (char*)(header + 1);
byte_fix(header);
print(header);
cmap_Subtable_Entry *entry = (cmap_Subtable_Entry*)cursor;
for (int i = 0; i < header->num_subtables; ++i, ++entry){
byte_fix(entry);
printf("\n");
print(entry);
if (entry->plat_id == 3 && entry->plat_encoding_id == 1){
printf("\n\tMicrosoft Unicode table:\n");
parse_cmap_subtable(start + entry->offset_from_cmap);
}
}
}
struct glyf_Glyph_Header{
short num_contours;
short x_min;
short x_max;
short y_min;
short y_max;
};
void
byte_fix(glyf_Glyph_Header *header){
byte_reverse(&header->num_contours, 2);
byte_reverse(&header->x_min, 2);
byte_reverse(&header->x_max, 2);
byte_reverse(&header->y_min, 2);
byte_reverse(&header->y_max, 2);
}
void
print(glyf_Glyph_Header *header){
printf("\tcontours %d\n", (int)(header->num_contours));
printf("\tx min %d\n", (int)(header->x_min));
printf("\tx max %d\n", (int)(header->x_max));
printf("\ty min %d\n", (int)(header->y_min));
printf("\ty max %d\n", (int)(header->y_max));
}
void
parse_glyf(char *start){
char *cursor = start;
glyf_Glyph_Header *header = (glyf_Glyph_Header*)cursor;
cursor = (char*)(header + 1);
byte_fix(header);
print(header);
}
#define TTF_Tag(a,b,c,d) ((a) + ((b) << 8) + ((c) << 16) + ((d) << 24))
#define TTF_Tag_cmap TTF_Tag('c', 'm', 'a', 'p')
#define TTF_Tag_glyf TTF_Tag('g', 'l', 'y', 'f')
#define TTF_Tag_fpgm TTF_Tag('f', 'p', 'g', 'm')
#define TTF_Tag_prep TTF_Tag('p', 'r', 'e', 'p')
#define TTF_Tag_cvt TTF_Tag('c', 'v', 't', ' ')
#define TTF_Tag_maxp TTF_Tag('m', 'a', 'x', 'p')
int
main(){
Data file;
char *filename;
filename = "test.ttf";
file = open_file(filename);
if (file.data == 0){
printf("could not open %s\n", filename);
return (1);
}
char *cursor;
Offset_Table *offset;
cursor = file.data;
offset = (Offset_Table*)cursor;
cursor = (char*)(offset + 1);
Table_Directory_Entry *directory_entries = (Table_Directory_Entry*)cursor;
byte_fix(offset);
print(offset);
int table_number = offset->num_tables;
Table_Directory_Entry *entry = directory_entries;
for (int i = 0; i < table_number; ++i, ++entry){
printf("\n");
byte_fix(entry);
print(entry);
switch (entry->tag){
case TTF_Tag_cmap:
parse_cmap(file.data + entry->offset);
break;
case TTF_Tag_glyf:
parse_glyf(file.data + entry->offset);
break;
}
}
return (0);
}
// BOTTOM

View File

@ -15,65 +15,18 @@ internal void
keycode_init(Key_Codes *codes){
set_dynamic_key_names(codes);
u16 code, loose;
for (u8 i = 0; i < 255; ++i){
if ((i >= '0' && i <= '9') ||
(i >= 'A' && i <= 'Z')){
keycode_lookup_table[i] = i;
loose_keycode_lookup_table[i] = 0;
}
else{
loose = 0;
switch (i){
case VK_SPACE: code = loose = ' '; break;
case VK_BACK: code = loose = codes->back; break;
case VK_OEM_MINUS: code = '-'; break;
case VK_OEM_PLUS: code = '='; break;
case VK_SUBTRACT: code = '-'; break;
case VK_ADD: code = '+'; break;
case VK_MULTIPLY: code = '*'; break;
case VK_DIVIDE: code = '/'; break;
case VK_OEM_3: code = '`'; break;
case VK_OEM_5: code = '\\'; break;
case VK_OEM_4: code = '['; break;
case VK_OEM_6: code = ']'; break;
case VK_TAB: code = loose = '\t'; break;
case VK_RETURN: code = loose = '\n'; break;
case VK_OEM_7: code = '\''; break;
case VK_OEM_1: code = ';'; break;
case VK_OEM_2: code = '/'; break;
case VK_OEM_PERIOD: code = '.'; break;
case VK_OEM_COMMA: code = ','; break;
case VK_DELETE: code = loose = codes->del; break;
case VK_UP: code = loose = codes->up; break;
case VK_DOWN: code = loose = codes->down; break;
case VK_LEFT: code = loose = codes->left; break;
case VK_RIGHT: code = loose = codes->right; break;
case VK_INSERT: code = loose = codes->insert; break;
case VK_HOME: code = loose = codes->home; break;
case VK_END: code = loose = codes->end; break;
case VK_PRIOR: code = loose = codes->page_up; break;
case VK_NEXT: code = loose = codes->page_down; break;
case VK_ESCAPE: code = loose = codes->esc; break;
case VK_NUMPAD0:
case VK_NUMPAD1: case VK_NUMPAD2: case VK_NUMPAD3:
case VK_NUMPAD4: case VK_NUMPAD5: case VK_NUMPAD6:
case VK_NUMPAD7: case VK_NUMPAD8: case VK_NUMPAD9:
code = (i - VK_NUMPAD0) + '0'; break;
default: code = 0; break;
}
keycode_lookup_table[i] = code;
loose_keycode_lookup_table[i] = loose;
}
}
keycode_lookup_table[VK_BACK] = codes->back;
keycode_lookup_table[VK_DELETE] = codes->del;
keycode_lookup_table[VK_UP] = codes->up;
keycode_lookup_table[VK_DOWN] = codes->down;
keycode_lookup_table[VK_LEFT] = codes->left;
keycode_lookup_table[VK_RIGHT] = codes->right;
keycode_lookup_table[VK_INSERT] = codes->insert;
keycode_lookup_table[VK_HOME] = codes->home;
keycode_lookup_table[VK_END] = codes->end;
keycode_lookup_table[VK_PRIOR] = codes->page_up;
keycode_lookup_table[VK_NEXT] = codes->page_down;
keycode_lookup_table[VK_ESCAPE] = codes->esc;
}
// BOTTOM

View File

@ -494,59 +494,8 @@ typedef struct Buffer_Measure_Starts{
} Buffer_Measure_Starts;
#endif
#if 0
internal_4tech int
buffer_measure_starts(Buffer_Measure_Starts *state, Buffer_Type *buffer){
Buffer_Stringify_Type loop;
int *starts;
int max;
char *data;
int size, end;
int start, count, i;
int result;
size = buffer_size(buffer);
starts = buffer->line_starts;
max = buffer->line_max;
result = 1;
i = state->i;
count = state->count;
start = state->start;
for (loop = buffer_stringify_loop(buffer, i, size);
buffer_stringify_good(&loop);
buffer_stringify_next(&loop)){
end = loop.size + loop.absolute_pos;
data = loop.data - loop.absolute_pos;
for (; i < end; ++i){
if (data[i] == '\n'){
if (count == max) goto buffer_measure_starts_end;
starts[count++] = start;
start = i + 1;
}
}
}
assert_4tech(i == size);
if (count == max) goto buffer_measure_starts_end;
starts[count++] = start;
result = 0;
buffer_measure_starts_end:
state->i = i;
state->count = count;
state->start = start;
return(result);
}
#endif
internal_4tech int
buffer_measure_starts_widths(Buffer_Measure_Starts *state, Buffer_Type *buffer, float *advance_data){
buffer_measure_starts_widths_(Buffer_Measure_Starts *state, Buffer_Type *buffer, float *advance_data){
Buffer_Stringify_Type loop;
int *start_ptr, *start_end;
float *width_ptr;
@ -612,6 +561,80 @@ buffer_measure_starts_widths_end:
return(result);
}
internal_4tech int
buffer_measure_starts_zero_widths_(Buffer_Measure_Starts *state, Buffer_Type *buffer){
Buffer_Stringify_Type loop;
int *start_ptr, *start_end;
float *width_ptr;
debug_4tech(int widths_max);
debug_4tech(int max);
char *data;
int size, end;
int start, i;
int result;
char ch;
size = buffer_size(buffer);
debug_4tech(max = buffer->line_max);
debug_4tech(widths_max = buffer->widths_max);
assert_4tech(max == widths_max);
result = 1;
i = state->i;
start = state->start;
start_ptr = buffer->line_starts + state->count;
width_ptr = buffer->line_widths + state->count;
start_end = buffer->line_starts + buffer->line_max;
for (loop = buffer_stringify_loop(buffer, i, size);
buffer_stringify_good(&loop);
buffer_stringify_next(&loop)){
end = loop.size + loop.absolute_pos;
data = loop.data - loop.absolute_pos;
for (; i < end; ++i){
ch = data[i];
if (ch == '\n'){
if (start_ptr == start_end) goto buffer_measure_starts_zero_widths_end;
*width_ptr++ = 0;
*start_ptr++ = start;
start = i + 1;
}
}
}
assert_4tech(i == size);
if (start_ptr == start_end) goto buffer_measure_starts_zero_widths_end;
*start_ptr++ = start;
*width_ptr++ = 0;
result = 0;
buffer_measure_starts_zero_widths_end:
state->i = i;
state->count = (int)(start_ptr - buffer->line_starts);
state->start = start;
return(result);
}
internal_4tech int
buffer_measure_starts_widths(Buffer_Measure_Starts *state, Buffer_Type *buffer, float *advance_data){
int result;
if (advance_data){
result = buffer_measure_starts_widths_(state, buffer, advance_data);
}
else{
result = buffer_measure_starts_zero_widths_(state, buffer);
}
return(result);
}
internal_4tech void
buffer_remeasure_starts(Buffer_Type *buffer, int line_start, int line_end, int line_shift, int text_shift){
Buffer_Stringify_Type loop;
@ -943,27 +966,32 @@ buffer_cursor_seek(Buffer_Type *buffer, Buffer_Seek seek, float max_width,
Seek_State state;
int xy_seek;
size = buffer_size(buffer);
xy_seek = (seek.type == buffer_seek_wrapped_xy || seek.type == buffer_seek_unwrapped_xy);
state.cursor = cursor;
result = 1;
i = cursor.pos;
for (loop = buffer_stringify_loop(buffer, i, size);
buffer_stringify_good(&loop);
buffer_stringify_next(&loop)){
end = loop.size + loop.absolute_pos;
data = loop.data - loop.absolute_pos;
for (; i < end; ++i){
result = cursor_seek_step(&state, seek, xy_seek, max_width,
font_height, advance_data, size, data[i]);
if (!result) goto buffer_cursor_seek_end;
if (advance_data){
size = buffer_size(buffer);
xy_seek = (seek.type == buffer_seek_wrapped_xy || seek.type == buffer_seek_unwrapped_xy);
result = 1;
i = cursor.pos;
for (loop = buffer_stringify_loop(buffer, i, size);
buffer_stringify_good(&loop);
buffer_stringify_next(&loop)){
end = loop.size + loop.absolute_pos;
data = loop.data - loop.absolute_pos;
for (; i < end; ++i){
result = cursor_seek_step(&state, seek, xy_seek, max_width,
font_height, advance_data, size, data[i]);
if (!result) goto buffer_cursor_seek_end;
}
}
}
if (result){
result = cursor_seek_step(&state, seek, xy_seek, max_width,
font_height, advance_data, size, 0);
assert_4tech(result == 0);
if (result){
result = cursor_seek_step(&state, seek, xy_seek, max_width,
font_height, advance_data, size, 0);
assert_4tech(result == 0);
}
}
buffer_cursor_seek_end:
@ -1131,84 +1159,94 @@ buffer_get_render_data(Buffer_Type *buffer, float *wraps, Buffer_Render_Item *it
item_i = 0;
item = items + item_i;
for (loop = buffer_stringify_loop(buffer, start_cursor.pos, size);
buffer_stringify_good(&loop);
buffer_stringify_next(&loop)){
if (advance_data){
for (loop = buffer_stringify_loop(buffer, start_cursor.pos, size);
buffer_stringify_good(&loop);
buffer_stringify_next(&loop)){
end = loop.size + loop.absolute_pos;
data = loop.data - loop.absolute_pos;
end = loop.size + loop.absolute_pos;
data = loop.data - loop.absolute_pos;
for (i = loop.absolute_pos; i < end; ++i){
ch = data[i];
ch_width = measure_character(advance_data, ch);
for (i = loop.absolute_pos; i < end; ++i){
ch = data[i];
ch_width = measure_character(advance_data, ch);
if (ch_width + x > width + shift_x && wrapped){
x = shift_x;
y += font_height;
if (ch_width + x > width + shift_x && wrapped){
x = shift_x;
y += font_height;
}
if (y > height + shift_y) goto buffer_get_render_data_end;
switch (ch){
case '\n':
write_render_item_inline(item, i, ' ', x, y, advance_data, font_height);
++item_i;
++item;
x = shift_x;
y += font_height;
break;
case 0:
ch_width = write_render_item_inline(item, i, '\\', x, y, advance_data, font_height);
++item_i;
++item;
x += ch_width;
ch_width = write_render_item_inline(item, i, '0', x, y, advance_data, font_height);
++item_i;
++item;
x += ch_width;
break;
case '\r':
ch_width = write_render_item_inline(item, i, '\\', x, y, advance_data, font_height);
++item_i;
++item;
x += ch_width;
ch_width = write_render_item_inline(item, i, 'r', x, y, advance_data, font_height);
++item_i;
++item;
x += ch_width;
break;
case '\t':
ch_width_sub = write_render_item_inline(item, i, '\\', x, y, advance_data, font_height);
++item_i;
++item;
write_render_item_inline(item, i, 't', x + ch_width_sub, y, advance_data, font_height);
++item_i;
++item;
x += ch_width;
break;
default:
write_render_item(item, i, ch, x, y, ch_width, font_height);
++item_i;
++item;
x += ch_width;
break;
}
if (y > height + shift_y) goto buffer_get_render_data_end;
}
if (y > height + shift_y) goto buffer_get_render_data_end;
switch (ch){
case '\n':
write_render_item_inline(item, i, ' ', x, y, advance_data, font_height);
++item_i;
++item;
x = shift_x;
y += font_height;
break;
case 0:
ch_width = write_render_item_inline(item, i, '\\', x, y, advance_data, font_height);
++item_i;
++item;
x += ch_width;
ch_width = write_render_item_inline(item, i, '0', x, y, advance_data, font_height);
++item_i;
++item;
x += ch_width;
break;
case '\r':
ch_width = write_render_item_inline(item, i, '\\', x, y, advance_data, font_height);
++item_i;
++item;
x += ch_width;
ch_width = write_render_item_inline(item, i, 'r', x, y, advance_data, font_height);
++item_i;
++item;
x += ch_width;
break;
case '\t':
ch_width_sub = write_render_item_inline(item, i, '\\', x, y, advance_data, font_height);
++item_i;
++item;
write_render_item_inline(item, i, 't', x + ch_width_sub, y, advance_data, font_height);
++item_i;
++item;
x += ch_width;
break;
default:
write_render_item(item, i, ch, x, y, ch_width, font_height);
++item_i;
++item;
x += ch_width;
break;
}
if (y > height + shift_y) goto buffer_get_render_data_end;
}
}
buffer_get_render_data_end:
if (y <= height + shift_y || item == items){
if (y <= height + shift_y || item == items){
ch = 0;
ch_width = measure_character(advance_data, ' ');
write_render_item(item, size, ch, x, y, ch_width, font_height);
++item_i;
++item;
x += ch_width;
}
}
else{
ch = 0;
ch_width = measure_character(advance_data, ' ');
ch_width = 0;
write_render_item(item, size, ch, x, y, ch_width, font_height);
++item_i;
++item;

3
build.bat Normal file
View File

@ -0,0 +1,3 @@
@echo off
call "w:\4ed\code\buildsuper.bat"

17
buildsuper.bat Normal file
View File

@ -0,0 +1,17 @@
@echo off
REM this is here to prevent the spammation of PATH
IF NOT DEFINED clset (call "C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\vcvarsall.bat" x64)
SET clset=64
SET WARNINGS=/W4 /wd4310 /wd4100 /wd4201 /wd4505 /wd4996 /wd4127 /wd4510 /wd4512 /wd4610 /WX
SET STUFF=/GR- /nologo
SET DEBUG=/Zi
SET EXPORTS=/EXPORT:get_bindings /EXPORT:set_extra_font
cl %WARNINGS% %STUFF% %DEBUG% 4coder_custom.cpp /Fe4coder_custom /LD /link /INCREMENTAL:NO /OPT:REF %EXPORTS%
REM more spammation preventation
del *.exp
del *.obj
del *.lib

View File

@ -1,22 +0,0 @@
/*
* YOUR INFO HERE!
*/
// a b c d e f g
#define swap(a,b) {auto t=a; a=b; b=t;}
struct Thing{
int x, y, z;
};
struct Stuff{
Thing x;
int a, b, c;
};
void insert_sort(int *items, int size){
}

View File

@ -1,7 +1,7 @@
/*
* Mr. 4th Dimention - Allen Webster
*
* 1.21.2015
* 21.1.2015
*
* Test for CPP lexer & parser layer for project codename "4ed"
*
@ -11,6 +11,8 @@
#include "../4ed_meta.h"
#define Debug(x) x
#include "../4cpp_types.h"
#define FCPP_STRING_IMPLEMENTATION
#include "../4cpp_string.h"
@ -22,8 +24,6 @@
#include <stdio.h>
#include <assert.h>
#define FCPP_PREPROCESSOR_DBG_LEVEL 1
internal bool
system_is_absoute_path(char *path){
bool is_absolute = 0;
@ -72,7 +72,32 @@ quickie_file(String filename){
return quickie_file(buffer);
}
#define STRICT_MEM_TEST 1
internal void
preproc_init(Cpp_PP_State *state, Cpp_PP_Definitions *definitions){
*state = {};
state->max = (32 << 10);
state->base = (byte*)malloc(state->max);
memset(state->base, 0, state->max);
*definitions = {};
definitions->max = 128 << 10;
definitions->items = (byte*)malloc(definitions->max);
memset(definitions->items, 0, definitions->max);
definitions->table.count = 0;
definitions->table.max = 4 << 10;
definitions->table.entries = (Cpp_PP_Table_Entry*)
malloc(definitions->table.max*sizeof(Cpp_PP_Table_Entry));
memset(definitions->table.entries, 0, definitions->table.max*sizeof(Cpp_PP_Table_Entry));
int str_size = 16 << 10;
int token_size = 16 << 10;
void *str_mem = malloc(str_size);
void *token_mem = malloc(token_size);
cpp_preproc_set_spare_space(definitions,
str_size, str_mem,
token_size, token_mem);
}
int main(int argc, char **argv){
if (argc < 2){
@ -86,166 +111,45 @@ int main(int argc, char **argv){
if (target_file.data == 0){
printf("could not open file %s\n", TEST_FILE);
exit(1);
return 1;
}
Cpp_Token_Stack target_tokens = {};
cpp_lex_file(target_file, &target_tokens);
Cpp_Parse_Context context = {};
Cpp_Parse_Definitions definitions = {};
Cpp_Preproc_State state = {};
Cpp_PP_State state = {};
Cpp_PP_Definitions definitions = {};
context.preserve_chunk_size = (200 << 10);
preproc_init(&state, &definitions);
definitions.table.size = 0;
#if STRICT_MEM_TEST
definitions.table.max_size = 16;
#else
definitions.table.max_size = 100;
#endif
definitions.table.table = (Table_Entry*)malloc(sizeof(Table_Entry)*definitions.table.max_size);
memset(definitions.table.table, 0, sizeof(Table_Entry)*definitions.table.max_size);
cpp_preproc_target(&state, &definitions, target_file, target_tokens);
definitions.count = 0;
#if STRICT_MEM_TEST
definitions.max = 16;
#else
definitions.max = 100;
#endif
definitions.slots = (Cpp_Def_Slot*)malloc(sizeof(Cpp_Def_Slot)*definitions.max);
for (Cpp_PP_Step step = {};
step.finished == 0;){
step = cpp_preproc_step_nonalloc(&state, &definitions);
{
String string_filename = make_lit_string("~ string space");
Cpp_File string_file;
#if STRICT_MEM_TEST
string_file.size = 100;
#else
string_file.size = (128 << 10);
#endif
string_file.data = (char*)malloc(string_file.size);
Cpp_Token_Stack string_tokens;
string_tokens.count = 0;
#if STRICT_MEM_TEST
string_tokens.max_count = 2;
#else
string_tokens.max_count = (128 << 10)/sizeof(Cpp_Token);
#endif
string_tokens.tokens = (Cpp_Token*)malloc(sizeof(Cpp_Token)*string_tokens.max_count);
Cpp_File_Data string_parse_file;
string_parse_file.file = string_file;
string_parse_file.tokens = string_tokens;
string_parse_file.filename = string_filename;
int string_index = cpp_defs_add(&definitions, {}, CPP_DEFTYPE_FILE);
cpp_set_parse_file(&definitions, string_index, string_parse_file);
definitions.string_file_index = string_index;
definitions.string_write_pos = 0;
{
Cpp_Token eof_token = {};
eof_token.type = CPP_TOKEN_EOF;
definitions.eof_token = cpp__preserve_token(&definitions, eof_token);
if (step.error_code){
printf("error: %s\n", cpp_preproc_error_str(step.error_code));
if (cpp_preproc_recommend_termination(step.error_code)){
return 1;
}
}
{
String string_va_args = make_lit_string("__VA_ARGS__");
Cpp_Token va_args_token;
va_args_token.type = CPP_TOKEN_IDENTIFIER;
va_args_token.start = definitions.string_write_pos;
va_args_token.size = string_va_args.size;
cpp__preserve_string(&definitions, string_va_args);
definitions.va_args_token = cpp__preserve_token(&definitions, va_args_token);
if (step.mem_size != 0){
void *memory = malloc(step.mem_size);
memory = cpp_preproc_provide_memory(&state, &definitions,
step.mem_type, step.mem_size, memory);
free(memory);
}
if (step.emit){
Cpp_File file = *cpp_preproc_get_file(&definitions, step.file_index);
Cpp_Token token = *cpp_preproc_get_token(&definitions, step.file_index, step.token_index);
printf("TOKEN: %.*s\n", token.size, file.data + token.start);
}
}
state.tokens.count = 0;
#if STRICT_MEM_TEST
state.tokens.max = 5;
#else
state.tokens.max = 100;
#endif
state.tokens.tokens = (Cpp_Loose_Token*)malloc(sizeof(Cpp_Loose_Token)*state.tokens.max);
state.spare_string_write_pos = 0;
#if STRICT_MEM_TEST
state.spare_string_size = 1;
#else
state.spare_string_size = (10 << 10);
#endif
state.spare_string = (char*)malloc(state.spare_string_size);
String target_filename = make_lit_string(TEST_FILE);
cpp_set_target(&state, &definitions, target_file, target_tokens, target_filename);
while (!state.finished){
Cpp_Preproc_Result result;
result = cpp_preproc_step_nonalloc(&state, &definitions, &context);
if (result.memory_request){
Cpp_Memory_Request request = cpp_get_memory_request(&state, &definitions, result);
void *memory = malloc(request.size);
void *old_memory = cpp_provide_memory(request, memory);
free(old_memory);
}
if (result.file_request){
Cpp_File_Request request = cpp_get_file_request(&state, result);
for (; cpp_has_more_files(&request); cpp_get_next_file(&request)){
if (!cpp_try_reuse_file(&request)){
Cpp_File new_file = quickie_file(request.filename);
if (new_file.data == 0){
printf("could not open file %s\n", request.filename);
exit(1);
}
Cpp_Token_Stack new_tokens = {};
cpp_lex_file(new_file, &new_tokens);
cpp_provide_file(&request, new_file, new_tokens);
}
}
}
if (result.error_code){
String error_message = cpp_get_error(result.error_code);
Cpp_File_Data file = *cpp_get_parse_file(&definitions, result.file_index);
Cpp_Token token = file.tokens.tokens[result.token_index];
bool terminate = cpp_recommend_termination(result.error_code);
if (terminate){
printf("FATAL ");
}
printf("ERROR IN %.*s AT %.*s\n%.*s\n",
file.filename.size, file.filename.str,
token.size, file.file.data + token.start,
error_message.size, error_message.str);
if (terminate){
break;
}
}
if (result.emit){
Cpp_File_Data file = *cpp_get_parse_file(&definitions, result.file_index);
Cpp_Token token = file.tokens.tokens[result.token_index];
if (result.from_macro){
Cpp_File_Data file = *cpp_get_parse_file(&definitions, result.invoking_file_index);
Cpp_Token token = file.tokens.tokens[result.invoking_token_index];
printf("EXPANDING %.*s => ", token.size, file.file.data + token.start);
}
printf("TOKEN %.*s\n", token.size, file.file.data + token.start);
}
}
assert(state.finished == 0 || state.expansion_level == 0);
assert(state.finished == 0 || state.param_info_used == 0);
assert(state.finished == 0 || state.state == 0);
return 0;
}

BIN
vc120.pdb Normal file

Binary file not shown.

File diff suppressed because it is too large Load Diff