diff --git a/4coder_default_framework.h b/4coder_default_framework.h index c840049b..d039ca8e 100644 --- a/4coder_default_framework.h +++ b/4coder_default_framework.h @@ -745,14 +745,7 @@ process_config_file(Application_Links *app){ char str_space[512]; String str = make_fixed_width_string(str_space); if (config_string_var(item, "treat_as_code", 0, &str)){ - if (str.size < sizeof(treat_as_code_exts.extension_space)){ - set_extensions(&treat_as_code_exts, str); - print_message(app, str.str, str.size); - print_message(app, "\n", 1); - } - else{ - print_message(app, literal("STRING TOO LONG!\n")); - } + set_extensions(&treat_as_code_exts, str); } } } diff --git a/4coder_lib/4coder_string.h b/4coder_lib/4coder_string.h index 38a8272c..c126ca17 100644 --- a/4coder_lib/4coder_string.h +++ b/4coder_lib/4coder_string.h @@ -1,5 +1,5 @@ /* -4coder_string.h - Version 1.0.59 +4coder_string.h - Version 1.0.66 no warranty implied; use at your own risk This software is in the public domain. Where that dedication is not @@ -142,8 +142,10 @@ FSTRING_INLINE b32_4tech has_substr_insensitive_s(String s, String see FSTRING_LINK i32_4tech copy_fast_unsafe_cc(char *dest, char *src); FSTRING_LINK i32_4tech copy_fast_unsafe_cs(char *dest, String src); FSTRING_LINK b32_4tech copy_checked_ss(String *dest, String src); +FSTRING_LINK b32_4tech copy_checked_cs(char *dest, i32_4tech dest_cap, String src); FSTRING_LINK b32_4tech copy_partial_sc(String *dest, char *src); FSTRING_LINK b32_4tech copy_partial_ss(String *dest, String src); +FSTRING_LINK b32_4tech copy_partial_cs(char *dest, i32_4tech dest_cap, String src); FSTRING_INLINE i32_4tech copy_cc(char *dest, char *src); FSTRING_INLINE void copy_ss(String *dest, String src); FSTRING_INLINE void copy_sc(String *dest, char *src); @@ -246,8 +248,10 @@ FSTRING_INLINE b32_4tech has_substr_insensitive(String s, String seek) FSTRING_LINK i32_4tech copy_fast_unsafe(char *dest, char *src){return(copy_fast_unsafe_cc(dest,src));} FSTRING_LINK i32_4tech copy_fast_unsafe(char *dest, String src){return(copy_fast_unsafe_cs(dest,src));} FSTRING_LINK b32_4tech copy_checked(String *dest, String src){return(copy_checked_ss(dest,src));} +FSTRING_LINK b32_4tech copy_checked(char *dest, i32_4tech dest_cap, String src){return(copy_checked_cs(dest,dest_cap,src));} FSTRING_LINK b32_4tech copy_partial(String *dest, char *src){return(copy_partial_sc(dest,src));} FSTRING_LINK b32_4tech copy_partial(String *dest, String src){return(copy_partial_ss(dest,src));} +FSTRING_LINK b32_4tech copy_partial(char *dest, i32_4tech dest_cap, String src){return(copy_partial_cs(dest,dest_cap,src));} FSTRING_INLINE i32_4tech copy(char *dest, char *src){return(copy_cc(dest,src));} FSTRING_INLINE void copy(String *dest, String src){return(copy_ss(dest,src));} FSTRING_INLINE void copy(String *dest, char *src){return(copy_sc(dest,src));} @@ -281,7 +285,7 @@ FSTRING_LINK b32_4tech string_set_match(void *str_set, i32_4tech ite // #if !defined(FSTRING_GUARD) -FSTRING_INLINE b32_4tech + FSTRING_INLINE b32_4tech char_is_slash(char c) { return (c == '\\' || c == '/'); @@ -289,7 +293,7 @@ char_is_slash(char c) #endif #if !defined(FSTRING_GUARD) -FSTRING_INLINE b32_4tech + FSTRING_INLINE b32_4tech char_is_upper(char c) { return (c >= 'A' && c <= 'Z'); @@ -297,7 +301,7 @@ char_is_upper(char c) #endif #if !defined(FSTRING_GUARD) -FSTRING_INLINE b32_4tech + FSTRING_INLINE b32_4tech char_is_lower(char c) { return (c >= 'a' && c <= 'z'); @@ -305,7 +309,7 @@ char_is_lower(char c) #endif #if !defined(FSTRING_GUARD) -FSTRING_INLINE char + FSTRING_INLINE char char_to_upper(char c) { return (c >= 'a' && c <= 'z') ? c + (char)('A' - 'a') : c; @@ -313,7 +317,7 @@ char_to_upper(char c) #endif #if !defined(FSTRING_GUARD) -FSTRING_INLINE char + FSTRING_INLINE char char_to_lower(char c) { return (c >= 'A' && c <= 'Z') ? c - (char)('A' - 'a') : c; @@ -321,7 +325,7 @@ char_to_lower(char c) #endif #if !defined(FSTRING_GUARD) -FSTRING_INLINE b32_4tech + FSTRING_INLINE b32_4tech char_is_whitespace(char c) { return (c == ' ' || c == '\n' || c == '\r' || c == '\t'); @@ -329,7 +333,7 @@ char_is_whitespace(char c) #endif #if !defined(FSTRING_GUARD) -FSTRING_INLINE b32_4tech + FSTRING_INLINE b32_4tech char_is_alpha_numeric(char c) { return (c >= 'a' && c <= 'z' || c >= 'A' && c <= 'Z' || c >= '0' && c <= '9' || c == '_'); @@ -337,7 +341,7 @@ char_is_alpha_numeric(char c) #endif #if !defined(FSTRING_GUARD) -FSTRING_INLINE b32_4tech + FSTRING_INLINE b32_4tech char_is_alpha_numeric_true(char c) { return (c >= 'a' && c <= 'z' || c >= 'A' && c <= 'Z' || c >= '0' && c <= '9'); @@ -345,7 +349,7 @@ char_is_alpha_numeric_true(char c) #endif #if !defined(FSTRING_GUARD) -FSTRING_INLINE b32_4tech + FSTRING_INLINE b32_4tech char_is_alpha(char c) { return (c >= 'a' && c <= 'z' || c >= 'A' && c <= 'Z' || c == '_'); @@ -353,7 +357,7 @@ char_is_alpha(char c) #endif #if !defined(FSTRING_GUARD) -FSTRING_INLINE b32_4tech + FSTRING_INLINE b32_4tech char_is_alpha_true(char c) { return (c >= 'a' && c <= 'z' || c >= 'A' && c <= 'Z'); @@ -361,7 +365,7 @@ char_is_alpha_true(char c) #endif #if !defined(FSTRING_GUARD) -FSTRING_INLINE b32_4tech + FSTRING_INLINE b32_4tech char_is_hex(char c) { return (c >= '0' && c <= '9' || c >= 'A' && c <= 'F' || c >= 'a' && c <= 'f'); @@ -369,7 +373,7 @@ char_is_hex(char c) #endif #if !defined(FSTRING_GUARD) -FSTRING_INLINE b32_4tech + FSTRING_INLINE b32_4tech char_is_numeric(char c) { return (c >= '0' && c <= '9'); @@ -383,7 +387,7 @@ char_is_numeric(char c) #if !defined(FSTRING_GUARD) -FSTRING_INLINE String + FSTRING_INLINE String make_string_cap(void *str, i32_4tech size, i32_4tech mem_size){ String result; result.str = (char*)str; @@ -394,7 +398,7 @@ make_string_cap(void *str, i32_4tech size, i32_4tech mem_size){ #endif #if !defined(FSTRING_GUARD) -FSTRING_INLINE String + FSTRING_INLINE String make_string(void *str, i32_4tech size){ String result; result.str = (char*)str; @@ -405,7 +409,7 @@ make_string(void *str, i32_4tech size){ #endif #if defined(FSTRING_IMPLEMENTATION) -FSTRING_LINK i32_4tech + FSTRING_LINK i32_4tech str_size(char *str) { i32_4tech i = 0; @@ -415,7 +419,7 @@ str_size(char *str) #endif #if !defined(FSTRING_GUARD) -FSTRING_INLINE String + FSTRING_INLINE String make_string_slowly(void *str) { String result; @@ -428,7 +432,7 @@ make_string_slowly(void *str) #if !defined(FSTRING_GUARD) -FSTRING_INLINE String + FSTRING_INLINE String substr_tail(String str, i32_4tech start) { String result; @@ -440,7 +444,7 @@ substr_tail(String str, i32_4tech start) #endif #if !defined(FSTRING_GUARD) -FSTRING_INLINE String + FSTRING_INLINE String substr(String str, i32_4tech start, i32_4tech size) { String result; @@ -455,7 +459,7 @@ substr(String str, i32_4tech start, i32_4tech size) #endif #if defined(FSTRING_IMPLEMENTATION) -FSTRING_LINK String + FSTRING_LINK String skip_whitespace(String str) { String result = {0}; @@ -468,7 +472,7 @@ skip_whitespace(String str) #if defined(FSTRING_IMPLEMENTATION) -FSTRING_LINK String + FSTRING_LINK String skip_whitespace_measure(String str, i32_4tech *skip_length) { String result = {0}; @@ -481,7 +485,7 @@ skip_whitespace_measure(String str, i32_4tech *skip_length) #endif #if defined(FSTRING_IMPLEMENTATION) -FSTRING_LINK String + FSTRING_LINK String chop_whitespace(String str) { String result = {0}; @@ -493,7 +497,7 @@ chop_whitespace(String str) #endif #if defined(FSTRING_IMPLEMENTATION) -FSTRING_LINK String + FSTRING_LINK String skip_chop_whitespace(String str) { str = skip_whitespace(str); @@ -504,7 +508,7 @@ skip_chop_whitespace(String str) #if defined(FSTRING_IMPLEMENTATION) -FSTRING_LINK String + FSTRING_LINK String skip_chop_whitespace_measure(String str, i32_4tech *skip_length) { str = skip_whitespace_measure(str, skip_length); @@ -514,7 +518,7 @@ skip_chop_whitespace_measure(String str, i32_4tech *skip_length) #endif #if !defined(FSTRING_GUARD) -FSTRING_INLINE String + FSTRING_INLINE String tailstr(String str) { String result; @@ -532,7 +536,7 @@ tailstr(String str) #if defined(FSTRING_IMPLEMENTATION) -FSTRING_LINK b32_4tech + FSTRING_LINK b32_4tech match_cc(char *a, char *b){ for (i32_4tech i = 0;; ++i){ if (a[i] != b[i]){ @@ -547,7 +551,7 @@ match_cc(char *a, char *b){ #if defined(FSTRING_IMPLEMENTATION) -FSTRING_LINK b32_4tech + FSTRING_LINK b32_4tech match_sc(String a, char *b){ i32_4tech i = 0; for (; i < a.size; ++i){ @@ -564,7 +568,7 @@ match_sc(String a, char *b){ #if !defined(FSTRING_GUARD) -FSTRING_INLINE b32_4tech + FSTRING_INLINE b32_4tech match_cs(char *a, String b){ return(match_sc(b,a)); } @@ -572,7 +576,7 @@ match_cs(char *a, String b){ #if defined(FSTRING_IMPLEMENTATION) -FSTRING_LINK b32_4tech + FSTRING_LINK b32_4tech match_ss(String a, String b){ if (a.size != b.size){ return 0; @@ -588,7 +592,7 @@ match_ss(String a, String b){ #if defined(FSTRING_IMPLEMENTATION) -FSTRING_LINK b32_4tech + FSTRING_LINK b32_4tech match_part_ccl(char *a, char *b, i32_4tech *len){ i32_4tech i; for (i = 0; b[i] != 0; ++i){ @@ -603,7 +607,7 @@ match_part_ccl(char *a, char *b, i32_4tech *len){ #if defined(FSTRING_IMPLEMENTATION) -FSTRING_LINK b32_4tech + FSTRING_LINK b32_4tech match_part_scl(String a, char *b, i32_4tech *len){ i32_4tech i; for (i = 0; b[i] != 0; ++i){ @@ -618,7 +622,7 @@ match_part_scl(String a, char *b, i32_4tech *len){ #if !defined(FSTRING_GUARD) -FSTRING_INLINE b32_4tech + FSTRING_INLINE b32_4tech match_part_cc(char *a, char *b){ i32_4tech x; return match_part_ccl(a,b,&x); @@ -627,7 +631,7 @@ match_part_cc(char *a, char *b){ #if !defined(FSTRING_GUARD) -FSTRING_INLINE b32_4tech + FSTRING_INLINE b32_4tech match_part_sc(String a, char *b){ i32_4tech x; return match_part_scl(a,b,&x); @@ -636,7 +640,7 @@ match_part_sc(String a, char *b){ #if defined(FSTRING_IMPLEMENTATION) -FSTRING_LINK b32_4tech + FSTRING_LINK b32_4tech match_part_cs(char *a, String b){ for (i32_4tech i = 0; i != b.size; ++i){ if (a[i] != b.str[i]){ @@ -649,7 +653,7 @@ match_part_cs(char *a, String b){ #if defined(FSTRING_IMPLEMENTATION) -FSTRING_LINK b32_4tech + FSTRING_LINK b32_4tech match_part_ss(String a, String b){ if (a.size < b.size){ return 0; @@ -665,7 +669,7 @@ match_part_ss(String a, String b){ #if defined(FSTRING_IMPLEMENTATION) -FSTRING_LINK b32_4tech + FSTRING_LINK b32_4tech match_insensitive_cc(char *a, char *b){ for (i32_4tech i = 0;; ++i){ if (char_to_upper(a[i]) != @@ -681,7 +685,7 @@ match_insensitive_cc(char *a, char *b){ #if defined(FSTRING_IMPLEMENTATION) -FSTRING_LINK b32_4tech + FSTRING_LINK b32_4tech match_insensitive_sc(String a, char *b){ i32_4tech i = 0; for (; i < a.size; ++i){ @@ -699,7 +703,7 @@ match_insensitive_sc(String a, char *b){ #if !defined(FSTRING_GUARD) -FSTRING_INLINE b32_4tech + FSTRING_INLINE b32_4tech match_insensitive_cs(char *a, String b){ return match_insensitive_sc(b,a); } @@ -707,7 +711,7 @@ match_insensitive_cs(char *a, String b){ #if defined(FSTRING_IMPLEMENTATION) -FSTRING_LINK b32_4tech + FSTRING_LINK b32_4tech match_insensitive_ss(String a, String b){ if (a.size != b.size){ return 0; @@ -724,7 +728,7 @@ match_insensitive_ss(String a, String b){ #if defined(FSTRING_IMPLEMENTATION) -FSTRING_LINK b32_4tech + FSTRING_LINK b32_4tech match_part_insensitive_ccl(char *a, char *b, i32_4tech *len){ i32_4tech i; for (i = 0; b[i] != 0; ++i){ @@ -739,7 +743,7 @@ match_part_insensitive_ccl(char *a, char *b, i32_4tech *len){ #if defined(FSTRING_IMPLEMENTATION) -FSTRING_LINK b32_4tech + FSTRING_LINK b32_4tech match_part_insensitive_scl(String a, char *b, i32_4tech *len){ i32_4tech i; for (i = 0; b[i] != 0; ++i){ @@ -755,7 +759,7 @@ match_part_insensitive_scl(String a, char *b, i32_4tech *len){ #if !defined(FSTRING_GUARD) -FSTRING_INLINE b32_4tech + FSTRING_INLINE b32_4tech match_part_insensitive_cc(char *a, char *b){ i32_4tech x; return match_part_insensitive_ccl(a,b,&x); @@ -764,7 +768,7 @@ match_part_insensitive_cc(char *a, char *b){ #if !defined(FSTRING_GUARD) -FSTRING_INLINE b32_4tech + FSTRING_INLINE b32_4tech match_part_insensitive_sc(String a, char *b){ i32_4tech x; return match_part_insensitive_scl(a,b,&x); @@ -773,7 +777,7 @@ match_part_insensitive_sc(String a, char *b){ #if defined(FSTRING_IMPLEMENTATION) -FSTRING_LINK b32_4tech + FSTRING_LINK b32_4tech match_part_insensitive_cs(char *a, String b){ for (i32_4tech i = 0; i != b.size; ++i){ if (char_to_upper(a[i]) != char_to_upper(b.str[i])){ @@ -786,7 +790,7 @@ match_part_insensitive_cs(char *a, String b){ #if defined(FSTRING_IMPLEMENTATION) -FSTRING_LINK b32_4tech + FSTRING_LINK b32_4tech match_part_insensitive_ss(String a, String b){ if (a.size < b.size){ return(0); @@ -802,7 +806,7 @@ match_part_insensitive_ss(String a, String b){ #if defined(FSTRING_IMPLEMENTATION) -FSTRING_LINK i32_4tech + FSTRING_LINK i32_4tech compare_cc(char *a, char *b){ i32_4tech i = 0, r = 0; while (a[i] == b[i] && a[i] != 0){ @@ -815,7 +819,7 @@ compare_cc(char *a, char *b){ #if defined(FSTRING_IMPLEMENTATION) -FSTRING_LINK i32_4tech + FSTRING_LINK i32_4tech compare_sc(String a, char *b){ i32_4tech i = 0, r = 0; while (i < a.size && a.str[i] == b[i]){ @@ -838,7 +842,7 @@ compare_sc(String a, char *b){ #if !defined(FSTRING_GUARD) -FSTRING_INLINE i32_4tech + FSTRING_INLINE i32_4tech compare_cs(char *a, String b){ i32_4tech r = -compare_sc(b,a); return(r); @@ -847,7 +851,7 @@ compare_cs(char *a, String b){ #if defined(FSTRING_IMPLEMENTATION) -FSTRING_LINK i32_4tech + FSTRING_LINK i32_4tech compare_ss(String a, String b){ i32_4tech i = 0, r = 0; i32_4tech m = a.size; @@ -875,7 +879,7 @@ compare_ss(String a, String b){ #if defined(FSTRING_IMPLEMENTATION) -FSTRING_LINK i32_4tech + FSTRING_LINK i32_4tech find_c_char(char *str, i32_4tech start, char character){ i32_4tech i = start; while (str[i] != character && str[i] != 0) ++i; @@ -885,7 +889,7 @@ find_c_char(char *str, i32_4tech start, char character){ #if defined(FSTRING_IMPLEMENTATION) -FSTRING_LINK i32_4tech + FSTRING_LINK i32_4tech find_s_char(String str, i32_4tech start, char character){ i32_4tech i = start; while (i < str.size && str.str[i] != character) ++i; @@ -895,7 +899,7 @@ find_s_char(String str, i32_4tech start, char character){ #if defined(FSTRING_IMPLEMENTATION) -FSTRING_LINK i32_4tech + FSTRING_LINK i32_4tech rfind_s_char(String str, i32_4tech start, char character){ i32_4tech i = start; while (i >= 0 && str.str[i] != character) --i; @@ -905,7 +909,7 @@ rfind_s_char(String str, i32_4tech start, char character){ #if defined(FSTRING_IMPLEMENTATION) -FSTRING_LINK i32_4tech + FSTRING_LINK i32_4tech find_c_chars(char *str, i32_4tech start, char *characters){ i32_4tech i = start, j; while (str[i] != 0){ @@ -922,7 +926,7 @@ find_c_chars(char *str, i32_4tech start, char *characters){ #if defined(FSTRING_IMPLEMENTATION) -FSTRING_LINK i32_4tech + FSTRING_LINK i32_4tech find_s_chars(String str, i32_4tech start, char *characters){ i32_4tech i = start, j; while (i < str.size){ @@ -939,7 +943,7 @@ find_s_chars(String str, i32_4tech start, char *characters){ #if defined(FSTRING_IMPLEMENTATION) -FSTRING_LINK i32_4tech + FSTRING_LINK i32_4tech find_substr_c(char *str, i32_4tech start, String seek){ i32_4tech i, j, k; b32_4tech hit; @@ -968,7 +972,7 @@ find_substr_c(char *str, i32_4tech start, String seek){ #if defined(FSTRING_IMPLEMENTATION) -FSTRING_LINK i32_4tech + FSTRING_LINK i32_4tech find_substr_s(String str, i32_4tech start, String seek){ i32_4tech stop_at, i, j, k; b32_4tech hit; @@ -997,7 +1001,7 @@ find_substr_s(String str, i32_4tech start, String seek){ #if defined(FSTRING_IMPLEMENTATION) -FSTRING_LINK i32_4tech + FSTRING_LINK i32_4tech rfind_substr_s(String str, i32_4tech start, String seek){ i32_4tech i, j, k; b32_4tech hit; @@ -1028,17 +1032,20 @@ rfind_substr_s(String str, i32_4tech start, String seek){ #if defined(FSTRING_IMPLEMENTATION) -FSTRING_LINK i32_4tech + FSTRING_LINK i32_4tech find_substr_insensitive_c(char *str, i32_4tech start, String seek){ i32_4tech i, j, k; b32_4tech hit; char a_upper, b_upper; + char first_test_char; if (seek.size == 0){ return str_size(str); } + first_test_char = char_to_upper(seek.str[0]); for (i = start; str[i]; ++i){ - if (str[i] == seek.str[0]){ + a_upper = char_to_upper(str[i]); + if (a_upper == first_test_char){ hit = 1; for (j = 1, k = i+1; j < seek.size; ++j, ++k){ a_upper = char_to_upper(str[k]); @@ -1059,19 +1066,22 @@ find_substr_insensitive_c(char *str, i32_4tech start, String seek){ #if defined(FSTRING_IMPLEMENTATION) -FSTRING_LINK i32_4tech + FSTRING_LINK i32_4tech find_substr_insensitive_s(String str, i32_4tech start, String seek){ i32_4tech i, j, k; i32_4tech stop_at; b32_4tech hit; char a_upper, b_upper; + char first_test_char; if (seek.size == 0){ return str.size; } stop_at = str.size - seek.size + 1; + first_test_char = char_to_upper(seek.str[0]); for (i = start; i < stop_at; ++i){ - if (str.str[i] == seek.str[0]){ + a_upper = char_to_upper(str.str[i]); + if (a_upper == first_test_char){ hit = 1; for (j = 1, k = i+1; j < seek.size; ++j, ++k){ a_upper = char_to_upper(str.str[k]); @@ -1092,7 +1102,7 @@ find_substr_insensitive_s(String str, i32_4tech start, String seek){ #if !defined(FSTRING_GUARD) -FSTRING_INLINE b32_4tech + FSTRING_INLINE b32_4tech has_substr_c(char *s, String seek){ return (s[find_substr_c(s, 0, seek)] != 0); } @@ -1100,7 +1110,7 @@ has_substr_c(char *s, String seek){ #if !defined(FSTRING_GUARD) -FSTRING_INLINE b32_4tech + FSTRING_INLINE b32_4tech has_substr_s(String s, String seek){ return (find_substr_s(s, 0, seek) < s.size); } @@ -1108,7 +1118,7 @@ has_substr_s(String s, String seek){ #if !defined(FSTRING_GUARD) -FSTRING_INLINE b32_4tech + FSTRING_INLINE b32_4tech has_substr_insensitive_c(char *s, String seek){ return (s[find_substr_insensitive_c(s, 0, seek)] != 0); } @@ -1116,7 +1126,7 @@ has_substr_insensitive_c(char *s, String seek){ #if !defined(FSTRING_GUARD) -FSTRING_INLINE b32_4tech + FSTRING_INLINE b32_4tech has_substr_insensitive_s(String s, String seek){ return (find_substr_insensitive_s(s, 0, seek) < s.size); } @@ -1128,7 +1138,7 @@ has_substr_insensitive_s(String s, String seek){ #if defined(FSTRING_IMPLEMENTATION) -FSTRING_LINK i32_4tech + FSTRING_LINK i32_4tech copy_fast_unsafe_cc(char *dest, char *src){ char *start = dest; while (*src != 0){ @@ -1142,7 +1152,7 @@ copy_fast_unsafe_cc(char *dest, char *src){ #if defined(FSTRING_IMPLEMENTATION) -FSTRING_LINK i32_4tech + FSTRING_LINK i32_4tech copy_fast_unsafe_cs(char *dest, String src){ i32_4tech i = 0; while (i != src.size){ @@ -1155,7 +1165,7 @@ copy_fast_unsafe_cs(char *dest, String src){ #if defined(FSTRING_IMPLEMENTATION) -FSTRING_LINK b32_4tech + FSTRING_LINK b32_4tech copy_checked_ss(String *dest, String src){ char *dest_str; i32_4tech i; @@ -1173,7 +1183,22 @@ copy_checked_ss(String *dest, String src){ #if defined(FSTRING_IMPLEMENTATION) -FSTRING_LINK b32_4tech + FSTRING_LINK b32_4tech +copy_checked_cs(char *dest, i32_4tech dest_cap, String src){ + i32_4tech i; + if (dest_cap < src.size){ + return 0; + } + for (i = 0; i < src.size; ++i){ + dest[i] = src.str[i]; + } + return 1; +} +#endif + + +#if defined(FSTRING_IMPLEMENTATION) + FSTRING_LINK b32_4tech copy_partial_sc(String *dest, char *src){ i32_4tech i = 0; i32_4tech memory_size = dest->memory_size; @@ -1192,7 +1217,7 @@ copy_partial_sc(String *dest, char *src){ #if defined(FSTRING_IMPLEMENTATION) -FSTRING_LINK b32_4tech + FSTRING_LINK b32_4tech copy_partial_ss(String *dest, String src){ char *dest_str = dest->str; i32_4tech memory_size = dest->memory_size; @@ -1205,13 +1230,31 @@ copy_partial_ss(String *dest, String src){ dest_str[i] = src.str[i]; } dest->size = memory_size; - return result; + return(result); +} +#endif + + +#if defined(FSTRING_IMPLEMENTATION) + FSTRING_LINK b32_4tech +copy_partial_cs(char *dest, i32_4tech dest_cap, String src){ + b32_4tech result = 0; + i32_4tech copy_size = dest_cap; + i32_4tech i; + if (dest_cap >= src.size){ + result = 1; + copy_size = src.size; + } + for (i = 0; i < copy_size; ++i){ + dest[i] = src.str[i]; + } + return(result); } #endif #if !defined(FSTRING_GUARD) -FSTRING_INLINE i32_4tech + FSTRING_INLINE i32_4tech copy_cc(char *dest, char *src){ return copy_fast_unsafe_cc(dest, src); } @@ -1219,7 +1262,7 @@ copy_cc(char *dest, char *src){ #if !defined(FSTRING_GUARD) -FSTRING_INLINE void + FSTRING_INLINE void copy_ss(String *dest, String src){ copy_checked_ss(dest, src); } @@ -1227,7 +1270,7 @@ copy_ss(String *dest, String src){ #if !defined(FSTRING_GUARD) -FSTRING_INLINE void + FSTRING_INLINE void copy_sc(String *dest, char *src){ copy_partial_sc(dest, src); } @@ -1235,7 +1278,7 @@ copy_sc(String *dest, char *src){ #if defined(FSTRING_IMPLEMENTATION) -FSTRING_LINK b32_4tech + FSTRING_LINK b32_4tech append_checked_ss(String *dest, String src){ String end; end = tailstr(*dest); @@ -1249,7 +1292,7 @@ append_checked_ss(String *dest, String src){ #if defined(FSTRING_IMPLEMENTATION) -FSTRING_LINK b32_4tech + FSTRING_LINK b32_4tech append_partial_sc(String *dest, char *src){ String end = tailstr(*dest); b32_4tech result = copy_partial_sc(&end, src); @@ -1260,7 +1303,7 @@ append_partial_sc(String *dest, char *src){ #if defined(FSTRING_IMPLEMENTATION) -FSTRING_LINK b32_4tech + FSTRING_LINK b32_4tech append_partial_ss(String *dest, String src){ String end = tailstr(*dest); b32_4tech result = copy_partial_ss(&end, src); @@ -1271,7 +1314,7 @@ append_partial_ss(String *dest, String src){ #if defined(FSTRING_IMPLEMENTATION) -FSTRING_LINK b32_4tech + FSTRING_LINK b32_4tech append_s_char(String *dest, char c){ b32_4tech result = 0; if (dest->size < dest->memory_size){ @@ -1284,7 +1327,7 @@ append_s_char(String *dest, char c){ #if !defined(FSTRING_GUARD) -FSTRING_INLINE b32_4tech + FSTRING_INLINE b32_4tech append_ss(String *dest, String src){ return append_partial_ss(dest, src); } @@ -1292,14 +1335,14 @@ append_ss(String *dest, String src){ #if !defined(FSTRING_GUARD) -FSTRING_INLINE b32_4tech + FSTRING_INLINE b32_4tech append_sc(String *dest, char *src){ return append_partial_sc(dest, src); } #endif #if defined(FSTRING_IMPLEMENTATION) -FSTRING_LINK b32_4tech + FSTRING_LINK b32_4tech terminate_with_null(String *str){ b32_4tech result = 0; if (str->size < str->memory_size){ @@ -1311,7 +1354,7 @@ terminate_with_null(String *str){ #endif #if defined(FSTRING_IMPLEMENTATION) -FSTRING_LINK b32_4tech + FSTRING_LINK b32_4tech append_padding(String *dest, char c, i32_4tech target_size){ b32_4tech result = 1; i32_4tech offset = target_size - dest->size; @@ -1334,7 +1377,7 @@ append_padding(String *dest, char c, i32_4tech target_size){ // #if defined(FSTRING_IMPLEMENTATION) -FSTRING_LINK void + FSTRING_LINK void replace_char(String *str, char replace, char with){ char *s = str->str; i32_4tech i = 0; @@ -1346,7 +1389,7 @@ replace_char(String *str, char replace, char with){ #if defined(FSTRING_IMPLEMENTATION) -FSTRING_LINK void + FSTRING_LINK void to_lower_cc(char *src, char *dst){ for (; *src != 0; ++src){ *dst++ = char_to_lower(*src); @@ -1357,7 +1400,7 @@ to_lower_cc(char *src, char *dst){ #if defined(FSTRING_IMPLEMENTATION) -FSTRING_LINK void + FSTRING_LINK void to_lower_ss(String *dst, String src){ i32_4tech i = 0; i32_4tech size = src.size; @@ -1375,7 +1418,7 @@ to_lower_ss(String *dst, String src){ #if defined(FSTRING_IMPLEMENTATION) -FSTRING_LINK void + FSTRING_LINK void to_lower_s(String *str){ i32_4tech i = 0; i32_4tech size = str->size; @@ -1388,7 +1431,7 @@ to_lower_s(String *str){ #if defined(FSTRING_IMPLEMENTATION) -FSTRING_LINK void + FSTRING_LINK void to_upper_cc(char *src, char *dst){ for (; *src != 0; ++src){ *dst++ = char_to_upper(*src); @@ -1399,7 +1442,7 @@ to_upper_cc(char *src, char *dst){ #if defined(FSTRING_IMPLEMENTATION) -FSTRING_LINK void + FSTRING_LINK void to_upper_ss(String *dst, String src){ i32_4tech i = 0; i32_4tech size = src.size; @@ -1417,7 +1460,7 @@ to_upper_ss(String *dst, String src){ #if defined(FSTRING_IMPLEMENTATION) -FSTRING_LINK void + FSTRING_LINK void to_upper_s(String *str){ i32_4tech i = 0; i32_4tech size = str->size; @@ -1430,7 +1473,7 @@ to_upper_s(String *str){ #if defined(FSTRING_IMPLEMENTATION) -FSTRING_LINK void + FSTRING_LINK void to_camel_cc(char *src, char *dst){ char *c, ch; i32_4tech is_first = 1; @@ -1460,7 +1503,7 @@ to_camel_cc(char *src, char *dst){ // #if defined(FSTRING_IMPLEMENTATION) -FSTRING_LINK i32_4tech + FSTRING_LINK i32_4tech int_to_str_size(i32_4tech x){ i32_4tech size = 1; if (x < 0){ @@ -1476,7 +1519,7 @@ int_to_str_size(i32_4tech x){ #endif #if defined(FSTRING_IMPLEMENTATION) -FSTRING_LINK b32_4tech + FSTRING_LINK b32_4tech int_to_str(String *dest, i32_4tech x){ b32_4tech result = 1; char *str = dest->str; @@ -1523,7 +1566,7 @@ int_to_str(String *dest, i32_4tech x){ #endif #if defined(FSTRING_IMPLEMENTATION) -FSTRING_LINK b32_4tech + FSTRING_LINK b32_4tech append_int_to_str(String *dest, i32_4tech x){ String last_part = tailstr(*dest); b32_4tech result = int_to_str(&last_part, x); @@ -1535,7 +1578,7 @@ append_int_to_str(String *dest, i32_4tech x){ #endif #if defined(FSTRING_IMPLEMENTATION) -FSTRING_LINK i32_4tech + FSTRING_LINK i32_4tech u64_to_str_size(uint64_t x){ i32_4tech size; if (x < 0){ @@ -1554,7 +1597,7 @@ u64_to_str_size(uint64_t x){ #endif #if defined(FSTRING_IMPLEMENTATION) -FSTRING_LINK b32_4tech + FSTRING_LINK b32_4tech u64_to_str(String *dest, uint64_t x){ b32_4tech result = 1; char *str = dest->str; @@ -1593,7 +1636,7 @@ u64_to_str(String *dest, uint64_t x){ #endif #if defined(FSTRING_IMPLEMENTATION) -FSTRING_LINK b32_4tech + FSTRING_LINK b32_4tech append_u64_to_str(String *dest, uint64_t x){ String last_part = tailstr(*dest); b32_4tech result = u64_to_str(&last_part, x); @@ -1628,7 +1671,7 @@ get_float_vars(float x){ #endif #if defined(FSTRING_IMPLEMENTATION) -FSTRING_LINK i32_4tech + FSTRING_LINK i32_4tech float_to_str_size(float x){ Float_To_Str_Variables vars = get_float_vars(x); i32_4tech size = vars.negative + int_to_str_size(vars.int_part) + 1 + int_to_str_size(vars.dec_part); @@ -1637,7 +1680,7 @@ float_to_str_size(float x){ #endif #if defined(FSTRING_IMPLEMENTATION) -FSTRING_LINK b32_4tech + FSTRING_LINK b32_4tech append_float_to_str(String *dest, float x){ b32_4tech result = 1; Float_To_Str_Variables vars = get_float_vars(x); @@ -1655,7 +1698,7 @@ append_float_to_str(String *dest, float x){ #endif #if defined(FSTRING_IMPLEMENTATION) -FSTRING_LINK b32_4tech + FSTRING_LINK b32_4tech float_to_str(String *dest, float x){ b32_4tech result = 1; dest->size = 0; @@ -1666,7 +1709,7 @@ float_to_str(String *dest, float x){ #if defined(FSTRING_IMPLEMENTATION) -FSTRING_LINK i32_4tech + FSTRING_LINK i32_4tech str_is_int_c(char *str){ b32_4tech result = 1; for (; *str; ++str){ @@ -1681,7 +1724,7 @@ str_is_int_c(char *str){ #if defined(FSTRING_IMPLEMENTATION) -FSTRING_LINK b32_4tech + FSTRING_LINK b32_4tech str_is_int_s(String str){ b32_4tech result = 1; for (i32_4tech i = 0; i < str.size; ++i){ @@ -1696,7 +1739,7 @@ str_is_int_s(String str){ #if defined(FSTRING_IMPLEMENTATION) -FSTRING_LINK i32_4tech + FSTRING_LINK i32_4tech str_to_int_c(char *str){ i32_4tech x = 0; for (; *str; ++str){ @@ -1715,7 +1758,7 @@ str_to_int_c(char *str){ #if defined(FSTRING_IMPLEMENTATION) -FSTRING_LINK i32_4tech + FSTRING_LINK i32_4tech str_to_int_s(String str){ i32_4tech x, i; if (str.size == 0){ @@ -1733,7 +1776,7 @@ str_to_int_s(String str){ #endif #if defined(FSTRING_IMPLEMENTATION) -FSTRING_LINK i32_4tech + FSTRING_LINK i32_4tech hexchar_to_int(char c){ i32_4tech x = 0; if (c >= '0' && c <= '9'){ @@ -1750,14 +1793,14 @@ hexchar_to_int(char c){ #endif #if defined(FSTRING_IMPLEMENTATION) -FSTRING_LINK char + FSTRING_LINK char int_to_hexchar(i32_4tech x){ return (x<10)?((char)x+'0'):((char)x+'a'-10); } #endif #if defined(FSTRING_IMPLEMENTATION) -FSTRING_LINK u32_4tech + FSTRING_LINK u32_4tech hexstr_to_int(String str){ u32_4tech x; i32_4tech i; @@ -1776,7 +1819,7 @@ hexstr_to_int(String str){ #endif #if defined(FSTRING_IMPLEMENTATION) -FSTRING_LINK b32_4tech + FSTRING_LINK b32_4tech color_to_hexstr(String *s, u32_4tech color){ b32_4tech result = 0; i32_4tech i; @@ -1805,7 +1848,7 @@ color_to_hexstr(String *s, u32_4tech color){ #endif #if defined(FSTRING_IMPLEMENTATION) -FSTRING_LINK b32_4tech + FSTRING_LINK b32_4tech hexstr_to_color(String s, u32_4tech *out){ b32_4tech result = 0; u32_4tech color = 0; @@ -1830,7 +1873,7 @@ hexstr_to_color(String s, u32_4tech *out){ #if defined(FSTRING_IMPLEMENTATION) -FSTRING_LINK i32_4tech + FSTRING_LINK i32_4tech reverse_seek_slash_pos(String str, i32_4tech pos){ i32_4tech i = str.size - 1 - pos; while (i >= 0 && !char_is_slash(str.str[i])){ @@ -1841,21 +1884,21 @@ reverse_seek_slash_pos(String str, i32_4tech pos){ #endif #if !defined(FSTRING_GUARD) -FSTRING_INLINE i32_4tech + FSTRING_INLINE i32_4tech reverse_seek_slash(String str){ return(reverse_seek_slash_pos(str, 0)); } #endif #if !defined(FSTRING_GUARD) -FSTRING_INLINE String + FSTRING_INLINE String front_of_directory(String dir){ return substr_tail(dir, reverse_seek_slash(dir) + 1); } #endif #if !defined(FSTRING_GUARD) -FSTRING_INLINE String + FSTRING_INLINE String path_of_directory(String dir){ return substr(dir, 0, reverse_seek_slash(dir) + 1); } @@ -1863,7 +1906,7 @@ path_of_directory(String dir){ #if defined(FSTRING_IMPLEMENTATION) -FSTRING_LINK b32_4tech + FSTRING_LINK b32_4tech set_last_folder_sc(String *dir, char *folder_name, char slash){ b32_4tech result = 0; i32_4tech size = reverse_seek_slash(*dir) + 1; @@ -1882,7 +1925,7 @@ set_last_folder_sc(String *dir, char *folder_name, char slash){ #if defined(FSTRING_IMPLEMENTATION) -FSTRING_LINK b32_4tech + FSTRING_LINK b32_4tech set_last_folder_ss(String *dir, String folder_name, char slash){ b32_4tech result = 0; i32_4tech size = reverse_seek_slash(*dir) + 1; @@ -1900,7 +1943,7 @@ set_last_folder_ss(String *dir, String folder_name, char slash){ #endif #if defined(FSTRING_IMPLEMENTATION) -FSTRING_LINK String + FSTRING_LINK String file_extension(String str){ i32_4tech i; for (i = str.size - 1; i >= 0; --i){ @@ -1912,7 +1955,7 @@ file_extension(String str){ #endif #if defined(FSTRING_IMPLEMENTATION) -FSTRING_LINK b32_4tech + FSTRING_LINK b32_4tech remove_extension(String *str){ b32_4tech result = 0; i32_4tech i; @@ -1928,7 +1971,7 @@ remove_extension(String *str){ #endif #if defined(FSTRING_IMPLEMENTATION) -FSTRING_LINK b32_4tech + FSTRING_LINK b32_4tech remove_last_folder(String *str){ b32_4tech result = 0; i32_4tech end = reverse_seek_slash_pos(*str, 1); @@ -1943,7 +1986,7 @@ remove_last_folder(String *str){ // TODO(allen): Add hash-table extension to string sets. #if defined(FSTRING_IMPLEMENTATION) -FSTRING_LINK b32_4tech + FSTRING_LINK b32_4tech string_set_match_table(void *str_set, i32_4tech item_size, i32_4tech count, String str, i32_4tech *match_index){ b32_4tech result = 0; i32_4tech i = 0; @@ -1960,7 +2003,7 @@ string_set_match_table(void *str_set, i32_4tech item_size, i32_4tech count, Stri #endif #if defined(FSTRING_IMPLEMENTATION) -FSTRING_LINK b32_4tech + FSTRING_LINK b32_4tech string_set_match(String *str_set, i32_4tech count, String str, i32_4tech *match_index){ b32_4tech result = string_set_match_table(str_set, sizeof(String), count, str, match_index); return(result); @@ -1968,7 +2011,7 @@ string_set_match(String *str_set, i32_4tech count, String str, i32_4tech *match_ #endif #if defined(FSTRING_IMPLEMENTATION) -FSTRING_LINK String + FSTRING_LINK String get_first_double_line(String source){ String line = {0}; i32_4tech pos0 = find_substr_s(source, 0, make_lit_string("\n\n")); @@ -1982,7 +2025,7 @@ get_first_double_line(String source){ #endif #if defined(FSTRING_IMPLEMENTATION) -FSTRING_LINK String + FSTRING_LINK String get_next_double_line(String source, String line){ String next = {0}; i32_4tech pos = (i32_4tech)(line.str - source.str) + line.size; @@ -2007,7 +2050,7 @@ get_next_double_line(String source, String line){ #endif #if defined(FSTRING_IMPLEMENTATION) -FSTRING_LINK String + FSTRING_LINK String get_next_word(String source, String prev_word){ String word = {0}; @@ -2038,7 +2081,7 @@ get_next_word(String source, String prev_word){ #endif #if defined(FSTRING_IMPLEMENTATION) -FSTRING_LINK String + FSTRING_LINK String get_first_word(String source){ String start_str = make_string(source.str, 0); String word = get_next_word(source, start_str); diff --git a/4coder_lib/4coder_utf8.h b/4coder_lib/4coder_utf8.h index 51209a9d..76d6580d 100644 --- a/4coder_lib/4coder_utf8.h +++ b/4coder_lib/4coder_utf8.h @@ -40,6 +40,15 @@ typedef int32_t b32_4tech; #endif // standard preamble end +static b32_4tech +codepoint_is_whitespace(u32_4tech codepoint){ + b32_4tech result = false; + if (codepoint == ' ' || codepoint == '\r' || codepoint == '\n' || codepoint == '\t'){ + result = true; + } + return(result); +} + static u32_4tech utf8_to_u32_length_unchecked(u8_4tech *buffer, u32_4tech *length_out){ u32_4tech result = 0; @@ -146,28 +155,28 @@ utf8_to_u32(u8_4tech **buffer_ptr, u8_4tech *end){ } static void -u32_to_utf8_unchecked(u32_4tech code_point, u8_4tech *buffer, u32_4tech *length_out){ - if (code_point <= 0x7F){ - buffer[0] = (u8_4tech)code_point; +u32_to_utf8_unchecked(u32_4tech codepoint, u8_4tech *buffer, u32_4tech *length_out){ + if (codepoint <= 0x7F){ + buffer[0] = (u8_4tech)codepoint; *length_out = 1; } - else if (code_point <= 0x7FF){ - buffer[0] = (u8_4tech)(0xC0 | (code_point >> 6)); - buffer[1] = (u8_4tech)(0x80 | (code_point & 0x3F)); + else if (codepoint <= 0x7FF){ + buffer[0] = (u8_4tech)(0xC0 | (codepoint >> 6)); + buffer[1] = (u8_4tech)(0x80 | (codepoint & 0x3F)); *length_out = 2; } - else if (code_point <= 0xFFFF){ - buffer[0] = (u8_4tech)(0xE0 | (code_point >> 12)); - buffer[1] = (u8_4tech)(0x80 | ((code_point >> 6) & 0x3F)); - buffer[2] = (u8_4tech)(0x80 | (code_point & 0x3F)); + else if (codepoint <= 0xFFFF){ + buffer[0] = (u8_4tech)(0xE0 | (codepoint >> 12)); + buffer[1] = (u8_4tech)(0x80 | ((codepoint >> 6) & 0x3F)); + buffer[2] = (u8_4tech)(0x80 | (codepoint & 0x3F)); *length_out = 3; } else{ - code_point &= 0x001FFFFF; - buffer[0] = (u8_4tech)(0xF0 | (code_point >> 18)); - buffer[1] = (u8_4tech)(0x80 | ((code_point >> 12) & 0x3F)); - buffer[2] = (u8_4tech)(0x80 | ((code_point >> 6) & 0x3F)); - buffer[3] = (u8_4tech)(0x80 | (code_point & 0x3F)); + codepoint &= 0x001FFFFF; + buffer[0] = (u8_4tech)(0xF0 | (codepoint >> 18)); + buffer[1] = (u8_4tech)(0x80 | ((codepoint >> 12) & 0x3F)); + buffer[2] = (u8_4tech)(0x80 | ((codepoint >> 6) & 0x3F)); + buffer[3] = (u8_4tech)(0x80 | (codepoint & 0x3F)); *length_out = 4; } } @@ -186,11 +195,11 @@ utf8_to_utf16_minimal_checking(u16_4tech *dst, umem_4tech max_wchars, u8_4tech * *error = false; for(; s < s_end;){ - u32_4tech code_point = 0; + u32_4tech codepoint = 0; u32_4tech utf8_size = 0; if (s[0] <= 0x7F){ - code_point = (u32_4tech)s[0]; + codepoint = (u32_4tech)s[0]; utf8_size = 1; } else if (s[0] <= 0xE0){ @@ -199,8 +208,8 @@ utf8_to_utf16_minimal_checking(u16_4tech *dst, umem_4tech max_wchars, u8_4tech * break; } - code_point = ((u32_4tech)((s[0])&0x1F)) << 6; - code_point |= ((u32_4tech)((s[1])&0x3F)); + codepoint = ((u32_4tech)((s[0])&0x1F)) << 6; + codepoint |= ((u32_4tech)((s[1])&0x3F)); utf8_size = 2; } else if (s[0] <= 0xF0){ @@ -209,9 +218,9 @@ utf8_to_utf16_minimal_checking(u16_4tech *dst, umem_4tech max_wchars, u8_4tech * break; } - code_point = ((u32_4tech)((s[0])&0x0F)) << 12; - code_point |= ((u32_4tech)((s[1])&0x3F)) << 6; - code_point |= ((u32_4tech)((s[2])&0x3F)); + codepoint = ((u32_4tech)((s[0])&0x0F)) << 12; + codepoint |= ((u32_4tech)((s[1])&0x3F)) << 6; + codepoint |= ((u32_4tech)((s[2])&0x3F)); utf8_size = 3; } else{ @@ -220,26 +229,26 @@ utf8_to_utf16_minimal_checking(u16_4tech *dst, umem_4tech max_wchars, u8_4tech * break; } - code_point = ((u32_4tech)((s[0])&0x07)) << 18; - code_point |= ((u32_4tech)((s[1])&0x3F)) << 12; - code_point |= ((u32_4tech)((s[2])&0x3F)) << 6; - code_point |= ((u32_4tech)((s[3])&0x3F)); + codepoint = ((u32_4tech)((s[0])&0x07)) << 18; + codepoint |= ((u32_4tech)((s[1])&0x3F)) << 12; + codepoint |= ((u32_4tech)((s[2])&0x3F)) << 6; + codepoint |= ((u32_4tech)((s[3])&0x3F)); utf8_size = 4; } s += utf8_size; limit -= utf8_size; - if (code_point <= 0xD7FF || (code_point >= 0xE000 && code_point <= 0xFFFF)){ - *d = (u16_4tech)(code_point); + if (codepoint <= 0xD7FF || (codepoint >= 0xE000 && codepoint <= 0xFFFF)){ + *d = (u16_4tech)(codepoint); d += advance; needed_max += 1; } - else if (code_point >= 0x10000 && code_point <= 0x10FFFF){ - code_point -= 0x10000; + else if (codepoint >= 0x10000 && codepoint <= 0x10FFFF){ + codepoint -= 0x10000; - u32_4tech high = (code_point >> 10) & 0x03FF; - u32_4tech low = (code_point) & 0x03FF; + u32_4tech high = (codepoint >> 10) & 0x03FF; + u32_4tech low = (codepoint) & 0x03FF; high += 0xD800; low += 0xDC00; @@ -283,11 +292,11 @@ utf16_to_utf8_minimal_checking(u8_4tech *dst, umem_4tech max_chars, u16_4tech *s *error = false; for (; s < s_end;){ - u32_4tech code_point = 0; + u32_4tech codepoint = 0; u32_4tech utf16_size = 0; if (s[0] <= 0xD7FF || (s[0] >= 0xE000 && s[0] <= 0xFFFF)){ - code_point = s[0]; + codepoint = s[0]; utf16_size = 1; } else{ @@ -299,7 +308,7 @@ utf16_to_utf8_minimal_checking(u8_4tech *dst, umem_4tech max_chars, u16_4tech *s u32_4tech high = s[0] - 0xD800; u32_4tech low = s[1] - 0xDC00; - code_point = ((high << 10) | (low)) + 0x10000; + codepoint = ((high << 10) | (low)) + 0x10000; utf16_size = 2; } else{ @@ -314,26 +323,26 @@ utf16_to_utf8_minimal_checking(u8_4tech *dst, umem_4tech max_chars, u16_4tech *s u8_4tech d_fill[4]; u32_4tech d_fill_count = 0; - if (code_point <= 0x7F){ - d_fill[0] = (u8_4tech)code_point; + if (codepoint <= 0x7F){ + d_fill[0] = (u8_4tech)codepoint; d_fill_count = 1; } - else if (code_point <= 0x7FF){ - d_fill[0] = (u8_4tech)(0xC0 | (code_point >> 6)); - d_fill[1] = (u8_4tech)(0x80 | (code_point & 0x3F)); + else if (codepoint <= 0x7FF){ + d_fill[0] = (u8_4tech)(0xC0 | (codepoint >> 6)); + d_fill[1] = (u8_4tech)(0x80 | (codepoint & 0x3F)); d_fill_count = 2; } - else if (code_point <= 0xFFFF){ - d_fill[0] = (u8_4tech)(0xE0 | (code_point >> 12)); - d_fill[1] = (u8_4tech)(0x80 | ((code_point >> 6) & 0x3F)); - d_fill[2] = (u8_4tech)(0x80 | (code_point & 0x3F)); + else if (codepoint <= 0xFFFF){ + d_fill[0] = (u8_4tech)(0xE0 | (codepoint >> 12)); + d_fill[1] = (u8_4tech)(0x80 | ((codepoint >> 6) & 0x3F)); + d_fill[2] = (u8_4tech)(0x80 | (codepoint & 0x3F)); d_fill_count = 3; } - else if (code_point <= 0x10FFFF){ - d_fill[0] = (u8_4tech)(0xF0 | (code_point >> 18)); - d_fill[1] = (u8_4tech)(0x80 | ((code_point >> 12) & 0x3F)); - d_fill[2] = (u8_4tech)(0x80 | ((code_point >> 6) & 0x3F)); - d_fill[3] = (u8_4tech)(0x80 | (code_point & 0x3F)); + else if (codepoint <= 0x10FFFF){ + d_fill[0] = (u8_4tech)(0xF0 | (codepoint >> 18)); + d_fill[1] = (u8_4tech)(0x80 | ((codepoint >> 12) & 0x3F)); + d_fill[2] = (u8_4tech)(0x80 | ((codepoint >> 6) & 0x3F)); + d_fill[3] = (u8_4tech)(0x80 | (codepoint & 0x3F)); d_fill_count = 4; } else{ diff --git a/4ed.cpp b/4ed.cpp index 73cf3efb..08cf2a1c 100644 --- a/4ed.cpp +++ b/4ed.cpp @@ -235,7 +235,7 @@ do_feedback_message(System_Functions *system, Models *models, String value, b32 for (View_Iter iter = file_view_iter_init(&models->layout, file, 0); file_view_iter_good(iter); iter = file_view_iter_next(iter)){ - view_cursor_move(iter.view, pos); + view_cursor_move(system, iter.view, pos); } } } @@ -247,16 +247,16 @@ do_feedback_message(System_Functions *system, Models *models, String value, b32 #define USE_FILE(n,v) Editing_File *n = (v)->file_data.file -#define USE_PANEL(n) Panel *n = 0;{ \ +#define USE_PANEL(n) Panel *n = 0; do{ \ i32 panel_index = command->models->layout.active_panel; \ n = command->models->layout.panels + panel_index; \ -} +}while(false) -#define USE_VIEW(n) View *n = 0;{ \ - i32 panel_index = command->models->layout.active_panel; \ - Panel *panel = command->models->layout.panels + panel_index; \ - n = panel->view; \ -} +#define USE_VIEW(n) View *n = 0; do{ \ + i32 panel_index = command->models->layout.active_panel; \ + Panel *__panel__ = command->models->layout.panels + panel_index; \ + n = __panel__->view; \ +}while(false) #define REQ_OPEN_VIEW(n) USE_VIEW(n); if (view_lock_level(n) > LockLevel_Open) return @@ -274,7 +274,7 @@ panel_make_empty(System_Functions *system, App_Vars *vars, Panel *panel){ Assert(panel->view == 0); new_view = live_set_alloc_view(&vars->live_set, panel, models); - view_set_file(new_view.view, models->scratch_buffer, models); + view_set_file(system, new_view.view, models->scratch_buffer, models); new_view.view->map = get_map(models, mapid_file); return(new_view.view); @@ -362,16 +362,15 @@ COMMAND_DECL(reopen){ init_normal_file(system, models, file, buffer, size); for (i32 i = 0; i < vptr_count; ++i){ - view_set_file(vptrs[i], file, models); + view_set_file(system, vptrs[i], file, models); int32_t line = line_number[i]; int32_t character = column_number[i]; *vptrs[i]->edit_pos = edit_poss[i]; - Full_Cursor cursor = view_compute_cursor(vptrs[i], seek_line_char(line, character), 0); + Full_Cursor cursor = view_compute_cursor(system, vptrs[i], seek_line_char(line, character), 0); - view_set_cursor(vptrs[i], cursor, true, - file->settings.unwrapped_lines); + view_set_cursor(vptrs[i], cursor, true, file->settings.unwrapped_lines); } } else{ @@ -449,12 +448,11 @@ COMMAND_DECL(toggle_line_wrap){ if (file->settings.unwrapped_lines){ file->settings.unwrapped_lines = 0; view->edit_pos->scroll.target_x = 0; - view_cursor_move(view, view->edit_pos->cursor.pos); } else{ file->settings.unwrapped_lines = 1; - view_cursor_move(view, view->edit_pos->cursor.pos); } + view_cursor_move(system, view, view->edit_pos->cursor.pos); view_set_relative_scrolling(view, scrolling); } @@ -520,7 +518,7 @@ COMMAND_DECL(open_menu){ COMMAND_DECL(open_debug){ USE_VIEW(view); view_show_GUI(view, VUI_Debug); - view->debug_vars = debug_vars_zero(); + view->debug_vars = null_debug_vars; } COMMAND_DECL(user_callback){ @@ -633,9 +631,6 @@ app_hardcode_styles(Models *models){ Style *styles = models->styles.styles; Style *style = styles + 1; - i16 fonts = 1; - models->global_font.font_id = fonts + 0; - ///////////////// style_set_name(style, make_lit_string("4coder")); @@ -967,7 +962,6 @@ enum Command_Line_Action{ CLAct_WindowStreamMode, CLAct_FontSize, CLAct_FontStartHinting, - CLAct_FontCustom, CLAct_Count }; @@ -1015,8 +1009,6 @@ init_command_line_settings(App_Settings *settings, Plat_Settings *plat_settings, case 'u': action = CLAct_UserFile; strict = 0; break; case 'U': action = CLAct_UserFile; strict = 1; break; - case 'c': action = CLAct_FontCustom; break; - case 'd': action = CLAct_CustomDLL; strict = 0; break; case 'D': action = CLAct_CustomDLL; strict = 1; break; @@ -1120,16 +1112,6 @@ init_command_line_settings(App_Settings *settings, Plat_Settings *plat_settings, action = CLAct_Nothing; }break; - case CLAct_FontCustom: - { - if ((i + 3) <= clparams.argc){ - settings->custom_font_file = clparams.argv[i++]; - settings->custom_font_name = clparams.argv[i++]; - settings->custom_font_size = str_to_int_c(clparams.argv[i]); - } - action = CLAct_Nothing; - }break; - case CLAct_FontStartHinting: { plat_settings->use_hinting = 1; @@ -1163,8 +1145,6 @@ app_setup_memory(System_Functions *system, Application_Memory *memory){ return(vars); } -static App_Settings null_app_settings = {0}; - App_Read_Command_Line_Sig(app_read_command_line){ i32 out_size = 0; App_Vars *vars = app_setup_memory(system, memory); @@ -1215,11 +1195,8 @@ App_Init_Sig(app_init){ models->app_links.cmd_context = &vars->command_data; partition = &models->mem.part; - target->partition = partition; { - i32 i; - panel_max_count = models->layout.panel_max_count = MAX_VIEWS; divider_max_count = panel_max_count - 1; models->layout.panel_count = 0; @@ -1231,7 +1208,7 @@ App_Init_Sig(app_init){ dll_init_sentinel(&models->layout.used_sentinel); panel = panels; - for (i = 0; i < panel_max_count; ++i, ++panel){ + for (i32 i = 0; i < panel_max_count; ++i, ++panel){ dll_insert(&models->layout.free_sentinel, panel); } @@ -1239,7 +1216,7 @@ App_Init_Sig(app_init){ models->layout.dividers = dividers; div = dividers; - for (i = 0; i < divider_max_count-1; ++i, ++div){ + for (i32 i = 0; i < divider_max_count-1; ++i, ++div){ div->next = (div + 1); } div->next = 0; @@ -1460,57 +1437,6 @@ App_Init_Sig(app_init){ setup_ui_commands(&models->map_ui, &models->mem.part, global_map); } - // NOTE(allen): font setup - { - models->font_set = &target->font_set; - - struct Font_Setup{ - char *c_file_name; - i32 file_name_len; - char *c_name; - i32 name_len; - i32 pt_size; - }; - - i32 font_size = models->settings.font_size; - - char *custom_font_file = models->settings.custom_font_file; - char *custom_font_name = models->settings.custom_font_name; - i32 custom_font_size = models->settings.custom_font_size; - b32 use_custom_font = true; - if (!custom_font_file){ - use_custom_font = false; - custom_font_file = ""; - custom_font_name = ""; - } - - if (font_size < 8) font_size = 8; - - Font_Setup font_setup[] = { - {literal("LiberationSans-Regular.ttf"), literal("Liberation Sans"), font_size}, - {literal("liberation-mono.ttf"), literal("Liberation Mono"), font_size}, - {literal("Hack-Regular.ttf"), literal("Hack"), font_size}, - {literal("CutiveMono-Regular.ttf"), literal("Cutive Mono"), font_size}, - {literal("Inconsolata-Regular.ttf"), literal("Inconsolata"), font_size}, - {custom_font_file, str_size(custom_font_file), - custom_font_name, str_size(custom_font_name), - custom_font_size}, - }; - i32 font_count = ArrayCount(font_setup); - if (!use_custom_font){ - --font_count; - } - - font_set_init(models->font_set, partition, 16, 6); - - for (i32 i = 0; i < font_count; ++i){ - String file_name = make_string(font_setup[i].c_file_name, font_setup[i].file_name_len); - String name = make_string(font_setup[i].c_name, font_setup[i].name_len); - i32 pt_size = font_setup[i].pt_size; - font_set_add(models->font_set, file_name, name, pt_size); - } - } - // NOTE(allen): file setup working_set_init(&models->working_set, partition, &vars->models.mem.general); models->working_set.default_display_width = DEFAULT_DISPLAY_WIDTH; @@ -1529,11 +1455,9 @@ App_Init_Sig(app_init){ } // NOTE(allen): style setup + models->global_font_id = 1; app_hardcode_styles(models); - models->palette_size = 40; - models->palette = push_array(partition, u32, models->palette_size); - // NOTE(allen): init first panel Command_Data *cmd = &vars->command_data; @@ -1556,8 +1480,8 @@ App_Init_Sig(app_init){ }; File_Init init_files[] = { - { make_lit_string("*messages*"), &models->message_buffer, 1, }, - { make_lit_string("*scratch*"), &models->scratch_buffer, 0, } + { make_lit_string("*messages*"), &models->message_buffer, true , }, + { make_lit_string("*scratch*"), &models->scratch_buffer, false, } }; for (i32 i = 0; i < ArrayCount(init_files); ++i){ @@ -1622,8 +1546,7 @@ update_cli_handle_without_file(System_Functions *system, Models *models, } internal i32 -update_cli_handle_with_file(System_Functions *system, Models *models, - CLI_Handles *cli, Editing_File *file, char *dest, i32 max, b32 cursor_at_end){ +update_cli_handle_with_file(System_Functions *system, Models *models, CLI_Handles *cli, Editing_File *file, char *dest, i32 max, b32 cursor_at_end){ i32 result = 0; u32 amount = 0; @@ -1648,7 +1571,7 @@ update_cli_handle_with_file(System_Functions *system, Models *models, for (View_Iter iter = file_view_iter_init(&models->layout, file, 0); file_view_iter_good(iter); iter = file_view_iter_next(iter)){ - view_cursor_move(iter.view, new_cursor); + view_cursor_move(system, iter.view, new_cursor); } } @@ -1657,12 +1580,11 @@ update_cli_handle_with_file(System_Functions *system, Models *models, App_Step_Sig(app_step){ - Application_Step_Result app_result = *result; + Application_Step_Result app_result = *app_result_; app_result.animating = 0; App_Vars *vars = (App_Vars*)memory->vars_memory; Models *models = &vars->models; - target->partition = &models->mem.part; // NOTE(allen): OS clipboard event handling String clipboard = input->clipboard; @@ -1760,24 +1682,24 @@ App_Step_Sig(app_step){ // NOTE(allen): detect mouse hover status i32 mx = input->mouse.x; i32 my = input->mouse.y; - b32 mouse_in_edit_area = 0; - b32 mouse_in_margin_area = 0; - Panel *mouse_panel, *used_panels; + b32 mouse_in_edit_area = false; + b32 mouse_in_margin_area = false; - used_panels = &models->layout.used_sentinel; - for (dll_items(mouse_panel, used_panels)){ - if (hit_check(mx, my, mouse_panel->inner)){ - mouse_in_edit_area = 1; - break; + Panel *mouse_panel = 0; + { + Panel *used_panels = &models->layout.used_sentinel, *panel = 0; + for (dll_items(panel, used_panels)){ + if (hit_check(mx, my, panel->inner)){ + mouse_panel = panel; + mouse_in_edit_area = true; + break; + } + else if (hit_check(mx, my, panel->full)){ + mouse_panel = panel; + mouse_in_margin_area = true; + break; + } } - else if (hit_check(mx, my, mouse_panel->full)){ - mouse_in_margin_area = 1; - break; - } - } - - if (!(mouse_in_edit_area || mouse_in_margin_area)){ - mouse_panel = 0; } b32 mouse_on_divider = 0; @@ -1954,7 +1876,7 @@ App_Step_Sig(app_step){ } if (i < models->layout.panel_count){ - view_set_file(panel->view, models->message_buffer, models); + view_set_file(system, panel->view, models->message_buffer, models); view_show_file(panel->view); ++i; panel = panel->next; @@ -2269,7 +2191,7 @@ App_Step_Sig(app_step){ if (!gui_scroll_eq(scroll_vars, &ip_result.vars)){ if (file_scroll){ - view_set_scroll(view, ip_result.vars); + view_set_scroll(system, view, ip_result.vars); } else{ *scroll_vars = ip_result.vars; @@ -2720,7 +2642,7 @@ App_Step_Sig(app_step){ app_result.lctrl_lalt_is_altgr = models->settings.lctrl_lalt_is_altgr; app_result.perform_kill = !models->keep_playing; - *result = app_result; + *app_result_ = app_result; // end-of-app_step } diff --git a/4ed.h b/4ed.h index 71a08546..b8c45832 100644 --- a/4ed.h +++ b/4ed.h @@ -64,12 +64,7 @@ typedef struct Plat_Settings{ } Plat_Settings; #define App_Read_Command_Line_Sig(name) \ -i32 name(System_Functions *system, \ -Application_Memory *memory, \ -String current_directory, \ -Plat_Settings *plat_settings, \ -char ***files, i32 **file_count, \ -Command_Line_Parameters clparams) +i32 name(System_Functions *system, Application_Memory *memory, String current_directory, Plat_Settings *plat_settings, char ***files, i32 **file_count, Command_Line_Parameters clparams) typedef App_Read_Command_Line_Sig(App_Read_Command_Line); @@ -110,12 +105,12 @@ struct Application_Step_Input{ String clipboard; }; -#define App_Step_Sig(name) void \ -name(System_Functions *system, \ -Render_Target *target, \ -Application_Memory *memory, \ -Application_Step_Input *input, \ -Application_Step_Result *result, \ +#define App_Step_Sig(name) void \ +name(System_Functions *system, \ +Render_Target *target, \ +Application_Memory *memory, \ +Application_Step_Input *input, \ +Application_Step_Result *app_result_, \ Command_Line_Parameters params) typedef App_Step_Sig(App_Step); diff --git a/4ed_api_implementation.cpp b/4ed_api_implementation.cpp index 0c92f83b..8617d859 100644 --- a/4ed_api_implementation.cpp +++ b/4ed_api_implementation.cpp @@ -64,7 +64,7 @@ fill_buffer_summary(Buffer_Summary *buffer, Editing_File *file, Command_Data *cm } internal void -fill_view_summary(View_Summary *view, View *vptr, Live_Views *live_set, Working_Set *working_set){ +fill_view_summary(System_Functions *system, View_Summary *view, View *vptr, Live_Views *live_set, Working_Set *working_set){ Buffer_ID buffer_id = 0; File_Viewing_Data *data = &vptr->file_data; @@ -84,7 +84,7 @@ fill_view_summary(View_Summary *view, View *vptr, Live_Views *live_set, Working_ view->buffer_id = buffer_id; - view->mark = view_compute_cursor(vptr, seek_pos(vptr->edit_pos->mark), 0); + view->mark = view_compute_cursor(system, vptr, seek_pos(vptr->edit_pos->mark), 0); view->cursor = vptr->edit_pos->cursor; view->preferred_x = vptr->edit_pos->preferred_x; @@ -96,8 +96,8 @@ fill_view_summary(View_Summary *view, View *vptr, Live_Views *live_set, Working_ inline void -fill_view_summary(View_Summary *view, View *vptr, Command_Data *cmd){ - fill_view_summary(view, vptr, &cmd->vars->live_set, &cmd->models->working_set); +fill_view_summary(System_Functions *system, View_Summary *view, View *vptr, Command_Data *cmd){ + fill_view_summary(system, view, vptr, &cmd->vars->live_set, &cmd->models->working_set); } internal Editing_File* @@ -195,8 +195,7 @@ DOC_PARAM(command, The command parameter specifies the command that shall be exe DOC_PARAM(command_len, The parameter command_len specifies the length of the command string.) DOC_PARAM(flags, Flags for the behavior of the call are specified in the flags parameter.) DOC_RETURN(This call returns non-zero on success.) -DOC( -A call to exec_system_command executes a command as if called from the command line, and sends the output to a buffer. The buffer identifier can name a new buffer that does not exist, name a buffer that does exist, or provide the id of a buffer that does exist. +DOC(A call to exec_system_command executes a command as if called from the command line, and sends the output to a buffer. The buffer identifier can name a new buffer that does not exist, name a buffer that does exist, or provide the id of a buffer that does exist. If the buffer is not already in an open view and the view parameter is not NULL, then the provided view will display the output buffer. @@ -316,8 +315,8 @@ DOC_SEE(Command_Line_Interface_Flag) command_string = make_string_terminated(part, command, command_len); } - if (vptr && bind_to_new_view){ - view_set_file(vptr, file, models); + if (vptr != 0 && bind_to_new_view){ + view_set_file(system, vptr, file, models); view_show_file(vptr); } @@ -342,7 +341,7 @@ DOC_SEE(Command_Line_Interface_Flag) goto done; } - done: + done:; end_temp_memory(temp); return(result); } @@ -877,10 +876,8 @@ DOC_SEE(Buffer_Setting_ID) new_value = 48; } if (new_value != file->settings.display_width){ - i16 font_id = file->settings.font_id; - Font_Info *font_info = get_font_info(models->font_set, font_id); - Render_Font *font = font_info->font; - file_set_width(models, file, new_value, font); + Render_Font *font = system->font.get_render_data_by_id(file->settings.font_id); + file_set_width(system, models, file, new_value, font); } }break; @@ -891,9 +888,8 @@ DOC_SEE(Buffer_Setting_ID) new_value = 0; } if (new_value != file->settings.minimum_base_display_width){ - i16 font_id = file->settings.font_id; - Render_Font *font = get_font_info(models->font_set, font_id)->font; - file_set_min_base_width(models, file, new_value, font); + Render_Font *font = system->font.get_render_data_by_id(file->settings.font_id); + file_set_min_base_width(system, models, file, new_value, font); } }break; @@ -977,13 +973,12 @@ DOC_SEE(Buffer_Setting_ID) } if (full_remeasure){ - i16 font_id = file->settings.font_id; - Render_Font *font = get_font_info(models->font_set, font_id)->font; + Render_Font *font = system->font.get_render_data_by_id(file->settings.font_id); file_allocate_character_starts_as_needed(&models->mem.general, file); - buffer_measure_character_starts(&file->state.buffer, file->state.character_starts, 0, file->settings.virtual_white); - file_measure_wraps(models, file, font); - file_update_cursor_positions(models, file); + buffer_measure_character_starts(system, font, &file->state.buffer, file->state.character_starts, 0, file->settings.virtual_white); + file_measure_wraps(system, models, file, font); + file_update_cursor_positions(system, models, file); } }break; @@ -1304,25 +1299,25 @@ internal_get_view_first(Command_Data *cmd, View_Summary *view){ Panel *panel = layout->used_sentinel.next; Assert(panel != &layout->used_sentinel); - fill_view_summary(view, panel->view, cmd); + System_Functions *system = cmd->system; + fill_view_summary(system, view, panel->view, cmd); } internal void internal_get_view_next(Command_Data *cmd, View_Summary *view){ + System_Functions *system = cmd->system; Editing_Layout *layout = &cmd->models->layout; Live_Views *live_set = &cmd->vars->live_set; int32_t index = view->view_id - 1; - View *vptr = 0; - Panel *panel = 0; if (index >= 0 && index < live_set->max){ - vptr = live_set->views + index; - panel = vptr->panel; + View *vptr = live_set->views + index; + Panel *panel = vptr->panel; if (panel){ panel = panel->next; } if (panel && panel != &layout->used_sentinel){ - fill_view_summary(view, panel->view, &cmd->vars->live_set, &cmd->models->working_set); + fill_view_summary(system, view, panel->view, &cmd->vars->live_set, &cmd->models->working_set); } else{ *view = null_view_summary; @@ -1390,15 +1385,15 @@ DOC_RETURN(This call returns a summary that describes the indicated view if it i DOC_SEE(Access_Flag) */{ Command_Data *cmd = (Command_Data*)app->cmd_context; + System_Functions *system = cmd->system; View_Summary view = {0}; Live_Views *live_set = cmd->live_set; i32 max = live_set->max; - View *vptr = 0; view_id -= 1; if (view_id >= 0 && view_id < max){ - vptr = live_set->views + view_id; - fill_view_summary(&view, vptr, live_set, &cmd->models->working_set); + View *vptr = live_set->views + view_id; + fill_view_summary(system, &view, vptr, live_set, &cmd->models->working_set); if (!access_test(view.lock_flags, access)){ view = null_view_summary; } @@ -1416,13 +1411,13 @@ DOC_SEE(set_active_view) DOC_SEE(Access_Flag) */{ Command_Data *cmd = (Command_Data*)app->cmd_context; - + System_Functions *system = cmd->system; Panel *panel = cmd->models->layout.panels + cmd->models->layout.active_panel; Assert(panel->view != 0); View_Summary view = {0}; - fill_view_summary(&view, panel->view, &cmd->vars->live_set, &cmd->models->working_set); + fill_view_summary(system, &view, panel->view, &cmd->vars->live_set, &cmd->models->working_set); if (!access_test(view.lock_flags, access)){ view = null_view_summary; } @@ -1483,7 +1478,7 @@ DOC_SEE(View_Split_Position) models->layout.active_panel = (i32)(split.panel - models->layout.panels); panel_make_empty(system, cmd->vars, split.panel); - fill_view_summary(&result, split.panel->view, cmd); + fill_view_summary(system, &result, split.panel->view, cmd); } return(result); @@ -1651,6 +1646,7 @@ DOC_RETURN(This call returns non-zero on success.) DOC_SEE(View_Setting_ID) */{ Command_Data *cmd = (Command_Data*)app->cmd_context; + System_Functions *system = cmd->system; View *vptr = imp_get_view(cmd, view); bool32 result = false; @@ -1673,7 +1669,7 @@ DOC_SEE(View_Setting_ID) }break; } - fill_view_summary(view, vptr, cmd); + fill_view_summary(system, view, vptr, cmd); } return(result); @@ -1724,16 +1720,16 @@ DOC_SEE(Buffer_Seek) DOC_SEE(Full_Cursor) */{ Command_Data *cmd = (Command_Data*)app->cmd_context; + System_Functions *system = cmd->system; View *vptr = imp_get_view(cmd, view); - Editing_File *file = 0; bool32 result = false; if (vptr){ - file = vptr->file_data.file; - if (file && !file->is_loading){ + Editing_File *file = vptr->file_data.file; + if (file != 0 && !file->is_loading){ result = true; - *cursor_out = view_compute_cursor(vptr, seek, 0); - fill_view_summary(view, vptr, cmd); + *cursor_out = view_compute_cursor(system, vptr, seek, 0); + fill_view_summary(system, view, vptr, cmd); } } @@ -1756,6 +1752,7 @@ cursor in the same column or x position. DOC_SEE(Buffer_Seek) */{ Command_Data *cmd = (Command_Data*)app->cmd_context; + System_Functions *system = cmd->system; View *vptr = imp_get_view(cmd, view); Editing_File *file = 0; bool32 result = false; @@ -1765,9 +1762,9 @@ DOC_SEE(Buffer_Seek) Assert(file); if (!file->is_loading){ result = true; - Full_Cursor cursor = view_compute_cursor(vptr, seek, 0); + Full_Cursor cursor = view_compute_cursor(system, vptr, seek, 0); view_set_cursor(vptr, cursor, set_preferred_x, file->settings.unwrapped_lines); - fill_view_summary(view, vptr, cmd); + fill_view_summary(system, view, vptr, cmd); } } @@ -1781,6 +1778,7 @@ DOC(TODO) DOC_SEE(GUI_Scroll_Vars) */{ Command_Data *cmd = (Command_Data*)app->cmd_context; + System_Functions *system = cmd->system; View *vptr = imp_get_view(cmd, view); Editing_File *file = 0; bool32 result = false; @@ -1789,8 +1787,8 @@ DOC_SEE(GUI_Scroll_Vars) file = vptr->file_data.file; if (file && !file->is_loading){ result = true; - view_set_scroll(vptr, scroll); - fill_view_summary(view, vptr, cmd); + view_set_scroll(system, vptr, scroll); + fill_view_summary(system, view, vptr, cmd); } } @@ -1807,6 +1805,7 @@ DOC(This call sets the the view's mark position.) DOC_SEE(Buffer_Seek) */{ Command_Data *cmd = (Command_Data*)app->cmd_context; + System_Functions *system = cmd->system; View *vptr = imp_get_view(cmd, view); Editing_File *file = 0; Full_Cursor cursor = {0}; @@ -1817,14 +1816,14 @@ DOC_SEE(Buffer_Seek) if (file && !file->is_loading){ if (seek.type != buffer_seek_pos){ result = true; - cursor = view_compute_cursor(vptr, seek, 0); + cursor = view_compute_cursor(system, vptr, seek, 0); vptr->edit_pos->mark = cursor.pos; } else{ result = true; vptr->edit_pos->mark = seek.pos; } - fill_view_summary(view, vptr, cmd); + fill_view_summary(system, view, vptr, cmd); } } @@ -1847,18 +1846,19 @@ and the turn_on set to false, will switch back to showing the cursor. ) */{ Command_Data *cmd = (Command_Data*)app->cmd_context; + System_Functions *system = cmd->system; View *vptr = imp_get_view(cmd, view); bool32 result = false; if (vptr){ result = true; if (turn_on){ - view_set_temp_highlight(vptr, start, end); + view_set_temp_highlight(system, vptr, start, end); } else{ vptr->file_data.show_temp_highlight = 0; } - fill_view_summary(view, vptr, cmd); + fill_view_summary(system, view, vptr, cmd); } return(result); @@ -1871,33 +1871,29 @@ DOC_PARAM(view, The view parameter specifies the view in which to display the bu DOC_PARAM(buffer_id, The buffer_id parameter specifies which buffer to show in the view.) DOC_PARAM(flags, The flags parameter specifies behaviors for setting the buffer.) DOC_RETURN(This call returns non-zero on success.) -DOC -( -On success view_set_buffer sets the specified view's current buffer and -cancels and dialogue shown in the view and displays the file. -) +DOC(On success view_set_buffer sets the specified view's current buffer and cancels and dialogue shown in the view and displays the file.) DOC_SEE(Set_Buffer_Flag) */{ Command_Data *cmd = (Command_Data*)app->cmd_context; + System_Functions *system = cmd->system; View *vptr = imp_get_view(cmd, view); Models *models = cmd->models; - Editing_File *file = 0; bool32 result = false; if (vptr){ - file = working_set_get_active_file(&models->working_set, buffer_id); + Editing_File *file = working_set_get_active_file(&models->working_set, buffer_id); - if (file){ + if (file != 0){ result = true; if (file != vptr->file_data.file){ - view_set_file(vptr, file, models); + view_set_file(system, vptr, file, models); if (!(flags & SetBuffer_KeepOriginalGUI)){ view_show_file(vptr); } } } - fill_view_summary(view, vptr, cmd); + fill_view_summary(system, view, vptr, cmd); } return(result); @@ -2095,6 +2091,8 @@ DOC_PARAM(apply_to_all_files, If this is set all open files change to this font. durring the start hook because several files already exist at that time.) DOC(This call changes 4coder's default font to one of the built in fonts.) */{ + +#if 0 Command_Data *cmd = (Command_Data*)app->cmd_context; Font_Set *set = cmd->models->font_set; @@ -2110,6 +2108,8 @@ DOC(This call changes 4coder's default font to one of the built in fonts.) global_font->font_id = font_id; } } +#endif + } API_EXPORT void @@ -2120,6 +2120,8 @@ DOC_PARAM(name, The name parameter specifies the name of the font to begin using DOC_PARAM(len, The len parameter specifies the length of the name string.) DOC(This call sets the display font of a particular buffer.) */{ + +#if 0 Command_Data *cmd = (Command_Data*)app->cmd_context; Models *models = cmd->models; Editing_File *file = imp_get_file(cmd, buffer); @@ -2133,6 +2135,8 @@ DOC(This call sets the display font of a particular buffer.) file_set_font(models, file, font_id); } } +#endif + } API_EXPORT bool32 @@ -2144,18 +2148,21 @@ DOC_PARAM(name_max, the capacity of name_out) DOC_RETURN(returns non-zero on success) */ { + bool32 result = false; + +#if 0 Command_Data *cmd = (Command_Data*)app->cmd_context; Models *models = cmd->models; Editing_File *file = imp_get_file(cmd, buffer); - bool32 result = 0; if (file){ Font_Set *set = models->font_set; String name = make_string_cap(name_out, 0, name_max); if (font_set_get_name(set, file->settings.font_id, &name)){ - result = name.size; + result = (name.size > 0); } } +#endif return(result); } diff --git a/4ed_app_models.h b/4ed_app_models.h index d63fe79f..d1b3ceda 100644 --- a/4ed_app_models.h +++ b/4ed_app_models.h @@ -29,6 +29,7 @@ struct App_Settings{ i32 custom_arg_start; i32 custom_arg_end; }; +global_const App_Settings null_app_settings = {0}; struct Debug_Input_Event{ Key_Code key; @@ -50,6 +51,8 @@ struct Models{ Mem_Options mem; App_Settings settings; + Font_ID global_font_id; + Command_Map map_top; Command_Map map_file; Command_Map map_ui; @@ -74,11 +77,8 @@ struct Models{ Input_Filter_Function *input_filter; Scroll_Rule_Function *scroll_rule; - Font_Set *font_set; - Style_Font global_font; Style_Library styles; u32 *palette; - i32 palette_size; Editing_Layout layout; Working_Set working_set; diff --git a/4ed_app_target.cpp b/4ed_app_target.cpp index 44d34bc7..1743cdda 100644 --- a/4ed_app_target.cpp +++ b/4ed_app_target.cpp @@ -35,24 +35,25 @@ #include "4ed_rendering.h" #include "4ed.h" +#include "4ed_buffer_model.h" #define FCPP_FORBID_MALLOC #include "4cpp/4cpp_lexer.h" #include "4ed_doubly_linked_list.cpp" -#include "4ed_font_set.cpp" +#include "4ed_translation.cpp" #include "4ed_rendering_helper.cpp" #include "4ed_style.h" #include "4ed_style.cpp" #include "4ed_command.cpp" -#include "file/4coder_buffer.cpp" -#include "file/4coder_undo.cpp" -#include "file/4coder_file.cpp" -#include "file/4coder_working_set.cpp" -#include "file/4coder_hot_directory.cpp" +#include "4ed_buffer.cpp" +#include "4ed_undo.cpp" +#include "4ed_file.cpp" +#include "4ed_working_set.cpp" +#include "4ed_hot_directory.cpp" #include "4ed_gui.h" #include "4ed_gui.cpp" @@ -61,5 +62,7 @@ #include "4ed_file_view.cpp" #include "4ed.cpp" +#include "font/4coder_font_static_functions.cpp" + // BOTTOM diff --git a/file/4coder_buffer.cpp b/4ed_buffer.cpp similarity index 80% rename from file/4coder_buffer.cpp rename to 4ed_buffer.cpp index b2d93e6b..ba098998 100644 --- a/file/4coder_buffer.cpp +++ b/4ed_buffer.cpp @@ -13,8 +13,8 @@ // Buffer low level operations // -#include "../file/4coder_font_data.h" -#include "../4coder_helper/4coder_seek_types.h" +#include "font/4coder_font_data.h" +#include "4coder_helper/4coder_seek_types.h" typedef struct Cursor_With_Index{ i32 pos; @@ -186,6 +186,8 @@ buffer_batch_edit_update_cursors(Cursor_With_Index *sorted_positions, i32 count, return(shift_amount); } +////////////////////////////////////// + internal i32 eol_convert_in(char *dest, char *src, i32 size){ i32 i = 0, j = 0, k = 0; @@ -271,256 +273,7 @@ eol_in_place_convert_out(char *data, i32 size, i32 max, i32 *size_out){ return(result); } -// TODO(allen): ditch this shit yo -inline i32 -is_whitespace(char c){ - i32 result; - result = (c == ' ' || c == '\n' || c == '\r' || c == '\t' || c == '\f' || c == '\v'); - return(result); -} - -inline i32 -is_alphanumeric_true(char c){ - return (c >= 'a' && c <= 'z' || c >= 'A' && c <= 'Z' || c >= '0' && c <= '9'); -} - -inline i32 -is_alphanumeric(char c){ - return (c >= 'a' && c <= 'z' || c >= 'A' && c <= 'Z' || c >= '0' && c <= '9' || c == '_'); -} - -inline i32 -is_upper(char c){ - return (c >= 'A' && c <= 'Z'); -} - -inline i32 -is_lower(char c){ - return (c >= 'a' && c <= 'z'); -} - -inline char -to_upper(char c){ - if (is_lower(c)){ - c += 'A' - 'a'; - } - return(c); -} - -internal i32 -is_match(char *a, char *b, i32 len){ - i32 result = 1; - for (;len > 0; --len, ++a, ++b) - if (*a != *b) { result = 0; break; } - - return(result); -} - -internal i32 -is_match_insensitive(char *a, char *b, i32 len){ - i32 result = 1; - for (;len > 0; --len, ++a, ++b) - if (to_upper(*a) != to_upper(*b)) { result = 0; break; } - - return(result); -} - -// -// Translation state for turning byte streams into unicode/trash byte streams -// - -struct Buffer_Model_Step{ - u32 type; - u32 value; - i32 i; - u32 byte_length; -}; - -enum{ - BufferModelUnit_None, - BufferModelUnit_Codepoint, - BufferModelUnit_Numbers, -}; - -struct Buffer_Translating_State{ - u8 fill_buffer[4]; - u32 fill_start_i; - u32 fill_i; - u32 fill_expected; - - u32 byte_class; - b32 emit_type; - b32 rebuffer_current; - b32 emit_current_as_cp; - - Buffer_Model_Step steps[5]; - Buffer_Model_Step step_current; - u32 step_count; - u32 step_j; - - u32 codepoint; - u32 codepoint_length; - b32 do_codepoint; - b32 do_numbers; - - b32 do_newline; - b32 do_codepoint_advance; - b32 do_number_advance; -}; -global_const Buffer_Translating_State null_buffer_translating_state = {0}; - -internal void -translating_consume_byte(Buffer_Translating_State *tran, u8 ch, u32 i, u32 size){ - tran->byte_class = 0; - if ((ch >= ' ' && ch < 0x7F) || ch == '\t' || ch == '\n' || ch == '\r'){ - tran->byte_class = 1; - } - else if (ch < 0xC0){ - tran->byte_class = 1000; - } - else if (ch < 0xE0){ - tran->byte_class = 2; - } - else if (ch < 0xF0){ - tran->byte_class = 3; - } - else{ - tran->byte_class = 4; - } - - tran->emit_type = BufferModelUnit_None; - tran->rebuffer_current = false; - tran->emit_current_as_cp = false; - if (tran->fill_expected == 0){ - tran->fill_buffer[0] = ch; - tran->fill_start_i = i; - tran->fill_i = 1; - - if (tran->byte_class == 1){ - tran->emit_type = BufferModelUnit_Codepoint; - } - else if (tran->byte_class == 0 || tran->byte_class == 1000){ - tran->emit_type = BufferModelUnit_Numbers; - } - else{ - tran->fill_expected = tran->byte_class; - } - } - else{ - if (tran->byte_class == 1000){ - tran->fill_buffer[tran->fill_i] = ch; - ++tran->fill_i; - - if (tran->fill_i == tran->fill_expected){ - tran->emit_type = BufferModelUnit_Codepoint; - } - } - else{ - if (tran->byte_class >= 2 && tran->byte_class <= 4){ - tran->rebuffer_current = true; - } - else if (tran->byte_class == 1){ - tran->emit_current_as_cp = true; - } - else{ - tran->fill_buffer[tran->fill_i] = ch; - ++tran->fill_i; - } - tran->emit_type = BufferModelUnit_Numbers; - } - } - - if (tran->emit_type == BufferModelUnit_None && i+1 == size){ - tran->emit_type = BufferModelUnit_Numbers; - } - - tran->codepoint = 0; - tran->codepoint_length = 0; - tran->do_codepoint = false; - tran->do_numbers = false; - if (tran->emit_type == BufferModelUnit_Codepoint){ - tran->codepoint = utf8_to_u32_length_unchecked(tran->fill_buffer, &tran->codepoint_length); - if ((tran->codepoint >= ' ' && tran->codepoint <= 255 && tran->codepoint != 127) || tran->codepoint == '\t' || tran->codepoint == '\n' || tran->codepoint == '\r'){ - tran->do_codepoint = true; - } - else{ - tran->do_numbers = true; - } - } - else if (tran->emit_type == BufferModelUnit_Numbers){ - tran->do_numbers = true; - } - - Assert((tran->do_codepoint + tran->do_numbers) <= 1); - - tran->step_count = 0; - if (tran->do_codepoint){ - tran->steps[0].type = 1; - tran->steps[0].value = tran->codepoint; - tran->steps[0].i = tran->fill_start_i; - tran->steps[0].byte_length = tran->codepoint_length; - tran->step_count = 1; - } - else if (tran->do_numbers){ - for (u32 j = 0; j < tran->fill_i; ++j){ - tran->steps[j].type = 0; - tran->steps[j].value = tran->fill_buffer[j]; - tran->steps[j].i = tran->fill_start_i + j; - tran->steps[j].byte_length = 1; - } - tran->step_count = tran->fill_i; - } - - if (tran->do_codepoint || tran->do_numbers){ - tran->fill_start_i = 0; - tran->fill_i = 0; - tran->fill_expected = 0; - } - - if (tran->rebuffer_current){ - Assert(tran->do_codepoint || tran->do_numbers); - - tran->fill_buffer[0] = ch; - tran->fill_start_i = i; - tran->fill_i = 1; - tran->fill_expected = tran->byte_class; - } - else if (tran->emit_current_as_cp){ - Assert(tran->do_codepoint || tran->do_numbers); - - tran->steps[tran->step_count].type = 1; - tran->steps[tran->step_count].value = ch; - tran->steps[tran->step_count].i = i; - tran->steps[tran->step_count].byte_length = 1; - ++tran->step_count; - } -} - -internal void -translation_step_read(Buffer_Translating_State *tran){ - tran->do_newline = false; - tran->do_codepoint_advance = false; - tran->do_number_advance = false; - if (tran->step_current.type == 1){ - switch (tran->step_current.value){ - case '\n': - { - tran->do_newline = true; - }break; - - default: - { - tran->do_codepoint_advance = true; - }break; - } - } - else{ - tran->do_number_advance = true; - } -} - -#define TRANSLATION_OUTPUT(t) (t)->step_j = 0; (t)->step_j < (t)->step_count; ++(t)->step_j -#define TRANSLATION_GET_STEP(t) (t)->step_current = (t)->steps[(t)->step_j]; translation_step_read(t) +////////////////////////////////////// // // Implementation of the gap buffer @@ -585,31 +338,30 @@ buffer_init_provide_page(Gap_Buffer_Init *init, void *page, i32 page_size){ buffer->max = page_size; } -internal i32 +internal b32 buffer_end_init(Gap_Buffer_Init *init, void *scratch, i32 scratch_size){ Gap_Buffer *buffer = init->buffer; - i32 osize1 = 0, size1 = 0, size2 = 0, size = init->size; - i32 result = 0; + b32 result = false; - if (buffer->data){ - if (buffer->max >= init->size){ - size2 = size >> 1; - size1 = osize1 = size - size2; - - if (size1 > 0){ - size1 = eol_convert_in(buffer->data, init->data, size1); - if (size2 > 0){ - size2 = eol_convert_in(buffer->data + size1, init->data + osize1, size2); - } + if (buffer->data && buffer->max >= init->size){ + i32 size = init->size; + i32 size2 = size >> 1; + i32 osize1 = size - size2; + i32 size1 = osize1; + + if (size1 > 0){ + size1 = eol_convert_in(buffer->data, init->data, size1); + if (size2 > 0){ + size2 = eol_convert_in(buffer->data + size1, init->data + osize1, size2); } - - buffer->size1 = size1; - buffer->size2 = size2; - buffer->gap_size = buffer->max - size1 - size2; - memmove(buffer->data + size1 + buffer->gap_size, buffer->data + size1, size2); - - result = 1; } + + buffer->size1 = size1; + buffer->size2 = size2; + buffer->gap_size = buffer->max - size1 - size2; + memmove(buffer->data + size1 + buffer->gap_size, buffer->data + size1, size2); + + result = true; } return(result); @@ -823,9 +575,9 @@ buffer_convert_out(Gap_Buffer *buffer, char *dest, i32 max){ if (buffer_stringify_loop(&stream, buffer, 0, size)){ b32 still_looping = 0; do{ - i32 size = stream.end - i; + i32 chunk_size = stream.end - i; i32 out_size = 0; - i32 result = eol_convert_out(dest + pos, max - pos, stream.data + i, size, &out_size); + i32 result = eol_convert_out(dest + pos, max - pos, stream.data + i, chunk_size, &out_size); assert(result); i = stream.end; pos += out_size; @@ -916,7 +668,7 @@ buffer_measure_starts(Buffer_Measure_Starts *state, Gap_Buffer *buffer){ } internal void -buffer_measure_character_starts(Gap_Buffer *buffer, i32 *character_starts, i32 mode, i32 virtual_white){ +buffer_measure_character_starts(System_Functions *system, Render_Font *font, Gap_Buffer *buffer, i32 *character_starts, i32 mode, i32 virtual_white){ assert(mode == 0); Gap_Buffer_Stream stream = {0}; @@ -934,7 +686,8 @@ buffer_measure_character_starts(Gap_Buffer *buffer, i32 *character_starts, i32 m skipping_whitespace = 1; } - Buffer_Translating_State tran = {0}; + Translation_State tran = {0}; + Translation_Emits emits = {0}; stream.use_termination_character = 1; stream.terminator = '\n'; @@ -944,19 +697,19 @@ buffer_measure_character_starts(Gap_Buffer *buffer, i32 *character_starts, i32 m for (; i < stream.end; ++i){ u8 ch = (u8)stream.data[i]; - translating_consume_byte(&tran, ch, i, size); + translating_fully_process_byte(system, font, &tran, ch, i, size, &emits); - for (TRANSLATION_OUTPUT(&tran)){ - TRANSLATION_GET_STEP(&tran); + for (TRANSLATION_DECL_EMIT_LOOP(J, emits)){ + TRANSLATION_DECL_GET_STEP(step, behavior, J, emits); - if (tran.do_newline){ + if (behavior.do_newline){ ++character_index; character_starts[line_index++] = character_index; if (virtual_white){ skipping_whitespace = 1; } } - else if (tran.do_codepoint_advance || tran.do_number_advance){ + else if (behavior.do_codepoint_advance || behavior.do_number_advance){ if (ch != ' ' && ch != '\t'){ skipping_whitespace = 0; } @@ -993,6 +746,7 @@ struct Buffer_Layout_Stop{ struct Buffer_Measure_Wrap_Params{ Gap_Buffer *buffer; i32 *wrap_line_index; + System_Functions *system; Render_Font *font; b32 virtual_white; }; @@ -1014,9 +768,11 @@ struct Buffer_Measure_Wrap_State{ b32 did_wrap; b32 first_of_the_line; - u8 ch; - - Buffer_Translating_State tran; + Translation_State tran; + Translation_Emits emits; + u32 J; + Buffer_Model_Step step; + Buffer_Model_Behavior behavior; i32 __pc__; }; @@ -1060,18 +816,20 @@ buffer_measure_wrap_y(Buffer_Measure_Wrap_State *S_ptr, Buffer_Measure_Wrap_Para S.still_looping = 0; do{ for (; S.i < S.stream.end; ++S.i){ - S.ch = (u8)S.stream.data[S.i]; - - if (S.ch != ' ' && S.ch != '\t'){ - S.skipping_whitespace = false; + { + u8 ch = (u8)S.stream.data[S.i]; + + if (ch != ' ' && ch != '\t'){ + S.skipping_whitespace = false; + } + + translating_fully_process_byte(params.system, params.font, &S.tran, ch, S.i, S.size, &S.emits); } - translating_consume_byte(&S.tran, S.ch, S.i, S.size); - - for (TRANSLATION_OUTPUT(&S.tran)){ - TRANSLATION_GET_STEP(&S.tran); + for (TRANSLATION_EMIT_LOOP(S.J, S.emits)){ + TRANSLATION_GET_STEP(S.step, S.behavior, S.J, S.emits); - if (S.tran.do_newline){ + if (S.behavior.do_newline){ ++S.current_wrap_index; params.wrap_line_index[S.line_index++] = S.current_wrap_index; @@ -1090,14 +848,13 @@ buffer_measure_wrap_y(Buffer_Measure_Wrap_State *S_ptr, Buffer_Measure_Wrap_Para } S.first_of_the_line = 1; } - else if (S.tran.do_number_advance || S.tran.do_codepoint_advance){ + else if (S.behavior.do_number_advance || S.behavior.do_codepoint_advance){ if (!S.skipping_whitespace){ - - if (S.tran.do_codepoint_advance){ - S.current_adv = get_codepoint_advance(params.font, S.tran.step_current.value); + if (S.behavior.do_codepoint_advance){ + S.current_adv = font_get_glyph_advance(params.system, params.font, S.step.value); } else{ - S.current_adv = params.font->byte_advance; + S.current_adv = font_get_byte_advance(params.font); } S.did_wrap = false; @@ -1228,7 +985,7 @@ buffer_remeasure_starts(Gap_Buffer *buffer, i32 line_start, i32 line_end, i32 li } internal void -buffer_remeasure_character_starts(Gap_Buffer *buffer, i32 line_start, i32 line_end, i32 line_shift, i32 *character_starts, i32 mode, i32 virtual_whitespace){ +buffer_remeasure_character_starts(System_Functions *system, Render_Font *font, Gap_Buffer *buffer, i32 line_start, i32 line_end, i32 line_shift, i32 *character_starts, i32 mode, i32 virtual_whitespace){ assert(mode == 0); i32 new_line_count = buffer->line_count; @@ -1266,7 +1023,8 @@ buffer_remeasure_character_starts(Gap_Buffer *buffer, i32 line_start, i32 line_e } // Translation - Buffer_Translating_State tran = {0}; + Translation_State tran = {0}; + Translation_Emits emits = {0}; stream.use_termination_character = 1; stream.terminator = '\n'; @@ -1275,12 +1033,12 @@ buffer_remeasure_character_starts(Gap_Buffer *buffer, i32 line_start, i32 line_e do{ for (; char_i < stream.end; ++char_i){ u8 ch = (u8)stream.data[char_i]; - translating_consume_byte(&tran, ch, char_i, size); + translating_fully_process_byte(system, font, &tran, ch, char_i, size, &emits); - for (TRANSLATION_OUTPUT(&tran)){ - TRANSLATION_GET_STEP(&tran); + for (TRANSLATION_DECL_EMIT_LOOP(J, emits)){ + TRANSLATION_DECL_GET_STEP(step, behavior, J, emits); - if (tran.do_newline){ + if (behavior.do_newline){ character_starts[line_i++] = last_char_start; ++current_char_start; last_char_start = current_char_start; @@ -1292,7 +1050,7 @@ buffer_remeasure_character_starts(Gap_Buffer *buffer, i32 line_start, i32 line_e goto buffer_remeasure_character_starts_end; } } - else if (tran.do_codepoint_advance || tran.do_number_advance){ + else if (behavior.do_codepoint_advance || behavior.do_number_advance){ if (ch != ' ' && ch != '\t'){ skipping_whitespace = 0; } @@ -1539,6 +1297,7 @@ buffer_partial_from_line_character(Gap_Buffer *buffer, i32 line, i32 character){ struct Buffer_Cursor_Seek_Params{ Gap_Buffer *buffer; Buffer_Seek seek; + System_Functions *system; Render_Font *font; i32 *wrap_line_index; i32 *character_starts; @@ -1561,9 +1320,15 @@ struct Buffer_Cursor_Seek_State{ b32 first_of_the_line; b32 xy_seek; f32 ch_width; - u8 ch; - Buffer_Translating_State tran; + i32 font_height; + + Translation_State tran; + Translation_Emits emits; + u32 J; + Buffer_Model_Step step; + Buffer_Model_Behavior behavior; + i32 __pc__; }; @@ -1585,6 +1350,8 @@ buffer_cursor_seek(Buffer_Cursor_Seek_State *S_ptr, Buffer_Cursor_Seek_Params pa DrCase(4); } + S.font_height = font_get_height(params.font); + S.xy_seek = (params.seek.type == buffer_seek_wrapped_xy || params.seek.type == buffer_seek_unwrapped_xy); S.size = buffer_size(params.buffer); @@ -1594,9 +1361,7 @@ buffer_cursor_seek(Buffer_Cursor_Seek_State *S_ptr, Buffer_Cursor_Seek_Params pa switch (params.seek.type){ case buffer_seek_pos: { - if (params.seek.pos > S.size){ - params.seek.pos = S.size; - } + params.seek.pos = clamp(0, params.seek.pos, S.size); line_index = buffer_get_line_index(params.buffer, params.seek.pos); }break; @@ -1605,53 +1370,45 @@ buffer_cursor_seek(Buffer_Cursor_Seek_State *S_ptr, Buffer_Cursor_Seek_Params pa { i32 line_count = params.buffer->line_count; i32 max_character = params.character_starts[line_count] - 1; - if (params.seek.pos > max_character){ - params.seek.pos = max_character; - } + params.seek.pos = clamp(0, params.seek.pos, max_character); - line_index = buffer_get_line_index_from_character_pos(params.character_starts, params.seek.pos, - 0, params.buffer->line_count); + line_index = buffer_get_line_index_from_character_pos(params.character_starts, params.seek.pos, 0, params.buffer->line_count); }break; case buffer_seek_line_char: { line_index = params.seek.line - 1; - if (line_index >= params.buffer->line_count){ - line_index = params.buffer->line_count - 1; - } - if (line_index < 0){ - line_index = 0; - } + line_index = clamp_bottom(0, line_index); }break; case buffer_seek_unwrapped_xy: { - line_index = (i32)(params.seek.y / params.font->height); - if (line_index >= params.buffer->line_count){ - line_index = params.buffer->line_count - 1; - } - if (line_index < 0){ - line_index = 0; - } + line_index = (i32)(params.seek.y / S.font_height); + line_index = clamp_bottom(0, line_index); }break; case buffer_seek_wrapped_xy: { - line_index = buffer_get_line_index_from_wrapped_y(params.wrap_line_index, params.seek.y, params.font->height, 0, params.buffer->line_count); + line_index = buffer_get_line_index_from_wrapped_y(params.wrap_line_index, params.seek.y, S.font_height, 0, params.buffer->line_count); }break; default: InvalidCodePath; } + i32 safe_line_index = line_index; + if (line_index >= params.buffer->line_count){ + safe_line_index = params.buffer->line_count-1; + } + // Build the cursor hint - S.next_cursor.pos = params.buffer->line_starts[line_index]; - S.next_cursor.character_pos = params.character_starts[line_index]; + S.next_cursor.pos = params.buffer->line_starts[safe_line_index]; + S.next_cursor.character_pos = params.character_starts[safe_line_index]; S.next_cursor.line = line_index + 1; S.next_cursor.character = 1; - S.next_cursor.wrap_line = params.wrap_line_index[line_index] + 1; - S.next_cursor.unwrapped_y = (f32)(line_index * params.font->height); + S.next_cursor.wrap_line = params.wrap_line_index[safe_line_index] + 1; + S.next_cursor.unwrapped_y = (f32)(safe_line_index * S.font_height); S.next_cursor.unwrapped_x = 0; - S.next_cursor.wrapped_y = (f32)(params.wrap_line_index[line_index] * params.font->height); + S.next_cursor.wrapped_y = (f32)(params.wrap_line_index[safe_line_index] * S.font_height); S.next_cursor.wrapped_x = 0; } @@ -1672,9 +1429,9 @@ buffer_cursor_seek(Buffer_Cursor_Seek_State *S_ptr, Buffer_Cursor_Seek_Params pa if (buffer_stringify_loop(&S.stream, params.buffer, S.next_cursor.pos, S.size)){ do{ for (; S.next_cursor.pos < S.stream.end; ++S.next_cursor.pos){ - S.ch = (u8)S.stream.data[S.next_cursor.pos]; + u8 ch = (u8)S.stream.data[S.next_cursor.pos]; - if (S.ch != ' ' && S.ch != '\t'){ + if (ch != ' ' && ch != '\t'){ goto double_break_vwhite; } else{ @@ -1748,22 +1505,23 @@ buffer_cursor_seek(Buffer_Cursor_Seek_State *S_ptr, Buffer_Cursor_Seek_Params pa S.still_looping = 0; do{ for (; S.i < S.stream.end; ++S.i){ - S.ch = (u8)S.stream.data[S.i]; + { + u8 ch = (u8)S.stream.data[S.i]; + translating_fully_process_byte(params.system, params.font, &S.tran, ch, S.i, S.size, &S.emits); + } - translating_consume_byte(&S.tran, S.ch, S.i, S.size); - - for (TRANSLATION_OUTPUT(&S.tran)){ - TRANSLATION_GET_STEP(&S.tran); + for (TRANSLATION_EMIT_LOOP(S.J, S.emits)){ + TRANSLATION_GET_STEP(S.step, S.behavior, S.J, S.emits); S.prev_cursor = S.this_cursor; S.this_cursor = S.next_cursor; - if (S.tran.do_newline){ + if (S.behavior.do_newline){ ++S.next_cursor.character_pos; ++S.next_cursor.line; ++S.next_cursor.wrap_line; - S.next_cursor.unwrapped_y += params.font->height; - S.next_cursor.wrapped_y += params.font->height; + S.next_cursor.unwrapped_y += S.font_height; + S.next_cursor.wrapped_y += S.font_height; S.next_cursor.character = 1; S.next_cursor.unwrapped_x = 0; @@ -1777,27 +1535,27 @@ buffer_cursor_seek(Buffer_Cursor_Seek_State *S_ptr, Buffer_Cursor_Seek_Params pa S.next_cursor.wrapped_x = line_shift; S.first_of_the_line = 1; } - else if (S.tran.do_number_advance || S.tran.do_codepoint_advance){ + else if (S.behavior.do_number_advance || S.behavior.do_codepoint_advance){ - if (S.tran.do_codepoint_advance){ - S.ch_width = get_codepoint_advance(params.font, S.tran.step_current.value); + if (S.behavior.do_codepoint_advance){ + S.ch_width = font_get_glyph_advance(params.system, params.font, S.step.value); } else{ - S.ch_width = params.font->byte_advance; + S.ch_width = font_get_byte_advance(params.font); } - if (S.tran.step_current.i >= S.wrap_unit_end){ + if (S.step.i >= S.wrap_unit_end){ S_stop.status = BLStatus_NeedWrapDetermination; S_stop.line_index = S.next_cursor.line-1; S_stop.wrap_line_index = S.next_cursor.wrap_line-1; - S_stop.pos = S.tran.step_current.i; + S_stop.pos = S.step.i; S_stop.x = S.next_cursor.wrapped_x; DrYield(4, S_stop); S.wrap_unit_end = wrap_unit_end; if (do_wrap && !S.first_of_the_line){ - S.next_cursor.wrapped_y += params.font->height; + S.next_cursor.wrapped_y += S.font_height; ++S.next_cursor.wrap_line; if (params.virtual_white){ @@ -1820,7 +1578,7 @@ buffer_cursor_seek(Buffer_Cursor_Seek_State *S_ptr, Buffer_Cursor_Seek_Params pa S.first_of_the_line = 0; } - S.next_cursor.pos += S.tran.step_current.byte_length; + S.next_cursor.pos += S.step.byte_length; f32 x = 0, px = 0, y = 0, py = 0; switch (params.seek.type){ @@ -1866,9 +1624,9 @@ buffer_cursor_seek(Buffer_Cursor_Seek_State *S_ptr, Buffer_Cursor_Seek_Params pa goto buffer_cursor_seek_end; } - if (y > params.seek.y - params.font->height && x >= params.seek.x){ + if (y > params.seek.y - S.font_height && x >= params.seek.x){ if (!params.seek.round_down){ - if (py >= y && S.ch != '\n' && (params.seek.x - px) < (x - params.seek.x)){ + if (py >= y && !S.behavior.do_newline && (params.seek.x - px) < (x - params.seek.x)){ S.this_cursor = S.prev_cursor; } goto buffer_cursor_seek_end; @@ -1963,7 +1721,7 @@ enum Buffer_Render_Flag{ typedef struct Buffer_Render_Item{ i32 index; - u32 glyphid; + u32 codepoint; u32 flags; f32 x0, y0; f32 x1, y1; @@ -1972,23 +1730,26 @@ typedef struct Buffer_Render_Item{ typedef struct Render_Item_Write{ Buffer_Render_Item *item; f32 x, y; + System_Functions *system; Render_Font *font; + i32 font_height; f32 x_min; f32 x_max; } Render_Item_Write; inline Render_Item_Write -write_render_item(Render_Item_Write write, i32 index, u32 glyphid, u32 flags){ - f32 ch_width = get_codepoint_advance(write.font, glyphid); +write_render_item(Render_Item_Write write, i32 index, u32 codepoint, u32 flags){ + + f32 ch_width = font_get_glyph_advance(write.system, write.font, codepoint); if (write.x <= write.x_max && write.x + ch_width >= write.x_min){ write.item->index = index; - write.item->glyphid = glyphid; + write.item->codepoint = codepoint; write.item->flags = flags; write.item->x0 = write.x; write.item->y0 = write.y; write.item->x1 = write.x + ch_width; - write.item->y1 = write.y + write.font->height; + write.item->y1 = write.y + write.font_height; ++write.item; } @@ -1998,7 +1759,6 @@ write_render_item(Render_Item_Write write, i32 index, u32 glyphid, u32 flags){ return(write); } -// TODO(allen): Reduce the number of parameters. struct Buffer_Render_Params{ Gap_Buffer *buffer; Buffer_Render_Item *items; @@ -2013,6 +1773,7 @@ struct Buffer_Render_Params{ f32 height; Full_Cursor start_cursor; i32 wrapped; + System_Functions *system; Render_Font *font; b32 virtual_white; i32 wrap_slashes; @@ -2028,9 +1789,9 @@ struct Buffer_Render_State{ f32 shift_y; f32 ch_width; - u8 ch; Render_Item_Write write; + f32 byte_advance; i32 line; i32 wrap_line; @@ -2038,7 +1799,11 @@ struct Buffer_Render_State{ b32 first_of_the_line; i32 wrap_unit_end; - Buffer_Translating_State tran; + Translation_State tran; + Translation_Emits emits; + u32 J; + Buffer_Model_Step step; + Buffer_Model_Behavior behavior; i32 __pc__; }; @@ -2086,10 +1851,14 @@ buffer_render_data(Buffer_Render_State *S_ptr, Buffer_Render_Params params, f32 S.write.item = params.items; S.write.x = S.shift_x + line_shift; S.write.y = S.shift_y; + S.write.system = params.system; S.write.font = params.font; + S.write.font_height = font_get_height(params.font); S.write.x_min = params.port_x; S.write.x_max = params.port_x + params.clip_w; + S.byte_advance = font_get_byte_advance(params.font); + if (params.virtual_white){ S.skipping_whitespace = 1; } @@ -2099,17 +1868,19 @@ buffer_render_data(Buffer_Render_State *S_ptr, Buffer_Render_Params params, f32 if (buffer_stringify_loop(&S.stream, params.buffer, S.i, S.size)){ do{ for (; S.i < S.stream.end; ++S.i){ - S.ch = (u8)S.stream.data[S.i]; - translating_consume_byte(&S.tran, S.ch, S.i, S.size); + { + u8 ch = (u8)S.stream.data[S.i]; + translating_fully_process_byte(params.system, params.font, &S.tran, ch, S.i, S.size, &S.emits); + } - for (TRANSLATION_OUTPUT(&S.tran)){ - TRANSLATION_GET_STEP(&S.tran); + for (TRANSLATION_EMIT_LOOP(S.J, S.emits)){ + TRANSLATION_GET_STEP(S.step, S.behavior, S.J, S.emits); - if (!S.tran.do_newline && S.tran.step_current.i >= S.wrap_unit_end){ + if (!S.behavior.do_newline && S.step.i >= S.wrap_unit_end){ S_stop.status = BLStatus_NeedWrapDetermination; S_stop.line_index = S.line; S_stop.wrap_line_index = S.wrap_line; - S_stop.pos = S.tran.step_current.i; + S_stop.pos = S.step.i; S_stop.x = S.write.x - S.shift_x; DrYield(4, S_stop); @@ -2129,7 +1900,7 @@ buffer_render_data(Buffer_Render_State *S_ptr, Buffer_Render_Params params, f32 switch (params.wrap_slashes){ case WrapIndicator_Show_After_Line: { - S.write = write_render_item(S.write, S.tran.step_current.i-1, '\\', BRFlag_Ghost_Character); + S.write = write_render_item(S.write, S.step.i-1, '\\', BRFlag_Ghost_Character); }break; case WrapIndicator_Show_At_Wrap_Edge: @@ -2137,12 +1908,12 @@ buffer_render_data(Buffer_Render_State *S_ptr, Buffer_Render_Params params, f32 if (S.write.x < S.shift_x + params.width){ S.write.x = S.shift_x + params.width; } - S.write = write_render_item(S.write, S.tran.step_current.i-1, '\\', BRFlag_Ghost_Character); + S.write = write_render_item(S.write, S.step.i-1, '\\', BRFlag_Ghost_Character); }break; } S.write.x = S.shift_x + line_shift; - S.write.y += params.font->height; + S.write.y += S.write.font_height; } } } @@ -2152,8 +1923,8 @@ buffer_render_data(Buffer_Render_State *S_ptr, Buffer_Render_Params params, f32 } S.first_of_the_line = false; - if (S.tran.do_newline){ - S.write = write_render_item(S.write, S.tran.step_current.i, ' ', 0); + if (S.behavior.do_newline){ + S.write = write_render_item(S.write, S.step.i, ' ', 0); if (params.virtual_white){ S_stop.status = BLStatus_NeedLineShift; @@ -2168,18 +1939,18 @@ buffer_render_data(Buffer_Render_State *S_ptr, Buffer_Render_Params params, f32 ++S.wrap_line; S.write.x = S.shift_x + line_shift; - S.write.y += params.font->height; + S.write.y += S.write.font_height; S.first_of_the_line = true; } - else if (S.tran.do_codepoint_advance){ - u32 n = S.tran.step_current.value; + else if (S.behavior.do_codepoint_advance){ + u32 n = S.step.value; if (n != ' ' && n != '\t'){ S.skipping_whitespace = false; } if (!S.skipping_whitespace){ - u32 I = S.tran.step_current.i; + u32 I = S.step.i; switch (n){ case '\r': { @@ -2191,7 +1962,8 @@ buffer_render_data(Buffer_Render_State *S_ptr, Buffer_Render_Params params, f32 case '\t': { - S.ch_width = get_codepoint_advance(params.font, '\t'); + S.ch_width = font_get_glyph_advance(params.system, params.font, '\t'); + f32 new_x = S.write.x + S.ch_width; S.write = write_render_item(S.write, I, ' ', 0); S.write.x = new_x; @@ -2204,12 +1976,12 @@ buffer_render_data(Buffer_Render_State *S_ptr, Buffer_Render_Params params, f32 } } } - else if (S.tran.do_number_advance){ - u8 n = (u8)S.tran.step_current.value; - u32 I = S.tran.step_current.i; + else if (S.behavior.do_number_advance){ + u8 n = (u8)S.step.value; + u32 I = S.step.i; S.skipping_whitespace = false; - S.ch_width = params.font->byte_advance; + S.ch_width = S.byte_advance; f32 new_x = S.write.x + S.ch_width; u8 cs[3]; @@ -2229,7 +2001,7 @@ buffer_render_data(Buffer_Render_State *S_ptr, Buffer_Render_Params params, f32 S.write.x = new_x; } - if (!S.skipping_whitespace && !S.tran.do_newline){ + if (!S.skipping_whitespace && !S.behavior.do_newline){ S.first_of_the_line = false; } } diff --git a/4ed_buffer_model.h b/4ed_buffer_model.h new file mode 100644 index 00000000..86431e3c --- /dev/null +++ b/4ed_buffer_model.h @@ -0,0 +1,37 @@ +/* + * Mr. 4th Dimention - Allen Webster + * + * 18.03.2017 + * + * Abstract model for the describing the characters of a buffer. + * + */ + +// TOP + +#if !defined(FRED_BUFFER_MODEL_H) +#define FRED_BUFFER_MODEL_H + +struct Buffer_Model_Step{ + u32 type; + u32 value; + i32 i; + u32 byte_length; +}; + +struct Buffer_Model_Behavior{ + b32 do_newline; + b32 do_codepoint_advance; + b32 do_number_advance; +}; + +enum{ + BufferModelUnit_None, + BufferModelUnit_Codepoint, + BufferModelUnit_Numbers, +}; + +#endif + +// BOTTOM + diff --git a/file/4coder_file.cpp b/4ed_file.cpp similarity index 99% rename from file/4coder_file.cpp rename to 4ed_file.cpp index e6558cbe..6543dbcc 100644 --- a/file/4coder_file.cpp +++ b/4ed_file.cpp @@ -95,13 +95,14 @@ struct Editing_File_Settings{ i32 wrap_indicator; b32 dos_write_mode; b32 virtual_white; - i16 font_id; + Font_ID font_id; b8 unwrapped_lines; b8 tokens_exist; b8 is_initialized; b8 unimportant; b8 read_only; b8 never_kill; + u8 pad[2]; }; global_const Editing_File_Settings null_editing_file_settings = {0}; diff --git a/4ed_file_track.h b/4ed_file_track.h new file mode 100644 index 00000000..0ea2ac37 --- /dev/null +++ b/4ed_file_track.h @@ -0,0 +1,56 @@ +/* + * Mr. 4th Dimention - Allen Webster + * + * 20.07.2016 + * + * File tracking API. + * + */ + +// TOP + +#if !defined(FILE_TRACK_4TECH_H) +#define FILE_TRACK_4TECH_H + +#if !defined(FILE_TRACK_LINK) +# define FILE_TRACK_LINK static +#endif + +typedef struct{ + u8 opaque[128]; +} File_Track_System; + +typedef i32 File_Track_Result; +enum{ + FileTrack_Good, + FileTrack_MemoryTooSmall, + FileTrack_OutOfTableMemory, + FileTrack_OutOfListenerMemory, + FileTrack_NoMoreEvents, + FileTrack_FileSystemError +}; + +FILE_TRACK_LINK File_Track_Result +init_track_system(File_Track_System *system, Partition *scratch, void *table_memory, i32 table_memory_size, void *listener_memory, i32 listener_memory_size); + +FILE_TRACK_LINK File_Track_Result +add_listener(File_Track_System *system, Partition *scratch, u8 *filename); + +FILE_TRACK_LINK File_Track_Result +remove_listener(File_Track_System *system, Partition *scratch, u8 *filename); + +FILE_TRACK_LINK File_Track_Result +move_track_system(File_Track_System *system, Partition *scratch, void *mem, i32 size); + +FILE_TRACK_LINK File_Track_Result +expand_track_system_listeners(File_Track_System *system, Partition *scratch, void *mem, i32 size); + +FILE_TRACK_LINK File_Track_Result +get_change_event(File_Track_System *system, Partition *scratch, u8 *buffer, i32 max); + +FILE_TRACK_LINK File_Track_Result +shut_down_track_system(File_Track_System *system, Partition *scratch); + +#endif + +// BOTTOM diff --git a/filetrack/4tech_file_track_general.c b/4ed_file_track_general.cpp similarity index 71% rename from filetrack/4tech_file_track_general.c rename to 4ed_file_track_general.cpp index 4afff856..0d156cc1 100644 --- a/filetrack/4tech_file_track_general.c +++ b/4ed_file_track_general.cpp @@ -1,45 +1,33 @@ /* - -Copy Right FourTech LLC, 2016 -All Rights Are Reserved - -The OS agnostic file tracking API for applications -that want to interact with potentially many files on -the disk that could be changed by other applications. - -Created on: 27.08.2016 - -*/ - + * Mr. 4th Dimention - Allen Webster + * + * 20.08.2016 + * + * File tracking shared. + * + */ // TOP -#ifndef Assert -# define Assert(c) do { if (!(c)) { *((int*)0) = 0xA11E; } } while (0) -#endif - -#ifndef ZeroStruct -# define ZeroStruct(s) for (int32_t i = 0; i < sizeof(s); ++i) { ((char*)(&(s)))[i] = 0; } -#endif - typedef struct{ - uint32_t id[4]; + u32 id[4]; } File_Index; -typedef uint32_t rptr32; +typedef u32 rptr32; #define to_ptr(b,p) ((void*)((char*)b + p)) #define to_rptr32(b,p) ((rptr32)((char*)(p) - (char*)(b))) typedef struct { File_Index hash; - uint32_t opaque[4]; + u32 opaque[4]; } File_Track_Entry; +global_const File_Track_Entry null_file_track_entry = {0}; typedef struct { - int32_t size; - uint32_t tracked_count; - uint32_t max; + i32 size; + u32 tracked_count; + u32 max; rptr32 file_table; } File_Track_Tables; @@ -50,13 +38,13 @@ typedef struct DLL_Node { -static File_Index +internal File_Index zero_file_index(){ File_Index a = {0}; return(a); } -static int32_t +internal i32 file_hash_is_zero(File_Index a){ return ((a.id[0] == 0) && (a.id[1] == 0) && @@ -64,7 +52,7 @@ file_hash_is_zero(File_Index a){ (a.id[3] == 0)); } -static int32_t +internal i32 file_hash_is_deleted(File_Index a){ return ((a.id[0] == 0xFFFFFFFF) && (a.id[1] == 0xFFFFFFFF) && @@ -72,7 +60,7 @@ file_hash_is_deleted(File_Index a){ (a.id[3] == 0xFFFFFFFF)); } -static int32_t +internal i32 file_index_eq(File_Index a, File_Index b){ return ((a.id[0] == b.id[0]) && (a.id[1] == b.id[1]) && @@ -80,7 +68,7 @@ file_index_eq(File_Index a, File_Index b){ (a.id[3] == b.id[3])); } -static void +internal void insert_node(DLL_Node *pos, DLL_Node *node){ node->prev = pos; node->next = pos->next; @@ -88,19 +76,19 @@ insert_node(DLL_Node *pos, DLL_Node *node){ node->next->prev = node; } -static void +internal void remove_node(DLL_Node *node){ node->next->prev = node->prev; node->prev->next = node->next; } -static void +internal void init_sentinel_node(DLL_Node *node){ node->next = node; node->prev = node; } -static DLL_Node* +internal DLL_Node* allocate_node(DLL_Node *sentinel){ DLL_Node *result = 0; if (sentinel->next != sentinel){ @@ -113,17 +101,17 @@ allocate_node(DLL_Node *sentinel){ #define FILE_ENTRY_COST (sizeof(File_Track_Entry)) -static int32_t -tracking_system_has_space(File_Track_Tables *tables, int32_t new_count){ - uint32_t count = tables->tracked_count; - uint32_t max = tables->max; - int32_t result = ((count + new_count)*8 < max*7); +internal i32 +tracking_system_has_space(File_Track_Tables *tables, i32 new_count){ + u32 count = tables->tracked_count; + u32 max = tables->max; + i32 result = ((count + new_count)*8 < max*7); return(result); } -static int32_t +internal i32 entry_is_available(File_Track_Entry *entry){ - int32_t result = 0; + i32 result = 0; if (entry){ result = file_hash_is_zero(entry->hash) || @@ -132,12 +120,12 @@ entry_is_available(File_Track_Entry *entry){ return (result); } -static File_Track_Entry* +internal File_Track_Entry* tracking_system_lookup_entry(File_Track_Tables *tables, File_Index key){ - uint32_t hash = key.id[0]; - uint32_t max = tables->max; - uint32_t index = (hash) % max; - uint32_t start = index; + u32 hash = key.id[0]; + u32 max = tables->max; + u32 index = (hash) % max; + u32 start = index; File_Track_Entry *entries = (File_Track_Entry*)to_ptr(tables, tables->file_table); @@ -169,7 +157,7 @@ tracking_system_lookup_entry(File_Track_Tables *tables, File_Index key){ return(result); } -static File_Track_Entry* +internal File_Track_Entry* get_file_entry(File_Track_Tables *tables, File_Index index){ File_Track_Entry *entry = 0; @@ -181,11 +169,11 @@ get_file_entry(File_Track_Tables *tables, File_Index index){ return(entry); } -static void +internal void internal_free_slot(File_Track_Tables *tables, File_Track_Entry *entry){ Assert(!entry_is_available(entry)); - ZeroStruct(*entry); + *entry = null_file_track_entry; entry->hash.id[0] = 0xFFFFFFFF; entry->hash.id[1] = 0xFFFFFFFF; entry->hash.id[2] = 0xFFFFFFFF; @@ -194,27 +182,26 @@ internal_free_slot(File_Track_Tables *tables, File_Track_Entry *entry){ --tables->tracked_count; } -static int32_t -enough_memory_to_init_table(int32_t table_memory_size){ - int32_t result = (sizeof(File_Track_Tables) + FILE_ENTRY_COST*8 <= table_memory_size); +internal i32 +enough_memory_to_init_table(i32 table_memory_size){ + i32 result = (sizeof(File_Track_Tables) + FILE_ENTRY_COST*8 <= table_memory_size); return(result); } -static void -init_table_memory(File_Track_Tables *tables, int32_t table_memory_size){ +internal void +init_table_memory(File_Track_Tables *tables, i32 table_memory_size){ tables->size = table_memory_size; tables->tracked_count = 0; - int32_t max_number_of_entries = - (table_memory_size - sizeof(*tables)) / FILE_ENTRY_COST; + i32 max_number_of_entries = (table_memory_size - sizeof(*tables)) / FILE_ENTRY_COST; tables->file_table = sizeof(*tables); tables->max = max_number_of_entries; } -static File_Track_Result +internal File_Track_Result move_table_memory(File_Track_Tables *original_tables, - void *mem, int32_t size){ + void *mem, i32 size){ File_Track_Result result = FileTrack_Good; if (original_tables->size < size){ @@ -224,24 +211,22 @@ move_table_memory(File_Track_Tables *original_tables, { tables->size = size; - int32_t likely_entry_size = FILE_ENTRY_COST; - int32_t max_number_of_entries = (size - sizeof(*tables)) / likely_entry_size; + i32 likely_entry_size = FILE_ENTRY_COST; + i32 max_number_of_entries = (size - sizeof(*tables)) / likely_entry_size; tables->file_table = sizeof(*tables); tables->max = max_number_of_entries; } if (tables->max > original_tables->max){ - uint32_t original_max = original_tables->max; + u32 original_max = original_tables->max; // NOTE(allen): Rehash the tracking table { File_Track_Entry *entries = (File_Track_Entry*) to_ptr(original_tables, original_tables->file_table); - for (uint32_t index = 0; - index < original_max; - ++index){ + for (u32 index = 0; index < original_max; ++index){ File_Track_Entry *entry = entries + index; if (!entry_is_available(entry)){ File_Index hash = entry->hash; @@ -267,4 +252,5 @@ move_table_memory(File_Track_Tables *original_tables, return(result); } -// BOTTOM \ No newline at end of file +// BOTTOM + diff --git a/4ed_file_view.cpp b/4ed_file_view.cpp index 13486f21..0ab0ab0c 100644 --- a/4ed_file_view.cpp +++ b/4ed_file_view.cpp @@ -186,11 +186,7 @@ struct Debug_Vars{ i32 mode; i32 inspecting_view_id; }; -inline Debug_Vars -debug_vars_zero(){ - Debug_Vars vars = {0}; - return(vars); -} +global_const Debug_Vars null_debug_vars = {0}; struct View{ View_Persistent persistent; @@ -229,7 +225,6 @@ struct View{ // theme stuff View *hot_file_view; u32 *palette; - i32 palette_size; Color_View_Mode color_mode; Super_Color color; b32 p4c_only; @@ -385,16 +380,18 @@ view_cursor_limits(View *view){ } internal Full_Cursor -view_compute_cursor(View *view, Buffer_Seek seek, b32 return_hint){ +view_compute_cursor(System_Functions *system, View *view, Buffer_Seek seek, b32 return_hint){ Editing_File *file = view->file_data.file; - Models *models = view->persistent.models; - Render_Font *font = get_font_info(models->font_set, file->settings.font_id)->font; + + Render_Font *font = system->font.get_render_data_by_id(file->settings.font_id); + Assert(font != 0); Full_Cursor result = {0}; Buffer_Cursor_Seek_Params params; params.buffer = &file->state.buffer; params.seek = seek; + params.system = system; params.font = font; params.wrap_line_index = file->state.wrap_line_index; params.character_starts = file->state.character_starts; @@ -458,7 +455,7 @@ view_compute_cursor(View *view, Buffer_Seek seek, b32 return_hint){ } inline Full_Cursor -view_compute_cursor_from_xy(View *view, f32 seek_x, f32 seek_y){ +view_compute_cursor_from_xy(System_Functions *system, View *view, f32 seek_x, f32 seek_y){ Buffer_Seek seek; if (view->file_data.file->settings.unwrapped_lines){ seek = seek_unwrapped_xy(seek_x, seek_y, 0); @@ -467,7 +464,7 @@ view_compute_cursor_from_xy(View *view, f32 seek_x, f32 seek_y){ seek = seek_wrapped_xy(seek_x, seek_y, 0); } - Full_Cursor result = view_compute_cursor(view, seek, 0); + Full_Cursor result = view_compute_cursor(system, view, seek, 0); return(result); } @@ -553,8 +550,7 @@ view_move_view_to_cursor(View *view, GUI_Scroll_Vars *scroll, b32 center_view){ } internal b32 -view_move_cursor_to_view(View *view, GUI_Scroll_Vars scroll, - Full_Cursor *cursor, f32 preferred_x){ +view_move_cursor_to_view(System_Functions *system, View *view, GUI_Scroll_Vars scroll, Full_Cursor *cursor, f32 preferred_x){ b32 result = 0; if (view->edit_pos){ @@ -583,8 +579,7 @@ view_move_cursor_to_view(View *view, GUI_Scroll_Vars scroll, cursor_y -= line_height; } - *cursor = view_compute_cursor_from_xy( - view, preferred_x, cursor_y); + *cursor = view_compute_cursor_from_xy(system, view, preferred_x, cursor_y); result = 1; } @@ -605,12 +600,11 @@ view_set_cursor(View *view, Full_Cursor cursor, b32 set_preferred_x, b32 unwrapp } internal void -view_set_scroll(View *view, GUI_Scroll_Vars scroll){ +view_set_scroll(System_Functions *system, View *view, GUI_Scroll_Vars scroll){ if (edit_pos_move_to_front(view->file_data.file, view->edit_pos)){ edit_pos_set_scroll(view->edit_pos, scroll); Full_Cursor cursor = view->edit_pos->cursor; - if (view_move_cursor_to_view(view, view->edit_pos->scroll, - &cursor, view->edit_pos->preferred_x)){ + if (view_move_cursor_to_view(system, view, view->edit_pos->scroll, &cursor, view->edit_pos->preferred_x)){ view->edit_pos->cursor = cursor; } } @@ -627,13 +621,12 @@ view_set_cursor_and_scroll(View *view, Full_Cursor cursor, b32 set_preferred_x, } inline void -view_set_temp_highlight(View *view, i32 pos, i32 end_pos){ - view->file_data.temp_highlight = view_compute_cursor(view, seek_pos(pos), 0); +view_set_temp_highlight(System_Functions *system, View *view, i32 pos, i32 end_pos){ + view->file_data.temp_highlight = view_compute_cursor(system, view, seek_pos(pos), 0); view->file_data.temp_highlight_end_pos = end_pos; view->file_data.show_temp_highlight = 1; - view_set_cursor(view, view->file_data.temp_highlight, - 0, view->file_data.file->settings.unwrapped_lines); + view_set_cursor(view, view->file_data.temp_highlight, 0, view->file_data.file->settings.unwrapped_lines); } struct View_And_ID{ @@ -881,7 +874,7 @@ file_grow_starts_as_needed(General_Memory *general, Gap_Buffer *buffer, i32 addi } internal void -file_update_cursor_positions(Models *models, Editing_File *file){ +file_update_cursor_positions(System_Functions *system, Models *models, Editing_File *file){ Editing_Layout *layout = &models->layout; for (View_Iter iter = file_view_iter_init(layout, file, 0); file_view_iter_good(iter); @@ -889,11 +882,11 @@ file_update_cursor_positions(Models *models, Editing_File *file){ i32 pos = view_get_cursor_pos(iter.view); if (!iter.view->file_data.show_temp_highlight){ - Full_Cursor cursor = view_compute_cursor(iter.view, seek_pos(pos), 0); + Full_Cursor cursor = view_compute_cursor(system, iter.view, seek_pos(pos), 0); view_set_cursor(iter.view, cursor, 1, iter.view->file_data.file->settings.unwrapped_lines); } else{ - view_set_temp_highlight(iter.view, pos, iter.view->file_data.temp_highlight_end_pos); + view_set_temp_highlight(system, iter.view, pos, iter.view->file_data.temp_highlight_end_pos); } } } @@ -957,10 +950,11 @@ file_allocate_character_starts_as_needed(General_Memory *general, Editing_File * } internal void -file_measure_character_starts(Models *models, Editing_File *file){ +file_measure_character_starts(System_Functions *system, Models *models, Editing_File *file){ file_allocate_character_starts_as_needed(&models->mem.general, file); - buffer_measure_character_starts(&file->state.buffer, file->state.character_starts, 0, file->settings.virtual_white); - file_update_cursor_positions(models, file); + Render_Font *font = system->font.get_render_data_by_id(file->settings.font_id); + buffer_measure_character_starts(system, font, &file->state.buffer, file->state.character_starts, 0, file->settings.virtual_white); + file_update_cursor_positions(system, models, file); } internal void @@ -1011,12 +1005,17 @@ struct Code_Wrap_State{ Render_Font *font; f32 tab_indent_amount; + f32 byte_advance; - Buffer_Translating_State tran; + Translation_State tran; + Translation_Emits emits; + u32 J; + Buffer_Model_Step step; + Buffer_Model_Behavior behavior; }; internal void -wrap_state_init(Code_Wrap_State *state, Editing_File *file, Render_Font *font){ +wrap_state_init(System_Functions *system, Code_Wrap_State *state, Editing_File *file, Render_Font *font){ state->token_array = file->state.token_array; state->token_ptr = state->token_array.tokens; state->end_token = state->token_ptr + state->token_array.count; @@ -1031,7 +1030,9 @@ wrap_state_init(Code_Wrap_State *state, Editing_File *file, Render_Font *font){ state->i = 0; state->font = font; - state->tab_indent_amount = get_codepoint_advance(font, '\t'); + + state->tab_indent_amount = font_get_glyph_advance(system, font, '\t'); + state->byte_advance = font_get_byte_advance(font); state->tran = null_buffer_translating_state; } @@ -1064,7 +1065,7 @@ struct Code_Wrap_Step{ }; internal Code_Wrap_Step -wrap_state_consume_token(Code_Wrap_State *state, i32 fixed_end_point){ +wrap_state_consume_token(System_Functions *system, Render_Font *font, Code_Wrap_State *state, i32 fixed_end_point){ Code_Wrap_Step result = {0}; i32 i = state->i; @@ -1112,9 +1113,7 @@ wrap_state_consume_token(Code_Wrap_State *state, i32 fixed_end_point){ end = fixed_end_point; } - if (i < line_start){ - i = line_start; - } + i = clamp_top(i, line_start); if (i == line_start){ skipping_whitespace = true; @@ -1129,27 +1128,27 @@ wrap_state_consume_token(Code_Wrap_State *state, i32 fixed_end_point){ } u8 ch = (u8)state->stream.data[i]; + translating_fully_process_byte(system, font, &state->tran, ch, i, state->size, &state->emits); - translating_consume_byte(&state->tran, ch, i, state->size); - - for (TRANSLATION_OUTPUT(&state->tran)){ - TRANSLATION_GET_STEP(&state->tran); + for (TRANSLATION_EMIT_LOOP(state->J, state->emits)){ + TRANSLATION_GET_STEP(state->step, state->behavior, state->J, state->emits); - if (state->tran.do_newline){ + if (state->behavior.do_newline){ state->consume_newline = 1; goto doublebreak; } - else if(state->tran.do_number_advance || state->tran.do_codepoint_advance){ - u32 n = state->tran.step_current.value; + else if(state->behavior.do_number_advance || state->behavior.do_codepoint_advance){ + u32 n = state->step.value; f32 adv = 0; - if (state->tran.do_codepoint_advance){ - adv = get_codepoint_advance(state->font, n); + if (state->behavior.do_codepoint_advance){ + adv = font_get_glyph_advance(system, state->font, n); + if (n != ' ' && n != '\t'){ skipping_whitespace = false; } } else{ - adv = state->font->byte_advance; + adv = state->byte_advance; skipping_whitespace = false; } @@ -1389,24 +1388,28 @@ stickieness_guess(Cpp_Token_Type type, Cpp_Token_Type other_type, u16 flags, u16 return(guess); } -internal f32 -get_current_shift(Code_Wrap_State *wrap_state, i32 next_line_start, b32 *adjust_top_to_this){ - f32 current_shift = wrap_state->wrap_x.paren_nesting[wrap_state->wrap_x.paren_safe_top]; +struct Wrap_Current_Shift{ + f32 shift; + b32 adjust_top_to_this; +}; + +internal Wrap_Current_Shift +get_current_shift(Code_Wrap_State *wrap_state, i32 next_line_start){ + Wrap_Current_Shift result = {0}; + + result.shift = wrap_state->wrap_x.paren_nesting[wrap_state->wrap_x.paren_safe_top]; - Assert(adjust_top_to_this != 0); if (wrap_state->token_ptr > wrap_state->token_array.tokens){ Cpp_Token prev_token = *(wrap_state->token_ptr-1); if (wrap_state->wrap_x.paren_safe_top != 0 && prev_token.type == CPP_TOKEN_PARENTHESE_OPEN){ - current_shift = wrap_state->wrap_x.paren_nesting[wrap_state->wrap_x.paren_safe_top-1] + wrap_state->tab_indent_amount; - - *adjust_top_to_this = 1; + result.shift = wrap_state->wrap_x.paren_nesting[wrap_state->wrap_x.paren_safe_top-1] + wrap_state->tab_indent_amount; + result.adjust_top_to_this = 1; } f32 statement_continuation_indent = 0.f; - if (current_shift != 0.f && wrap_state->wrap_x.paren_safe_top == 0){ - if (!(prev_token.flags & CPP_TFLAG_PP_BODY) && !(prev_token.flags & CPP_TFLAG_PP_DIRECTIVE)){ - + if (result.shift != 0.f && wrap_state->wrap_x.paren_safe_top == 0){ + if (!(prev_token.flags & (CPP_TFLAG_PP_DIRECTIVE|CPP_TFLAG_PP_BODY))){ switch (prev_token.type){ case CPP_TOKEN_BRACKET_OPEN: case CPP_TOKEN_BRACE_OPEN: @@ -1422,31 +1425,32 @@ get_current_shift(Code_Wrap_State *wrap_state, i32 next_line_start, b32 *adjust_ switch (wrap_state->token_ptr->type){ case CPP_TOKEN_BRACE_CLOSE: case CPP_TOKEN_BRACE_OPEN: break; - default: current_shift += statement_continuation_indent; break; + default: result.shift += statement_continuation_indent; break; } } if (wrap_state->token_ptr->start < next_line_start){ if (wrap_state->token_ptr->flags & CPP_TFLAG_PP_DIRECTIVE){ - current_shift = 0; + result.shift = 0; } else{ switch (wrap_state->token_ptr->type){ case CPP_TOKEN_BRACE_CLOSE: { if (wrap_state->wrap_x.paren_safe_top == 0){ - current_shift -= wrap_state->tab_indent_amount; + result.shift -= wrap_state->tab_indent_amount; } }break; } } } - return(current_shift); + result.shift = clamp_bottom(0.f, result.shift); + return(result); } internal void -file_measure_wraps(Models *models, Editing_File *file, Render_Font *font){ +file_measure_wraps(System_Functions *system, Models *models, Editing_File *file, Render_Font *font){ General_Memory *general = &models->mem.general; Partition *part = &models->mem.part; @@ -1459,6 +1463,7 @@ file_measure_wraps(Models *models, Editing_File *file, Render_Font *font){ Buffer_Measure_Wrap_Params params; params.buffer = &file->state.buffer; params.wrap_line_index = file->state.wrap_line_index; + params.system = system; params.font = font; params.virtual_white = file->settings.virtual_white; @@ -1475,7 +1480,7 @@ file_measure_wraps(Models *models, Editing_File *file, Render_Font *font){ edge_tolerance = width; } - f32 line_shift = 0.f; + f32 current_line_shift = 0.f; b32 do_wrap = 0; i32 wrap_unit_end = 0; @@ -1491,7 +1496,7 @@ file_measure_wraps(Models *models, Editing_File *file, Render_Font *font){ i32 max_wrap_indent_mark = 0; if (params.virtual_white && file->state.tokens_complete && !file->state.still_lexing){ - wrap_state_init(&wrap_state, file, font); + wrap_state_init(system, &wrap_state, file, font); use_tokens = true; potential_marks = push_array(part, Potential_Wrap_Indent_Pair, floor32(width)); @@ -1505,7 +1510,7 @@ file_measure_wraps(Models *models, Editing_File *file, Render_Font *font){ i32 stage = 0; do{ - stop = buffer_measure_wrap_y(&state, params, line_shift, do_wrap, wrap_unit_end); + stop = buffer_measure_wrap_y(&state, params, current_line_shift, do_wrap, wrap_unit_end); switch (stop.status){ case BLStatus_NeedWrapDetermination: @@ -1543,7 +1548,8 @@ file_measure_wraps(Models *models, Editing_File *file, Render_Font *font){ word_stage = 1; } else{ - f32 adv = get_codepoint_advance(params.font, ch); + f32 adv = font_get_glyph_advance(params.system, params.font, ch); + x += adv; self_x += adv; if (self_x > width){ @@ -1600,15 +1606,15 @@ file_measure_wraps(Models *models, Editing_File *file, Render_Font *font){ potential_count = 0; stage = 0; - b32 adjust_top_to_this = 0; - f32 current_shift = get_current_shift(&wrap_state, next_line_start, &adjust_top_to_this); + Wrap_Current_Shift current_shift = get_current_shift(&wrap_state, next_line_start); - if (adjust_top_to_this){ - wrap_state_set_top(&wrap_state, current_shift); + + if (current_shift.adjust_top_to_this){ + wrap_state_set_top(&wrap_state, current_shift.shift); } wrap_indent_marks[real_count].wrap_position = 0; - wrap_indent_marks[real_count].line_shift = clamp_bottom(0.f, current_shift); + wrap_indent_marks[real_count].line_shift =current_shift.shift; ++real_count; wrap_state.wrap_x.base_x = wrap_state.wrap_x.paren_nesting[0]; @@ -1670,7 +1676,7 @@ file_measure_wraps(Models *models, Editing_File *file, Render_Font *font){ goto doublebreak_stage1; } - f32 adv = get_codepoint_advance(params.font, ch); + f32 adv = font_get_glyph_advance(params.system, params.font, ch); x += adv; if (!first_word && x > current_width){ emit_comment_position = 1; @@ -1696,7 +1702,9 @@ file_measure_wraps(Models *models, Editing_File *file, Render_Font *font){ goto doublebreak_stage2; } - f32 adv = get_codepoint_advance(params.font, ch); + + f32 adv = font_get_glyph_advance(params.system, params.font, ch); + x += adv; } still_looping = buffer_stringify_next(&stream); @@ -1716,7 +1724,7 @@ file_measure_wraps(Models *models, Editing_File *file, Render_Font *font){ } if (!emit_comment_position){ - step = wrap_state_consume_token(&wrap_state, next_line_start-1); + step = wrap_state_consume_token(system, font, &wrap_state, next_line_start-1); } b32 need_to_choose_a_wrap = 0; @@ -1724,18 +1732,17 @@ file_measure_wraps(Models *models, Editing_File *file, Render_Font *font){ need_to_choose_a_wrap = 1; } - adjust_top_to_this = 0; - current_shift = get_current_shift(&wrap_state, next_line_start, &adjust_top_to_this); + current_shift = get_current_shift(&wrap_state, next_line_start); b32 next_token_is_on_line = 0; if (wrap_state.token_ptr->start < next_line_start){ next_token_is_on_line = 1; } - i32 wrap_position = step.position_end; + i32 next_wrap_position = step.position_end; f32 wrap_x = step.final_x; - if (wrap_state.token_ptr->start > step.position_start && wrap_position < wrap_state.token_ptr->start && next_token_is_on_line){ - wrap_position = wrap_state.token_ptr->start; + if (wrap_state.token_ptr->start > step.position_start && next_wrap_position < wrap_state.token_ptr->start && next_token_is_on_line){ + next_wrap_position = wrap_state.token_ptr->start; } if (!need_to_choose_a_wrap){ @@ -1778,18 +1785,18 @@ file_measure_wraps(Models *models, Editing_File *file, Render_Font *font){ wrappable_score = 64*50; wrappable_score += 101 - general_stickieness - wrap_state.wrap_x.paren_safe_top*80; - potential_marks[potential_count].wrap_position = wrap_position; - potential_marks[potential_count].line_shift = current_shift; + potential_marks[potential_count].wrap_position = next_wrap_position; + potential_marks[potential_count].line_shift = current_shift.shift; potential_marks[potential_count].wrappable_score = wrappable_score; potential_marks[potential_count].wrap_x = wrap_x; - potential_marks[potential_count].adjust_top_to_this = adjust_top_to_this; + potential_marks[potential_count].adjust_top_to_this = current_shift.adjust_top_to_this; ++potential_count; } if (need_to_choose_a_wrap){ if (potential_count == 0){ - wrap_indent_marks[real_count].wrap_position = wrap_position; - wrap_indent_marks[real_count].line_shift = current_shift; + wrap_indent_marks[real_count].wrap_position = next_wrap_position; + wrap_indent_marks[real_count].line_shift = current_shift.shift; ++real_count; } else{ @@ -1834,7 +1841,7 @@ file_measure_wraps(Models *models, Editing_File *file, Render_Font *font){ wrap_state = original_wrap_state; for (;;){ - step = wrap_state_consume_token(&wrap_state, wrap_position); + step = wrap_state_consume_token(system, font, &wrap_state, wrap_position); if (step.position_end >= wrap_position){ break; } @@ -1860,34 +1867,29 @@ file_measure_wraps(Models *models, Editing_File *file, Render_Font *font){ ++real_count; for (i32 l = 0; wrap_state.i < next_line_start && l < 3; ++l){ - wrap_state_consume_token(&wrap_state, next_line_start); + wrap_state_consume_token(system, font, &wrap_state, next_line_start); } } - line_shift = wrap_indent_marks[stage].line_shift; + current_line_shift = wrap_indent_marks[stage].line_shift; if (stage > 0){ ++stage; } - if (line_shift < 0){ - line_shift = 0; - } - + current_line_shift = clamp_bottom(0.f, current_line_shift); } else{ - line_shift = 0.f; + current_line_shift = 0.f; } - if (line_shift > current_width - edge_tolerance){ - line_shift = current_width - edge_tolerance; - } + current_line_shift = clamp_top(current_line_shift, current_width - edge_tolerance); if (stop.wrap_line_index >= file->state.line_indent_max){ file_allocate_indents_as_needed(general, file, stop.wrap_line_index); } - file->state.line_indents[stop.wrap_line_index] = line_shift; + file->state.line_indents[stop.wrap_line_index] = current_line_shift; file->state.wrap_line_count = stop.wrap_line_index; }break; } @@ -1903,21 +1905,21 @@ file_measure_wraps(Models *models, Editing_File *file, Render_Font *font){ } internal void -file_measure_wraps_and_fix_cursor(Models *models, Editing_File *file, Render_Font *font){ - file_measure_wraps(models, file, font); - file_update_cursor_positions(models, file); +file_measure_wraps_and_fix_cursor(System_Functions *system, Models *models, Editing_File *file, Render_Font *font){ + file_measure_wraps(system, models, file, font); + file_update_cursor_positions(system, models, file); } internal void -file_set_width(Models *models, Editing_File *file, i32 display_width, Render_Font *font){ +file_set_width(System_Functions *system, Models *models, Editing_File *file, i32 display_width, Render_Font *font){ file->settings.display_width = display_width; - file_measure_wraps_and_fix_cursor(models, file, font); + file_measure_wraps_and_fix_cursor(system, models, file, font); } internal void -file_set_min_base_width(Models *models, Editing_File *file, i32 minimum_base_display_width, Render_Font *font){ +file_set_min_base_width(System_Functions *system, Models *models, Editing_File *file, i32 minimum_base_display_width, Render_Font *font){ file->settings.minimum_base_display_width = minimum_base_display_width; - file_measure_wraps_and_fix_cursor(models, file, font); + file_measure_wraps_and_fix_cursor(system, models, file, font); } // @@ -1927,7 +1929,7 @@ file_set_min_base_width(Models *models, Editing_File *file, i32 minimum_base_dis internal void file_create_from_string(System_Functions *system, Models *models, Editing_File *file, String val, b8 read_only = 0){ - Font_Set *font_set = models->font_set; + //Font_Set *font_set = models->font_set; General_Memory *general = &models->mem.general; Partition *part = &models->mem.part; Open_File_Hook_Function *hook_open_file = models->hook_open_file; @@ -1955,18 +1957,16 @@ file_create_from_string(System_Functions *system, Models *models, Editing_File * } file_synchronize_times(system, file); - // TODO(allen): batch some of these together so we can avoid - // making so many passes over the buffer? + Font_ID font_id = models->global_font_id; + file->settings.font_id = font_id; + Render_Font *font = system->font.get_render_data_by_id(font_id); + file_measure_starts(general, &file->state.buffer); file_allocate_character_starts_as_needed(general, file); - buffer_measure_character_starts(&file->state.buffer, file->state.character_starts, 0, file->settings.virtual_white); + buffer_measure_character_starts(system, font, &file->state.buffer, file->state.character_starts, 0, file->settings.virtual_white); - i16 font_id = models->global_font.font_id; - file->settings.font_id = font_id; - Render_Font *font = get_font_info(font_set, font_id)->font; - - file_measure_wraps(models, file, font); + file_measure_wraps(system, models, file, font); file->settings.read_only = read_only; if (!read_only){ @@ -2774,9 +2774,9 @@ file_view_nullify_file(View *view){ } internal void -update_view_line_height(Models *models, View *view, i16 font_id){ - Render_Font *font = get_font_info(models->font_set, font_id)->font; - view->line_height = font->height; +update_view_line_height(System_Functions *system, Models *models, View *view, Font_ID font_id){ + Render_Font *font = system->font.get_render_data_by_id(font_id); + view->line_height = font_get_height(font); } inline void @@ -2786,13 +2786,13 @@ view_cursor_move(View *view, Full_Cursor cursor){ } inline void -view_cursor_move(View *view, i32 pos){ - Full_Cursor cursor = view_compute_cursor(view, seek_pos(pos), 0); +view_cursor_move(System_Functions *system, View *view, i32 pos){ + Full_Cursor cursor = view_compute_cursor(system, view, seek_pos(pos), 0); view_cursor_move(view, cursor); } inline void -view_cursor_move(View *view, f32 x, f32 y, b32 round_down = 0){ +view_cursor_move(System_Functions *system, View *view, f32 x, f32 y, b32 round_down = 0){ Buffer_Seek seek; if (view->file_data.file->settings.unwrapped_lines){ seek = seek_unwrapped_xy(x, y, round_down); @@ -2801,13 +2801,13 @@ view_cursor_move(View *view, f32 x, f32 y, b32 round_down = 0){ seek = seek_wrapped_xy(x, y, round_down); } - Full_Cursor cursor = view_compute_cursor(view, seek, 0); + Full_Cursor cursor = view_compute_cursor(system, view, seek, 0); view_cursor_move(view, cursor); } inline void -view_cursor_move(View *view, i32 line, i32 character){ - Full_Cursor cursor = view_compute_cursor(view, seek_line_char(line, character), 0); +view_cursor_move(System_Functions *system, View *view, i32 line, i32 character){ + Full_Cursor cursor = view_compute_cursor(system, view, seek_line_char(line, character), 0); view_cursor_move(view, cursor); } @@ -2828,7 +2828,7 @@ view_show_file(View *view){ } internal void -view_set_file(View *view, Editing_File *file, Models *models){ +view_set_file(System_Functions *system, View *view, Editing_File *file, Models *models){ Assert(file); if (view->file_data.file != 0){ @@ -2848,10 +2848,10 @@ view_set_file(View *view, Editing_File *file, Models *models){ edit_pos = edit_pos_get_new(file, view->persistent.id); view->edit_pos = edit_pos; - update_view_line_height(models, view, file->settings.font_id); + update_view_line_height(system, models, view, file->settings.font_id); if (edit_pos->cursor.line == 0){ - view_cursor_move(view, 0); + view_cursor_move(system, view, 0); } if (view->showing_ui == VUI_None){ @@ -2950,19 +2950,23 @@ file_update_history_before_edit(Mem_Options *mem, Editing_File *file, Edit_Step Edit_Step *redo_start = redo_end; i32 steps_of_redo = 0; i32 strings_of_redo = 0; - i32 undo_count = 0; - while (redo_start->type == ED_REDO || redo_start->type == ED_UNDO){ - if (redo_start->type == ED_REDO){ - if (undo_count > 0) --undo_count; - else{ - ++steps_of_redo; - strings_of_redo += redo_start->edit.len; + { + i32 undo_count = 0; + while (redo_start->type == ED_REDO || redo_start->type == ED_UNDO){ + if (redo_start->type == ED_REDO){ + if (undo_count > 0){ + --undo_count; + } + else{ + ++steps_of_redo; + strings_of_redo += redo_start->edit.len; + } } + else{ + ++undo_count; + } + --redo_start; } - else{ - ++undo_count; - } - --redo_start; } if (redo_start < redo_end){ @@ -2982,31 +2986,33 @@ file_update_history_before_edit(Mem_Options *mem, Editing_File *file, Edit_Step Edit_Step *edit_src = redo_end; Edit_Step *edit_dest = file->state.undo.redo.edits + file->state.undo.redo.edit_count + steps_of_redo; - i32 undo_count = 0; - for (i32 i = 0; i < steps_of_redo;){ - --edit_src; - str_src -= edit_src->edit.len; - if (edit_src->type == ED_REDO){ - if (undo_count > 0){ - --undo_count; + { + i32 undo_count = 0; + for (i32 i = 0; i < steps_of_redo;){ + --edit_src; + str_src -= edit_src->edit.len; + if (edit_src->type == ED_REDO){ + if (undo_count > 0){ + --undo_count; + } + else{ + ++i; + + --edit_dest; + *edit_dest = *edit_src; + + str_redo_pos -= edit_dest->edit.len; + edit_dest->edit.str_start = str_redo_pos; + + memcpy(str_dest_base + str_redo_pos, str_src, edit_dest->edit.len); + } } else{ - ++i; - - --edit_dest; - *edit_dest = *edit_src; - - str_redo_pos -= edit_dest->edit.len; - edit_dest->edit.str_start = str_redo_pos; - - memcpy(str_dest_base + str_redo_pos, str_src, edit_dest->edit.len); + ++undo_count; } } - else{ - ++undo_count; - } + Assert(undo_count == 0); } - Assert(undo_count == 0); file->state.undo.redo.size += strings_of_redo; file->state.undo.redo.edit_count += steps_of_redo; @@ -3154,7 +3160,7 @@ file_edit_cursor_fix(System_Functions *system, Models *models, Editing_File *fil Assert(view->edit_pos); i32 cursor_pos = cursors[cursor_count++].pos; - Full_Cursor new_cursor = view_compute_cursor(view, seek_pos(cursor_pos), 0); + Full_Cursor new_cursor = view_compute_cursor(system, view, seek_pos(cursor_pos), 0); GUI_Scroll_Vars scroll = view->edit_pos->scroll; @@ -3163,7 +3169,7 @@ file_edit_cursor_fix(System_Functions *system, Models *models, Editing_File *fil if (view->edit_pos->scroll_i != new_scroll_i){ view->edit_pos->scroll_i = new_scroll_i; - Full_Cursor temp_cursor = view_compute_cursor(view, seek_pos(view->edit_pos->scroll_i), 0); + Full_Cursor temp_cursor = view_compute_cursor(system, view, seek_pos(view->edit_pos->scroll_i), 0); f32 y_offset = MOD(view->edit_pos->scroll.scroll_y, view->line_height); f32 y_position = temp_cursor.wrapped_y; @@ -3224,8 +3230,7 @@ file_do_single_edit(System_Functions *system, Models *models, Editing_File *file Assert(scratch_size > 0); i32 request_amount = 0; Assert(end <= buffer_size(&file->state.buffer)); - while (buffer_replace_range(&file->state.buffer, start, end, str, str_len, &shift_amount, - part->base + part->pos, scratch_size, &request_amount)){ + while (buffer_replace_range(&file->state.buffer, start, end, str, str_len, &shift_amount, part->base + part->pos, scratch_size, &request_amount)){ void *new_data = 0; if (request_amount > 0){ new_data = general_memory_allocate(general, request_amount); @@ -3254,12 +3259,12 @@ file_do_single_edit(System_Functions *system, Models *models, Editing_File *file i32 new_line_count = buffer_count_newlines(&file->state.buffer, start, start+str_len); i32 line_shift = new_line_count - replaced_line_count; - Render_Font *font = get_font_info(models->font_set, file->settings.font_id)->font; + Render_Font *font = system->font.get_render_data_by_id(file->settings.font_id); file_grow_starts_as_needed(general, buffer, line_shift); buffer_remeasure_starts(buffer, line_start, line_end, line_shift, shift_amount); file_allocate_character_starts_as_needed(general, file); - buffer_remeasure_character_starts(buffer, line_start, line_end, line_shift, file->state.character_starts, 0, file->settings.virtual_white); + buffer_remeasure_character_starts(system, font, buffer, line_start, line_end, line_shift, file->state.character_starts, 0, file->settings.virtual_white); // TODO(allen): Redo this as some sort of dialogical API #if 0 @@ -3267,7 +3272,7 @@ file_do_single_edit(System_Functions *system, Models *models, Editing_File *file buffer_remeasure_wrap_y(buffer, line_start, line_end, line_shift, file->state.wraps, (f32)font->height, font->advance_data, (f32)file->settings.display_width); #endif - file_measure_wraps(models, file, font); + file_measure_wraps(system, models, file, font); // NOTE(allen): cursor fixing Cursor_Fix_Descriptor desc = {0}; @@ -3376,12 +3381,13 @@ file_do_batch_edit(System_Functions *system, Models *models, Editing_File *file, Buffer_Measure_Starts measure_state = {}; buffer_measure_starts(&measure_state, &file->state.buffer); + Render_Font *font = system->font.get_render_data_by_id(file->settings.font_id); + // TODO(allen): write the remeasurement version file_allocate_character_starts_as_needed(&models->mem.general, file); - buffer_measure_character_starts(&file->state.buffer, file->state.character_starts, 0, file->settings.virtual_white); + buffer_measure_character_starts(system, font, &file->state.buffer, file->state.character_starts, 0, file->settings.virtual_white); - Render_Font *font = get_font_info(models->font_set, file->settings.font_id)->font; - file_measure_wraps(models, file, font); + file_measure_wraps(system, models, file, font); // NOTE(allen): cursor fixing Cursor_Fix_Descriptor desc = {0}; @@ -3447,7 +3453,7 @@ apply_history_edit(System_Functions *system, Models *models, Editing_File *file, file_do_single_edit(system, models, file, spec, history_mode); if (view){ - view_cursor_move(view, step.edit.start + step.edit.len); + view_cursor_move(system, view, step.edit.start + step.edit.len); view->edit_pos->mark = view->edit_pos->cursor.pos; Style *style = main_style(models); @@ -3658,30 +3664,28 @@ style_get_color(Style *style, Cpp_Token token){ } internal void -file_set_font(Models *models, Editing_File *file, i16 font_id){ +file_set_font(System_Functions *system, Models *models, Editing_File *file, Font_ID font_id){ file->settings.font_id = font_id; - Font_Info *font_info = get_font_info(models->font_set, file->settings.font_id); - Render_Font *font = font_info->font; - file_measure_wraps_and_fix_cursor(models, file, font); + Render_Font *font = system->font.get_render_data_by_id(font_id); + file_measure_wraps_and_fix_cursor(system, models, file, font); Editing_Layout *layout = &models->layout; for (View_Iter iter = file_view_iter_init(layout, file, 0); file_view_iter_good(iter); iter = file_view_iter_next(iter)){ - update_view_line_height(models, iter.view, font_id); + update_view_line_height(system, models, iter.view, font_id); } } internal void -global_set_font(Models *models, i16 font_id){ +global_set_font(System_Functions *system, Models *models, Font_ID font_id){ File_Node *node = 0; File_Node *sentinel = &models->working_set.used_sentinel; for (dll_items(node, sentinel)){ Editing_File *file = (Editing_File*)node; - file_set_font(models, file, font_id); + file_set_font(system, models, file, font_id); } - - models->global_font.font_id = font_id; + models->global_font_id = font_id; } inline void @@ -3817,7 +3821,7 @@ view_open_file(System_Functions *system, Models *models, View *view, String file } if (file){ - view_set_file(view, file, models); + view_set_file(system, view, file, models); } } @@ -3858,7 +3862,7 @@ view_interactive_new_file(System_Functions *system, Models *models, View *view, } if (file){ - view_set_file(view, file, models); + view_set_file(system, view, file, models); } } @@ -3881,12 +3885,12 @@ kill_file(System_Functions *system, Models *models, Editing_File *file){ iter = file_view_iter_next(iter)){ if (node != used){ iter.view->file_data.file = 0; - view_set_file(iter.view, (Editing_File*)node, models); + view_set_file(system, iter.view, (Editing_File*)node, models); node = node->next; } else{ iter.view->file_data.file = 0; - view_set_file(iter.view, 0, models); + view_set_file(system, iter.view, 0, models); } } } @@ -3988,7 +3992,7 @@ interactive_view_complete(System_Functions *system, View *view, String dest, i32 { Editing_File *file = working_set_name_contains(&models->working_set, dest); if (file){ - view_set_file(view, file, models); + view_set_file(system, view, file, models); } view_show_file(view); }break; @@ -4122,17 +4126,13 @@ struct File_Bar{ f32 pos_x, pos_y; f32 text_shift_x, text_shift_y; i32_Rect rect; - i16 font_id; + Font_ID font_id; }; internal void -intbar_draw_string(Render_Target *target, File_Bar *bar, String str, u32 char_color){ - i16 font_id = bar->font_id; - draw_string(target, font_id, str, - (i32)(bar->pos_x + bar->text_shift_x), - (i32)(bar->pos_y + bar->text_shift_y), - char_color); - bar->pos_x += font_string_width(target, font_id, str); +intbar_draw_string(System_Functions *system, Render_Target *target, File_Bar *bar, String str, u32 char_color){ + draw_string(system, target, bar->font_id, str, (i32)(bar->pos_x + bar->text_shift_x), (i32)(bar->pos_y + bar->text_shift_y), char_color); + bar->pos_x += font_string_width(system, target, bar->font_id, str); } internal GUI_Scroll_Vars @@ -4696,102 +4696,104 @@ step_file_view(System_Functions *system, View *view, View *active_view, Input_Su switch (view->color_mode){ case CV_Mode_Library: - message = make_lit_string("Current Theme - Click to Edit"); - gui_do_text_field(target, message, empty_string); - - id.id[0] = (u64)(main_style(models)); - if (gui_do_style_preview(target, id, 0)){ - view->color_mode = CV_Mode_Adjusting; - } - - if (view->file_data.file){ - message = make_lit_string("Set Font"); - id.id[0] = (u64)(&view->file_data.file->settings.font_id); - - if (gui_do_button(target, id, message)){ - view->color_mode = CV_Mode_Font; - } - } - - message = make_lit_string("Set Global Font"); - id.id[0] = (u64)(&models->global_font); - - if (gui_do_button(target, id, message)){ - view->color_mode = CV_Mode_Global_Font; - } - - - - message = make_lit_string("Theme Library - Click to Select"); - gui_do_text_field(target, message, empty_string); - - gui_begin_scrollable(target, scroll_context, view->gui_scroll, - 9 * view->line_height, show_scrollbar); - { - i32 count = models->styles.count; - Style *style; - i32 i; + message = make_lit_string("Current Theme - Click to Edit"); + gui_do_text_field(target, message, empty_string); - for (i = 1; i < count; ++i, ++style){ - style = get_style(models, i); - id.id[0] = (u64)(style); - if (gui_do_style_preview(target, id, i)){ - style_copy(main_style(models), style); + id.id[0] = (u64)(main_style(models)); + if (gui_do_style_preview(target, id, 0)){ + view->color_mode = CV_Mode_Adjusting; + } + + if (view->file_data.file){ + message = make_lit_string("Set Font"); + id.id[0] = (u64)(&view->file_data.file->settings.font_id); + + if (gui_do_button(target, id, message)){ + view->color_mode = CV_Mode_Font; } } + + message = make_lit_string("Set Global Font"); + id.id[0] = (u64)(&models->global_font_id); + + if (gui_do_button(target, id, message)){ + view->color_mode = CV_Mode_Global_Font; + } + + message = make_lit_string("Theme Library - Click to Select"); + gui_do_text_field(target, message, empty_string); + + gui_begin_scrollable(target, scroll_context, view->gui_scroll, + 9 * view->line_height, show_scrollbar); + + { + i32 count = models->styles.count; + for (i32 i = 1; i < count; ++i){ + Style *style = get_style(models, i); + id.id[0] = (u64)(style); + if (gui_do_style_preview(target, id, i)){ + style_copy(main_style(models), style); + } + } + } + + gui_end_scrollable(target); } - - gui_end_scrollable(target); break; case CV_Mode_Global_Font: case CV_Mode_Font: { - Assert(view->file_data.file); + Editing_File *file = view->file_data.file; + Assert(file != 0); - Font_Set *font_set = models->font_set; - Font_Info *info = 0; - - i16 i = 1, count = (i16)models->font_set->count + 1; - - String message = make_lit_string("Back"); + message = make_lit_string("Back"); id.id[0] = 0; if (gui_do_button(target, id, message)){ view->color_mode = CV_Mode_Library; } - i16 font_id = models->global_font.font_id; + Font_ID font_id = models->global_font_id; if (view->color_mode == CV_Mode_Font){ - font_id = view->file_data.file->settings.font_id; + font_id = file->settings.font_id; } - i16 new_font_id = font_id; + // TODO(allen): paginate the display + Font_ID new_font_id = font_id; + u32 total_count = system->font.get_count(); + u32 count = Min(total_count, 10); - for (i = 1; i < count; ++i){ - info = get_font_info(font_set, i); - id.id[0] = (u64)i; - if (i != font_id){ - if (gui_do_font_button(target, id, i, info->name)){ - new_font_id = i; + for (u32 font_index = 0; font_index < count; ++font_index){ + Font_ID this_font_id = 0; + system->font.get_ids_by_index(font_index, 1, &this_font_id); + + char name_space[256]; + String name = make_fixed_width_string(name_space); + name.size = system->font.get_name_by_index(font_index, name.str, name.memory_size); + + id.id[0] = (u64)font_index + 1; + if (this_font_id != font_id){ + if (gui_do_font_button(target, id, this_font_id, name)){ + new_font_id = this_font_id; } } else{ char message_space[256]; message = make_fixed_width_string(message_space); copy_ss(&message, make_lit_string("currently selected: ")); - append_ss(&message, info->name); - gui_do_font_button(target, id, i, message); + append_ss(&message, name); + gui_do_font_button(target, id, this_font_id, message); } } if (font_id != new_font_id){ if (view->color_mode == CV_Mode_Font){ - file_set_font(models, view->file_data.file, new_font_id); + file_set_font(system, models, file, new_font_id); } else{ - global_set_font(models, new_font_id); + global_set_font(system, models, new_font_id); } } }break; @@ -4803,7 +4805,7 @@ step_file_view(System_Functions *system, View *view, View *active_view, Input_Su u32 *fore = 0, *back = 0; i32 i = 0; - String message = make_lit_string("Back"); + message = make_lit_string("Back"); id.id[0] = 0; if (gui_do_button(target, id, message)){ @@ -4915,7 +4917,7 @@ step_file_view(System_Functions *system, View *view, View *active_view, Input_Su autocomplete_with_enter = 0; } - String message = {0}; + String message = null_string; switch (view->action){ case IAct_Open: message = make_lit_string("Open: "); break; case IAct_Save_As: message = make_lit_string("Save As: "); break; @@ -4927,8 +4929,6 @@ step_file_view(System_Functions *system, View *view, View *active_view, Input_Su GUI_Item_Update update = {0}; Hot_Directory *hdir = &models->hot_directory; - b32 do_new_directory = 0; - i32 i = 0; { Single_Line_Input_Step step = {0}; @@ -4969,8 +4969,9 @@ step_file_view(System_Functions *system, View *view, View *active_view, Input_Su gui_standard_list(target, id, &view->gui_scroll, view->scroll_region, &keys, &view->list_i, &update, user_up_key, user_down_key); } + b32 do_new_directory = false; begin_exhaustive_loop(&loop, hdir); - for (i = 0; i < loop.count; ++i){ + for (i32 i = 0; i < loop.count; ++i){ file_info = get_exhaustive_info(system, &models->working_set, &loop, i); if (file_info.name_match){ @@ -5013,7 +5014,7 @@ step_file_view(System_Functions *system, View *view, View *active_view, Input_Su local_persist String message_unsaved = make_lit_string(" *"); local_persist String message_unsynced = make_lit_string(" !"); - String message = {0}; + String message = null_string; switch (view->action){ case IAct_Switch: message = make_lit_string("Switch: "); break; case IAct_Kill: message = make_lit_string("Kill: "); break; @@ -5885,7 +5886,7 @@ do_step_file_view(System_Functions *system, View *view, i32_Rect rect, b32 is_ac } internal i32 -draw_file_loaded(View *view, i32_Rect rect, b32 is_active, Render_Target *target){ +draw_file_loaded(System_Functions *system, View *view, i32_Rect rect, b32 is_active, Render_Target *target){ Models *models = view->persistent.models; Editing_File *file = view->file_data.file; Style *style = main_style(models); @@ -5914,8 +5915,8 @@ draw_file_loaded(View *view, i32_Rect rect, b32 is_active, Render_Target *target i32 max = partition_remaining(part) / sizeof(Buffer_Render_Item); Buffer_Render_Item *items = push_array(part, Buffer_Render_Item, max); - i16 font_id = file->settings.font_id; - Render_Font *font = get_font_info(models->font_set, font_id)->font; + Font_ID font_id = file->settings.font_id; + Render_Font *font = system->font.get_render_data_by_id(font_id); f32 scroll_x = view->edit_pos->scroll.scroll_x; f32 scroll_y = view->edit_pos->scroll.scroll_y; @@ -5927,10 +5928,10 @@ draw_file_loaded(View *view, i32_Rect rect, b32 is_active, Render_Target *target Full_Cursor render_cursor; if (!file->settings.unwrapped_lines){ - render_cursor = view_compute_cursor(view, seek_wrapped_xy(0, scroll_y, 0), 1); + render_cursor = view_compute_cursor(system, view, seek_wrapped_xy(0, scroll_y, 0), 1); } else{ - render_cursor = view_compute_cursor(view, seek_unwrapped_xy(0, scroll_y, 0), 1); + render_cursor = view_compute_cursor(system, view, seek_unwrapped_xy(0, scroll_y, 0), 1); } view->edit_pos->scroll_i = render_cursor.pos; @@ -5953,6 +5954,7 @@ draw_file_loaded(View *view, i32_Rect rect, b32 is_active, Render_Target *target params.height = (f32)max_y; params.start_cursor = render_cursor; params.wrapped = wrapped; + params.system = system; params.font = font; params.virtual_white = file->settings.virtual_white; params.wrap_slashes = file->settings.wrap_indicator; @@ -6070,8 +6072,7 @@ draw_file_loaded(View *view, i32_Rect rect, b32 is_active, Render_Target *target f32_Rect char_rect = f32R(item->x0, item->y0, item->x1, item->y1); - if (view->file_data.show_whitespace && highlight_color == 0 && - char_is_whitespace((char)item->glyphid)){ + if (view->file_data.show_whitespace && highlight_color == 0 && codepoint_is_whitespace(item->codepoint)){ highlight_this_color = style->main.highlight_white_color; } else{ @@ -6109,8 +6110,8 @@ draw_file_loaded(View *view, i32_Rect rect, b32 is_active, Render_Target *target if (ind == view->edit_pos->mark && prev_ind != ind){ draw_rectangle_outline(target, char_rect, mark_color); } - if (item->glyphid != 0){ - font_draw_glyph(target, font_id, (u8)item->glyphid, item->x0, item->y0, char_color); + if (item->codepoint != 0){ + font_draw_glyph(target, font_id, item->codepoint, item->x0, item->y0, char_color); } prev_ind = ind; } @@ -6121,8 +6122,7 @@ draw_file_loaded(View *view, i32_Rect rect, b32 is_active, Render_Target *target } internal void -draw_text_field(Render_Target *target, View *view, i16 font_id, - i32_Rect rect, String p, String t){ +draw_text_field(System_Functions *system, Render_Target *target, View *view, Font_ID font_id, i32_Rect rect, String p, String t){ Models *models = view->persistent.models; Style *style = main_style(models); @@ -6135,13 +6135,13 @@ draw_text_field(Render_Target *target, View *view, i16 font_id, if (target){ draw_rectangle(target, rect, back_color); - x = ceil32(draw_string(target, font_id, p, x, y, text2_color)); - draw_string(target, font_id, t, x, y, text1_color); + x = ceil32(draw_string(system, target, font_id, p, x, y, text2_color)); + draw_string(system, target, font_id, t, x, y, text1_color); } } internal void -draw_text_with_cursor(Render_Target *target, View *view, i16 font_id, i32_Rect rect, String s, i32 pos){ +draw_text_with_cursor(System_Functions *system, Render_Target *target, View *view, Font_ID font_id, i32_Rect rect, String s, i32 pos){ Models *models = view->persistent.models; Style *style = main_style(models); @@ -6157,33 +6157,33 @@ draw_text_with_cursor(Render_Target *target, View *view, i16 font_id, i32_Rect r draw_rectangle(target, rect, back_color); if (pos >= 0 && pos < s.size){ - String part1, part2, part3; + Render_Font *font = system->font.get_render_data_by_id(font_id); + + String part1 = substr(s, 0, pos); + String part2 = substr(s, pos, 1); + String part3 = substr(s, pos+1, s.size-pos-1); + + x = draw_string(system, target, font_id, part1, floor32(x), y, text_color); + + f32 adv = font_get_glyph_advance(system, font, s.str[pos]); i32_Rect cursor_rect; - Render_Font *font = get_font_info(models->font_set, font_id)->font; - - part1 = substr(s, 0, pos); - part2 = substr(s, pos, 1); - part3 = substr(s, pos+1, s.size-pos-1); - - x = draw_string(target, font_id, part1, floor32(x), y, text_color); - cursor_rect.x0 = floor32(x); - cursor_rect.x1 = floor32(x) + ceil32(get_codepoint_advance(font, s.str[pos])); + cursor_rect.x1 = floor32(x) + ceil32(adv); cursor_rect.y0 = y; cursor_rect.y1 = y + view->line_height; draw_rectangle(target, cursor_rect, cursor_color); - x = draw_string(target, font_id, part2, floor32(x), y, at_cursor_color); + x = draw_string(system, target, font_id, part2, floor32(x), y, at_cursor_color); - draw_string(target, font_id, part3, floor32(x), y, text_color); + draw_string(system, target, font_id, part3, floor32(x), y, text_color); } else{ - draw_string(target, font_id, s, floor32(x), y, text_color); + draw_string(system, target, font_id, s, floor32(x), y, text_color); } } } internal void -draw_file_bar(Render_Target *target, View *view, Editing_File *file, i32_Rect rect){ +draw_file_bar(System_Functions *system, Render_Target *target, View *view, Editing_File *file, i32_Rect rect){ File_Bar bar; Models *models = view->persistent.models; Style *style = main_style(models); @@ -6207,11 +6207,11 @@ draw_file_bar(Render_Target *target, View *view, Editing_File *file, i32_Rect re Assert(file); - intbar_draw_string(target, &bar, file->name.live_name, base_color); - intbar_draw_string(target, &bar, make_lit_string(" -"), base_color); + intbar_draw_string(system, target, &bar, file->name.live_name, base_color); + intbar_draw_string(system, target, &bar, make_lit_string(" -"), base_color); if (file->is_loading){ - intbar_draw_string(target, &bar, make_lit_string(" loading"), base_color); + intbar_draw_string(system, target, &bar, make_lit_string(" loading"), base_color); } else{ char bar_space[526]; @@ -6230,11 +6230,11 @@ draw_file_bar(Render_Target *target, View *view, Editing_File *file, i32_Rect re append_ss(&bar_text, make_lit_string(" nix")); } - intbar_draw_string(target, &bar, bar_text, base_color); + intbar_draw_string(system, target, &bar, bar_text, base_color); if (file->state.still_lexing){ - intbar_draw_string(target, &bar, make_lit_string(" parsing"), pop1_color); + intbar_draw_string(system, target, &bar, make_lit_string(" parsing"), pop1_color); } if (!file->settings.unimportant){ @@ -6242,13 +6242,13 @@ draw_file_bar(Render_Target *target, View *view, Editing_File *file, i32_Rect re case DirtyState_UnloadedChanges: { local_persist String out_of_sync = make_lit_string(" !"); - intbar_draw_string(target, &bar, out_of_sync, pop2_color); + intbar_draw_string(system, target, &bar, out_of_sync, pop2_color); }break; case DirtyState_UnsavedChanges: { local_persist String out_of_sync = make_lit_string(" *"); - intbar_draw_string(target, &bar, out_of_sync, pop2_color); + intbar_draw_string(system, target, &bar, out_of_sync, pop2_color); }break; } } @@ -6278,8 +6278,7 @@ get_margin_color(i32 active_level, Style *style){ } internal void -draw_color_button(GUI_Target *gui_target, Render_Target *target, View *view, - i16 font_id, i32_Rect rect, GUI_id id, u32 fore, u32 back, String text){ +draw_color_button(System_Functions *system, GUI_Target *gui_target, Render_Target *target, View *view, Font_ID font_id, i32_Rect rect, GUI_id id, u32 fore, u32 back, String text){ i32 active_level = gui_active_level(gui_target, id); if (active_level > 0){ @@ -6287,12 +6286,11 @@ draw_color_button(GUI_Target *gui_target, Render_Target *target, View *view, } draw_rectangle(target, rect, back); - draw_string(target, font_id, text, rect.x0, rect.y0 + 1, fore); + draw_string(system, target, font_id, text, rect.x0, rect.y0 + 1, fore); } internal void -draw_font_button(GUI_Target *gui_target, Render_Target *target, View *view, - i32_Rect rect, GUI_id id, i16 font_id, String text){ +draw_font_button(System_Functions *system, GUI_Target *gui_target, Render_Target *target, View *view, i32_Rect rect, GUI_id id, Font_ID font_id, String text){ Models *models = view->persistent.models; Style *style = main_style(models); @@ -6304,13 +6302,11 @@ draw_font_button(GUI_Target *gui_target, Render_Target *target, View *view, draw_rectangle(target, rect, back_color); draw_rectangle_outline(target, rect, margin_color); - draw_string(target, font_id, text, rect.x0, rect.y0 + 1, text_color); + draw_string(system, target, font_id, text, rect.x0, rect.y0 + 1, text_color); } internal void -draw_fat_option_block(GUI_Target *gui_target, Render_Target *target, View *view, - i16 font_id, i32_Rect rect, GUI_id id, - String text, String pop, i8 checkbox = -1){ +draw_fat_option_block(System_Functions *system, GUI_Target *gui_target, Render_Target *target, View *view, Font_ID font_id, i32_Rect rect, GUI_id id, String text, String pop, i8 checkbox = -1){ Models *models = view->persistent.models; Style *style = main_style(models); @@ -6345,12 +6341,12 @@ draw_fat_option_block(GUI_Target *gui_target, Render_Target *target, View *view, x = checkbox_rect.x1 + 3; } - x = ceil32(draw_string(target, font_id, text, x, y, text_color)); - draw_string(target, font_id, pop, x, y, pop_color); + x = ceil32(draw_string(system, target, font_id, text, x, y, text_color)); + draw_string(system, target, font_id, pop, x, y, pop_color); } internal void -draw_button(GUI_Target *gui_target, Render_Target *target, View *view, i16 font_id, i32_Rect rect, GUI_id id, String text){ +draw_button(System_Functions *system, GUI_Target *gui_target, Render_Target *target, View *view, Font_ID font_id, i32_Rect rect, GUI_id id, String text){ Models *models = view->persistent.models; Style *style = main_style(models); @@ -6365,21 +6361,24 @@ draw_button(GUI_Target *gui_target, Render_Target *target, View *view, i16 font_ i32 h = view->line_height; i32 y = inner.y0 + h/2 - 1; - i32 w = (i32)font_string_width(target, font_id, text); + i32 w = (i32)font_string_width(system, target, font_id, text); i32 x = (inner.x1 + inner.x0 - w)/2; draw_rectangle(target, inner, back); draw_rectangle_outline(target, inner, margin); - draw_string(target, font_id, text, x, y, text_color); + draw_string(system, target, font_id, text, x, y, text_color); } internal void -draw_style_preview(GUI_Target *gui_target, Render_Target *target, View *view, i16 font_id, i32_Rect rect, GUI_id id, Style *style){ - Models *models = view->persistent.models; +draw_style_preview(System_Functions *system, GUI_Target *gui_target, Render_Target *target, View *view, Font_ID font_id, i32_Rect rect, GUI_id id, Style *style){ + Models *models = view->persistent.models; AllowLocal(models); i32 active_level = gui_active_level(gui_target, id); - Font_Info *info = get_font_info(models->font_set, font_id); + char font_name_space[256]; + String font_name = make_fixed_width_string(font_name_space); + font_name.size = system->font.get_name_by_id(font_id, font_name.str, font_name.memory_size); + Render_Font *font = system->font.get_render_data_by_id(font_id); i32_Rect inner = get_inner_rect(rect, 3); @@ -6395,32 +6394,30 @@ draw_style_preview(GUI_Target *gui_target, Render_Target *target, View *view, i1 i32 y = inner.y0; i32 x = inner.x0; - x = ceil32(draw_string(target, font_id, style->name.str, x, y, text_color)); - i32 font_x = (i32)(inner.x1 - font_string_width(target, font_id, info->name.str)); + x = ceil32(draw_string(system, target, font_id, style->name.str, x, y, text_color)); + i32 font_x = (i32)(inner.x1 - font_string_width(system, target, font_id, font_name)); if (font_x > x + 10){ - draw_string(target, font_id, info->name.str, font_x, y, text_color); + draw_string(system, target, font_id, font_name, font_x, y, text_color); } - i32 height = info->font->height; + i32 height = font_get_height(font); x = inner.x0; y += height; - x = ceil32(draw_string(target, font_id, "if", x, y, keyword_color)); - x = ceil32(draw_string(target, font_id, "(x < ", x, y, text_color)); - x = ceil32(draw_string(target, font_id, "0", x, y, int_constant_color)); - x = ceil32(draw_string(target, font_id, ") { x = ", x, y, text_color)); - x = ceil32(draw_string(target, font_id, "0", x, y, int_constant_color)); - x = ceil32(draw_string(target, font_id, "; } ", x, y, text_color)); - x = ceil32(draw_string(target, font_id, "// comment", x, y, comment_color)); + x = ceil32(draw_string(system, target, font_id, "if", x, y, keyword_color)); + x = ceil32(draw_string(system, target, font_id, "(x < ", x, y, text_color)); + x = ceil32(draw_string(system, target, font_id, "0", x, y, int_constant_color)); + x = ceil32(draw_string(system, target, font_id, ") { x = ", x, y, text_color)); + x = ceil32(draw_string(system, target, font_id, "0", x, y, int_constant_color)); + x = ceil32(draw_string(system, target, font_id, "; } ", x, y, text_color)); + x = ceil32(draw_string(system, target, font_id, "// comment", x, y, comment_color)); x = inner.x0; y += height; - draw_string(target, font_id, "[] () {}; * -> +-/ <>= ! && || % ^", x, y, text_color); + draw_string(system, target, font_id, "[] () {}; * -> +-/ <>= ! && || % ^", x, y, text_color); } internal i32 -do_render_file_view(System_Functions *system, View *view, GUI_Scroll_Vars *scroll, - View *active, i32_Rect rect, b32 is_active, - Render_Target *target, Input_Summary *user_input){ +do_render_file_view(System_Functions *system, View *view, GUI_Scroll_Vars *scroll, View *active, i32_Rect rect, b32 is_active, Render_Target *target, Input_Summary *user_input){ Editing_File *file = view->file_data.file; i32 result = 0; @@ -6432,11 +6429,10 @@ do_render_file_view(System_Functions *system, View *view, GUI_Scroll_Vars *scrol f32 v = {0}; i32 max_y = view_compute_max_target_y(view); - i16 font_id = 0; Assert(file != 0); - font_id = file->settings.font_id; + Font_ID font_id = file->settings.font_id; if (gui_target->push.pos > 0){ gui_session_init(&gui_session, gui_target, rect, view->line_height); @@ -6460,13 +6456,13 @@ do_render_file_view(System_Functions *system, View *view, GUI_Scroll_Vars *scrol switch (h->type){ case guicom_top_bar: { - draw_file_bar(target, view, file, gui_session.rect); + draw_file_bar(system, target, view, file, gui_session.rect); }break; case guicom_file: { if (file_is_ready(file)){ - result = draw_file_loaded(view, gui_session.rect, is_active, target); + result = draw_file_loaded(system, view, gui_session.rect, is_active, target); } }break; @@ -6475,7 +6471,7 @@ do_render_file_view(System_Functions *system, View *view, GUI_Scroll_Vars *scrol void *ptr = (h+1); String p = gui_read_string(&ptr); String t = gui_read_string(&ptr); - draw_text_field(target, view, font_id, gui_session.rect, p, t); + draw_text_field(system, target, view, font_id, gui_session.rect, p, t); }break; case guicom_text_with_cursor: @@ -6484,7 +6480,7 @@ do_render_file_view(System_Functions *system, View *view, GUI_Scroll_Vars *scrol String s = gui_read_string(&ptr); i32 pos = gui_read_integer(&ptr); - draw_text_with_cursor(target, view, font_id, gui_session.rect, s, pos); + draw_text_with_cursor(system, target, view, font_id, gui_session.rect, s, pos); }break; case guicom_color_button: @@ -6495,17 +6491,17 @@ do_render_file_view(System_Functions *system, View *view, GUI_Scroll_Vars *scrol u32 back = (u32)gui_read_integer(&ptr); String t = gui_read_string(&ptr); - draw_color_button(gui_target, target, view, font_id, gui_session.rect, b->id, fore, back, t); + draw_color_button(system, gui_target, target, view, font_id, gui_session.rect, b->id, fore, back, t); }break; case guicom_font_button: { GUI_Interactive *b = (GUI_Interactive*)h; void *ptr = (b + 1); - i16 font_id = (i16)gui_read_integer(&ptr); + Font_ID this_font_id = (Font_ID)gui_read_integer(&ptr); String t = gui_read_string(&ptr); - draw_font_button(gui_target, target, view, gui_session.rect, b->id, font_id, t); + draw_font_button(system, gui_target, target, view, gui_session.rect, b->id, this_font_id, t); }break; case guicom_file_option: @@ -6520,7 +6516,7 @@ do_render_file_view(System_Functions *system, View *view, GUI_Scroll_Vars *scrol append_s_char(&f, '/'); } - draw_fat_option_block(gui_target, target, view, font_id, gui_session.rect, b->id, f, m); + draw_fat_option_block(system, gui_target, target, view, font_id, gui_session.rect, b->id, f, m); }break; case guicom_style_preview: @@ -6529,7 +6525,7 @@ do_render_file_view(System_Functions *system, View *view, GUI_Scroll_Vars *scrol i32 style_index = *(i32*)(b + 1); Style *style = get_style(view->persistent.models, style_index); - draw_style_preview(gui_target, target, view, font_id, gui_session.rect, b->id, style); + draw_style_preview(system, gui_target, target, view, font_id, gui_session.rect, b->id, style); }break; case guicom_fixed_option: @@ -6545,7 +6541,7 @@ do_render_file_view(System_Functions *system, View *view, GUI_Scroll_Vars *scrol status = (i8)gui_read_byte(&ptr); } - draw_fat_option_block(gui_target, target, view, font_id, gui_session.rect, b->id, f, m, status); + draw_fat_option_block(system, gui_target, target, view, font_id, gui_session.rect, b->id, f, m, status); }break; case guicom_button: @@ -6554,7 +6550,7 @@ do_render_file_view(System_Functions *system, View *view, GUI_Scroll_Vars *scrol void *ptr = (b + 1); String t = gui_read_string(&ptr); - draw_button(gui_target, target, view, font_id, gui_session.rect, b->id, t); + draw_button(system, gui_target, target, view, font_id, gui_session.rect, b->id, t); }break; case guicom_scrollable_bar: diff --git a/4ed_font_set.cpp b/4ed_font_set.cpp deleted file mode 100644 index a4439e71..00000000 --- a/4ed_font_set.cpp +++ /dev/null @@ -1,244 +0,0 @@ -/* -* 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; -} - -inline Font_Slot -font_slot_zero(){ - Font_Slot slot = {0}; - return(slot); -} - -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 = font_slot_zero(); - set->used_slots = font_slot_zero(); - - dll_init_sentinel(&set->free_slots); - dll_init_sentinel(&set->used_slots); - - char *ptr = (char*)set->font_block; - for (i32 i = 0; i < live_max; ++i){ - dll_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(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(font, info->filename.str, info->name.str, info->pt_size, 4, true); - 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(Font_Set *set, i16 font_id){ - b8 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(set, font_id); - } - slot = ((Font_Slot*)info->font) - 1; - - font__remove(slot); - font__insert(&set->used_slots, slot); - } -} - -internal b32 -font_set_add(Font_Set *set, String filename, String name, i32 pt_size){ - b32 result = 0; - if (font_set_can_add(set)){ - Render_Font dummy_font = {0}; - 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_load(&dummy_font, info->filename.str, info->name.str, info->pt_size, 4, false); - //info->height = dummy_font.height; - //info->advance = dummy_font.advance; - - font_set_add_hash(set, name, font_id); - - if (font_set_can_load(set)){ - font_set_load(set, font_id); - } - - result = 1; - } - return(result); -} - -internal b32 -font_set_find_pos(Font_Set *set, String name, u32 *position){ - u32 hash = font_hash(name); - u32 i = hash % set->max; - u32 j = i - 1; - if (j <= 1){ - j += set->max; - } - - b32 result = 0; - for (; i != j; ++i){ - if (i == set->max){ - i = 0; - } - - Font_Table_Entry *entry = set->entries + i; - if (entry->hash == hash){ - if (match_ss(name, entry->name)){ - result = 1; - *position = i; - break; - } - } - } - - return(result); -} - -internal b32 -font_set_get_name(Font_Set *set, i16 font_id, String *name){ - Font_Info *info = get_font_info(set, font_id); - b32 result = copy_checked_ss(name, info->name); - return(result); -} - -internal b32 -font_set_extract(Font_Set *set, String name, i16 *font_id){ - u32 position; - b32 result = font_set_find_pos(set, name, &position); - if (result){ - *font_id = set->entries[position].font_id; - } - return(result); -} - -// BOTTOM - diff --git a/4ed_gui.cpp b/4ed_gui.cpp index 15719c2c..521bf4f7 100644 --- a/4ed_gui.cpp +++ b/4ed_gui.cpp @@ -451,7 +451,7 @@ gui_do_color_button(GUI_Target *target, GUI_id id, u32 fore, u32 back, String te } internal b32 -gui_do_font_button(GUI_Target *target, GUI_id id, i16 font_id, String text){ +gui_do_font_button(GUI_Target *target, GUI_id id, Font_ID font_id, String text){ b32 result = 0; i32 font_id32 = font_id; GUI_Interactive *b = gui_push_button_command(target, guicom_font_button, id); diff --git a/file/4coder_hot_directory.cpp b/4ed_hot_directory.cpp similarity index 100% rename from file/4coder_hot_directory.cpp rename to 4ed_hot_directory.cpp diff --git a/4ed_math.h b/4ed_math.h index 129ae6a7..9f3df328 100644 --- a/4ed_math.h +++ b/4ed_math.h @@ -28,15 +28,15 @@ ABS(f32 x){ inline f32 MOD(f32 x, i32 m){ - f32 whole, frac, r; - frac = modff(x, &whole); - r = ((i32)(whole) % m) + frac; + f32 whole; + f32 frac = modff(x, &whole); + f32 r = ((i32)(whole) % m) + frac; return(r); } inline f32 SQRT(f32 x){ - f32 r = sqrt(x); + f32 r = sqrtf(x); return(r); } @@ -431,18 +431,6 @@ unlerp(f32 a, f32 x, f32 b){ return(r); } -inline f32 -clamp_bottom(f32 a, f32 n){ - if (n < a) n = a; - return (n); -} - -inline f32 -clamp_top(f32 n, f32 z){ - if (n > z) n = z; - return (n); -} - inline f32 clamp(f32 a, f32 n, f32 z){ if (n < a) n = a; @@ -450,18 +438,6 @@ clamp(f32 a, f32 n, f32 z){ return (n); } -inline i32 -clamp_bottom(i32 a, i32 n){ - if (n < a) n = a; - return (n); -} - -inline i32 -clamp_top(i32 n, i32 z){ - if (n > z) n = z; - return (n); -} - inline i32 clamp(i32 a, i32 n, i32 z){ if (n < a) n = a; @@ -469,18 +445,6 @@ clamp(i32 a, i32 n, i32 z){ return (n); } -inline u32 -clamp_bottom(u32 a, u32 n){ - if (n < a) n = a; - return (n); -} - -inline u32 -clamp_top(u32 n, u32 z){ - if (n > z) n = z; - return (n); -} - inline u32 clamp(u32 a, u32 n, u32 z){ if (n < a) n = a; @@ -488,6 +452,9 @@ clamp(u32 a, u32 n, u32 z){ return (n); } +#define clamp_top(a,b) Min(a,b) +#define clamp_bottom(a,b) Max(a,b) + /* * Color */ diff --git a/4ed_mem_ansi.c b/4ed_mem_ansi.c index 07dd9f1e..f0714944 100644 --- a/4ed_mem_ansi.c +++ b/4ed_mem_ansi.c @@ -1,7 +1,9 @@ /* - * Replacements for common memory block managing functions. +* Mr. 4th Dimention - Allen Webster * - * 30.08.2016 (dd.mm.yyyy) + * 30.08.2016 + * + * Replacements for common memory block managing functions. */ // TOP diff --git a/4ed_rendering.h b/4ed_rendering.h index a85a4d6f..2cd9af0d 100644 --- a/4ed_rendering.h +++ b/4ed_rendering.h @@ -12,54 +12,6 @@ #ifndef FRED_RENDERING_H #define FRED_RENDERING_H -// -// Fonts -// - -#include "file/4coder_font_data.h" - -struct Font_Table_Entry{ - u32 hash; - String name; - i16 font_id; -}; - -struct Font_Info{ - Render_Font *font; - String filename; - String name; - i32 pt_size; -}; - -struct Font_Slot{ - Font_Slot *next, *prev; - i16 font_id; - u8 padding[6]; -}; - -#define Font_Load_Sig(name) i32 name(Render_Font *font_out, char *filename, char *fontname, i32 pt_size, i32 tab_width, b32 store_texture) -typedef Font_Load_Sig(Font_Load); - -#define Release_Font_Sig(name) void name(Render_Font *font) -typedef Release_Font_Sig(Release_Font); - -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_Load *font_load; - Release_Font *release_font; - - b8 *font_used_flags; - i16 used_this_frame; - i16 live_max; -}; - // // Render Commands // @@ -92,16 +44,16 @@ struct Render_Piece_Gradient{ struct Render_Piece_Glyph{ Vec2 pos; u32 color; - i16 font_id; - u8 character; + Font_ID font_id; + u32 codepoint; }; struct Render_Piece_Glyph_Advance{ Vec2 pos; u32 color; f32 advance; - i16 font_id; - u8 character; + Font_ID font_id; + u32 codepoint; }; struct Render_Piece_Change_Clip{ @@ -150,10 +102,6 @@ struct Render_Target{ Draw_Push_Clip *push_clip; Draw_Pop_Clip *pop_clip; Draw_Push_Piece *push_piece; - - // TODO(allen): Does the font set really belong here? Actually, do we still want it at all? - Font_Set font_set; - Partition *partition; }; #define DpiMultiplier(n,dpi) ((n) * (dpi) / 96) @@ -168,12 +116,6 @@ rect_from_target(Render_Target *target){ return(r); } -inline Font_Info* -get_font_info(Font_Set *set, i16 font_id){ - Font_Info *result = set->info + font_id - 1; - return(result); -} - #endif // BOTTOM diff --git a/4ed_rendering_helper.cpp b/4ed_rendering_helper.cpp index 078af7ff..14ea3b15 100644 --- a/4ed_rendering_helper.cpp +++ b/4ed_rendering_helper.cpp @@ -28,9 +28,6 @@ draw_change_clip(Render_Target *target, i32_Rect clip_box){ internal void begin_render_section(Render_Target *target, System_Functions *system){ - Font_Set *font_set = &target->font_set; - font_set->used_this_frame = 0; - memset(font_set->font_used_flags, 0, font_set->max); target->size = 0; target->clip_top = -1; @@ -116,38 +113,72 @@ font_predict_size(i32 pt_size){ } internal void -font_draw_glyph(Render_Target *target, i16 font_id, i32 type, u8 character, f32 x, f32 y, u32 color){ +font_draw_glyph(Render_Target *target, Font_ID font_id, i32 type, u32 codepoint, f32 x, f32 y, u32 color){ Render_Piece_Combined piece; piece.header.type = type; piece.glyph.pos.x = x; piece.glyph.pos.y = y; piece.glyph.color = color; piece.glyph.font_id = font_id; - piece.glyph.character = character; + piece.glyph.codepoint = codepoint; target->push_piece(target, piece); - font_set_use(&target->font_set, font_id); } internal void -font_draw_glyph(Render_Target *target, i16 font_id, u8 character, f32 x, f32 y, u32 color){ - font_draw_glyph(target, font_id, piece_type_glyph, character, x, y, color); +font_draw_glyph(Render_Target *target, Font_ID font_id, u32 codepoint, f32 x, f32 y, u32 color){ + font_draw_glyph(target, font_id, piece_type_glyph, codepoint, x, y, color); } internal f32 -draw_string_base(Render_Target *target, i16 font_id, i32 type, String str_, i32 x_, i32 y_, u32 color){ - Font_Info *font_info = get_font_info(&target->font_set, font_id); - Render_Font *font = font_info->font; +draw_string_base(System_Functions *system, Render_Target *target, Font_ID font_id, i32 type, String str_, i32 x_, i32 y_, u32 color){ f32 x = 0; - if (font){ + Render_Font *font = system->font.get_render_data_by_id(font_id); + if (font != 0){ f32 y = (f32)y_; x = (f32)x_; - f32 byte_advance = font->byte_advance; + f32 byte_advance = font_get_byte_advance(font); + f32 *sub_advances = font_get_byte_sub_advances(font); u8 *str = (u8*)str_.str; u8 *str_end = str + str_.size; + Translation_State tran = {0}; + Translation_Emits emits = {0}; + + for (u32 i = 0; str < str_end; ++str, ++i){ + translating_fully_process_byte(system, font, &tran, *str, i, str_.size, &emits); + + for (TRANSLATION_DECL_EMIT_LOOP(J, emits)){ + TRANSLATION_DECL_GET_STEP(step, behavior, J, emits); + + if (behavior.do_codepoint_advance){ + u32 codepoint = step.value; + if (color != 0){ + font_draw_glyph(target, font_id, type, codepoint, x, y, color); + } + x += font_get_glyph_advance(system, font, codepoint); + } + else if (behavior.do_number_advance){ + u8 n = (u8)(step.value); + if (color != 0){ + u8 cs[3]; + cs[0] = '\\'; + byte_to_ascii(n, cs+1); + + f32 xx = x; + for (u32 j = 0; j < 3; ++j){ + font_draw_glyph(target, font_id, type, cs[j], xx, y, color); + xx += sub_advances[j]; + } + } + x += byte_advance; + } + } + } + +#if 0 for (;str < str_end;){ u8 *byte = str; u32 codepoint = utf8_to_u32(&str, str_end); @@ -170,7 +201,7 @@ draw_string_base(Render_Target *target, i16 font_id, i32 type, String str_, i32 if (color != 0){ font_draw_glyph(target, font_id, type, (u8)codepoint, x, y, color); } - x += get_codepoint_advance(font, codepoint); + x += font_get_glyph_advance(system, font, codepoint); } else if (do_numbers){ for (;byte < str; ++byte){ @@ -180,10 +211,12 @@ draw_string_base(Render_Target *target, i16 font_id, i32 type, String str_, i32 cs[0] = '\\'; byte_to_ascii(n, cs+1); + f32 *advances = font_get_byte_sub_advances(font); + f32 xx = x; for (u32 j = 0; j < 3; ++j){ font_draw_glyph(target, font_id, type, cs[j], xx, y, color); - xx += byte_advance; + xx += advances[j]; } } @@ -191,47 +224,48 @@ draw_string_base(Render_Target *target, i16 font_id, i32 type, String str_, i32 } } } +#endif } return(x); } internal f32 -draw_string(Render_Target *target, i16 font_id, String str, i32 x, i32 y, u32 color){ - f32 w = draw_string_base(target, font_id, piece_type_glyph, str, x, y, color); +draw_string(System_Functions *system, Render_Target *target, Font_ID font_id, String str, i32 x, i32 y, u32 color){ + f32 w = draw_string_base(system, target, font_id, piece_type_glyph, str, x, y, color); return(w); } internal f32 -draw_string(Render_Target *target, i16 font_id, char *str, i32 x, i32 y, u32 color){ +draw_string(System_Functions *system, Render_Target *target, Font_ID font_id, char *str, i32 x, i32 y, u32 color){ String string = make_string_slowly(str); - f32 w = draw_string_base(target, font_id, piece_type_glyph, string, x, y, color); + f32 w = draw_string_base(system, target, font_id, piece_type_glyph, string, x, y, color); return(w); } internal f32 -draw_string_mono(Render_Target *target, i16 font_id, String str, i32 x, i32 y, f32 advance, u32 color){ - f32 w = draw_string_base(target, font_id, piece_type_mono_glyph, str, x, y, color); +draw_string_mono(System_Functions *system, Render_Target *target, Font_ID font_id, String str, i32 x, i32 y, f32 advance, u32 color){ + f32 w = draw_string_base(system, target, font_id, piece_type_mono_glyph, str, x, y, color); return(w); } internal f32 -draw_string_mono(Render_Target *target, i16 font_id, char *str, i32 x, i32 y, f32 advance, u32 color){ +draw_string_mono(System_Functions *system, Render_Target *target, Font_ID font_id, char *str, i32 x, i32 y, f32 advance, u32 color){ String string = make_string_slowly(str); - f32 w = draw_string_base(target, font_id, piece_type_mono_glyph, string, x, y, color); + f32 w = draw_string_base(system, target, font_id, piece_type_mono_glyph, string, x, y, color); return(w); } internal f32 -font_string_width(Render_Target *target, i16 font_id, String str){ - f32 w = draw_string_base(target, font_id, piece_type_glyph, str, 0, 0, 0); +font_string_width(System_Functions *system, Render_Target *target, Font_ID font_id, String str){ + f32 w = draw_string_base(system, target, font_id, piece_type_glyph, str, 0, 0, 0); return(w); } internal f32 -font_string_width(Render_Target *target, i16 font_id, char *str){ +font_string_width(System_Functions *system, Render_Target *target, Font_ID font_id, char *str){ String string = make_string_slowly(str); - f32 w = draw_string_base(target, font_id, piece_type_glyph, string, 0, 0, 0); + f32 w = draw_string_base(system, target, font_id, piece_type_glyph, string, 0, 0, 0); return(w); } diff --git a/4ed_site.ctm b/4ed_site.ctm index 417f0e38..4a18e394 100644 Binary files a/4ed_site.ctm and b/4ed_site.ctm differ diff --git a/4ed_style.cpp b/4ed_style.cpp index d46ef063..d22b41bf 100644 --- a/4ed_style.cpp +++ b/4ed_style.cpp @@ -10,7 +10,7 @@ // TOP struct Style_Font{ - i16 font_id; + Font_ID font_id; }; struct Style{ diff --git a/4ed_system.h b/4ed_system.h index 49c6cf38..41eb4a2f 100644 --- a/4ed_system.h +++ b/4ed_system.h @@ -9,33 +9,32 @@ // TOP +#if !defined(FCODER_SYSTEM_INTERFACE_H) +#define FCODER_SYSTEM_INTERFACE_H + +#include "font/4coder_font_interface.h" + +// types struct Plat_Handle{ u32 d[4]; }; static Plat_Handle null_plat_handle = {0}; -inline int32_t +inline b32 handle_equal(Plat_Handle a, Plat_Handle b){ - int32_t result = (memcmp(&a, &b, sizeof(a)) == 0); + b32 result = (memcmp(&a, &b, sizeof(a)) == 0); return(result); } +// files #define Sys_Set_File_List_Sig(name) void name(File_List *file_list, char *directory, char *canon_directory_out, u32 *canon_directory_size_out, u32 canon_directory_max) typedef Sys_Set_File_List_Sig(System_Set_File_List); #define Sys_Get_Canonical_Sig(name) u32 name(char *filename, u32 len, char *buffer, u32 max) typedef Sys_Get_Canonical_Sig(System_Get_Canonical); -#define Sys_Add_Listener_Sig(name) b32 name(char *filename) -typedef Sys_Add_Listener_Sig(System_Add_Listener); - -#define Sys_Remove_Listener_Sig(name) b32 name(char *filename) -typedef Sys_Remove_Listener_Sig(System_Remove_Listener); - -#define Sys_Get_File_Change_Sig(name) i32 name(char *buffer, i32 max, b32 *mem_too_small, i32 *required_size) -typedef Sys_Get_File_Change_Sig(System_Get_File_Change); - +// file load/save #define Sys_Load_Handle_Sig(name) b32 name(char *filename, Plat_Handle *handle_out) typedef Sys_Load_Handle_Sig(System_Load_Handle); @@ -51,10 +50,21 @@ typedef Sys_Load_Close_Sig(System_Load_Close); #define Sys_Save_File_Sig(name) b32 name(char *filename, char *buffer, u32 size) typedef Sys_Save_File_Sig(System_Save_File); +// file changes +#define Sys_Add_Listener_Sig(name) b32 name(char *filename) +typedef Sys_Add_Listener_Sig(System_Add_Listener); + +#define Sys_Remove_Listener_Sig(name) b32 name(char *filename) +typedef Sys_Remove_Listener_Sig(System_Remove_Listener); + +#define Sys_Get_File_Change_Sig(name) i32 name(char *buffer, i32 max, b32 *mem_too_small, i32 *required_size) +typedef Sys_Get_File_Change_Sig(System_Get_File_Change); + +// time #define Sys_Now_Time_Sig(name) u64 name() typedef Sys_Now_Time_Sig(System_Now_Time); - +// clipboard #define Sys_Post_Clipboard_Sig(name) void name(String str) typedef Sys_Post_Clipboard_Sig(System_Post_Clipboard); @@ -80,7 +90,6 @@ typedef Sys_CLI_Update_Step_Sig(System_CLI_Update_Step); typedef Sys_CLI_End_Update_Sig(System_CLI_End_Update); // coroutine - #define Coroutine_Function_Sig(name) void name(struct Coroutine *coroutine) typedef Coroutine_Function_Sig(Coroutine_Function); @@ -230,6 +239,8 @@ typedef Sys_Send_Exit_Signal_Sig(System_Send_Exit_Signal); typedef INTERNAL_Sys_Get_Thread_States_Sig(INTERNAL_System_Get_Thread_States); struct System_Functions{ + Font_Functions font; + // files (tracked api): 10 System_Set_File_List *set_file_list; System_Get_Canonical *get_canonical; @@ -284,5 +295,7 @@ struct System_Functions{ INTERNAL_System_Get_Thread_States *internal_get_thread_states; }; +#endif + // BOTTOM diff --git a/4ed_system_shared.cpp b/4ed_system_shared.cpp index 1261feee..4bb6d099 100644 --- a/4ed_system_shared.cpp +++ b/4ed_system_shared.cpp @@ -9,9 +9,13 @@ // TOP +#if !defined(FCODER_SYSTEM_SHARED_CPP) +#define FCODER_SYSTEM_SHARED_CPP + +#include "font/4coder_font_data.h" + // -// Standard implementation of file system stuff -// based on the file track layer. +// Standard implementation of file system stuff based on the file track layer. // struct Shared_Vars{ @@ -19,19 +23,25 @@ struct Shared_Vars{ void *track_table; u32 track_table_size; u32 track_node_size; + + Partition scratch; }; -static Shared_Vars shared_vars; +global Shared_Vars shared_vars; internal void init_shared_vars(){ - shared_vars.track_table_size = (16 << 10); + umem scratch_size = KB(128); + void *scratch_memory = system_get_memory(scratch_size); + shared_vars.scratch = make_part(scratch_memory, scratch_size); + + shared_vars.track_table_size = KB(16); shared_vars.track_table = system_get_memory(shared_vars.track_table_size); - shared_vars.track_node_size = (16 << 10); + shared_vars.track_node_size = KB(16); void *track_nodes = system_get_memory(shared_vars.track_node_size); - i32 track_result = init_track_system(&shared_vars.track, shared_vars.track_table, shared_vars.track_table_size, track_nodes, shared_vars.track_node_size); + i32 track_result = init_track_system(&shared_vars.track, &shared_vars.scratch, shared_vars.track_table, shared_vars.track_table_size, track_nodes, shared_vars.track_node_size); if (track_result != FileTrack_Good){ exit(1); @@ -47,7 +57,7 @@ handle_track_out_of_memory(i32 val){ { u32 new_table_size = shared_vars.track_table_size*2; void *new_table = system_get_memory(new_table_size); - move_track_system(&shared_vars.track, new_table, new_table_size); + move_track_system(&shared_vars.track, &shared_vars.scratch, new_table, new_table_size); system_free_memory(shared_vars.track_table); shared_vars.track_table_size = new_table_size; shared_vars.track_table = new_table; @@ -57,7 +67,7 @@ handle_track_out_of_memory(i32 val){ { shared_vars.track_node_size *= 2; void *node_expansion = system_get_memory(shared_vars.track_node_size); - expand_track_system_listeners(&shared_vars.track, node_expansion, shared_vars.track_node_size); + expand_track_system_listeners(&shared_vars.track, &shared_vars.scratch, node_expansion, shared_vars.track_node_size); }break; default: result = 1; break; @@ -71,7 +81,7 @@ Sys_Add_Listener_Sig(system_add_listener){ b32 result = 0; for (;;){ - i32 track_result = add_listener(&shared_vars.track, filename); + i32 track_result = add_listener(&shared_vars.track, &shared_vars.scratch, filename); if (handle_track_out_of_memory(track_result)){ if (track_result == FileTrack_Good){ result = 1; @@ -86,7 +96,7 @@ Sys_Add_Listener_Sig(system_add_listener){ internal Sys_Remove_Listener_Sig(system_remove_listener){ i32 result = 0; - i32 track_result = remove_listener(&shared_vars.track, filename); + i32 track_result = remove_listener(&shared_vars.track, &shared_vars.scratch, filename); if (track_result == FileTrack_Good){ result = 1; } @@ -95,19 +105,19 @@ Sys_Remove_Listener_Sig(system_remove_listener){ internal Sys_Get_File_Change_Sig(system_get_file_change){ - i32 result = 0; + b32 result = false; i32 size = 0; - i32 get_result = get_change_event(&shared_vars.track, buffer, max, &size); + i32 get_result = get_change_event(&shared_vars.track, &shared_vars.scratch, buffer, max, &size); *required_size = size; - *mem_too_small = 0; + *mem_too_small = false; if (get_result == FileTrack_Good){ - result = 1; + result = true; } else if (get_result == FileTrack_MemoryTooSmall){ - *mem_too_small = 1; - result = 1; + *mem_too_small = true; + result = true; } return(result); @@ -182,8 +192,7 @@ internal void sysshared_partition_grow(Partition *part, i32 new_size){ void *data = 0; if (new_size > part->max){ - // TODO(allen): attempt to grow in place by just - // acquiring next vpages?! + // TODO(allen): attempt to grow in place by just acquiring next vpages?! data = system_get_memory(new_size); memcpy(data, part->base, part->pos); system_free_memory(part->base); @@ -218,7 +227,7 @@ sysshared_to_binary_path(String *out_filename, char *filename){ translate_success = 1; } } - return (translate_success); + return(translate_success); } // @@ -421,9 +430,9 @@ get_exact_render_quad(Glyph_Bounds *b, i32 pw, i32 ph, float xpos, float ypos){ } inline void -private_draw_glyph(Render_Target *target, Render_Font *font, u32 character, f32 x, f32 y, u32 color){ - Glyph_Data glyph = {0}; - if (get_codepoint_glyph_data(font, character, &glyph)){ +private_draw_glyph(System_Functions *system, Render_Target *target, Render_Font *font, u32 codepoint, f32 x, f32 y, u32 color){ + Glyph_Data glyph = font_get_glyph(system, font, codepoint); + if (glyph.tex != 0){ Render_Quad q = get_render_quad(&glyph.bounds, glyph.tex_width, glyph.tex_height, x, y); draw_set_color(target, color); @@ -440,9 +449,9 @@ private_draw_glyph(Render_Target *target, Render_Font *font, u32 character, f32 } inline void -private_draw_glyph_mono(Render_Target *target, Render_Font *font, u8 character, f32 x, f32 y, f32 advance, u32 color){ - Glyph_Data glyph = {0}; - if (get_codepoint_glyph_data(font, character, &glyph)){ +private_draw_glyph_mono(System_Functions *system, Render_Target *target, Render_Font *font, u32 codepoint, f32 x, f32 y, f32 advance, u32 color){ + Glyph_Data glyph = font_get_glyph(system, font, codepoint); + if (glyph.tex != 0){ f32 left = glyph.bounds.x0; f32 right = glyph.bounds.x1; f32 width = (right - left); @@ -466,12 +475,13 @@ private_draw_glyph_mono(Render_Target *target, Render_Font *font, u8 character, } inline void -private_draw_glyph_mono(Render_Target *target, Render_Font *font, u8 character, f32 x, f32 y, u32 color){ - private_draw_glyph_mono(target, font, character, x, y, (f32)font->advance, color); +private_draw_glyph_mono(System_Functions *system, Render_Target *target, Render_Font *font, u32 character, f32 x, f32 y, u32 color){ + f32 advance = (f32)font_get_advance(font); + private_draw_glyph_mono(system, target, font, character, x, y, advance, color); } internal void -launch_rendering(Render_Target *target){ +launch_rendering(System_Functions *system, Render_Target *target){ char *cursor = target->push_buffer; char *cursor_end = cursor + target->size; @@ -502,36 +512,32 @@ launch_rendering(Render_Target *target){ { Render_Piece_Glyph *glyph = ExtractStruct(Render_Piece_Glyph); - 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); - } + Render_Font *font = system->font.get_render_data_by_id(glyph->font_id); + Assert(font != 0); + private_draw_glyph(system, target, font, glyph->codepoint, 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 = 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); - } + Render_Font *font = system->font.get_render_data_by_id(glyph->font_id); + Assert(font != 0); + private_draw_glyph_mono(system, target, font, glyph->codepoint, 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 = 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); - } + Render_Font *font = system->font.get_render_data_by_id(glyph->font_id); + Assert(font != 0); + private_draw_glyph_mono(system, target, font, glyph->codepoint, glyph->pos.x, glyph->pos.y, glyph->advance, glyph->color); }break; case piece_type_change_clip: { - Render_Piece_Change_Clip *clip = - ExtractStruct(Render_Piece_Change_Clip); + Render_Piece_Change_Clip *clip = ExtractStruct(Render_Piece_Change_Clip); draw_set_clip(target, clip->box); }break; } @@ -545,77 +551,28 @@ launch_rendering(Render_Target *target){ #undef internal #include #include FT_FREETYPE_H -#include FT_LCD_FILTER_H #define internal static -internal u32 -next_pow_of_2(u32 v){ - --v; - v |= v >> 1; - v |= v >> 2; - v |= v >> 4; - v |= v >> 8; - v |= v >> 16; - return ++v; -} - -#define NUM_GLYPHS 256 -#define ENABLE_LCD_FILTER 0 - -internal b32 -font_load_freetype(Partition *part, Render_Font *rf, char *filename, i32 pt_size, i32 tab_width, b32 use_hinting){ - - memset(rf, 0, sizeof(*rf)); - - //TODO(inso): put stuff in linuxvars / init in main - FT_Library ft; - FT_Face face; - b32 use_lcd_filter = 0; - - FT_Init_FreeType(&ft); - - //NOTE(inso): i'm not sure the LCD filter looks better, and it doesn't work perfectly with the coloring stuff - // it will probably need shaders to work properly -#if ENABLE_LCD_FILTER - if(FT_Library_SetLcdFilter(ft, FT_LCD_FILTER_DEFAULT) == 0){ - puts("LCD Filter on"); - use_lcd_filter = 1; - glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA); - } -#endif - - FT_New_Face(ft, filename, 0, &face); - - // set size & metrics - FT_Size_RequestRec_ size = {}; - size.type = FT_SIZE_REQUEST_TYPE_NOMINAL; - size.height = pt_size << 6; - FT_Request_Size(face, &size); - - rf->loaded = 1; - rf->ascent = ceil32 (face->size->metrics.ascender / 64.0f); - rf->descent = floor32 (face->size->metrics.descender / 64.0f); - rf->advance = ceil32 (face->size->metrics.max_advance / 64.0f); - rf->height = ceil32 (face->size->metrics.height / 64.0f); - rf->line_skip = rf->height - (rf->ascent - rf->descent); - - rf->height -= rf->line_skip; - rf->line_skip = 0; +internal void +font_load_page_inner(Partition *part, Render_Font *font, FT_Library ft, FT_Face face, b32 use_hinting, Glyph_Page *page, u32 page_number, i32 tab_width){ + Temp_Memory temp = begin_temp_memory(part); + Assert(page != 0); + page->page_number = page_number; + // prepare to read glyphs into a temporary texture buffer i32 max_glyph_w = face->size->metrics.x_ppem; - i32 max_glyph_h = rf->height; + i32 max_glyph_h = font_get_height(font); i32 tex_width = 64; i32 tex_height = 0; - // estimate upper bound on texture width do { tex_width *= 2; float glyphs_per_row = ceilf(tex_width / (float) max_glyph_w); - float rows = ceilf(NUM_GLYPHS / glyphs_per_row); + float rows = ceilf(ITEM_PER_FONT_PAGE / glyphs_per_row); tex_height = ceil32(rows * (max_glyph_h + 2)); } while(tex_height > tex_width); - tex_height = next_pow_of_2(tex_height); + tex_height = round_up_pot_u32(tex_height); i32 pen_x = 0; i32 pen_y = 0; @@ -623,132 +580,75 @@ font_load_freetype(Partition *part, Render_Font *rf, char *filename, i32 pt_size u32* pixels = push_array(part, u32, tex_width * tex_height); memset(pixels, 0, tex_width * tex_height * sizeof(u32)); - u32 ft_extra_flags = 0; - if (use_lcd_filter){ - ft_extra_flags = FT_LOAD_TARGET_LCD; + u32 ft_flags = FT_LOAD_RENDER; + if (use_hinting){ + // NOTE(inso): FT_LOAD_TARGET_LIGHT does hinting only vertically, which looks nicer imo + // maybe it could be exposed as an option for hinting, instead of just on/off. + ft_flags |= FT_LOAD_FORCE_AUTOHINT | FT_LOAD_TARGET_LIGHT; } else{ - if (use_hinting){ - // NOTE(inso): FT_LOAD_TARGET_LIGHT does hinting only vertically, which looks nicer imo - // maybe it could be exposed as an option for hinting, instead of just on/off. - ft_extra_flags = FT_LOAD_FORCE_AUTOHINT | FT_LOAD_TARGET_LIGHT; - } - else{ - ft_extra_flags = (FT_LOAD_NO_AUTOHINT | FT_LOAD_NO_HINTING); - } + ft_flags |= (FT_LOAD_NO_AUTOHINT | FT_LOAD_NO_HINTING); } - for(i32 i = 0; i < NUM_GLYPHS; ++i){ - if(FT_Load_Char(face, i, FT_LOAD_RENDER | ft_extra_flags) != 0) continue; + // fill the texture + u32 base_codepoint = (page_number << 8); + Glyph_Bounds *glyphs = &page->glyphs[0]; + Glyph_Bounds *glyph_ptr = glyphs; + + f32 *advances = &page->advance[0]; + f32 *advance_ptr = advances; + for(u32 i = 0; i < ITEM_PER_FONT_PAGE; ++i, ++glyph_ptr, ++advance_ptr){ + u32 codepoint = i + base_codepoint; - i32 w = face->glyph->bitmap.width; - i32 h = face->glyph->bitmap.rows; - - // lcd filter produces RGB bitmaps, need to account for the extra components - if(use_lcd_filter){ - w /= 3; - } - - // move to next line if necessary - if(pen_x + w >= tex_width){ - pen_x = 0; - pen_y += (max_glyph_h + 2); - } - - // set all this stuff the renderer needs - Glyph_Bounds* c = 0; - f32 *advance_ptr = 0; - get_codepoint_memory(rf, i, &c, &advance_ptr); - if (c != 0 && advance_ptr != 0){ - c->exists = true; + if(FT_Load_Char(face, codepoint, ft_flags) == 0){ + i32 w = face->glyph->bitmap.width; + i32 h = face->glyph->bitmap.rows; - c->x0 = (f32)(pen_x); - c->y0 = (f32)(pen_y); - c->x1 = (f32)(pen_x + w); - c->y1 = (f32)(pen_y + h + 1); + i32 ascent = font_get_ascent(font); - c->xoff = (f32)(face->glyph->bitmap_left); - c->yoff = (f32)(rf->ascent - face->glyph->bitmap_top); + // move to next line if necessary + if(pen_x + w >= tex_width){ + pen_x = 0; + pen_y += (max_glyph_h + 2); + } - c->xoff2 = w + c->xoff; - c->yoff2 = h + c->yoff + 1; + // set all this stuff the renderer needs + glyph_ptr->x0 = (f32)(pen_x); + glyph_ptr->y0 = (f32)(pen_y); + glyph_ptr->x1 = (f32)(pen_x + w); + glyph_ptr->y1 = (f32)(pen_y + h + 1); - // TODO(allen): maybe advance data should be integers for a while... - // I require the actual values to be integers anyway... hmm... - f32 advance = (f32)ceil32(face->glyph->advance.x / 64.0f); - *advance_ptr = advance; + glyph_ptr->xoff = (f32)(face->glyph->bitmap_left); + glyph_ptr->yoff = (f32)(ascent - face->glyph->bitmap_top); + glyph_ptr->xoff2 = glyph_ptr->xoff + w; + glyph_ptr->yoff2 = glyph_ptr->yoff + h + 1; + + // TODO(allen): maybe advance data should be integers? + *advance_ptr = (f32)ceil32(face->glyph->advance.x / 64.0f); // write to texture atlas i32 pitch = face->glyph->bitmap.pitch; - for(i32 j = 0; j < h; ++j){ - for(i32 i = 0; i < w; ++i){ - i32 x = pen_x + i; - i32 y = pen_y + j; + for(i32 Y = 0; Y < h; ++Y){ + for(i32 X = 0; X < w; ++X){ + i32 x = pen_x + X; + i32 y = pen_y + Y; - if(use_lcd_filter){ -#if 1 - u8 a = face->glyph->bitmap.buffer[j * pitch + i * 3 + 1]; - u8 r = face->glyph->bitmap.buffer[j * pitch + i * 3 + 0]; - u8 b = face->glyph->bitmap.buffer[j * pitch + i * 3 + 2]; - - pixels[y * tex_width + x] = (a << 24) | (b << 16) | (a << 8) | r; - -#else - - u8 r = face->glyph->bitmap.buffer[j * pitch + i * 3]; - u8 g = face->glyph->bitmap.buffer[j * pitch + i * 3 + 1]; - u8 b = face->glyph->bitmap.buffer[j * pitch + i * 3 + 2]; - u8 a = (u8)ROUND32((r + g + b) / 3.0f); - - pixels[y * tex_width + x] = (a << 24) | (r << 16) | (g << 8) | b; -#endif - } else { - pixels[y * tex_width + x] = face->glyph->bitmap.buffer[j * pitch + i] * 0x1010101; - } + pixels[y * tex_width + x] = face->glyph->bitmap.buffer[Y * pitch + X] * 0x01010101; } } - pen_x = ceil32(c->x1 + 1); + pen_x = ceil32(glyph_ptr->x1 + 1); } } - // NOTE(allen): Setup some basic spacing stuff. - f32 space_adv = get_codepoint_advance(rf, ' '); - f32 backslash_adv = get_codepoint_advance(rf, '\\'); - f32 r_adv = get_codepoint_advance(rf, 'r'); - - set_codepoint_advance(rf, '\n', space_adv); - set_codepoint_advance(rf, '\r', backslash_adv + r_adv); - set_codepoint_advance(rf, '\t', space_adv*tab_width); - - f32 max_hex_advance = 0.f; - for (u32 i = '0'; i <= '9'; ++i){ - f32 adv = get_codepoint_advance(rf, i); - max_hex_advance = Max(max_hex_advance, adv); - } - for (u32 i = 'a'; i <= 'f'; ++i){ - f32 adv = get_codepoint_advance(rf, i); - max_hex_advance = Max(max_hex_advance, adv); - } - for (u32 i = 'A'; i <= 'F'; ++i){ - f32 adv = get_codepoint_advance(rf, i); - max_hex_advance = Max(max_hex_advance, adv); - } - - rf->byte_advance = backslash_adv + max_hex_advance*2; - - FT_Done_FreeType(ft); - - tex_height = next_pow_of_2(pen_y + max_glyph_h + 2); - - u32 page_index = 0; - rf->glyph_pages[page_index].tex_width = tex_width; - rf->glyph_pages[page_index].tex_height = tex_height; - // upload texture - u32 tex; - glGenTextures(1, &tex); - glBindTexture(GL_TEXTURE_2D, tex); + tex_height = round_up_pot_u32(pen_y + max_glyph_h + 2); + + page->tex_width = tex_width; + page->tex_height = tex_height; + + glGenTextures(1, &page->tex); + glBindTexture(GL_TEXTURE_2D, page->tex); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); @@ -756,30 +656,154 @@ font_load_freetype(Partition *part, Render_Font *rf, char *filename, i32 pt_size glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0); - if(use_lcd_filter){ - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tex_width, tex_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels); - } else { - glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, tex_width, tex_height, 0, GL_ALPHA, GL_UNSIGNED_INT, pixels); - } + glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, tex_width, tex_height, 0, GL_ALPHA, GL_UNSIGNED_INT, pixels); glBindTexture(GL_TEXTURE_2D, 0); - rf->glyph_pages[page_index].tex = tex; - rf->glyph_pages[page_index].exists = true; + end_temp_memory(temp); + + // whitespace spacing stuff + if (page_number == 0){ + f32 space_adv = advances[' ']; + f32 backslash_adv = advances['\\']; + f32 r_adv = advances['r']; + + advances['\n'] = space_adv; + advances['\r'] = backslash_adv + r_adv; + advances['\t'] = space_adv*tab_width; + } +} + +internal b32 +font_load_page(System_Functions *system, Partition *part, Render_Font *font, Glyph_Page *page, u32 page_number, u32 pt_size, b32 use_hinting){ + + char *filename = font->filename; + + // TODO(allen): Stop redoing all this init for each call. + FT_Library ft; + FT_Init_FreeType(&ft); + + FT_Face face; + FT_New_Face(ft, filename, 0, &face); + + FT_Size_RequestRec_ size = {}; + size.type = FT_SIZE_REQUEST_TYPE_NOMINAL; + size.height = pt_size << 6; + FT_Request_Size(face, &size); + + // NOTE(allen): set texture and glyph data. + font_load_page_inner(part, font, ft, face, use_hinting, page, page_number, 4); + + FT_Done_FreeType(ft); return(true); } -internal -Release_Font_Sig(draw_release_font){ - for (u32 i = 0; i < ArrayCount(font->glyph_pages); ++i){ - Glyph_Page *page = &font->glyph_pages[i]; - if (page->exists){ - glDeleteTextures(1, &page->tex); +internal b32 +font_load(System_Functions *system, Partition *part, Render_Font *font, i32 pt_size, b32 use_hinting){ + + char *filename = font->filename; + + // TODO(allen): Stop redoing all this init for each call. + FT_Library ft; + FT_Init_FreeType(&ft); + + FT_Face face; + FT_New_Face(ft, filename, 0, &face); + + FT_Size_RequestRec_ size = {}; + size.type = FT_SIZE_REQUEST_TYPE_NOMINAL; + size.height = pt_size << 6; + FT_Request_Size(face, &size); + + // set size & metrics + font->ascent = ceil32 (face->size->metrics.ascender / 64.0f); + font->descent = floor32 (face->size->metrics.descender / 64.0f); + font->advance = ceil32 (face->size->metrics.max_advance / 64.0f); + font->height = ceil32 (face->size->metrics.height / 64.0f); + font->line_skip = font->height - (font->ascent - font->descent); + + font->height -= font->line_skip; + font->line_skip = 0; + + // NOTE(allen): set texture and glyph data. + Glyph_Page *page = font_get_or_make_page(system, font, 0); + + // NOTE(allen): Setup some basic spacing stuff. + f32 backslash_adv = page->advance['\\']; + f32 max_hex_advance = 0.f; + for (u32 i = '0'; i <= '9'; ++i){ + f32 adv = page->advance[i]; + max_hex_advance = Max(max_hex_advance, adv); + } + for (u32 i = 'a'; i <= 'f'; ++i){ + f32 adv = page->advance[i]; + max_hex_advance = Max(max_hex_advance, adv); + } + for (u32 i = 'A'; i <= 'F'; ++i){ + f32 adv = page->advance[i]; + max_hex_advance = Max(max_hex_advance, adv); + } + + font->byte_advance = backslash_adv + max_hex_advance*2; + font->byte_sub_advances[0] = backslash_adv; + font->byte_sub_advances[1] = max_hex_advance; + font->byte_sub_advances[2] = max_hex_advance; + + FT_Done_FreeType(ft); + + return(true); +} + +internal void +system_set_page(System_Functions *system, Partition *part, Render_Font *font, Glyph_Page *page, u32 page_number, u32 pt_size, b32 use_hinting){ + memset(page, 0, sizeof(*page)); + + if (part->base == 0){ + *part = sysshared_scratch_partition(MB(8)); + } + + b32 success = false; + for (u32 R = 0; R < 3; ++R){ + success = font_load_page(system, part, font, page, page_number, pt_size, use_hinting); + if (success){ + break; + } + else{ + sysshared_partition_double(part); } - page->tex = 0; } } +internal void +system_set_font(System_Functions *system, Partition *part, Render_Font *font, String filename, String name, u32 pt_size, b32 use_hinting){ + memset(font, 0, sizeof(*font)); + + copy_partial_cs(font->filename, sizeof(font->filename)-1, filename); + font->filename_len = filename.size; + font->filename[font->filename_len] = 0; + copy_partial_cs(font->name, sizeof(font->name)-1, name); + font->name_len = name.size; + font->name[font->name_len] = 0; + + if (part->base == 0){ + *part = sysshared_scratch_partition(MB(8)); + } + + b32 success = false; + for (u32 R = 0; R < 3; ++R){ + success = font_load(system, part, font, pt_size, use_hinting); + if (success){ + break; + } + else{ + sysshared_partition_double(part); + } + } +} + + +#endif + // BOTTOM diff --git a/4ed_system_shared.h b/4ed_system_shared.h index 108f23b4..dd52d280 100644 --- a/4ed_system_shared.h +++ b/4ed_system_shared.h @@ -14,6 +14,9 @@ // the application code, but system_shared.cpp // rely on the functions listed here. +#if !defined(FRED_SYSTEM_SHARED_H) +#define FRED_SYSTEM_SHARED_H + struct File_Data{ char *data; u32 size; @@ -33,5 +36,7 @@ internal Sys_Get_Binary_Path_Sig(system_get_binary_path); #define system_get_memory(size) system_get_memory_((size), __LINE__, __FILE__) +#endif + // BOTTOM diff --git a/4ed_translation.cpp b/4ed_translation.cpp new file mode 100644 index 00000000..259240c0 --- /dev/null +++ b/4ed_translation.cpp @@ -0,0 +1,244 @@ +/* + * Mr. 4th Dimention - Allen Webster + * + * 11.03.2017 + * + * Translation system for turning byte streams into a stream of buffer model steps. + * + */ + +// TOP + +#include "4ed_buffer_model.h" + +struct Translation_State{ + u8 fill_buffer[4]; + u32 fill_start_i; + u8 fill_i; + u8 fill_expected; +}; +global_const Translation_State null_buffer_translating_state = {0}; + +enum{ + TranLBH_None, + TranLBH_Rebuffer, + TranLBH_EmitAsCP, +}; +struct Translation_Byte_Description{ + u8 byte_class; + u8 last_byte_handler; + u8 prelim_emit_type; +}; + +struct Translation_Emit_Rule{ + u8 byte_class; + u8 last_byte_handler; + u8 emit_type; + + u32 codepoint; + u32 codepoint_length; +}; + +struct Translation_Emits{ + Buffer_Model_Step steps[5]; + u32 step_count; +}; + +#define SINGLE_BYTE_ERROR_CLASS max_u8 + +internal void +translating_consume_byte(Translation_State *tran, u8 ch, u32 i, u32 size, Translation_Byte_Description *desc_out){ + desc_out->byte_class = 0; + if ((ch >= ' ' && ch < 0x7F) || ch == '\t' || ch == '\n' || ch == '\r'){ + desc_out->byte_class = 1; + } + else if (ch < 0xC0){ + desc_out->byte_class = SINGLE_BYTE_ERROR_CLASS; + } + else if (ch < 0xE0){ + desc_out->byte_class = 2; + } + else if (ch < 0xF0){ + desc_out->byte_class = 3; + } + else{ + desc_out->byte_class = 4; + } + + desc_out->prelim_emit_type = BufferModelUnit_None; + desc_out->last_byte_handler = TranLBH_None; + if (tran->fill_expected == 0){ + tran->fill_buffer[0] = ch; + tran->fill_start_i = i; + tran->fill_i = 1; + + if (desc_out->byte_class == 1){ + desc_out->prelim_emit_type = BufferModelUnit_Codepoint; + } + else if (desc_out->byte_class == 0 || desc_out->byte_class == SINGLE_BYTE_ERROR_CLASS){ + desc_out->prelim_emit_type = BufferModelUnit_Numbers; + } + else{ + tran->fill_expected = desc_out->byte_class; + } + } + else{ + if (desc_out->byte_class == SINGLE_BYTE_ERROR_CLASS){ + tran->fill_buffer[tran->fill_i] = ch; + ++tran->fill_i; + + if (tran->fill_i == tran->fill_expected){ + desc_out->prelim_emit_type = BufferModelUnit_Codepoint; + } + } + else{ + if (desc_out->byte_class >= 2 && desc_out->byte_class <= 4){ + desc_out->last_byte_handler = TranLBH_Rebuffer; + } + else if (desc_out->byte_class == 1){ + desc_out->last_byte_handler = TranLBH_EmitAsCP; + } + else{ + tran->fill_buffer[tran->fill_i] = ch; + ++tran->fill_i; + } + desc_out->prelim_emit_type = BufferModelUnit_Numbers; + } + } + + if (desc_out->prelim_emit_type == BufferModelUnit_None && i+1 == size){ + desc_out->prelim_emit_type = BufferModelUnit_Numbers; + } +} + +internal void +translating_select_emit_rule_ASCII(Translation_State *tran, Translation_Byte_Description desc, Translation_Emit_Rule *type_out){ + type_out->byte_class = desc.byte_class; + type_out->last_byte_handler = desc.last_byte_handler; + type_out->emit_type = desc.prelim_emit_type; + + type_out->codepoint = 0; + type_out->codepoint_length = 0; + if (desc.prelim_emit_type == BufferModelUnit_Codepoint){ + u32 cp = utf8_to_u32_length_unchecked(tran->fill_buffer, &type_out->codepoint_length); + type_out->codepoint = cp; + if (!(cp == '\n' || cp == '\t' || cp == '\r' || (cp >= ' ' && cp <= 255 && cp != 127))){ + type_out->emit_type = BufferModelUnit_Numbers; + } + } +} + +internal void +translating_select_emit_rule_with_font(System_Functions *system, Render_Font *font, Translation_State *tran, Translation_Byte_Description desc, Translation_Emit_Rule *type_out){ + type_out->byte_class = desc.byte_class; + type_out->last_byte_handler = desc.last_byte_handler; + type_out->emit_type = desc.prelim_emit_type; + + type_out->codepoint = 0; + type_out->codepoint_length = 0; + if (desc.prelim_emit_type == BufferModelUnit_Codepoint){ + u32 cp = utf8_to_u32_length_unchecked(tran->fill_buffer, &type_out->codepoint_length); + type_out->codepoint = cp; + if (!font_can_render(system, font, cp)){ + type_out->emit_type = BufferModelUnit_Numbers; + } + } +} + +internal void +translating_generate_emits(Translation_State *tran, Translation_Emit_Rule emit_rule, u8 ch, u32 i, Translation_Emits *emits_out){ + emits_out->step_count = 0; + switch (emit_rule.emit_type){ + default: goto skip_all; + + case BufferModelUnit_Codepoint: + { + emits_out->steps[0].type = 1; + emits_out->steps[0].value = emit_rule.codepoint; + emits_out->steps[0].i = tran->fill_start_i; + emits_out->steps[0].byte_length = emit_rule.codepoint_length; + emits_out->step_count = 1; + }break; + + case BufferModelUnit_Numbers: + { + for (u32 j = 0; j < tran->fill_i; ++j){ + emits_out->steps[j].type = 0; + emits_out->steps[j].value = tran->fill_buffer[j]; + emits_out->steps[j].i = tran->fill_start_i + j; + emits_out->steps[j].byte_length = 1; + } + emits_out->step_count = tran->fill_i; + }break; + } + + tran->fill_start_i = 0; + tran->fill_i = 0; + tran->fill_expected = 0; + + switch (emit_rule.last_byte_handler){ + case TranLBH_Rebuffer: + { + tran->fill_buffer[0] = ch; + tran->fill_start_i = i; + tran->fill_i = 1; + tran->fill_expected = emit_rule.byte_class; + }break; + + case TranLBH_EmitAsCP: + { + emits_out->steps[emits_out->step_count].type = 1; + emits_out->steps[emits_out->step_count].value = ch; + emits_out->steps[emits_out->step_count].i = i; + emits_out->steps[emits_out->step_count].byte_length = 1; + ++emits_out->step_count; + }break; + } + + skip_all:; +} + +internal void +translating_fully_process_byte(System_Functions *system, Render_Font *font, Translation_State *tran, u8 ch, u32 i, u32 size, Translation_Emits *emits_out){ + Translation_Byte_Description description = {0}; + translating_consume_byte(tran, ch, i, size, &description); + Translation_Emit_Rule emit_rule = {0}; + translating_select_emit_rule_with_font(system, font, tran, description, &emit_rule); + translating_generate_emits(tran, emit_rule, ch, i, emits_out); +} + +internal void +translation_step_read(Buffer_Model_Step step, Buffer_Model_Behavior *behavior_out){ + behavior_out->do_newline = false; + behavior_out->do_codepoint_advance = false; + behavior_out->do_number_advance = false; + if (step.type == 1){ + switch (step.value){ + case '\n': + { + behavior_out->do_newline = true; + }break; + default: + { + behavior_out->do_codepoint_advance = true; + }break; + } + } + else{ + behavior_out->do_number_advance = true; + } +} + +#define TRANSLATION_DECL_EMIT_LOOP(_j,_emit) u32 _j = 0; _j < (_emit).step_count; ++_j +#define TRANSLATION_DECL_GET_STEP(_step,_behav,_j,_emit) \ +Buffer_Model_Step _step = _emit.steps[_j]; Buffer_Model_Behavior _behav; \ +translation_step_read(_step, &_behav) + +#define TRANSLATION_EMIT_LOOP(_j,_emit) _j = 0; _j < (_emit).step_count; ++_j +#define TRANSLATION_GET_STEP(_step,_behav,_j,_emit)\ +(_step) = _emit.steps[_j]; translation_step_read((_step), &(_behav)) + +// BOTTOM + + + diff --git a/file/4coder_undo.cpp b/4ed_undo.cpp similarity index 100% rename from file/4coder_undo.cpp rename to 4ed_undo.cpp diff --git a/file/4coder_working_set.cpp b/4ed_working_set.cpp similarity index 98% rename from file/4coder_working_set.cpp rename to 4ed_working_set.cpp index 6c103056..4150c39f 100644 --- a/file/4coder_working_set.cpp +++ b/4ed_working_set.cpp @@ -67,24 +67,20 @@ tbl_name_compare(void *a, void *b, void *arg){ internal void working_set_extend_memory(Working_Set *working_set, Editing_File *new_space, i16 number_of_files){ - Buffer_Slot_ID id; - i16 i, high_part; - Editing_File *file_ptr; - File_Node *free_sentinel; - Assert(working_set->array_count < working_set->array_max); - high_part = working_set->array_count++; + i16 high_part = working_set->array_count++; working_set->file_arrays[high_part].files = new_space; working_set->file_arrays[high_part].size = number_of_files; working_set->file_max += number_of_files; + Buffer_Slot_ID id = {0}; id.part[1] = high_part; - file_ptr = new_space; - free_sentinel = &working_set->free_sentinel; - for (i = 0; i < number_of_files; ++i, ++file_ptr){ + Editing_File *file_ptr = new_space; + File_Node *free_sentinel = &working_set->free_sentinel; + for (i16 i = 0; i < number_of_files; ++i, ++file_ptr){ id.part[0] = i; file_ptr->id = id; dll_insert(free_sentinel, &file_ptr->node); diff --git a/4tech_defines.h b/4tech_defines.h index f916793a..93ae61da 100644 --- a/4tech_defines.h +++ b/4tech_defines.h @@ -60,33 +60,44 @@ typedef double f64; #define Min(a,b) (((a)<(b))?(a):(b)) inline i32 ceil32(f32 v){ - return(((v)>0)?( (v == (i32)(v))?((i32)(v)):((i32)((v)+1.f)) ):( ((i32)(v)) )); - } - - inline i32 floor32(f32 v){ - return(((v)<0)?( (v == (i32)(v))?((i32)(v)):((i32)((v)-1.f)) ):( ((i32)(v)) )); - } - - inline i32 round32(f32 v){ - return(floor32(v + 0.5f)); - } - - inline i32 trun32(f32 v){ - return((i32)(v)); - } - - inline i32 div_ceil(i32 n, i32 d){ - return( ((n) % (d) != 0) + ((n) / (d)) ); - } - - inline i32 l_round_up_i32(i32 x, i32 b){ -return( ((x)+(b)-1) - (((x)+(b)-1)%(b)) ); - } - - inline u32 l_round_up_u32(u32 x, u32 b){ - return( ((x)+(b)-1) - (((x)+(b)-1)%(b)) ); - } - + return(((v)>0)?( (v == (i32)(v))?((i32)(v)):((i32)((v)+1.f)) ):( ((i32)(v)) )); +} + +inline i32 floor32(f32 v){ + return(((v)<0)?( (v == (i32)(v))?((i32)(v)):((i32)((v)-1.f)) ):( ((i32)(v)) )); +} + +inline i32 round32(f32 v){ + return(floor32(v + 0.5f)); +} + +inline i32 trun32(f32 v){ + return((i32)(v)); +} + +inline i32 div_ceil(i32 n, i32 d){ + return( ((n) % (d) != 0) + ((n) / (d)) ); +} + +inline i32 l_round_up_i32(i32 x, i32 b){ + return( ((x)+(b)-1) - (((x)+(b)-1)%(b)) ); +} + +inline u32 l_round_up_u32(u32 x, u32 b){ + return( ((x)+(b)-1) - (((x)+(b)-1)%(b)) ); +} + +inline u32 round_up_pot_u32(u32 x){ + --x; + x |= x >> 1; + x |= x >> 2; + x |= x >> 4; + x |= x >> 8; + x |= x >> 16; + ++x; + return(x); +} + #define STR__(s) #s #define STR_(s) STR__(s) diff --git a/README.txt b/README.txt deleted file mode 100644 index 7d4abba0..00000000 --- a/README.txt +++ /dev/null @@ -1,175 +0,0 @@ -Distribution Date: 2.9.2016 (dd.mm.yyyy) - -Thank you for contributing to the 4coder project! - -To submit bug reports or to request particular features email editor@4coder.net. - -Watch 4coder.net blog and @AllenWebster4th twitter for news about 4coder progress. - ---------------------------------- -FAIR WARNING ---------------------------------- - -THINGS WILL GET CRASHY FAST IF ANY .ttf FILES ARE MISSING. -THIS EFFECT WILL ALSO OCCUR IF YOU LAUNCH FROM A DIRECTORY -THAT DOESN'T CONTAIN THE .ttf FILES. (This problem will be -fixed eventually). - -This build is extremely "janky" for lack of a better term. From what limitted testing -I have been able to do I think it should run on a Windows 7 machine. It has not been -launched at all on any other version of Windows. I have done what I can to get rid of -the bugs and crashes that would make it unusable, but there are certainly more in there -if you start digging and pressing hard enough. - -**Please USE SOURCE CONTROL WITH 4CODER for now** - ------------------------------------------------------ -INSTRUCTIONS FOR USE ------------------------------------------------------ - -****Command line options**** -4ed [] [options] - --d/-D -- use a dll other than 4coder_custom.dll for your customizations - -d -- if the file isn't found look for 4coder_custom.dll - -D -- only look for the specified - --i -- line number to jump to in first file to open specified on command line - --w -- width and height of the 4coder window --p -- position of the 4coder window - --W -- open in full screen, overrides -w and -p, although the size will still be the default size of the window - --T -- invoke special tool isntead of launching 4coder normally - -T version : prints the 4coder version string - -****Command Bindings**** -Basic Navigation: -mouse left click - move cursor -mouse right click - set mark -arrows - move cursor -home & end - move cursor to beginning/end of line -page up & page down - move up/down by close to the height of the entire screen -control + left/right - move cursor left/right to first whitespace -control + up/down - move cursor up or down to first blank line - -Fancy Navigation: -control + f : begin find mode, uses interaction bar -control + r : begin reverse-find mode, uses interaction bar - -control + F : list all locations of a word in all open buffers, uses interaction bar - > This command creates a *search* buffer that displays the locations and the line of each - > occurence of the requested word. By positioning the cursor and pressing return the user - > jump to the word's occurence. - -While in find mode or reverse-find mode, pressing enter ends the mode -leaving the cursor wherever the find highlighter is, and pressing escape -ends the mode leaving the cursor wherever it was before the find mode began. - -control + g - goto line number, uses interaction bar -control + m - swap cursor and mark - -control + e - center the view vertically on the cursor -control + E - in a view with unwrapped lines move the view to a position just left of the cursor - -Basic Editing: -characters keys, delete, and backspace -control + c : copy between cursor and mark -control + x : cut between cursor and mark -control + v : paste at cursor -control + V : use after normal paste to cycle through older copied text -control + d : delete between cursor and mark -control + SPACE : set mark to cursor -control + backspace : backspace one word -control + delete : delete one word -alt + backspace : snipe one word - -Undo and History: -control + z : undo -control + y : redo -control + h: history back step -control + H: history forward step - -Fancy Editing: -control + u : to uppercase between cursor and mark -control + j : to lowercase between cursor and mark -control + q : query replace -control + a : replace in range -control + ~ : clean the trailing whitespace off of all lines - -Fancy Editing in Code Files: -control + [ : write "{}" pair with cursor in line between -control + { : as control + [ with a semicolon after "}" -control + } : as control + [ with a "break;" after "}" -control + 0 : write "= {0};" at the cursor -control + i : wrap the range specified by mark and cursor in #if 0 #endif - -alt + 1 : if cursor is inside a string, treat the string as a filename and - > try to open the file with that name in the other panel - -Whitespace Boringness: -Typing characters: },],),; and inserting newlines cause the line to autotab -TAB: word complete -control + TAB : auto indent lines between cursor and mark -shift + TAB: auto indent cursor line -control + 1 : set the file to dos mode for writing to disk -control + ! : set the flie to nix mode for writing to disk - -Viewing Options: -alt + c - open theme selection UI -alt + d - open debug view - -control + p : vertically split the current panel (max 16) -control + _ : horizontally split the current panel (max 16) -control + P : close the currently selected panel -control + , : switch to another panel - -control + l : toggle line wrapping -control + ? : toggle highlight whitespace mode - -f2 : toggle mouse suppresion mode - -alt + s : show the scrollbar in this view -alt + w : hide the scrollbar in this view - -Build Tools: -alt + m : -[On Windows] search in the current hot directory and up through all parent - > directories for a build.bat, and execute that bat if it discovered, sending - > output to the buffer *compilation* -[On Linux] The behavior is similar but the search looks for build.sh and if that - > fails it looks for a Makefile - -alt + . : change to the build panel -alt + , : close the build panel -alt + n : goto the next error listed in the build panel -alt + N : goto the previous error listed in the build panel -alt + M : goto the first error listed in the build panel - -alt + z : execute any command line command you specify and send the output to the buffer you specify -alt + Z : repeat the command previously executed by the alt + z command - -File Managing: -control + n : create a new file, begins interactive input mode -control + o : open file, begins interactive input mode -alt + o : open file in other panel, same as control + o but runs first changes the active view -control + O : reopen the current file - (discarding any differences the live version has from the file system's version) -control + s : save -control + w : save as, begins interative input mode -control + i : switch active file in this panel, begins interactive input mode -control + k : kill (close) a file, begins interactive input mode -control + K : kill (close) the file being viewed in the currently active panel - -While in interactive input mode, there are several ways to select an option. -The options can be clicked. One option is always highlighted and pressing -return or tab will select the highlighted option. Arrow keys navigate the -highlighted option. Typing in characters narrows down the list of options. - -Menu UI -Keyboard options: - > left control + left alt act as AltGr - -Theme selection UI -esc - close UI view return to major view if one was open previously diff --git a/README_body.txt b/README_body.txt deleted file mode 100644 index f340212d..00000000 --- a/README_body.txt +++ /dev/null @@ -1,167 +0,0 @@ ---------------------------------- -FAIR WARNING ---------------------------------- - -THINGS WILL GET CRASHY FAST IF ANY .ttf FILES ARE MISSING. -THIS EFFECT WILL ALSO OCCUR IF YOU LAUNCH FROM A DIRECTORY -THAT DOESN'T CONTAIN THE .ttf FILES. (This problem will be -fixed eventually). - -This build is extremely "janky" for lack of a better term. From what limitted testing -I have been able to do I think it should run on a Windows 7 machine. It has not been -launched at all on any other version of Windows. I have done what I can to get rid of -the bugs and crashes that would make it unusable, but there are certainly more in there -if you start digging and pressing hard enough. - -**Please USE SOURCE CONTROL WITH 4CODER for now** - ------------------------------------------------------ -INSTRUCTIONS FOR USE ------------------------------------------------------ - -****Command line options**** -4ed [] [options] - --d/-D -- use a dll other than 4coder_custom.dll for your customizations - -d -- if the file isn't found look for 4coder_custom.dll - -D -- only look for the specified - --i -- line number to jump to in first file to open specified on command line - --w -- width and height of the 4coder window --p -- position of the 4coder window - --W -- open in full screen, overrides -w and -p, although the size will still be the default size of the window - --T -- invoke special tool isntead of launching 4coder normally - -T version : prints the 4coder version string - -****Command Bindings**** -Basic Navigation: -mouse left click - move cursor -mouse right click - set mark -arrows - move cursor -home & end - move cursor to beginning/end of line -page up & page down - move up/down by close to the height of the entire screen -control + left/right - move cursor left/right to first whitespace -control + up/down - move cursor up or down to first blank line - -Fancy Navigation: -control + f : begin find mode, uses interaction bar -control + r : begin reverse-find mode, uses interaction bar - -control + F : list all locations of a word in all open buffers, uses interaction bar - > This command creates a *search* buffer that displays the locations and the line of each - > occurence of the requested word. By positioning the cursor and pressing return the user - > jump to the word's occurence. - -While in find mode or reverse-find mode, pressing enter ends the mode -leaving the cursor wherever the find highlighter is, and pressing escape -ends the mode leaving the cursor wherever it was before the find mode began. - -control + g - goto line number, uses interaction bar -control + m - swap cursor and mark - -control + e - center the view vertically on the cursor -control + E - in a view with unwrapped lines move the view to a position just left of the cursor - -Basic Editing: -characters keys, delete, and backspace -control + c : copy between cursor and mark -control + x : cut between cursor and mark -control + v : paste at cursor -control + V : use after normal paste to cycle through older copied text -control + d : delete between cursor and mark -control + SPACE : set mark to cursor -control + backspace : backspace one word -control + delete : delete one word -alt + backspace : snipe one word - -Undo and History: -control + z : undo -control + y : redo -control + h: history back step -control + H: history forward step - -Fancy Editing: -control + u : to uppercase between cursor and mark -control + j : to lowercase between cursor and mark -control + q : query replace -control + a : replace in range -control + ~ : clean the trailing whitespace off of all lines - -Fancy Editing in Code Files: -control + [ : write "{}" pair with cursor in line between -control + { : as control + [ with a semicolon after "}" -control + } : as control + [ with a "break;" after "}" -control + 0 : write "= {0};" at the cursor -control + i : wrap the range specified by mark and cursor in #if 0 #endif - -alt + 1 : if cursor is inside a string, treat the string as a filename and - > try to open the file with that name in the other panel - -Whitespace Boringness: -Typing characters: },],),; and inserting newlines cause the line to autotab -TAB: word complete -control + TAB : auto indent lines between cursor and mark -shift + TAB: auto indent cursor line -control + 1 : set the file to dos mode for writing to disk -control + ! : set the flie to nix mode for writing to disk - -Viewing Options: -alt + c - open theme selection UI -alt + d - open debug view - -control + p : vertically split the current panel (max 16) -control + _ : horizontally split the current panel (max 16) -control + P : close the currently selected panel -control + , : switch to another panel - -control + l : toggle line wrapping -control + ? : toggle highlight whitespace mode - -f2 : toggle mouse suppresion mode - -alt + s : show the scrollbar in this view -alt + w : hide the scrollbar in this view - -Build Tools: -alt + m : -[On Windows] search in the current hot directory and up through all parent - > directories for a build.bat, and execute that bat if it discovered, sending - > output to the buffer *compilation* -[On Linux] The behavior is similar but the search looks for build.sh and if that - > fails it looks for a Makefile - -alt + . : change to the build panel -alt + , : close the build panel -alt + n : goto the next error listed in the build panel -alt + N : goto the previous error listed in the build panel -alt + M : goto the first error listed in the build panel - -alt + z : execute any command line command you specify and send the output to the buffer you specify -alt + Z : repeat the command previously executed by the alt + z command - -File Managing: -control + n : create a new file, begins interactive input mode -control + o : open file, begins interactive input mode -alt + o : open file in other panel, same as control + o but runs first changes the active view -control + O : reopen the current file - (discarding any differences the live version has from the file system's version) -control + s : save -control + w : save as, begins interative input mode -control + i : switch active file in this panel, begins interactive input mode -control + k : kill (close) a file, begins interactive input mode -control + K : kill (close) the file being viewed in the currently active panel - -While in interactive input mode, there are several ways to select an option. -The options can be clicked. One option is always highlighted and pressing -return or tab will select the highlighted option. Arrow keys navigate the -highlighted option. Typing in characters narrows down the list of options. - -Menu UI -Keyboard options: - > left control + left alt act as AltGr - -Theme selection UI -esc - close UI view return to major view if one was open previously diff --git a/build.bat b/build.bat index 386d1699..826c7e09 100644 --- a/build.bat +++ b/build.bat @@ -11,7 +11,7 @@ SET BUILD_MODE=%1 if "%BUILD_MODE%" == "" (SET BUILD_MODE="/DDEV_BUILD") pushd ..\build -cl %OPTS% ..\code\meta\build.cpp /Zi /Febuild %BUILD_MODE% +cl %OPTS% kernel32.lib ..\code\meta\build.cpp /Zi /Febuild %BUILD_MODE% if %ERRORLEVEL% neq 0 (set FirstError=1) if %ERRORLEVEL% neq 0 (goto END) popd diff --git a/buildsuper.bat b/buildsuper.bat index 0e4b2c61..8fe10a30 100644 --- a/buildsuper.bat +++ b/buildsuper.bat @@ -1,5 +1,6 @@ @echo off +REM TODO(allen): Figure out a way to find vcvarsall for any MSVC version. IF NOT DEFINED LIB (call "C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\vcvarsall.bat" amd64) SET SRC=%1 @@ -15,9 +16,10 @@ REM This stores the path of the buildsuper.bat script REM in CODE_HOME. This way you can always include the REM default files no matter where you store your code. REM And no matter how you call buildsuper.bat. + SET CODE_HOME=%~dp0 -cl /I%CODE_HOME% %OPTS% %DEBUG% %SRC% /Fecustom_4coder %BUILD_DLL% %EXPORTS% +cl %OPTS% /I"%CODE_HOME% " %DEBUG% "%SRC%" /Fecustom_4coder %BUILD_DLL% %EXPORTS% REM file spammation preventation del *.exp diff --git a/file/4coder_font_data.h b/file/4coder_font_data.h deleted file mode 100644 index ab0afd5b..00000000 --- a/file/4coder_font_data.h +++ /dev/null @@ -1,137 +0,0 @@ -/* - * Mr. 4th Dimention - Allen Webster - * - * 03.03.2017 - * - * Font data type definitions. - * - */ - -// TOP - -#if !defined(FCODER_FONT_DATA_H) -#define FCODER_FONT_DATA_H - -#define FONT_PAGE_ITEMS 256 - -struct Glyph_Bounds{ - b32 exists; - - f32 x0, x1; - f32 y0, y1; - - f32 xoff, yoff; - f32 xoff2, yoff2; -}; - -struct Glyph_Page{ - Glyph_Bounds glyphs[256]; - u32 tex; - i32 tex_width, tex_height; - b32 exists; -}; - -struct Glyph_Data{ - Glyph_Bounds bounds; - u32 tex; - i32 tex_width, tex_height; -}; - -struct Advance_Page{ - f32 advance[256]; -}; - -struct Render_Font{ - char name_[24]; - String name; - b32 loaded; - - Glyph_Page glyph_pages[1]; - Advance_Page advance_pages[1]; - - f32 byte_advance; - i32 height, ascent, descent, line_skip; - i32 advance; -}; - -internal b32 -get_codepoint_can_render(Render_Font *font, u32 codepoint){ - b32 exists = false; - if (codepoint < FONT_PAGE_ITEMS){ - exists = true; - } - return(exists); -} - -internal u32 -get_codepoint_page_index(Render_Font *font, u32 codepoint, u32 *page_base_codepoint){ - *page_base_codepoint = 0; - return(0); -} - -internal void -get_codepoint_memory(Render_Font *font, u32 codepoint, Glyph_Bounds **bounds_mem_out, f32 **advance_mem_out){ - Glyph_Bounds *bounds = 0; - f32 *advance = 0; - - if (get_codepoint_can_render(font, codepoint)){ - u32 base_codepoint = 0; - u32 page_index = get_codepoint_page_index(font, codepoint, &base_codepoint); - Glyph_Page *bounds_page = &font->glyph_pages[page_index]; - Advance_Page *advance_page = &font->advance_pages[page_index]; - u32 glyph_index = codepoint - base_codepoint; - - bounds = &bounds_page->glyphs[glyph_index]; - advance = &advance_page->advance[glyph_index]; - } - - *bounds_mem_out = bounds; - *advance_mem_out = advance; -} - -internal b32 -get_codepoint_glyph_data(Render_Font *font, u32 codepoint, Glyph_Data *data_out){ - b32 success = false; - if (get_codepoint_can_render(font, codepoint)){ - u32 base_codepoint = 0; - u32 page_index = get_codepoint_page_index(font, codepoint, &base_codepoint); - Glyph_Page *page = &font->glyph_pages[page_index]; - data_out->bounds = page->glyphs[codepoint - base_codepoint]; - data_out->tex = page->tex; - data_out->tex_width = page->tex_width; - data_out->tex_height = page->tex_height; - success = true; - } - return(success); -} - -internal f32 -get_codepoint_advance(Render_Font *font, u32 codepoint){ - f32 advance = (f32)font->advance; - if (get_codepoint_can_render(font, codepoint)){ - u32 base_codepoint = 0; - u32 page_index = get_codepoint_page_index(font, codepoint, &base_codepoint); - Advance_Page *page = &font->advance_pages[page_index]; - advance = page->advance[codepoint - base_codepoint]; - } - return(advance); -} - -internal b32 -set_codepoint_advance(Render_Font *font, u32 codepoint, f32 value){ - b32 success = false; - if (get_codepoint_can_render(font, codepoint)){ - u32 base_codepoint = 0; - u32 page_index = get_codepoint_page_index(font, codepoint, &base_codepoint); - Advance_Page *page = &font->advance_pages[page_index]; - page->advance[codepoint - base_codepoint] = value; - success = true; - } - return(success); -} - -#endif - -// BOTTOM - - diff --git a/filetrack/4tech_file_track.h b/filetrack/4tech_file_track.h deleted file mode 100644 index f00a2df0..00000000 --- a/filetrack/4tech_file_track.h +++ /dev/null @@ -1,65 +0,0 @@ -/* - -Copy Right FourTech LLC, 2016 -All Rights Are Reserved - -The OS agnostic file tracking API for applications -that want to interact with potentially many files on -the disk that could be changed by other applications. - -Created on: 20.07.2016 - -*/ - -// TOP - -#ifndef FILE_TRACK_4TECH_H -#define FILE_TRACK_4TECH_H - -#ifndef FILE_TRACK_LINK -#define FILE_TRACK_LINK static -#endif - -#include - -enum{ - FileTrack_Good, - FileTrack_MemoryTooSmall, - FileTrack_OutOfTableMemory, - FileTrack_OutOfListenerMemory, - FileTrack_NoMoreEvents, - FileTrack_FileSystemError -}; - -typedef struct{ - uint8_t opaque[128]; -} File_Track_System; - -typedef int32_t File_Track_Result; - -FILE_TRACK_LINK File_Track_Result -init_track_system(File_Track_System *system, - void *table_memory, int32_t table_memory_size, - void *listener_memory, int32_t listener_memory_size); - -FILE_TRACK_LINK File_Track_Result -add_listener(File_Track_System *system, char *filename); - -FILE_TRACK_LINK File_Track_Result -remove_listener(File_Track_System *system, char *filename); - -FILE_TRACK_LINK File_Track_Result -move_track_system(File_Track_System *system, void *mem, int32_t size); - -FILE_TRACK_LINK File_Track_Result -expand_track_system_listeners(File_Track_System *system, void *mem, int32_t size); - -FILE_TRACK_LINK File_Track_Result -get_change_event(File_Track_System *system, char *buffer, int32_t max); - -FILE_TRACK_LINK File_Track_Result -shut_down_track_system(File_Track_System *system); - -#endif - -// BOTTOM diff --git a/font/4coder_font_data.h b/font/4coder_font_data.h new file mode 100644 index 00000000..07231146 --- /dev/null +++ b/font/4coder_font_data.h @@ -0,0 +1,59 @@ +/* + * Mr. 4th Dimention - Allen Webster + * + * 03.03.2017 + * + * Font data type definitions. + * + */ + +// TOP + +#if !defined(FCODER_FONT_DATA_H) +#define FCODER_FONT_DATA_H + +#define ITEM_PER_FONT_PAGE 256 + +struct Glyph_Bounds{ + f32 x0, x1; + f32 y0, y1; + f32 xoff, yoff; + f32 xoff2, yoff2; +}; +global_const Glyph_Bounds null_glyph_bounds = {0}; + +struct Glyph_Page{ + u32 page_number; + f32 advance[ITEM_PER_FONT_PAGE]; + Glyph_Bounds glyphs[ITEM_PER_FONT_PAGE]; + u32 tex; + i32 tex_width, tex_height; +}; + +#define FONT_PAGE_EMPTY ((Glyph_Page*)0) +#define FONT_PAGE_DELETED ((Glyph_Page*)(1)) +#define FONT_PAGE_MAX 0x1100 + +struct Render_Font{ + Glyph_Page **pages; + u32 page_count, page_max; + f32 byte_advance; + f32 byte_sub_advances[3]; + i32 height, ascent, descent, line_skip, advance; + + u32 filename_len; + u32 name_len; + char filename[256]; + char name[256]; +}; + +struct Glyph_Data{ + Glyph_Bounds bounds; + u32 tex; + i32 tex_width, tex_height; +}; + +#endif + +// BOTTOM + diff --git a/font/4coder_font_interface.h b/font/4coder_font_interface.h new file mode 100644 index 00000000..d1f1eeb6 --- /dev/null +++ b/font/4coder_font_interface.h @@ -0,0 +1,76 @@ +/* + * Mr. 4th Dimention - Allen Webster + * + * 11.03.2017 + * + * Font system interface. + * + */ + +// TOP + +#if !defined(FCODER_FONT_INTERFACE_H) +#define FCODER_FONT_INTERFACE_H + +typedef u32 Font_ID; + +struct Render_Font; +struct Glyph_Page; + +#define Sys_Font_Get_Count_Sig(name_) u32 (name_)(void) +typedef Sys_Font_Get_Count_Sig(Font_Get_Count_Function); + +#define Sys_Font_Get_IDs_By_Index_Sig(name_) b32 (name_)(u32 first_index, u32 index_count, u32 *id_out) +typedef Sys_Font_Get_IDs_By_Index_Sig(Font_Get_IDs_By_Index_Function); + +#define Sys_Font_Get_Name_By_Index_Sig(name_) u32 (name_)(u32 font_index, char *str_out, u32 str_out_cap) +typedef Sys_Font_Get_Name_By_Index_Sig(Font_Get_Name_By_Index_Function); + +#define Sys_Font_Get_Name_By_ID_Sig(name_) u32 (name_)(u32 font_id, char *str_out, u32 str_out_cap) +typedef Sys_Font_Get_Name_By_ID_Sig(Font_Get_Name_By_ID_Function); + +#define Sys_Font_Get_Render_Data_By_ID_Sig(name_) Render_Font* (name_)(u32 font_id) +typedef Sys_Font_Get_Render_Data_By_ID_Sig(Font_Get_Render_Data_By_ID_Function); + +#define Sys_Font_Load_Page_Sig(name_) void (name_)(Render_Font *font, Glyph_Page *page, u32 page_number) +typedef Sys_Font_Load_Page_Sig(Font_Load_Page_Function); + +#define Sys_Font_Allocate_Sig(name_) void* (name_)(i32 size) +typedef Sys_Font_Allocate_Sig(Font_Allocate_Function); + +#define Sys_Font_Free_Sig(name_) void (name_)(void *ptr) +typedef Sys_Font_Free_Sig(Font_Free_Function); + +struct Font_Functions{ + Font_Get_Count_Function *get_count; + Font_Get_IDs_By_Index_Function *get_ids_by_index; + Font_Get_Name_By_Index_Function *get_name_by_index; + Font_Get_Name_By_ID_Function *get_name_by_id; + Font_Get_Render_Data_By_ID_Function *get_render_data_by_id; + Font_Load_Page_Function *load_page; + + Font_Allocate_Function *allocate; + Font_Free_Function *free; +}; + +internal f32 font_get_byte_advance(Render_Font *font); +internal f32*font_get_byte_sub_advances(Render_Font *font); +internal i32 font_get_height(Render_Font *font); +internal i32 font_get_ascent(Render_Font *font); +internal i32 font_get_descent(Render_Font *font); +internal i32 font_get_line_skip(Render_Font *font); +internal i32 font_get_advance(Render_Font *font); + +internal b32 font_can_render(struct System_Functions *system, Render_Font *font, u32 codepoint); +internal f32 font_get_glyph_advance(struct System_Functions *system, Render_Font *font, u32 codepoint); + +struct Glyph_Data; +internal Glyph_Data font_get_glyph(System_Functions *system, Render_Font *font, u32 codepoint); + +internal Glyph_Page *font_get_or_make_page(struct System_Functions *system, Render_Font *font, u32 page_number); + +#endif + +// BOTTOM + + diff --git a/font/4coder_font_interface_to_os.h b/font/4coder_font_interface_to_os.h new file mode 100644 index 00000000..e93efb6c --- /dev/null +++ b/font/4coder_font_interface_to_os.h @@ -0,0 +1,24 @@ +/* + * Mr. 4th Dimention - Allen Webster + * + * 13.03.2017 + * + * Font system interface to the OS layer. + * + */ + +// TOP + +#if !defined(FCODER_FONT_INTERFACE_TO_OS_H) +#define FCODER_FONT_INTERFACE_TO_OS_H + +#define Sys_Font_Init_Sig(name_) void (name_)(Font_Functions *font, void *memory, umem memory_size, u32 font_size, b32 use_hinting) +internal Sys_Font_Init_Sig(system_font_init); + + +#endif + +// BOTTOM + + + diff --git a/font/4coder_font_internal.cpp b/font/4coder_font_internal.cpp new file mode 100644 index 00000000..a8e66e65 --- /dev/null +++ b/font/4coder_font_internal.cpp @@ -0,0 +1,493 @@ +/* + * Mr. 4th Dimention - Allen Webster + * + * 10.03.2017 + * + * Where I save crappy old font stuff. + * + */ + +// TOP + +#include "font/4coder_font_data.h" + +struct Font_Table_Entry{ + u32 hash; + String name; + Font_ID font_id; +}; + +struct Font_Info{ + Render_Font *font; + String filename; + String name; + i32 pt_size; +}; + +struct Font_Slot{ + Font_Slot *next, *prev; + Font_ID font_id; + u8 padding[6]; +}; +global_const Font_Slot null_font_slot = {0}; + +#define Font_Load_Sig(name)\ +i32 name(Render_Font *font_out, char *filename, char *fontname, i32 pt_size, i32 tab_width, b32 store_texture) +typedef Font_Load_Sig(Font_Load); + +#define Font_Load_Page_Sig(name)\ +i32 name(Render_Font *font, Glyph_Page *page, char *filename, i32 pt_size, i32 tab_width) +typedef Font_Load_Page_Sig(Font_Load_Page); + +#define Release_Font_Sig(name) void name(Render_Font *font) +typedef Release_Font_Sig(Release_Font); + +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_Load *font_load; + Font_Load_Page *font_load_page; + Release_Font *release_font; + + b8 *font_used_flags; + Font_ID used_this_frame; + Font_ID live_max; +}; + +inline Font_Info* +get_font_info(Font_Set *set, Font_ID font_id){ + Font_Info *result = set->info + font_id - 1; + return(result); +} + +internal void +font_set_begin_render(Font_Set *font_set){ + font_set->used_this_frame = 0; + memset(font_set->font_used_flags, 0, font_set->max); +} + +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, Font_ID 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 = null_font_slot; + set->used_slots = null_font_slot; + + dll_init_sentinel(&set->free_slots); + dll_init_sentinel(&set->used_slots); + + char *ptr = (char*)set->font_block; + for (i32 i = 0; i < live_max; ++i){ + dll_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, Font_ID font_id){ + Font_Table_Entry entry; + entry.hash = font_hash(name); + entry.name = name; + entry.font_id = font_id; + + u32 i = entry.hash % set->max; + u32 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(Font_Set *set, Font_ID 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(font, info->filename.str, info->name.str, info->pt_size, 4, true); + 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); + + Font_ID 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(Font_Set *set, Font_ID font_id){ + b8 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(set, font_id); + } + slot = ((Font_Slot*)info->font) - 1; + + font__remove(slot); + font__insert(&set->used_slots, slot); + } +} + +internal b32 +font_set_add(Font_Set *set, String filename, String name, i32 pt_size){ + b32 result = false; + if (font_set_can_add(set)){ + Render_Font dummy_font = {0}; + Font_ID 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_load(&dummy_font, info->filename.str, info->name.str, info->pt_size, 4, false); + + font_set_add_hash(set, name, font_id); + + if (font_set_can_load(set)){ + font_set_load(set, font_id); + } + + result = true; + } + return(result); +} + +internal b32 +font_set_find_pos(Font_Set *set, String name, u32 *position){ + u32 hash = font_hash(name); + u32 i = hash % set->max; + u32 j = i - 1; + if (j <= 1){ + j += set->max; + } + + b32 result = 0; + for (; i != j; ++i){ + if (i == set->max){ + i = 0; + } + + Font_Table_Entry *entry = set->entries + i; + if (entry->hash == hash){ + if (match_ss(name, entry->name)){ + result = 1; + *position = i; + break; + } + } + } + + return(result); +} + +internal b32 +font_set_get_name(Font_Set *set, Font_ID font_id, String *name){ + Font_Info *info = get_font_info(set, font_id); + b32 result = copy_checked_ss(name, info->name); + return(result); +} + +internal b32 +font_set_extract(Font_Set *set, String name, Font_ID *font_id){ + u32 position; + b32 result = font_set_find_pos(set, name, &position); + if (result){ + *font_id = set->entries[position].font_id; + } + return(result); +} + +////////////////////////////////// + +internal b32 +get_codepoint_can_render(Render_Font *font, u32 codepoint){ + b32 exists = false; + if (codepoint < 0x10FFFF){ + exists = true; + } + return(exists); +} + +struct Codepoint_Indexes{ + b32 exists; + u32 page_number; + u32 glyph_index; +}; + +internal Codepoint_Indexes +get_codepoint_page_number(Render_Font *font, u32 codepoint){ + Codepoint_Indexes result = {0}; + u32 page_number = (codepoint >> 8); + if (page_number <= 0x10FF){ + result.exists = true; + result.page_number = page_number; + result.glyph_index = (codepoint & 0x000000FF); + } + return(result); +} + +#define MAX_PAGE_COUNT (u32)(0x1100) +#define GLYPH_PAGE_EMPTY ((Glyph_Page*)(0)) +#define GLYPH_PAGE_DELETED ((Glyph_Page*)(max_u64)) +#define IS_REAL_FONT_PAGE(p) (((p) != GLYPH_PAGE_EMPTY) && ((p) != GLYPH_PAGE_DELETED)) + +internal Glyph_Page** +font_lookup_page(Render_Font *font, u32 page_number, b32 find_empty_slot){ + Glyph_Page **result = 0; + if (font->page_max > 0){ + u32 first_index = page_number % font->page_max; + + u32 range_count = 0; + u32 ranges[4]; + if (first_index == 0){ + ranges[0] = 0; + ranges[1] = font->page_max; + range_count = 2; + } + else{ + ranges[0] = first_index; + ranges[1] = font->page_max; + ranges[2] = 0; + ranges[3] = first_index; + range_count = 4; + } + + if (find_empty_slot){ + for(u32 j = 0; j < range_count; j += 2){ + u32 start = ranges[j]; + u32 stop = ranges[j+1]; + for (u32 i = start; i < stop; ++i){ + Glyph_Page *ptr = font->pages[i]; + if (ptr == GLYPH_PAGE_EMPTY || ptr == GLYPH_PAGE_DELETED){ + result = &font->pages[i]; + goto break2; + } + if (ptr->page_number == page_number){ + goto break2; + } + } + } + } + else{ + for(u32 j = 0; j < range_count; j += 2){ + u32 start = ranges[j]; + u32 stop = ranges[j+1]; + for (u32 i = start; i < stop; ++i){ + Glyph_Page *ptr = font->pages[i]; + if (ptr == GLYPH_PAGE_EMPTY){ + goto break2; + } + if (ptr != GLYPH_PAGE_DELETED){ + if (ptr->page_number == page_number){ + result = &font->pages[i]; + goto break2; + } + } + } + } + } + break2:; + } + return(result); +} + +internal Glyph_Page* +font_get_or_make_page(Render_Font *font, u32 page_number){ + Glyph_Page *page = 0; + if (page_number <= 0x10FF){ + Glyph_Page **page_ptr = font_lookup_page(font, page_number, false); + page = 0; + if (page_ptr != 0){ + page = *page_ptr; + } + + if (page == 0){ + u32 new_count = 1; + if (font->page_max < MAX_PAGE_COUNT && (font->page_count+new_count)*3 < font->page_max*2){ + u32 new_page_max = (font->page_count+new_count)*3; + new_page_max = clamp_top(new_page_max, MAX_PAGE_COUNT); + Glyph_Page **new_pages = (Glyph_Page**)ALLOCATE(new_page_max * sizeof(Glyph_Page*)); + + u32 old_page_max = font->page_max; + Glyph_Page **pages = font->pages; + for (u32 i = 0; i < old_page_max; ++i){ + Glyph_Page *current_page = pages[i]; + if (current_page != GLYPH_PAGE_EMPTY && current_page != GLYPH_PAGE_DELETED){ + Glyph_Page **dest = font_lookup_page(font, current_page->page_number, true); + Assert(dest != 0); + *dest = current_page; + } + } + + FREE(font->pages); + font->pages = new_pages; + font->page_max = new_page_max; + } + + Glyph_Page *new_page = (Glyph_Page*)ALLOCATE(sizeof(Glyph_Page)); + Glyph_Page **dest = font_lookup_page(font, page_number, true); + *dest = new_page; + ++font->page_count; + + //set->font_load_page(font, new_page, ); + } + } + return(page); +} + +internal void +get_codepoint_memory(Render_Font *font, u32 codepoint, Glyph_Bounds **bounds_mem_out, f32 **advance_mem_out){ + Glyph_Bounds *bounds = 0; + f32 *advance = 0; + + if (get_codepoint_can_render(font, codepoint)){ + Codepoint_Indexes indexes = get_codepoint_page_number(font, codepoint); + Glyph_Page *page = font_get_or_make_page(font, indexes.page_number); + bounds = &page->glyphs[indexes.glyph_index]; + advance = &page->advance[indexes.glyph_index]; + } + + *bounds_mem_out = bounds; + *advance_mem_out = advance; +} + +internal b32 +get_codepoint_glyph_data(Render_Font *font, u32 codepoint, Glyph_Data *data_out){ + b32 success = false; + if (get_codepoint_can_render(font, codepoint)){ + Codepoint_Indexes indexes = get_codepoint_page_number(font, codepoint); + Glyph_Page *page = font_get_or_make_page(font, indexes.page_number); + data_out->bounds = page->glyphs[indexes.glyph_index]; + data_out->tex = page->tex; + data_out->tex_width = page->tex_width; + data_out->tex_height = page->tex_height; + success = true; + } + return(success); +} + +internal f32 +get_codepoint_advance(Render_Font *font, u32 codepoint){ + f32 advance = (f32)font->advance; + if (get_codepoint_can_render(font, codepoint)){ + Codepoint_Indexes indexes = get_codepoint_page_number(font, codepoint); + Glyph_Page *page = font_get_or_make_page(font, indexes.page_number); + advance = page->advance[indexes.glyph_index]; + } + return(advance); +} + +internal b32 +set_codepoint_advance(Render_Font *font, u32 codepoint, f32 value){ + b32 success = false; + if (get_codepoint_can_render(font, codepoint)){ + Codepoint_Indexes indexes = get_codepoint_page_number(font, codepoint); + Glyph_Page *page = font_get_or_make_page(font, indexes.page_number); + page->advance[indexes.glyph_index] = value; + success = true; + } + return(success); +} + +// BOTTOM + + + + diff --git a/font/4coder_font_static_functions.cpp b/font/4coder_font_static_functions.cpp new file mode 100644 index 00000000..32dfdc3a --- /dev/null +++ b/font/4coder_font_static_functions.cpp @@ -0,0 +1,198 @@ +/* + * Mr. 4th Dimention - Allen Webster + * + * 11.03.2017 + * + * Implements some basic getters for fonts set up to make the font type opaque. + * + */ + +// TOP + +#include "4coder_font_data.h" + +internal f32 +font_get_byte_advance(Render_Font *font){ + return(font->byte_advance); +} + +internal f32* +font_get_byte_sub_advances(Render_Font *font){ + return(font->byte_sub_advances); +} + +internal i32 +font_get_height(Render_Font *font){ + return(font->height); +} + +internal i32 +font_get_ascent(Render_Font *font){ + return(font->ascent); +} + +internal i32 +font_get_descent(Render_Font *font){ + return(font->descent); +} + +internal i32 +font_get_line_skip(Render_Font *font){ + return(font->line_skip); +} + +internal i32 +font_get_advance(Render_Font *font){ + return(font->advance); +} + +internal b32 +font_can_render(System_Functions *system, Render_Font *font, u32 codepoint){ + b32 result = false; + u32 page_number = (codepoint >> 8); + u32 glyph_index = codepoint & 0xFF; + Glyph_Page *page = font_get_or_make_page(system, font, page_number); + if (page != 0 && page->advance[glyph_index] > 0.f){ + result = true; + } + return(result); +} + +internal f32 +font_get_glyph_advance(System_Functions *system, Render_Font *font, u32 codepoint){ + f32 result = 0.f; + u32 page_number = (codepoint >> 8); + u32 glyph_index = codepoint & 0xFF; + Glyph_Page *page = font_get_or_make_page(system, font, page_number); + if (page != 0 && page->advance[glyph_index] > 0.f){ + result = page->advance[glyph_index]; + } + return(result); +} + +internal Glyph_Data +font_get_glyph(System_Functions *system, Render_Font *font, u32 codepoint){ + Glyph_Data result = {0}; + u32 page_number = (codepoint >> 8); + u32 glyph_index = codepoint & 0xFF; + Glyph_Page *page = font_get_or_make_page(system, font, page_number); + if (page != 0 && page->advance[glyph_index] > 0.f){ + result.bounds = page->glyphs[glyph_index]; + result.tex = page->tex; + result.tex_width = page->tex_width; + result.tex_height = page->tex_height; + } + return(result); +} + +internal Glyph_Page** +font_page_lookup(Render_Font *font, u32 page_number, b32 get_empty_slot){ + Glyph_Page **result = 0; + + if (font->page_max > 0){ + u32 first_index = page_number % font->page_max; + + u32 range_count = 0; + u32 ranges[4]; + if (first_index == 0){ + ranges[0] = 0; + ranges[1] = font->page_max; + range_count = 2; + } + else{ + ranges[0] = first_index; + ranges[1] = font->page_max; + ranges[2] = 0; + ranges[3] = first_index; + range_count = 4; + } + + Glyph_Page **pages = font->pages; + if (get_empty_slot){ + for (u32 j = 0; j < range_count; j += 2){ + u32 stop = ranges[j+1]; + for (u32 i = ranges[j]; i < stop; ++i){ + if (pages[i] == FONT_PAGE_EMPTY || pages[i] == FONT_PAGE_DELETED){ + result = &pages[i]; + goto break2; + } + if (pages[i]->page_number == page_number){ + goto break2; + } + } + } + } + else{ + for (u32 j = 0; j < range_count; j += 2){ + u32 stop = ranges[j+1]; + for (u32 i = ranges[j]; i < stop; ++i){ + if (pages[i] == FONT_PAGE_EMPTY){ + goto break2; + } + if (pages[i] != FONT_PAGE_DELETED && pages[i]->page_number == page_number){ + result = &pages[i]; + goto break2; + } + } + } + } + + break2:; + } + + return(result); +} + +internal Glyph_Page* +font_get_or_make_page(System_Functions *system, Render_Font *font, u32 page_number){ + Glyph_Page *result = 0; + if (page_number <= 0x10FF){ + Glyph_Page **page_get_result = font_page_lookup(font, page_number, false); + + if (page_get_result == 0){ + b32 has_space = true; + u32 new_page_count = 1; + u32 new_max = (font->page_count+new_page_count)*3; + if (font->page_max < FONT_PAGE_MAX && new_max > font->page_max*2){ + Glyph_Page **pages = (Glyph_Page**)system->font.allocate(sizeof(Glyph_Page*)*new_max); + has_space = false; + if (pages != 0){ + memset(pages, 0, sizeof(*pages)*new_max); + u32 old_max = font->page_max; + for (u32 i = 0; i < old_max; ++i){ + Glyph_Page *this_page = pages[i]; + if (this_page != FONT_PAGE_EMPTY && this_page != FONT_PAGE_DELETED){ + u32 this_page_number = this_page->page_number; + Glyph_Page **dest = font_page_lookup(font, this_page_number, true); + Assert(dest != 0); + *dest = this_page; + } + } + system->font.free(font->pages); + font->pages = pages; + font->page_max = new_max; + has_space = true; + } + } + + if (has_space){ + Glyph_Page *new_page = (Glyph_Page*)system->font.allocate(sizeof(Glyph_Page)); + if (new_page != 0){ + Glyph_Page **dest = font_page_lookup(font, page_number, true); + Assert(dest != 0); + *dest = new_page; + font->page_count += new_page_count; + result = new_page; + system->font.load_page(font, new_page, page_number); + } + } + } + else{ + result = *page_get_result; + } + } + return(result); +} + +// BOTTOM + diff --git a/linux_4ed.cpp b/linux_4ed.cpp index 98e59a2c..0466c92a 100644 --- a/linux_4ed.cpp +++ b/linux_4ed.cpp @@ -103,13 +103,14 @@ #endif #define SUPPORT_DPI 1 -#define LINUX_FONTS 1 #define InterlockedCompareExchange(dest, ex, comp) __sync_val_compare_and_swap((dest), (comp), (ex)) -#include "filetrack/4tech_file_track_linux.c" +#include "4ed_file_track.h" #include "4ed_system_shared.h" +#include "linux_4ed_file_track.cpp" + // // Linux structs / enums // @@ -207,8 +208,6 @@ struct Linux_Vars{ pthread_cond_t conds[8]; sem_t thread_semaphore; - Partition font_part; - #if SUPPORT_DPI i32 dpi_x, dpi_y; #endif @@ -1337,60 +1336,7 @@ INTERNAL_Sys_Get_Thread_States_Sig(internal_get_thread_states){ // #include "4ed_system_shared.cpp" -#include "linux_font.cpp" - -internal f32 -size_change(i32 dpi_x, i32 dpi_y){ - // TODO(allen): We're just hoping dpi_x == dpi_y for now I guess. - f32 size_x = dpi_x / 96.f; - f32 size_y = dpi_y / 96.f; - f32 size_max = Max(size_x, size_y); - return(size_max); -} - -internal -Font_Load_Sig(system_draw_font_load){ - b32 success = 0; - i32 attempts = 0; - - LINUX_FN_DEBUG("%s, %dpt, tab_width: %d", filename, pt_size, tab_width); - - if (linuxvars.font_part.base == 0){ - linuxvars.font_part = sysshared_scratch_partition(MB(8)); - } - - i32 oversample = 2; - -#if SUPPORT_DPI - pt_size = round32(pt_size * size_change(linuxvars.dpi_x, linuxvars.dpi_y)); -#endif - - for(; attempts < 3; ++attempts){ -#if LINUX_FONTS - success = linux_font_load(&linuxvars.font_part, font_out, filename, pt_size, tab_width, - linuxvars.settings.use_hinting); -#else - success = font_load( - &linuxvars.font_part, - font_out, - filename, - pt_size, - tab_width, - oversample, - store_texture - ); -#endif - - if(success){ - break; - } else { - fprintf(stderr, "draw_font_load failed, %p %d\n", linuxvars.font_part.base, linuxvars.font_part.max); - sysshared_partition_double(&linuxvars.font_part); - } - } - - return success; -} +#include "linux_4ed_fonts.cpp" // // End of system funcs @@ -1488,9 +1434,6 @@ LinuxLoadRenderCode(){ linuxvars.target.push_clip = draw_push_clip; linuxvars.target.pop_clip = draw_pop_clip; linuxvars.target.push_piece = draw_push_piece; - - linuxvars.target.font_set.font_load = system_draw_font_load; - linuxvars.target.font_set.release_font = draw_release_font; } // @@ -1499,7 +1442,7 @@ LinuxLoadRenderCode(){ internal void LinuxRedrawTarget(){ - launch_rendering(&linuxvars.target); + launch_rendering(&linuxvars.system, &linuxvars.target); //glFlush(); glXSwapBuffers(linuxvars.XDisplay, linuxvars.XWindow); } @@ -2435,13 +2378,18 @@ LinuxGetXSettingsDPI(Display* dpy, int screen) // X11 window init // +internal i32 +size_change(i32 x, i32 y){ + f32 xs = x/96.f; + f32 ys = y/96.f; + f32 s = Min(xs, ys); + i32 r = floor32(s); + return(r); +} + internal b32 LinuxX11WindowInit(int argc, char** argv, int* WinWidth, int* WinHeight) { - // NOTE(allen): Here begins the linux screen setup stuff. - // Behold the true nature of this wonderful OS: - // (thanks again to Casey for providing this stuff) - #define BASE_W 800 #define BASE_H 600 @@ -2468,17 +2416,10 @@ LinuxX11WindowInit(int argc, char** argv, int* WinWidth, int* WinHeight) swa.backing_store = WhenMapped; swa.event_mask = StructureNotifyMask; swa.bit_gravity = NorthWestGravity; - swa.colormap = XCreateColormap(linuxvars.XDisplay, - RootWindow(linuxvars.XDisplay, Config.BestInfo.screen), - Config.BestInfo.visual, AllocNone); + swa.colormap = XCreateColormap(linuxvars.XDisplay, RootWindow(linuxvars.XDisplay, Config.BestInfo.screen), Config.BestInfo.visual, AllocNone); - linuxvars.XWindow = - XCreateWindow(linuxvars.XDisplay, - RootWindow(linuxvars.XDisplay, Config.BestInfo.screen), - 0, 0, *WinWidth, *WinHeight, - 0, Config.BestInfo.depth, InputOutput, - Config.BestInfo.visual, - CWBackingStore|CWBitGravity|CWBackPixel|CWBorderPixel|CWColormap|CWEventMask, &swa); + linuxvars.XWindow = XCreateWindow(linuxvars.XDisplay, RootWindow(linuxvars.XDisplay, Config.BestInfo.screen), + 0, 0, *WinWidth, *WinHeight, 0, Config.BestInfo.depth, InputOutput, Config.BestInfo.visual, CWBackingStore|CWBitGravity|CWBackPixel|CWBorderPixel|CWColormap|CWEventMask, &swa); if (!linuxvars.XWindow){ LinuxFatalErrorMsg("XCreateWindow failed. Make sure your display is set up correctly."); @@ -3241,6 +3182,12 @@ main(int argc, char **argv) } + // + // Font System Init + // + + system_font_init(&linuxvars.system.font, 0, 0, 16, true); + // // Epoll init // @@ -3429,6 +3376,8 @@ main(int argc, char **argv) return 0; } +#include "font/4coder_font_static_functions.cpp" + // BOTTOM // vim: expandtab:ts=4:sts=4:sw=4 diff --git a/filetrack/4tech_file_track_linux.c b/linux_4ed_file_track.cpp similarity index 85% rename from filetrack/4tech_file_track_linux.c rename to linux_4ed_file_track.cpp index 2850bcbe..7aa3c29a 100644 --- a/filetrack/4tech_file_track_linux.c +++ b/linux_4ed_file_track.cpp @@ -1,17 +1,17 @@ /* - - The OS agnostic file tracking API for applications - that want to interact with potentially many files on - the disk that could be changed by other applications. - - Created on: 29.08.2016 - -*/ + * Mr. 4th Dimention - Allen Webster + * + * 20.07.2016 + * + * File tracking linux. + * + */ // TOP -#include "4tech_file_track.h" -#include "4tech_file_track_general.c" +#include "4ed_file_track.h" +#include "4ed_file_track_general.cpp" + #include // dirname typedef struct { @@ -32,61 +32,59 @@ typedef struct { #define to_tables(v) ((File_Track_Tables*)(v->tables)) FILE_TRACK_LINK File_Track_Result -init_track_system(File_Track_System *system, - void *table_memory, int32_t table_memory_size, - void *listener_memory, int32_t listener_memory_size){ +init_track_system(File_Track_System *system, Partition *scratch, void *table_memory, int32_t table_memory_size, void *listener_memory, int32_t listener_memory_size){ File_Track_Result result = FileTrack_MemoryTooSmall; - + Assert(sizeof(Linux_File_Track_Vars) <= sizeof(File_Track_System)); - + Linux_File_Track_Vars *vars = to_vars(system); - + Assert(sizeof(Linux_File_Track_Entry) <= sizeof(File_Track_Entry)); - + if (enough_memory_to_init_table(table_memory_size)){ - + // NOTE(allen): Initialize main data tables vars->tables = (File_Track_Tables*) table_memory; File_Track_Tables *tables = to_tables(vars); init_table_memory(tables, table_memory_size); - + vars->inotify = inotify_init1(IN_NONBLOCK); - + pthread_mutex_init(&vars->lock, NULL); - + vars->string_mem_begin = (char*)listener_memory; vars->string_mem_end = (char*)listener_memory + listener_memory_size; - + result = FileTrack_Good; } - + LINUX_FN_DEBUG("result: %d", result); - + return(result); } FILE_TRACK_LINK File_Track_Result -add_listener(File_Track_System *system, char *filename){ +add_listener(File_Track_System *system, Partition *scratch, char *filename){ File_Track_Result result = FileTrack_Good; Linux_File_Track_Vars *vars = to_vars(system); File_Track_Tables *tables = to_tables(vars); - + pthread_mutex_lock(&vars->lock); - + if(tracking_system_has_space(tables, 1)){ char *dir = dirname(strdupa(filename)); size_t dir_len = strlen(dir) + 1; - + if(vars->string_mem_end - vars->string_mem_begin >= dir_len){ int wd = inotify_add_watch(vars->inotify, dir, IN_CREATE | IN_DELETE | IN_MODIFY | IN_MOVE); - + if(wd != -1){ File_Index key = { wd, 1 }; File_Track_Entry *entry = tracking_system_lookup_entry(tables, key); Linux_File_Track_Entry *linux_entry = (Linux_File_Track_Entry*) entry; - + LINUX_FN_DEBUG("map %s to wd %d", filename, wd); - + if(entry_is_available(entry)){ linux_entry->hash = key; linux_entry->dir = vars->string_mem_begin; @@ -107,26 +105,26 @@ add_listener(File_Track_System *system, char *filename){ } else { result = FileTrack_OutOfTableMemory; } - + pthread_mutex_unlock(&vars->lock); - + LINUX_FN_DEBUG("result: %d", result); - + return(result); } FILE_TRACK_LINK File_Track_Result -remove_listener(File_Track_System *system, char *filename){ +remove_listener(File_Track_System *system, Partition *scratch, char *filename){ File_Track_Result result = FileTrack_Good; Linux_File_Track_Vars *vars = to_vars(system); File_Track_Tables *tables = to_tables(vars); File_Track_Entry *entries = (File_Track_Entry*) to_ptr(tables, tables->file_table); - + pthread_mutex_lock(&vars->lock); - + char *dir = dirname(strdupa(filename)); // NOTE(inso): this assumes the filename was previously added - + for(uint32_t i = 0; i < tables->max; ++i){ Linux_File_Track_Entry *e = (Linux_File_Track_Entry*)(entries + i); if(e->hash.id[1] != 1) continue; @@ -144,21 +142,21 @@ remove_listener(File_Track_System *system, char *filename){ break; } } - + pthread_mutex_unlock(&vars->lock); - + LINUX_FN_DEBUG("result: %d", result); - + return(result); } FILE_TRACK_LINK File_Track_Result -move_track_system(File_Track_System *system, void *mem, int32_t size){ +move_track_system(File_Track_System *system, Partition *scratch, void *mem, int32_t size){ File_Track_Result result = FileTrack_Good; Linux_File_Track_Vars *vars = to_vars(system); - + pthread_mutex_lock(&vars->lock); - + { File_Track_Tables *original_tables = to_tables(vars); result = move_table_memory(original_tables, mem, size); @@ -166,80 +164,80 @@ move_track_system(File_Track_System *system, void *mem, int32_t size){ vars->tables = mem; } } - + pthread_mutex_unlock(&vars->lock); - + LINUX_FN_DEBUG("size: %d, %d", size, result); - + return(result); } FILE_TRACK_LINK File_Track_Result -expand_track_system_listeners(File_Track_System *system, void *mem, int32_t size){ +expand_track_system_listeners(File_Track_System *system, Partition *scratch, void *mem, int32_t size){ File_Track_Result result = FileTrack_Good; Linux_File_Track_Vars *vars = to_vars(system); - + pthread_mutex_lock(&vars->lock); - + // NOTE(inso): pointer to old string mem is lost here. // would need to keep it around if we want to free in the future - + // NOTE(inso): assuming PATH_MAX is a reasonable lower bound of extra memory to get - + if(size < PATH_MAX){ result = FileTrack_MemoryTooSmall; } else { vars->string_mem_begin = (char*) mem; vars->string_mem_end = (char*) mem + size;; } - + pthread_mutex_unlock(&vars->lock); - + LINUX_FN_DEBUG("size: %d, result: %d", size, result); - + return(result); } FILE_TRACK_LINK File_Track_Result -get_change_event(File_Track_System *system, char *buffer, int32_t max, int32_t *size){ +get_change_event(File_Track_System *system, Partition *scratch, char *buffer, int32_t max, int32_t *size){ File_Track_Result result = FileTrack_NoMoreEvents; Linux_File_Track_Vars *vars = to_vars(system); File_Track_Tables *tables = to_tables(vars); - + pthread_mutex_lock(&vars->lock); - + struct inotify_event *ev; char buff[sizeof(*ev) + NAME_MAX + 1] __attribute__((aligned(__alignof__(*ev)))); - + // NOTE(inso): make sure we only read one event size_t read_count = sizeof(*ev); ssize_t n; - + do { n = read(vars->inotify, buff, read_count); read_count++; } while(n == -1 && errno == EINVAL); - + if(n == -1 && errno != EAGAIN){ perror("inotify read"); } else if(n > 0){ ev = (struct inotify_event*) buff; - + File_Index key = { ev->wd, 1 }; File_Track_Entry *entry = tracking_system_lookup_entry(tables, key); Linux_File_Track_Entry *linux_entry = (Linux_File_Track_Entry*) entry; - - LINUX_FN_DEBUG("mask: %#x", ev->mask); - + + LINUX_FN_DEBUG("mask: %#x", ev->mask); + if(!entry_is_available(entry)){ - + char* full_name = (char*) alloca(strlen(linux_entry->dir) + ev->len + 1); strcpy(full_name, linux_entry->dir); strcat(full_name, "/"); strcat(full_name, ev->name); - + LINUX_FN_DEBUG("event from wd %d (%s)", ev->wd, full_name); - + size_t full_name_size = strlen(full_name); if(max < full_name_size){ result = FileTrack_MemoryTooSmall; @@ -254,26 +252,26 @@ get_change_event(File_Track_System *system, char *buffer, int32_t max, int32_t * LINUX_FN_DEBUG("dead event from wd %d", ev->wd); } } - + pthread_mutex_unlock(&vars->lock); - + return(result); } FILE_TRACK_LINK File_Track_Result -shut_down_track_system(File_Track_System *system){ +shut_down_track_system(File_Track_System *system, Partition *scratch){ File_Track_Result result = FileTrack_Good; Linux_File_Track_Vars *vars = to_vars(system); - + // NOTE(allen): Close all the global track system resources. if(close(vars->inotify) == -1){ result = FileTrack_FileSystemError; } - + pthread_mutex_destroy(&vars->lock); - + LINUX_FN_DEBUG("result: %d", result); - + return(result); } diff --git a/linux_4ed_fonts.cpp b/linux_4ed_fonts.cpp new file mode 100644 index 00000000..86faed7d --- /dev/null +++ b/linux_4ed_fonts.cpp @@ -0,0 +1,136 @@ +/* + * Mr. 4th Dimention - Allen Webster + * + * 09.02.2016 + * + * Shared system functions + * + */ + +// TOP + +#include "4ed_system_shared.h" +#include "font/4coder_font_interface.h" +#include "font/4coder_font_interface_to_os.h" +#include "font/4coder_font_data.h" + +struct Linux_Fonts{ + Partition part; + Render_Font fonts[5]; + u32 font_count; +}; + +global Linux_Fonts linux_fonts = {0}; + +internal +Sys_Font_Get_Count_Sig(system_font_get_count){ + return(5); +} + +internal +Sys_Font_Get_IDs_By_Index_Sig(system_font_get_ids_by_index){ + b32 result = false; + u32 stop_index = first_index + index_count; + if (stop_index <= linux_fonts.font_count){ + result = true; + for (u32 i = first_index; i < stop_index; ++i){ + id_out[i-first_index] = i; + } + } + return(result); +} + +internal +Sys_Font_Get_Name_By_Index_Sig(system_font_get_name_by_index){ + u32 length = 0; + if (font_index < linux_fonts.font_count){ + Render_Font *font = &linux_fonts.fonts[font_index]; + char *name = font->name; + length = font->name_len; + copy_partial_cs(str_out, str_out_cap, make_string(name, length)); + } + return(length); +} + +internal +Sys_Font_Get_Name_By_ID_Sig(system_font_get_name_by_id){ + u32 font_index = font_id; + u32 result = system_font_get_name_by_index(font_index, str_out, str_out_cap); + return(result); +} + +internal +Sys_Font_Get_Render_Data_By_ID_Sig(system_font_get_render_data_by_id){ + Render_Font *result = 0; + u32 font_index = font_id; + if (font_index < linux_fonts.font_count){ + result = &linux_fonts.fonts[font_index]; + } + return(result); +} + +internal +Sys_Font_Load_Page_Sig(system_font_load_page){ + system_set_page(&linuxvars.system, &linux_fonts.part, font, page, page_number, 16, true); +} + +internal +Sys_Font_Allocate_Sig(system_font_allocate){ + void *result = system_memory_allocate(size); + return(result); +} + +internal +Sys_Font_Free_Sig(system_font_free){ + system_memory_free(ptr, 0); +} + +internal +Sys_Font_Init_Sig(system_font_init){ + font->get_count = system_font_get_count; + font->get_ids_by_index = system_font_get_ids_by_index; + font->get_name_by_index = system_font_get_name_by_index; + font->get_name_by_id = system_font_get_name_by_id; + font->get_render_data_by_id = system_font_get_render_data_by_id; + font->load_page = system_font_load_page; + font->allocate = system_font_allocate; + font->free = system_font_free; + + font_size = clamp_bottom(8, font_size); + + struct Font_Setup{ + char *c_filename; + i32 filename_len; + char *c_name; + i32 name_len; + u32 pt_size; + }; + Font_Setup font_setup[] = { + {literal("LiberationSans-Regular.ttf"), literal("Liberation Sans"), font_size}, + {literal("liberation-mono.ttf"), literal("Liberation Mono"), font_size}, + {literal("Hack-Regular.ttf"), literal("Hack"), font_size}, + {literal("CutiveMono-Regular.ttf"), literal("Cutive Mono"), font_size}, + {literal("Inconsolata-Regular.ttf"), literal("Inconsolata"), font_size}, + }; + + u32 font_count = Min(ArrayCount(linux_fonts.fonts), ArrayCount(font_setup)); + for (u32 i = 0; i < font_count; ++i){ + String filename = make_string(font_setup[i].c_filename, font_setup[i].filename_len); + String name = make_string(font_setup[i].c_name, font_setup[i].name_len); + u32 pt_size = font_setup[i].pt_size; + Render_Font *render_font = &linux_fonts.fonts[i]; + + char full_filename_space[256]; + String full_filename = make_fixed_width_string(full_filename_space); + sysshared_to_binary_path(&full_filename, filename.str); + + system_set_font(&linuxvars.system, &linux_fonts.part, render_font, full_filename, name, pt_size, use_hinting); + } + + linux_fonts.font_count = font_count; +} + +// BOTTOM + + + diff --git a/linux_font.cpp b/linux_font.cpp index 9f69b4ac..5fb476d7 100644 --- a/linux_font.cpp +++ b/linux_font.cpp @@ -1,3 +1,15 @@ +/* + * Insofaras + * + * ??.??.2016 + * + * For getting the font files on Linux. + * + */ + +// TOP + +#if 0 #undef internal #include #define internal static @@ -8,26 +20,26 @@ static FcConfig* fc; internal char* linux_get_sys_font(char* name, i32 pt_size){ char* result = 0; - + if(!fc){ fc = FcInitLoadConfigAndFonts(); } - + FcPattern* pat = FcPatternBuild( NULL, FC_POSTSCRIPT_NAME, FcTypeString, name, FC_SIZE, FcTypeDouble, (double)pt_size, FC_FONTFORMAT, FcTypeString, "TrueType", NULL - ); - + ); + FcConfigSubstitute(fc, pat, FcMatchPattern); FcDefaultSubstitute(pat); - + FcResult res; FcPattern* font = FcFontMatch(fc, pat, &res); FcChar8* fname = 0; - + if(font){ FcPatternGetString(font, FC_FILE, 0, &fname); if(fname){ @@ -36,9 +48,9 @@ linux_get_sys_font(char* name, i32 pt_size){ } FcPatternDestroy(font); } - + FcPatternDestroy(pat); - + if(!result){ char space[1024]; String str = make_fixed_width_string(space); @@ -48,16 +60,16 @@ linux_get_sys_font(char* name, i32 pt_size){ result = strdup(name); } } - + return result; } internal b32 linux_font_load(Partition *part, Render_Font *rf, char *name, i32 pt_size, i32 tab_width, b32 use_hinting){ b32 result = 0; - + Temp_Memory temp = begin_temp_memory(part); - + #if 0 char* filename = linux_get_sys_font(name, pt_size); #else @@ -67,22 +79,26 @@ linux_font_load(Partition *part, Render_Font *rf, char *name, i32 pt_size, i32 t sysshared_to_binary_path(&str, name); } #endif - + if (filename != 0){ struct stat st; if(stat(filename, &st) == -1 || S_ISDIR(st.st_mode)){ char buff[1024]; - + // NOTE(inso): if/when you can load fonts from anywhere, the message should be changed. snprintf(buff, sizeof(buff), "Unable to load font '%s'. Make sure this file is in the same directory as the '4ed' executable.", filename); LinuxFatalErrorMsg(buff); exit(1); } - + result = font_load_freetype(part, rf, filename, pt_size, tab_width, use_hinting); } - + end_temp_memory(temp); - + return(result); } +#endif + +// BOTTOM + diff --git a/meta/build.cpp b/meta/build.cpp index b2923460..5e49fb7a 100644 --- a/meta/build.cpp +++ b/meta/build.cpp @@ -21,8 +21,10 @@ #define IS_64BIT +#define LLU_CAST(n) (long long unsigned int)(n) + #define BEGIN_TIME_SECTION() uint64_t start = get_time() -#define END_TIME_SECTION(n) uint64_t total = get_time() - start; printf("%-20s: %.2lu.%.6lu\n", (n), total/1000000, total%1000000); +#define END_TIME_SECTION(n) uint64_t total = get_time() - start; printf("%-20s: %.2llu.%.6llu\n", (n), LLU_CAST(total/1000000), LLU_CAST(total%1000000)); // // 4coder specific @@ -230,7 +232,7 @@ build_cl(u32 flags, char *code_path, char *code_file, char *out_path, char *out_ swap_ptr(&line_prefix.build_options, &line_prefix.build_options_prev); Temp_Dir temp = pushdir(out_path); - systemf("%scl %s %s\\%s /Fe%s /link /INCREMENTAL:NO %s", line_prefix.build_options, line.build_options, code_path, code_file, out_file, link_line.build_options); + systemf("%scl %s \"%s\\%s\" /Fe%s /link /INCREMENTAL:NO %s", line_prefix.build_options, line.build_options, code_path, code_file, out_file, link_line.build_options); popdir(temp); } @@ -351,7 +353,7 @@ buildsuper(char *code_path, char *out_path, char *filename, b32 x86_build){ } #elif defined(IS_GCC) { - systemf("\"%s/buildsuper.sh\" %s", code_path, filename); + systemf("\"%s/buildsuper.sh\" \"%s\"", code_path, filename); } #else #error The build rule for this compiler is not ready @@ -401,7 +403,7 @@ metagen(char *cdir){ } if (prev_error == 0){ - DECL_STR(cmd, META_DIR"/metagen"); + DECL_STR(cmd, META_DIR "/metagen"); BEGIN_TIME_SECTION(); execute_in_dir(cdir, cmd, 0); END_TIME_SECTION("run metagen"); @@ -468,7 +470,7 @@ build_main(char *cdir, u32 flags){ { DECL_STR(file, "4ed_app_target.cpp"); BEGIN_TIME_SECTION(); - build(OPTS | INCLUDES | SHARED_CODE | flags, cdir, file, dir, "4ed_app"DLL, "/EXPORT:app_get_functions"); + build(OPTS | INCLUDES | SHARED_CODE | flags, cdir, file, dir, "4ed_app" DLL, "/EXPORT:app_get_functions"); END_TIME_SECTION("build 4ed_app"); } @@ -624,11 +626,10 @@ package(char *cdir){ clear_folder(par_dir); make_folder_if_missing(dir, "3rdparty"); make_folder_if_missing(pack_dir, zip_dir); - copy_file(build_dir, "4ed"EXE, dir, 0, 0); - copy_file(build_dir, "4ed_app"DLL, dir, 0, 0); + copy_file(build_dir, "4ed" EXE, dir, 0, 0); + copy_file(build_dir, "4ed_app" DLL, dir, 0, 0); copy_all (pack_data_dir, "*", dir); - copy_file(0, "README.txt", dir, 0, 0); - copy_file(0, "TODO.txt", dir, 0, 0); + //copy_file(0, "TODO.txt", dir, 0, 0); copy_file(data_dir, "release-config.4coder", dir, 0, "config.4coder"); get_4coder_dist_name(&str, true, zip_dir, tier, arch, "zip"); @@ -692,20 +693,17 @@ package(char *cdir){ make_folder_if_missing(dir, "3rdparty"); make_folder_if_missing(pack_dir, zip_dir); - copy_file(build_dir, "4ed"EXE, dir, 0, 0); - //ONLY_WINDOWS(copy_file(build_dir, "4ed"PDB, dir, 0, 0)); - copy_file(build_dir, "4ed_app"DLL, dir, 0, 0); - //ONLY_WINDOWS(copy_file(build_dir, "4ed_app"PDB, dir, 0, 0)); - copy_file(build_dir, "custom_4coder"DLL, dir, 0, 0); + copy_file(build_dir, "4ed" EXE, dir, 0, 0); + copy_file(build_dir, "4ed_app" DLL, dir, 0, 0); + copy_file(build_dir, "custom_4coder" DLL, dir, 0, 0); copy_all (pack_data_dir, "*", dir); - copy_file(0, "README.txt", dir, 0, 0); - copy_file(0, "TODO.txt", dir, 0, 0); + //copy_file(0, "TODO.txt", dir, 0, 0); copy_file(data_dir, "release-config.4coder", dir, 0, "config.4coder"); copy_all(0, "4coder_*", dir); - copy_file(0, "buildsuper"BAT, dir, 0, 0); + copy_file(0, "buildsuper" BAT, dir, 0, 0); DECL_STR(custom_dir, "4coder_API"); DECL_STR(custom_helper_dir, "4coder_helper"); @@ -720,18 +718,18 @@ package(char *cdir){ }; i32 dir_count = ArrayCount(dir_array); - for (i32 i = 0; i < dir_count; ++i){ - char *d = dir_array[i]; + for (i32 j = 0; j < dir_count; ++j){ + char *d = dir_array[j]; make_folder_if_missing(dir, d); char space[256]; - String str = make_fixed_width_string(space); - append_sc(&str, dir); - append_s_char(&str, platform_correct_slash); - append_sc(&str, d); - terminate_with_null(&str); + String copy_name = make_fixed_width_string(space); + append_sc(©_name, dir); + append_s_char(©_name, platform_correct_slash); + append_sc(©_name, d); + terminate_with_null(©_name); - copy_all(d, "*", str.str); + copy_all(d, "*", copy_name.str); } get_4coder_dist_name(&str, true, zip_dir, tier, arch, "zip"); diff --git a/meta/meta_parser.cpp b/meta/meta_parser.cpp index 70d70e26..0c0f618d 100644 --- a/meta/meta_parser.cpp +++ b/meta/meta_parser.cpp @@ -284,7 +284,7 @@ typedef enum Doc_Note_Type{ } Doc_Note_Type; static String -doc_note_string[] = { +defined_doc_notes[] = { make_lit_string("DOC_PARAM"), make_lit_string("DOC_RETURN"), make_lit_string("DOC"), @@ -446,7 +446,7 @@ perform_doc_parse(Partition *part, String doc_string, Documentation *doc){ } else{ int32_t doc_note_type; - if (string_set_match(doc_note_string, ArrayCount(doc_note_string), doc_note, &doc_note_type)){ + if (string_set_match(defined_doc_notes, ArrayCount(defined_doc_notes), doc_note, &doc_note_type)){ doc_parse_note_string(doc_string, &pos); @@ -480,7 +480,7 @@ perform_doc_parse(Partition *part, String doc_string, Documentation *doc){ } else{ int32_t doc_note_type; - if (string_set_match(doc_note_string, ArrayCount(doc_note_string), doc_note, &doc_note_type)){ + if (string_set_match(defined_doc_notes, ArrayCount(defined_doc_notes), doc_note, &doc_note_type)){ String doc_note_string = doc_parse_note_string(doc_string, &pos); @@ -760,10 +760,10 @@ static int32_t enum_parse(Partition *part, Parse_Context *context, Item_Node *item){ int32_t result = false; - String doc_string = {0}; - get_doc_string_from_prev(context, &doc_string); + String parent_doc_string = {0}; + get_doc_string_from_prev(context, &parent_doc_string); - Cpp_Token *start_token = get_token(context); + Cpp_Token *parent_start_token = get_token(context); Cpp_Token *token = 0; for (; (token = get_token(context)) != 0; get_next_token(context)){ @@ -773,7 +773,7 @@ enum_parse(Partition *part, Parse_Context *context, Item_Node *item){ } if (token){ - String name = {0}; + String parent_name = {0}; Cpp_Token *token_j = 0; for (; (token_j = get_token(context)) != 0; get_prev_token(context)){ @@ -782,10 +782,10 @@ enum_parse(Partition *part, Parse_Context *context, Item_Node *item){ } } - name = get_lexeme(*token_j, context->data); + parent_name = get_lexeme(*token_j, context->data); set_token(context, token); - for (; (token = get_token(context)) > start_token; get_next_token(context)){ + for (; (token = get_token(context)) > parent_start_token; get_next_token(context)){ if (token->type == CPP_TOKEN_BRACE_OPEN){ break; } @@ -855,8 +855,8 @@ enum_parse(Partition *part, Parse_Context *context, Item_Node *item){ get_next_token(context); item->t = Item_Enum; - item->name = name; - item->doc_string = doc_string; + item->name = parent_name; + item->doc_string = parent_doc_string; item->first_child = first_member; result = true; } @@ -912,9 +912,9 @@ parameter_parse(Partition *part, char *data, Cpp_Token *args_start_token, Cpp_To param_name_token->start > param_string_start; --param_name_token){ if (param_name_token->type == CPP_TOKEN_IDENTIFIER){ - int32_t start = param_name_token->start; - int32_t size = param_name_token->size; - breakdown.args[arg_index].param_name = make_string(data + start, size); + int32_t name_start = param_name_token->start; + int32_t name_size = param_name_token->size; + breakdown.args[arg_index].param_name = make_string(data + name_start, name_size); break; } } @@ -1190,7 +1190,7 @@ macro_parse(Partition *part, Parse_Context *context, Item_Node *item){ } static Meta_Unit -compile_meta_unit(Partition *part, char *code_directory, char **files, Meta_Keywords *keywords, int32_t key_count){ +compile_meta_unit(Partition *part, char *code_directory, char **files, Meta_Keywords *meta_keywords, int32_t key_count){ Meta_Unit unit = {0}; int32_t file_count = 0; @@ -1232,8 +1232,8 @@ compile_meta_unit(Partition *part, char *code_directory, char **files, Meta_Keyw String lexeme = get_lexeme(*token, context->data); int32_t match_index = 0; - if (string_set_match_table(keywords, sizeof(*keywords), key_count, lexeme, &match_index)){ - Item_Type type = keywords[match_index].type; + if (string_set_match_table(meta_keywords, sizeof(*meta_keywords), key_count, lexeme, &match_index)){ + Item_Type type = meta_keywords[match_index].type; if (type > Item_Null && type < Item_Type_Count){ ++unit.set.count; @@ -1265,8 +1265,8 @@ compile_meta_unit(Partition *part, char *code_directory, char **files, Meta_Keyw String lexeme = get_lexeme(*token, context->data); int32_t match_index = 0; - if (string_set_match_table(keywords, sizeof(*keywords), key_count, lexeme, &match_index)){ - Item_Type type = keywords[match_index].type; + if (string_set_match_table(meta_keywords, sizeof(*meta_keywords), key_count, lexeme, &match_index)){ + Item_Type type = meta_keywords[match_index].type; switch (type){ case Item_Function: @@ -1364,9 +1364,9 @@ compile_meta_unit(Partition *part, char *code_directory, char **files, Meta_Keyw } static Meta_Unit -compile_meta_unit(Partition *part, char *code_directory, char *file, Meta_Keywords *keywords, int32_t key_count){ +compile_meta_unit(Partition *part, char *code_directory, char *file, Meta_Keywords *meta_keywords, int32_t key_count){ char *file_array[2] = {file, 0}; - Meta_Unit unit = compile_meta_unit(part, code_directory, file_array, keywords, key_count); + Meta_Unit unit = compile_meta_unit(part, code_directory, file_array, meta_keywords, key_count); return(unit); } diff --git a/meta/readme_generator.c b/meta/readme_generator.c deleted file mode 100644 index 5e5ddbe6..00000000 --- a/meta/readme_generator.c +++ /dev/null @@ -1,97 +0,0 @@ - -/* - * For generating the header of the TODO files so I don't have to - * keep doing that by hand and accidentally forgetting half the time. - * -Allen - * 12.05.2016 (dd.mm.yyyy) - * - */ - -// TOP - -#include -#include -#include -#include - -char *header = -"Distribution Date: %d.%d.%d (dd.mm.yyyy)\n" -"\n" -"Thank you for contributing to the 4coder project!\n" -"\n" -"To submit bug reports or to request particular features email editor@4coder.net.\n" -"\n" -"Watch 4coder.net blog and @AllenWebster4th twitter for news about 4coder progress.\n" -"\n" -; - -typedef struct Readme_Variables{ - int32_t day, month, year; -} Readme_Variables; - -typedef struct File_Data{ - char *data; - int32_t size; - int32_t file_exists; -} File_Data; - -File_Data -dump(char *file_name){ - File_Data result = {0}; - FILE *file = fopen(file_name, "rb"); - - if (file){ - result.file_exists = 1; - fseek(file, 0, SEEK_END); - result.size = ftell(file); - if (result.size > 0){ - result.data = (char*)malloc(result.size + 1); - result.data[result.size + 1] = 0; - fseek(file, 0, SEEK_SET); - fread(result.data, 1, result.size, file); - } - fclose(file); - } - - return(result); -} - -void -generate(char *file_name_out, char *file_name_body, Readme_Variables vars){ - File_Data in; - FILE *out; - - in = dump(file_name_body); - - if (in.file_exists){ - out = fopen(file_name_out, "wb"); - fprintf(out, header, vars.day, vars.month,vars.year); - if (in.size > 0){ - fprintf(out, "%s", in.data); - } - fclose(out); - } -} - -int -main(){ - time_t ctime; - struct tm tm; - Readme_Variables vars; - - ctime = time(0); - localtime_s(&tm, &ctime); - - vars.day = tm.tm_mday; - vars.month = tm.tm_mon + 1; - vars.year = tm.tm_year + 1900; - - generate("README.txt", "README_body.txt", vars); - - - return(0); -} - -// BOTTOM - - diff --git a/string/4coder_string_build_num.txt b/string/4coder_string_build_num.txt index 6d58b80b..3c4899bf 100644 --- a/string/4coder_string_build_num.txt +++ b/string/4coder_string_build_num.txt @@ -1,5 +1,5 @@ 1 0 -63 +68 diff --git a/string/_4coder_string.ctm b/string/_4coder_string.ctm index 108a7bd6..77f6a743 100644 Binary files a/string/_4coder_string.ctm and b/string/_4coder_string.ctm differ diff --git a/string/internal_4coder_string.cpp b/string/internal_4coder_string.cpp index 0b7c9658..c2bc3a5b 100644 --- a/string/internal_4coder_string.cpp +++ b/string/internal_4coder_string.cpp @@ -970,6 +970,23 @@ This call returns non-zero on a successful copy.) */{ return 1; } +CPP_NAME(copy_checked) +API_EXPORT FSTRING_LINK b32_4tech +copy_checked_cs(char *dest, i32_4tech dest_cap, String src)/* +DOC(This call performs a copy from the src string to the dest string. +The value dest_cap is checked before any coppying is done. +This call returns non-zero on a successful copy.) +*/{ + i32_4tech i; + if (dest_cap < src.size){ + return 0; + } + for (i = 0; i < src.size; ++i){ + dest[i] = src.str[i]; + } + return 1; +} + CPP_NAME(copy_partial) API_EXPORT FSTRING_LINK b32_4tech copy_partial_sc(String *dest, char *src)/* @@ -995,9 +1012,9 @@ CPP_NAME(copy_partial) API_EXPORT FSTRING_LINK b32_4tech copy_partial_ss(String *dest, String src)/* DOC(This call performs a copy from the src string to the dest string. -The memory_size of dest is checked if the entire copy cannot be performed, -as many bytes as possible are coppied to dest. This call returns non-zero -if the entire string is coppied to dest.) */{ +The memory_size of dest is checked. If the entire copy cannot be performed, +as many bytes as possible are coppied to dest. +This call returns non-zero if the entire string is coppied to dest.) */{ char *dest_str = dest->str; i32_4tech memory_size = dest->memory_size; b32_4tech result = 0; @@ -1009,7 +1026,28 @@ if the entire string is coppied to dest.) */{ dest_str[i] = src.str[i]; } dest->size = memory_size; - return result; + return(result); +} + +CPP_NAME(copy_partial) +API_EXPORT FSTRING_LINK b32_4tech +copy_partial_cs(char *dest, i32_4tech dest_cap, String src)/* +DOC(This call performs a copy from the src string to the dest string. +The value dest_cap is checked. If the entire copy cannot be performed, +as many bytes as possible are coppied to dest. +This call returns non-zero if the entire string is coppied to dest.) +*/{ + b32_4tech result = 0; + i32_4tech copy_size = dest_cap; + i32_4tech i; + if (dest_cap >= src.size){ + result = 1; + copy_size = src.size; + } + for (i = 0; i < copy_size; ++i){ + dest[i] = src.str[i]; + } + return(result); } CPP_NAME(copy) diff --git a/win32_4ed.cpp b/win32_4ed.cpp index cb266f64..5fbc36e7 100644 --- a/win32_4ed.cpp +++ b/win32_4ed.cpp @@ -28,6 +28,12 @@ // Program setup // +#define SUPPORT_DPI 1 +#define UNICODE + +#define FPS 60 +#define frame_useconds (1000000 / FPS) + #include #include #include "4tech_defines.h" @@ -63,22 +69,19 @@ #define GL_TEXTURE_MAX_LEVEL 0x813D -#include "filetrack/4tech_file_track_win32.c" +////////////////////////////// + +#include "4ed_file_track.h" #include "4ed_system_shared.h" -#define SUPPORT_DPI 1 -#define USE_FT_FONTS 1 - -#define FPS 60 -#define frame_useconds (1000000 / FPS) - -#define WM_4coder_ANIMATE (WM_USER + 0) - +#include "win32_4ed_file_track.cpp" // // Win32_Vars structs // +#define WM_4coder_ANIMATE (WM_USER + 0) + struct Thread_Context{ u32 job_id; b32 running; @@ -185,10 +188,8 @@ typedef struct Win32_Vars{ b32 next_clipboard_is_self; DWORD clipboard_sequence; - HWND window_handle; Render_Target target; - Partition font_part; #if SUPPORT_DPI i32 dpi_x, dpi_y; #endif @@ -333,9 +334,7 @@ Sys_Release_Lock_Sig(system_release_lock){ internal void system_wait_cv(i32 crit_id, i32 cv_id){ - SleepConditionVariableCS(win32vars.condition_vars + cv_id, - win32vars.locks + crit_id, - INFINITE); + SleepConditionVariableCS(win32vars.condition_vars + cv_id, win32vars.locks + crit_id, INFINITE); } internal void @@ -372,9 +371,7 @@ JobThreadProc(LPVOID lpParameter){ // wrapping by the queue wrap. That was super stupid what was that? // Now it just wraps by the queue wrap. u32 next_read_index = (read_index + 1) % QUEUE_WRAP; - u32 safe_read_index = - InterlockedCompareExchange(&queue->read_position, - next_read_index, read_index); + u32 safe_read_index = InterlockedCompareExchange(&queue->read_position, next_read_index, read_index); if (safe_read_index == read_index){ Full_Job_Data *full_job = queue->jobs + safe_read_index; @@ -382,16 +379,13 @@ JobThreadProc(LPVOID lpParameter){ // with the cancel job routine, which may try to cancel this job // at the same time that we try to run it - i32 safe_running_thread = - InterlockedCompareExchange(&full_job->running_thread, - thread->id, THREAD_NOT_ASSIGNED); + i32 safe_running_thread =InterlockedCompareExchange(&full_job->running_thread, thread->id, THREAD_NOT_ASSIGNED); if (safe_running_thread == THREAD_NOT_ASSIGNED){ thread->job_id = full_job->id; thread->running = 1; - full_job->job.callback(&win32vars.system, - thread, thread_memory, full_job->job.data); + full_job->job.callback(&win32vars.system, thread, thread_memory, full_job->job.data); PostMessage(win32vars.window_handle, WM_4coder_ANIMATE, 0, 0); //full_job->running_thread = 0; thread->running = 0; @@ -1392,75 +1386,7 @@ Sys_Send_Exit_Signal_Sig(system_send_exit_signal){ #include "4ed_system_shared.cpp" -#if USE_FT_FONTS -# include "win32_ft_font.cpp" -#endif - -internal f32 -size_change(i32 dpi_x, i32 dpi_y){ - // TODO(allen): We're just hoping dpi_x == dpi_y for now I guess. - f32 size_x = dpi_x / 96.f; - f32 size_y = dpi_y / 96.f; - f32 size_max = Max(size_x, size_y); - return(size_max); -} - -internal -Font_Load_Sig(system_draw_font_load){ - if (win32vars.font_part.base == 0){ - win32vars.font_part = Win32ScratchPartition(MB(8)); - } - - i32 oversample = 2; - AllowLocal(oversample); - -#if SUPPORT_DPI - pt_size = round32(pt_size * size_change(win32vars.dpi_x, win32vars.dpi_y)); -#endif - - for (b32 success = 0; success == 0;){ -#if USE_WIN32_FONTS - - success = win32_font_load(&win32vars.font_part, - font_out, - filename, - fontname, - pt_size, - tab_width, - oversample, - store_texture); - -#elif USE_FT_FONTS - - success = win32_ft_font_load(&win32vars.font_part, - font_out, - filename, - pt_size, - tab_width, - win32vars.settings.use_hinting); - -#else - - success = stb_font_load(&win32vars.font_part, - font_out, - filename, - pt_size, - tab_width, - oversample, - store_texture); - -#endif - - // TODO(allen): Make the growable partition something - // that can just be passed directly to font load and - // let it be grown there. - if (!success){ - Win32ScratchPartitionDouble(&win32vars.font_part); - } - } - - return(1); -} +#include "win32_4ed_fonts.cpp" // // Linkage to Custom and Application @@ -1529,7 +1455,6 @@ Win32LoadSystemCode(){ win32vars.system.is_fullscreen = system_is_fullscreen;win32vars.system.show_mouse_cursor = system_show_mouse_cursor; win32vars.system.send_exit_signal = system_send_exit_signal; - #if FRED_INTERNAL win32vars.system.internal_get_thread_states = INTERNAL_get_thread_states; #endif @@ -1540,9 +1465,6 @@ Win32LoadRenderCode(){ win32vars.target.push_clip = draw_push_clip; win32vars.target.pop_clip = draw_pop_clip; win32vars.target.push_piece = draw_push_piece; - - win32vars.target.font_set.font_load = system_draw_font_load; - win32vars.target.font_set.release_font = draw_release_font; } // @@ -1587,7 +1509,7 @@ Win32KeycodeInit(){ internal void Win32RedrawScreen(HDC hdc){ - launch_rendering(&win32vars.target); + launch_rendering(&win32vars.system, &win32vars.target); glFlush(); SwapBuffers(hdc); } @@ -1912,7 +1834,7 @@ Win32Callback(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam){ case WM_MOUSEWHEEL: { win32vars.got_useful_event = 1; - i16 rotation = GET_WHEEL_DELTA_WPARAM(wParam); + Font_ID rotation = GET_WHEEL_DELTA_WPARAM(wParam); if (rotation > 0){ win32vars.input_chunk.trans.mouse_wheel = 1; } @@ -2103,11 +2025,10 @@ WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdS win32vars.target.max = MB(1); win32vars.target.push_buffer = (char*)system_get_memory(win32vars.target.max); - if (!memory_vars.vars_memory || !memory_vars.target_memory || !memory_vars.user_memory || !win32vars.target.push_buffer){ + if (memory_vars.vars_memory == 0 || memory_vars.target_memory == 0 || memory_vars.user_memory == 0 || win32vars.target.push_buffer == 0){ exit(1); } - // // System and Application Layer Linkage // @@ -2117,17 +2038,14 @@ WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdS } Win32LoadSystemCode(); - Win32LoadRenderCode(); - // // Shared Systems Init // init_shared_vars(); - // // Read Command Line // @@ -2151,7 +2069,6 @@ WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdS sysshared_filter_real_files(files, file_count); - // // Custom Layer Linkage // @@ -2242,25 +2159,32 @@ WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdS exit(1); } - HDC hdc = GetDC(win32vars.window_handle); - + { + HDC hdc = GetDC(win32vars.window_handle); + #if SUPPORT_DPI - // TODO(allen): not Windows XP compatible, how do I handle that? - SetProcessDPIAware(); - - win32vars.dpi_x = GetDeviceCaps(hdc, LOGPIXELSX); - win32vars.dpi_y = GetDeviceCaps(hdc, LOGPIXELSY); + // TODO(allen): not Windows XP compatible, how do I handle that? + SetProcessDPIAware(); + + win32vars.dpi_x = GetDeviceCaps(hdc, LOGPIXELSX); + win32vars.dpi_y = GetDeviceCaps(hdc, LOGPIXELSY); #else - win32vars.dpi_x = 1; - win32vars.dpi_y = 1; + win32vars.dpi_x = 1; + win32vars.dpi_y = 1; #endif - - GetClientRect(win32vars.window_handle, &window_rect); - ReleaseDC(win32vars.window_handle, hdc); + + GetClientRect(win32vars.window_handle, &window_rect); + ReleaseDC(win32vars.window_handle, hdc); + } Win32InitGL(); Win32Resize(window_rect.right - window_rect.left, window_rect.bottom - window_rect.top); + // + // Font System Init + // + + system_font_init(&win32vars.system.font, 0, 0, 16, true); // // Misc System Initializations @@ -2543,13 +2467,15 @@ WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdS return(0); } +#include "font/4coder_font_static_functions.cpp" + #if 0 // NOTE(allen): In case I want to switch back to a console // application at some point. int main(int argc, char **argv){ HINSTANCE hInstance = GetModuleHandle(0); +} #endif - - // BOTTOM - - + +// BOTTOM + diff --git a/filetrack/4tech_file_track_win32.c b/win32_4ed_file_track.cpp similarity index 56% rename from filetrack/4tech_file_track_win32.c rename to win32_4ed_file_track.cpp index 9156a8f0..6e1b61c5 100644 --- a/filetrack/4tech_file_track_win32.c +++ b/win32_4ed_file_track.cpp @@ -1,26 +1,26 @@ /* - -The OS agnostic file tracking API for applications -that want to interact with potentially many files on -the disk that could be changed by other applications. - -Created on: 20.07.2016 - -*/ + * Mr. 4th Dimention - Allen Webster + * + * 20.07.2016 + * + * File tracking win32. + * + */ // TOP -#include "4tech_file_track.h" -#include "4tech_file_track_general.c" +#include "4ed_file_track.h" +#include "4ed_file_track_general.cpp" #include typedef struct { OVERLAPPED overlapped; - char result[2048]; + u16 result[1024]; HANDLE dir; - int32_t user_count; + i32 user_count; } Win32_Directory_Listener; +global_const OVERLAPPED null_overlapped = {0}; typedef struct { DLL_Node node; @@ -44,9 +44,7 @@ typedef struct { #define to_tables(v) ((File_Track_Tables*)(v->tables)) FILE_TRACK_LINK File_Track_Result -init_track_system(File_Track_System *system, - void *table_memory, int32_t table_memory_size, - void *listener_memory, int32_t listener_memory_size){ +init_track_system(File_Track_System *system, void *table_memory, i32 table_memory_size, void *listener_memory, i32 listener_memory_size){ File_Track_Result result = FileTrack_MemoryTooSmall; Win32_File_Track_Vars *vars = to_vars(system); @@ -65,8 +63,8 @@ init_track_system(File_Track_System *system, init_sentinel_node(&vars->free_sentinel); Win32_Directory_Listener_Node *listener = (Win32_Directory_Listener_Node*)listener_memory; - int32_t count = listener_memory_size / sizeof(Win32_Directory_Listener_Node); - for (int32_t i = 0; i < count; ++i, ++listener){ + i32 count = listener_memory_size / sizeof(Win32_Directory_Listener_Node); + for (i32 i = 0; i < count; ++i, ++listener){ insert_node(&vars->free_sentinel, &listener->node); } } @@ -83,30 +81,26 @@ init_track_system(File_Track_System *system, return(result); } -static int32_t -internal_get_parent_name(char *out, int32_t max, char *name){ - int32_t len, slash_i; - - char *ptr = name; +internal umem +internal_utf8_file_to_utf16_parent(u16 *out, u32 max, u8 *name){ + u8 *ptr = name; for (; *ptr != 0; ++ptr); - len = (int32_t)(ptr - name); + umem len = (umem)(ptr - name); // TODO(allen): make this system real Assert(len < max); - for (slash_i = len-1; - slash_i > 0 && name[slash_i] != '\\' && name[slash_i] != '/'; - --slash_i); + umem slash_i = len-1; + for (;slash_i > 0 && name[slash_i] != '\\' && name[slash_i] != '/';--slash_i); - for (int32_t i = 0; i < slash_i; ++i){ - out[i] = name[i]; - } + b32 error = false; + slash_i = utf8_to_utf16_minimal_checking(out, max-1, name, len, &error); out[slash_i] = 0; return(slash_i); } -static File_Index +internal File_Index internal_get_file_index(BY_HANDLE_FILE_INFORMATION info){ File_Index hash; hash.id[0] = info.nFileIndexLow; @@ -128,7 +122,7 @@ FILE_NOTIFY_CHANGE_CREATION | \ 0) FILE_TRACK_LINK File_Track_Result -add_listener(File_Track_System *system, char *filename){ +add_listener(File_Track_System *system, u8 *filename){ File_Track_Result result = FileTrack_Good; Win32_File_Track_Vars *vars = to_vars(system); @@ -137,10 +131,10 @@ add_listener(File_Track_System *system, char *filename){ File_Track_Tables *tables = to_tables(vars); // TODO(allen): make this real! - char dir_name[1024]; - internal_get_parent_name(dir_name, sizeof(dir_name), filename); + u16 dir_name[1024]; + internal_utf8_file_to_utf16_parent(dir_name, ArrayCount(dir_name), filename); - HANDLE dir = CreateFile(dir_name, FILE_LIST_DIRECTORY, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, 0, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OVERLAPPED, 0); + HANDLE dir = CreateFile((LPCWSTR)dir_name, FILE_LIST_DIRECTORY, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, 0, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OVERLAPPED, 0); if (dir != INVALID_HANDLE_VALUE){ BY_HANDLE_FILE_INFORMATION dir_info = {0}; @@ -157,7 +151,7 @@ add_listener(File_Track_System *system, char *filename){ allocate_node(&vars->free_sentinel); if (node){ if (CreateIoCompletionPort(dir, vars->iocp, (ULONG_PTR)node, 1)){ - ZeroStruct(node->listener.overlapped); + node->listener.overlapped = null_overlapped; if (ReadDirectoryChangesW(dir, node->listener.result, sizeof(node->listener.result), 1, FLAGS, 0, &node->listener.overlapped, 0)){ node->listener.dir = dir; node->listener.user_count = 1; @@ -210,57 +204,48 @@ add_listener(File_Track_System *system, char *filename){ } FILE_TRACK_LINK File_Track_Result -remove_listener(File_Track_System *system, char *filename){ +remove_listener(File_Track_System *system, u8 *filename){ File_Track_Result result = FileTrack_Good; Win32_File_Track_Vars *vars = to_vars(system); EnterCriticalSection(&vars->table_lock); - { - File_Track_Tables *tables = to_tables(vars); + File_Track_Tables *tables = to_tables(vars); + + // TODO(allen): make this real! + u16 dir_name[1024]; + internal_utf8_file_to_utf16_parent(dir_name, ArrayCount(dir_name), filename); + + HANDLE dir = CreateFile((LPCWSTR)dir_name, FILE_LIST_DIRECTORY, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, 0, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OVERLAPPED, 0); + + if (dir != INVALID_HANDLE_VALUE){ + BY_HANDLE_FILE_INFORMATION dir_info = {0}; + DWORD getinfo_result = GetFileInformationByHandle(dir, &dir_info); - // TODO(allen): make this real! - char dir_name[1024]; - internal_get_parent_name(dir_name, sizeof(dir_name), filename); - - HANDLE dir = CreateFile( - dir_name, - FILE_LIST_DIRECTORY, - FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, - 0, - OPEN_EXISTING, - FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OVERLAPPED, - 0); - - if (dir != INVALID_HANDLE_VALUE){ - BY_HANDLE_FILE_INFORMATION dir_info = {0}; - DWORD getinfo_result = GetFileInformationByHandle(dir, &dir_info); + if (getinfo_result){ + File_Index dir_hash = internal_get_file_index(dir_info); + File_Track_Entry *dir_lookup = tracking_system_lookup_entry(tables, dir_hash); + Win32_File_Track_Entry *win32_dir = (Win32_File_Track_Entry*)dir_lookup; - if (getinfo_result){ - File_Index dir_hash = internal_get_file_index(dir_info); - File_Track_Entry *dir_lookup = tracking_system_lookup_entry(tables, dir_hash); - Win32_File_Track_Entry *win32_dir = (Win32_File_Track_Entry*)dir_lookup; - - Assert(!entry_is_available(dir_lookup)); - Win32_Directory_Listener_Node *node = win32_dir->listener_node; - --node->listener.user_count; - - if (node->listener.user_count == 0){ - insert_node(&vars->free_sentinel, &node->node); - CancelIo(win32_dir->dir); - CloseHandle(win32_dir->dir); - internal_free_slot(tables, dir_lookup); - } - } - else{ - result = FileTrack_FileSystemError; - } + Assert(!entry_is_available(dir_lookup)); + Win32_Directory_Listener_Node *node = win32_dir->listener_node; + --node->listener.user_count; - CloseHandle(dir); + if (node->listener.user_count == 0){ + insert_node(&vars->free_sentinel, &node->node); + CancelIo(win32_dir->dir); + CloseHandle(win32_dir->dir); + internal_free_slot(tables, dir_lookup); + } } else{ result = FileTrack_FileSystemError; } + + CloseHandle(dir); + } + else{ + result = FileTrack_FileSystemError; } LeaveCriticalSection(&vars->table_lock); @@ -269,17 +254,15 @@ remove_listener(File_Track_System *system, char *filename){ } FILE_TRACK_LINK File_Track_Result -move_track_system(File_Track_System *system, void *mem, int32_t size){ +move_track_system(File_Track_System *system, void *mem, i32 size){ File_Track_Result result = FileTrack_Good; Win32_File_Track_Vars *vars = to_vars(system); EnterCriticalSection(&vars->table_lock); - { - File_Track_Tables *original_tables = to_tables(vars); - result = move_table_memory(original_tables, mem, size); - if (result == FileTrack_Good){ - vars->tables = mem; - } + File_Track_Tables *original_tables = to_tables(vars); + result = move_table_memory(original_tables, mem, size); + if (result == FileTrack_Good){ + vars->tables = mem; } LeaveCriticalSection(&vars->table_lock); @@ -287,7 +270,7 @@ move_track_system(File_Track_System *system, void *mem, int32_t size){ } FILE_TRACK_LINK File_Track_Result -expand_track_system_listeners(File_Track_System *system, void *mem, int32_t size){ +expand_track_system_listeners(File_Track_System *system, void *mem, i32 size){ File_Track_Result result = FileTrack_Good; Win32_File_Track_Vars *vars = to_vars(system); @@ -295,8 +278,8 @@ expand_track_system_listeners(File_Track_System *system, void *mem, int32_t size if (sizeof(Win32_Directory_Listener_Node) <= size){ Win32_Directory_Listener_Node *listener = (Win32_Directory_Listener_Node*)mem; - int32_t count = size / sizeof(Win32_Directory_Listener_Node); - for (int32_t i = 0; i < count; ++i, ++listener){ + i32 count = size / sizeof(Win32_Directory_Listener_Node); + for (i32 i = 0; i < count; ++i, ++listener){ insert_node(&vars->free_sentinel, &listener->node); } } @@ -310,99 +293,82 @@ expand_track_system_listeners(File_Track_System *system, void *mem, int32_t size } FILE_TRACK_LINK File_Track_Result -get_change_event(File_Track_System *system, char *buffer, int32_t max, int32_t *size){ +get_change_event(File_Track_System *system, u8 *buffer, i32 max, i32 *size){ File_Track_Result result = FileTrack_NoMoreEvents; Win32_File_Track_Vars *vars = to_vars(system); - static int32_t has_buffered_event = 0; - static DWORD offset = 0; - static Win32_Directory_Listener listener; + local_persist i32 has_buffered_event = 0; + local_persist DWORD offset = 0; + local_persist Win32_Directory_Listener listener = {0}; EnterCriticalSection(&vars->table_lock); - { - OVERLAPPED *overlapped = 0; - DWORD length = 0; - ULONG_PTR key = 0; - - int32_t has_result = 0; - - if (has_buffered_event){ - has_buffered_event = 0; + OVERLAPPED *overlapped = 0; + DWORD length = 0; + ULONG_PTR key = 0; + + b32 has_result = 0; + + if (has_buffered_event){ + has_buffered_event = 0; + has_result = 1; + } + else{ + if (GetQueuedCompletionStatus(vars->iocp, &length, &key, &overlapped, 0)){ + Win32_Directory_Listener *listener_ptr = (Win32_Directory_Listener*)overlapped; + + // NOTE(allen): Get a copy of the state of this node so we can set the node + // to work listening for changes again right away. + listener = *listener_ptr; + + listener_ptr->overlapped = null_overlapped; + ReadDirectoryChangesW(listener_ptr->dir, listener_ptr->result, sizeof(listener_ptr->result), 1, FLAGS, 0, &listener_ptr->overlapped, 0); + + offset = 0; has_result = 1; } - else{ - if (GetQueuedCompletionStatus(vars->iocp, - &length, - &key, - &overlapped, - 0)){ - Win32_Directory_Listener *listener_ptr = (Win32_Directory_Listener*)overlapped; - - // NOTE(allen): Get a copy of the state of this node so we can set the node - // to work listening for changes again right away. - listener = *listener_ptr; - - ZeroStruct(listener_ptr->overlapped); - ReadDirectoryChangesW(listener_ptr->dir, - listener_ptr->result, - sizeof(listener_ptr->result), - 1, - FLAGS, - 0, - &listener_ptr->overlapped, - 0); - - offset = 0; - has_result = 1; + } + + if (has_result){ + + FILE_NOTIFY_INFORMATION *info = (FILE_NOTIFY_INFORMATION*)(listener.result + offset); + + i32 len = info->FileNameLength / 2; + i32 dir_len = GetFinalPathNameByHandle(listener.dir, 0, 0, FILE_NAME_NORMALIZED); + + i32 req_size = dir_len + 1 + len; + *size = req_size; + if (req_size < max){ + i32 pos = GetFinalPathNameByHandle(listener.dir, buffer, max, FILE_NAME_NORMALIZED); + buffer[pos++] = '\\'; + + for (i32 i = 0; i < len; ++i, ++pos){ + buffer[pos] = (char)info->FileName[i]; } + + if (buffer[0] == '\\'){ + for (i32 i = 0; i+4 < pos; ++i){ + buffer[i] = buffer[i+4]; + } + *size -= 4; + } + + result = FileTrack_Good; + } + else{ + // TODO(allen): Need some way to stash this result so that if the + // user comes back with more memory we can give them the change + // notification they missed. + result = FileTrack_MemoryTooSmall; } - if (has_result){ - - FILE_NOTIFY_INFORMATION *info = (FILE_NOTIFY_INFORMATION*)(listener.result + offset); - - int32_t len = info->FileNameLength / 2; - int32_t dir_len = GetFinalPathNameByHandle(listener.dir, 0, 0, - FILE_NAME_NORMALIZED); - - int32_t req_size = dir_len + 1 + len; - *size = req_size; - if (req_size < max){ - int32_t pos = 0; - - pos = GetFinalPathNameByHandle(listener.dir, buffer, max, - FILE_NAME_NORMALIZED); - buffer[pos++] = '\\'; - - for (int32_t i = 0; i < len; ++i, ++pos){ - buffer[pos] = (char)info->FileName[i]; - } - - if (buffer[0] == '\\'){ - for (int32_t i = 0; i+4 < pos; ++i){ - buffer[i] = buffer[i+4]; - } - *size -= 4; - } - - result = FileTrack_Good; - } - else{ - // TODO(allen): Need some way to stash this result so that if the - // user comes back with more memory we can give them the change - // notification they missed. - result = FileTrack_MemoryTooSmall; - } - - if (info->NextEntryOffset != 0){ - // TODO(allen): We're not ready to handle this yet. - // For now I am breaking. In the future, if there - // are more results we should stash them and return - // them in future calls. - offset += info->NextEntryOffset; - has_buffered_event = 1; - } + if (info->NextEntryOffset != 0){ + // TODO(allen): We're not ready to handle this yet. + // For now I am breaking. In the future, if there + // are more results we should stash them and return + // them in future calls. + offset += info->NextEntryOffset; + has_buffered_event = 1; } } @@ -423,9 +389,9 @@ shut_down_track_system(File_Track_System *system){ File_Track_Tables *tables = to_tables(vars); File_Track_Entry *entries = (File_Track_Entry*)to_ptr(tables, tables->file_table); - uint32_t max = tables->max; + u32 max = tables->max; - for (uint32_t index = 0; index < max; ++index){ + for (u32 index = 0; index < max; ++index){ File_Track_Entry *entry = entries + index; if (!entry_is_available(entry)){ diff --git a/win32_4ed_fonts.cpp b/win32_4ed_fonts.cpp new file mode 100644 index 00000000..3b50b8f3 --- /dev/null +++ b/win32_4ed_fonts.cpp @@ -0,0 +1,134 @@ +/* + * Mr. 4th Dimention - Allen Webster + * + * 09.02.2016 + * + * Shared system functions + * + */ + +// TOP + +#include "4ed_system_shared.h" +#include "font/4coder_font_interface.h" +#include "font/4coder_font_interface_to_os.h" +#include "font/4coder_font_data.h" + +struct Win32_Fonts{ + Partition part; + Render_Font fonts[5]; + u32 font_count; +}; + +global Win32_Fonts win32_fonts = {0}; + +internal +Sys_Font_Get_Count_Sig(system_font_get_count){ + return(5); +} + +internal +Sys_Font_Get_IDs_By_Index_Sig(system_font_get_ids_by_index){ + b32 result = false; + u32 stop_index = first_index + index_count; + if (stop_index <= win32_fonts.font_count){ + result = true; + for (u32 i = first_index; i < stop_index; ++i){ + id_out[i-first_index] = i; + } + } + return(result); +} + +internal +Sys_Font_Get_Name_By_Index_Sig(system_font_get_name_by_index){ + u32 length = 0; + if (font_index < win32_fonts.font_count){ + Render_Font *font = &win32_fonts.fonts[font_index]; + char *name = font->name; + length = font->name_len; + copy_partial_cs(str_out, str_out_cap, make_string(name, length)); + } + return(length); +} + +internal +Sys_Font_Get_Name_By_ID_Sig(system_font_get_name_by_id){ + u32 font_index = font_id; + u32 result = system_font_get_name_by_index(font_index, str_out, str_out_cap); + return(result); +} + +internal +Sys_Font_Get_Render_Data_By_ID_Sig(system_font_get_render_data_by_id){ + Render_Font *result = 0; + u32 font_index = font_id; + if (font_index < win32_fonts.font_count){ + result = &win32_fonts.fonts[font_index]; + } + return(result); +} + +internal +Sys_Font_Load_Page_Sig(system_font_load_page){ + system_set_page(&win32vars.system, &win32_fonts.part, font, page, page_number, 16, true); +} + +internal +Sys_Font_Allocate_Sig(system_font_allocate){ + void *result = system_memory_allocate(size); + return(result); +} + +internal +Sys_Font_Free_Sig(system_font_free){ + system_memory_free(ptr, 0); +} + +internal +Sys_Font_Init_Sig(system_font_init){ + font->get_count = system_font_get_count; + font->get_ids_by_index = system_font_get_ids_by_index; + font->get_name_by_index = system_font_get_name_by_index; + font->get_name_by_id = system_font_get_name_by_id; + font->get_render_data_by_id = system_font_get_render_data_by_id; + font->load_page = system_font_load_page; + font->allocate = system_font_allocate; + font->free = system_font_free; + + font_size = clamp_bottom(8, font_size); + + struct Font_Setup{ + char *c_filename; + i32 filename_len; + char *c_name; + i32 name_len; + u32 pt_size; + }; + Font_Setup font_setup[] = { + {literal("LiberationSans-Regular.ttf"), literal("Liberation Sans"), font_size}, + {literal("liberation-mono.ttf"), literal("Liberation Mono"), font_size}, + {literal("Hack-Regular.ttf"), literal("Hack"), font_size}, + {literal("CutiveMono-Regular.ttf"), literal("Cutive Mono"), font_size}, + {literal("Inconsolata-Regular.ttf"), literal("Inconsolata"), font_size}, + }; + + u32 font_count = Min(ArrayCount(win32_fonts.fonts), ArrayCount(font_setup)); + for (u32 i = 0; i < font_count; ++i){ + String filename = make_string(font_setup[i].c_filename, font_setup[i].filename_len); + String name = make_string(font_setup[i].c_name, font_setup[i].name_len); + u32 pt_size = font_setup[i].pt_size; + Render_Font *render_font = &win32_fonts.fonts[i]; + + char full_filename_space[256]; + String full_filename = make_fixed_width_string(full_filename_space); + sysshared_to_binary_path(&full_filename, filename.str); + + system_set_font(&win32vars.system, &win32_fonts.part, render_font, full_filename, name, pt_size, use_hinting); + } + + win32_fonts.font_count = font_count; +} + +// BOTTOM + diff --git a/win32_ft_font.cpp b/win32_ft_font.cpp deleted file mode 100644 index 45c49b29..00000000 --- a/win32_ft_font.cpp +++ /dev/null @@ -1,29 +0,0 @@ -// NOTE(allen): Thanks to insofaras. -// This is copy-pasted from some work he -// did to get free type working on linux. -// Once it is working on both sides it might -// be possible to pull some parts out as -// portable FT rendering. - -internal b32 -win32_ft_font_load(Partition *part, Render_Font *rf, char *name, i32 pt_size, i32 tab_width, b32 use_hinting){ - - b32 result = 0; - - Temp_Memory temp = begin_temp_memory(part); - - char* filename = push_array(part, char, 256); - - if (filename != 0){ - String str = make_string_cap(filename, 0, 256); - sysshared_to_binary_path(&str, name); - - result = font_load_freetype(part, rf, filename, pt_size, tab_width, use_hinting); - } - - end_temp_memory(temp); - - return(result); -} - - diff --git a/win32_gl.h b/win32_gl.h index 7cc6248b..2ba985ed 100644 --- a/win32_gl.h +++ b/win32_gl.h @@ -79,6 +79,7 @@ wglGetExtensionsStringARB_Function(HDC hdc); typedef void CALL_CONVENTION GLDEBUGPROC_TYPE(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const char * message, const GLvoid * userParam); +// TODO(allen): these don't belong here, but the organizational stuff is not fully in place yet. typedef GLDEBUGPROC_TYPE * GLDEBUGPROC; typedef void CALL_CONVENTION glDebugMessageControl_type(GLenum source, GLenum type, GLenum severity, GLsizei count, GLuint * ids, GLboolean enabled);