utf8 encoded buffers fully working on windows
parent
59267a6418
commit
67f6e7b743
|
@ -19,7 +19,7 @@
|
|||
/* DOC(bool32 is an alias name to signal that an integer parameter or field is for true/false values.) */
|
||||
TYPEDEF int32_t bool32;
|
||||
|
||||
/* DOC(int_color is an alias name to signal that an integer parameter or field is for a color value, colors are specified as 24 bit integers in 3 channels: 0xRRGGBB.) */
|
||||
/* DOC(int_color is an alias name to signal that an integer parameter or field is for a color value, colors are specified as 32 bit integers (8 bit + 24 bit) with 3 channels: 0x**RRGGBB.) */
|
||||
TYPEDEF uint32_t int_color;
|
||||
|
||||
/* DOC(Buffer_ID is used to name a 4coder buffer. Each buffer has a unique id but when a buffer is closed it's id may be recycled by future, different buffers.) */
|
||||
|
|
|
@ -25,16 +25,17 @@ CUSTOM_COMMAND_SIG(write_character){
|
|||
|
||||
User_Input in = get_command_input(app);
|
||||
|
||||
char character = 0;
|
||||
uint8_t character[4];
|
||||
uint32_t length = 0;
|
||||
if (in.type == UserInputKey){
|
||||
character = to_writable_char(in.key.character);
|
||||
u32_to_utf8_unchecked(in.key.character, character, &length);
|
||||
}
|
||||
|
||||
if (character != 0){
|
||||
if (length != 0){
|
||||
Buffer_Summary buffer = get_buffer(app, view.buffer_id, access);
|
||||
int32_t pos = view.cursor.pos;
|
||||
buffer_replace_range(app, &buffer, pos, pos, &character, 1);
|
||||
view_set_cursor(app, &view, seek_pos(view.cursor.pos + 1), true);
|
||||
buffer_replace_range(app, &buffer, pos, pos, (char*)character, length);
|
||||
view_set_cursor(app, &view, seek_character_pos(view.cursor.character_pos + 1), true);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -151,7 +151,7 @@ inline char
|
|||
buffer_get_char(Application_Links *app, Buffer_Summary *buffer, int32_t pos){
|
||||
char result = ' ';
|
||||
*buffer = get_buffer(app, buffer->buffer_id, AccessAll);
|
||||
if (pos >= 0 && pos < buffer->size){
|
||||
if (pos < buffer->size){
|
||||
buffer_read_range(app, buffer, pos, pos+1, &result);
|
||||
}
|
||||
return(result);
|
||||
|
|
|
@ -17,7 +17,7 @@ struct Stream_Chunk{
|
|||
int32_t start, end;
|
||||
int32_t min_start, max_end;
|
||||
bool32 add_null;
|
||||
int32_t data_size;
|
||||
uint32_t data_size;
|
||||
|
||||
char *data;
|
||||
};
|
||||
|
@ -42,7 +42,7 @@ round_up(int32_t x, int32_t b){
|
|||
|
||||
static bool32
|
||||
init_stream_chunk(Stream_Chunk *chunk, Application_Links *app, Buffer_Summary *buffer,
|
||||
int32_t pos, char *data, int32_t size){
|
||||
int32_t pos, char *data, uint32_t size){
|
||||
bool32 result = 0;
|
||||
|
||||
refresh_buffer(app, buffer);
|
||||
|
|
|
@ -41,31 +41,137 @@ typedef int32_t b32_4tech;
|
|||
// standard preamble end
|
||||
|
||||
static u32_4tech
|
||||
utf8_to_u32_unchecked(u8_4tech *buffer){
|
||||
utf8_to_u32_length_unchecked(u8_4tech *buffer, u32_4tech *length_out){
|
||||
u32_4tech result = 0;
|
||||
|
||||
if (buffer[0] <= 0x7F){
|
||||
result = (u32_4tech)buffer[0];
|
||||
*length_out = 1;
|
||||
}
|
||||
else if (buffer[0] <= 0xE0){
|
||||
result = ((u32_4tech)((buffer[0])&0x1F)) << 6;
|
||||
result |= ((u32_4tech)((buffer[1])&0x3F));
|
||||
*length_out = 2;
|
||||
}
|
||||
else if (buffer[0] <= 0xF0){
|
||||
result = ((u32_4tech)((buffer[0])&0x0F)) << 12;
|
||||
result |= ((u32_4tech)((buffer[1])&0x3F)) << 6;
|
||||
result |= ((u32_4tech)((buffer[2])&0x3F));
|
||||
*length_out = 3;
|
||||
}
|
||||
else{
|
||||
result = ((u32_4tech)((buffer[0])&0x07)) << 18;
|
||||
result |= ((u32_4tech)((buffer[1])&0x3F)) << 12;
|
||||
result |= ((u32_4tech)((buffer[2])&0x3F)) << 6;
|
||||
result |= ((u32_4tech)((buffer[3])&0x3F));
|
||||
*length_out = 4;
|
||||
}
|
||||
|
||||
return(result);
|
||||
}
|
||||
|
||||
static u32_4tech
|
||||
utf8_to_u32_unchecked(u8_4tech *buffer){
|
||||
u32_4tech ignore;
|
||||
u32_4tech result = utf8_to_u32_length_unchecked(buffer, &ignore);
|
||||
return(result);
|
||||
}
|
||||
|
||||
static u32_4tech
|
||||
utf8_to_u32(u8_4tech **buffer_ptr, u8_4tech *end){
|
||||
u8_4tech *buffer = *buffer_ptr;
|
||||
u32_4tech limit = (u32_4tech)(end - buffer);
|
||||
|
||||
u32_4tech length = 0;
|
||||
if (buffer[0] < 0x80){
|
||||
length = 1;
|
||||
}
|
||||
else if (buffer[0] < 0xC0){
|
||||
length = 0;
|
||||
}
|
||||
else if (buffer[0] < 0xE0){
|
||||
length = 2;
|
||||
}
|
||||
else if (buffer[0] < 0xF0){
|
||||
length = 3;
|
||||
}
|
||||
else{
|
||||
length = 4;
|
||||
}
|
||||
|
||||
for (u32_4tech i = 1; i < length; ++i){
|
||||
if ((buffer[i] & 0xC0) != 0x80){
|
||||
length = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
u32_4tech result = 0;
|
||||
if (length != 0 && length <= limit){
|
||||
switch (length){
|
||||
case 1:
|
||||
{
|
||||
result = (u32_4tech)buffer[0];
|
||||
}break;
|
||||
|
||||
case 2:
|
||||
{
|
||||
result = ((u32_4tech)((buffer[0])&0x1F)) << 6;
|
||||
result |= ((u32_4tech)((buffer[1])&0x3F));
|
||||
}break;
|
||||
|
||||
case 3:
|
||||
{
|
||||
result = ((u32_4tech)((buffer[0])&0x0F)) << 12;
|
||||
result |= ((u32_4tech)((buffer[1])&0x3F)) << 6;
|
||||
result |= ((u32_4tech)((buffer[2])&0x3F));
|
||||
}break;
|
||||
|
||||
case 4:
|
||||
{
|
||||
result = ((u32_4tech)((buffer[0])&0x07)) << 18;
|
||||
result |= ((u32_4tech)((buffer[1])&0x3F)) << 12;
|
||||
result |= ((u32_4tech)((buffer[2])&0x3F)) << 6;
|
||||
result |= ((u32_4tech)((buffer[3])&0x3F));
|
||||
}break;
|
||||
}
|
||||
|
||||
*buffer_ptr = buffer + length;
|
||||
}
|
||||
else{
|
||||
*buffer_ptr = end;
|
||||
}
|
||||
|
||||
return(result);
|
||||
}
|
||||
|
||||
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;
|
||||
*length_out = 1;
|
||||
}
|
||||
else if (code_point <= 0x7FF){
|
||||
buffer[0] = (u8_4tech)(0xC0 | (code_point >> 6));
|
||||
buffer[1] = (u8_4tech)(0x80 | (code_point & 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));
|
||||
*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));
|
||||
*length_out = 4;
|
||||
}
|
||||
}
|
||||
|
||||
static umem_4tech
|
||||
utf8_to_utf16_minimal_checking(u16_4tech *dst, umem_4tech max_wchars, u8_4tech *src, umem_4tech length, b32_4tech *error){
|
||||
u8_4tech *s = src;
|
||||
|
@ -247,6 +353,22 @@ utf16_to_utf8_minimal_checking(u8_4tech *dst, umem_4tech max_chars, u16_4tech *s
|
|||
return(needed_max);
|
||||
}
|
||||
|
||||
static void
|
||||
byte_to_ascii(u8_4tech n, u8_4tech *out){
|
||||
u8_4tech C = '0' + (n / 0x10);
|
||||
if ((n / 0x10) > 0x9){
|
||||
C = ('A' - 0xA) + (n / 0x10);
|
||||
}
|
||||
out[0] = C;
|
||||
|
||||
n = (n % 0x10);
|
||||
C = '0' + n;
|
||||
if (n > 0x9){
|
||||
C = ('A' - 0xA) + n;
|
||||
}
|
||||
out[1] = C;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
// BOTTOM
|
||||
|
|
4
4ed.cpp
4
4ed.cpp
|
@ -2361,6 +2361,10 @@ App_Step_Sig(app_step){
|
|||
"If you're new to 4coder there are some tutorials at http://4coder.net/tutorials.html\n"
|
||||
"\n"
|
||||
"Newest features:\n"
|
||||
"-New support for extended ascii input.\n"
|
||||
"-Extended ascii encoded in buffers as utf8.\n"
|
||||
"\n"
|
||||
"New in alpha 4.0.16:\n"
|
||||
"-<alt 2> If the current file is a C++ code file, this opens the matching header.\n"" If the current file is a C++ header, this opens the matching code file.\n"
|
||||
"-Option to automatically save changes on build in the config file.\n"
|
||||
" This works for builds triggered by <alt m>.\n"
|
||||
|
|
|
@ -786,7 +786,7 @@ DOC_SEE(Buffer_Setting_ID)
|
|||
if (new_value != file->settings.display_width){
|
||||
i16 font_id = file->settings.font_id;
|
||||
Render_Font *font = get_font_info(models->font_set, font_id)->font;
|
||||
file_set_display_width_and_fix_cursor(models, file, new_value, (f32)font->height, font->advance_data);
|
||||
file_set_width(models, file, new_value, (f32)font->height, font->codepoint_advance_data, font->byte_advance);
|
||||
}
|
||||
}break;
|
||||
|
||||
|
@ -799,7 +799,7 @@ DOC_SEE(Buffer_Setting_ID)
|
|||
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_minimum_base_display_width_and_fix_cursor(models, file, new_value, (f32)font->height, font->advance_data);
|
||||
file_set_min_base_width(models, file, new_value, (f32)font->height, font->codepoint_advance_data, font->byte_advance);
|
||||
}
|
||||
}break;
|
||||
|
||||
|
@ -888,7 +888,7 @@ DOC_SEE(Buffer_Setting_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, (f32)font->height, font->advance_data);
|
||||
file_measure_wraps(models, file, (f32)font->height, font->codepoint_advance_data, font->byte_advance);
|
||||
file_update_cursor_positions(models, file);
|
||||
}
|
||||
}break;
|
||||
|
@ -2071,12 +2071,9 @@ Set_Theme_Colors(Application_Links *app, Theme_Color *colors, int32_t count)
|
|||
/*
|
||||
DOC_PARAM(colors, The colors pointer provides an array of color structs pairing differet style tags to color codes.)
|
||||
DOC_PARAM(count, The count parameter specifies the number of Theme_Color structs in the colors array.)
|
||||
DOC
|
||||
(
|
||||
For each struct in the array, the slot in the main color pallet specified by the
|
||||
struct's tag is set to the color code in the struct. If the tag value is invalid
|
||||
no change is made to the color pallet.
|
||||
)
|
||||
DOC(
|
||||
For each struct in the array, the slot in the main color pallet specified by the struct's tag is set to the color code in the struct. If the tag value is invalid no change is made to the color pallet.)
|
||||
DOC_SEE(Theme_Color)
|
||||
*/{
|
||||
Command_Data *cmd = (Command_Data*)app->cmd_context;
|
||||
Style *style = main_style(cmd->models);
|
||||
|
@ -2098,11 +2095,8 @@ Get_Theme_Colors(Application_Links *app, Theme_Color *colors, int32_t count)
|
|||
/*
|
||||
DOC_PARAM(colors, an array of color structs listing style tags to get color values for)
|
||||
DOC_PARAM(count, the number of color structs in the colors array)
|
||||
DOC(
|
||||
For each struct in the array, the color field of the struct is filled with the
|
||||
color from the slot in the main color pallet specified by the tag. If the tag
|
||||
value is invalid the color is filled with black.
|
||||
)
|
||||
DOC(For each struct in the array, the color field of the struct is filled with the color from the slot in the main color pallet specified by the tag. If the tag value is invalid the color is filled with black.)
|
||||
DOC_SEE(Theme_Color)
|
||||
*/{
|
||||
Command_Data *cmd = (Command_Data*)app->cmd_context;
|
||||
Style *style = main_style(cmd->models);
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
#include "4coder_lib/4coder_string.h"
|
||||
#include "4coder_lib/4coder_mem.h"
|
||||
#include "4coder_lib/4coder_table.h"
|
||||
#include "4coder_lib/4coder_utf8.h"
|
||||
#if defined(USE_DEBUG_MEMORY)
|
||||
# include "4ed_debug_mem.h"
|
||||
#endif
|
||||
|
|
|
@ -396,7 +396,8 @@ view_compute_cursor(View *view, Buffer_Seek seek, b32 return_hint){
|
|||
params.buffer = &file->state.buffer;
|
||||
params.seek = seek;
|
||||
params.font_height = (f32)font->height;
|
||||
params.adv = font->advance_data;
|
||||
params.cp_adv = font->codepoint_advance_data;
|
||||
params.byte_adv = font->byte_advance;
|
||||
params.wrap_line_index = file->state.wrap_line_index;
|
||||
params.character_starts = file->state.character_starts;
|
||||
params.virtual_white = file->settings.virtual_white;
|
||||
|
@ -1007,14 +1008,18 @@ struct Code_Wrap_State{
|
|||
b32 consume_newline;
|
||||
|
||||
Gap_Buffer_Stream stream;
|
||||
i32 size;
|
||||
i32 i;
|
||||
|
||||
f32 *adv;
|
||||
f32 *cp_adv;
|
||||
f32 byte_adv;
|
||||
f32 tab_indent_amount;
|
||||
|
||||
Buffer_Translating_State tran;
|
||||
};
|
||||
|
||||
internal void
|
||||
wrap_state_init(Code_Wrap_State *state, Editing_File *file, f32 *adv){
|
||||
wrap_state_init(Code_Wrap_State *state, Editing_File *file, f32 *cp_adv, f32 byte_adv){
|
||||
state->token_array = file->state.token_array;
|
||||
state->token_ptr = state->token_array.tokens;
|
||||
state->end_token = state->token_ptr + state->token_array.count;
|
||||
|
@ -1025,9 +1030,14 @@ wrap_state_init(Code_Wrap_State *state, Editing_File *file, f32 *adv){
|
|||
Gap_Buffer *buffer = &file->state.buffer;
|
||||
i32 size = buffer_size(buffer);
|
||||
buffer_stringify_loop(&state->stream, buffer, 0, size);
|
||||
state->size = size;
|
||||
state->i = 0;
|
||||
|
||||
state->adv = adv;
|
||||
state->tab_indent_amount = adv['\t'];
|
||||
state->cp_adv = cp_adv;
|
||||
state->byte_adv = byte_adv;
|
||||
state->tab_indent_amount = cp_adv['\t'];
|
||||
|
||||
state->tran = null_buffer_translating_state;
|
||||
}
|
||||
|
||||
internal void
|
||||
|
@ -1085,11 +1095,11 @@ wrap_state_consume_token(Code_Wrap_State *state, i32 fixed_end_point){
|
|||
}
|
||||
}
|
||||
|
||||
b32 skipping_whitespace = 0;
|
||||
b32 skipping_whitespace = false;
|
||||
if (i >= state->next_line_start){
|
||||
state->x = state->wrap_x.paren_nesting[state->wrap_x.paren_safe_top];
|
||||
state->x = state->wrap_x.paren_nesting[state->wrap_x.paren_safe_top];
|
||||
skipping_whitespace = 1;
|
||||
skipping_whitespace = true;
|
||||
}
|
||||
|
||||
// TODO(allen): exponential search this shit!
|
||||
|
@ -1111,34 +1121,49 @@ wrap_state_consume_token(Code_Wrap_State *state, i32 fixed_end_point){
|
|||
}
|
||||
|
||||
if (i == line_start){
|
||||
skipping_whitespace = 1;
|
||||
skipping_whitespace = true;
|
||||
}
|
||||
|
||||
b32 recorded_start_x = 0;
|
||||
b32 recorded_start_x = false;
|
||||
do{
|
||||
for (; i < state->stream.end; ++i){
|
||||
if (!(i < end)){
|
||||
Assert(state->tran.fill_expected == 0);
|
||||
goto doublebreak;
|
||||
}
|
||||
|
||||
u8 ch = (u8)state->stream.data[i];
|
||||
|
||||
if (ch != ' ' && ch != '\t'){
|
||||
skipping_whitespace = 0;
|
||||
}
|
||||
translating_consume_byte(&state->tran, ch, i, state->size);
|
||||
|
||||
if (!skipping_whitespace){
|
||||
if (ch == '\n'){
|
||||
for (TRANSLATION_OUTPUT(&state->tran)){
|
||||
TRANSLATION_GET_STEP(&state->tran);
|
||||
|
||||
if (state->tran.do_newline){
|
||||
state->consume_newline = 1;
|
||||
goto doublebreak;
|
||||
}
|
||||
else{
|
||||
if (!recorded_start_x){
|
||||
result.start_x = state->x;
|
||||
recorded_start_x = 1;
|
||||
else if(state->tran.do_number_advance || state->tran.do_codepoint_advance){
|
||||
u32 n = state->tran.step_current.value;
|
||||
f32 adv = 0;
|
||||
if (state->tran.do_codepoint_advance){
|
||||
adv = state->cp_adv[n];
|
||||
if (n != ' ' && n != '\t'){
|
||||
skipping_whitespace = false;
|
||||
}
|
||||
}
|
||||
else{
|
||||
adv = state->byte_adv;
|
||||
skipping_whitespace = false;
|
||||
}
|
||||
|
||||
state->x += state->adv[ch];
|
||||
if (!skipping_whitespace){
|
||||
if (!recorded_start_x){
|
||||
result.start_x = state->x;
|
||||
recorded_start_x = 1;
|
||||
}
|
||||
state->x += adv;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1425,7 +1450,7 @@ get_current_shift(Code_Wrap_State *wrap_state, i32 next_line_start, b32 *adjust_
|
|||
}
|
||||
|
||||
internal void
|
||||
file_measure_wraps(Models *models, Editing_File *file, f32 font_height, f32 *adv){
|
||||
file_measure_wraps(Models *models, Editing_File *file, f32 font_height, f32 *cp_adv, f32 byte_adv){
|
||||
General_Memory *general = &models->mem.general;
|
||||
Partition *part = &models->mem.part;
|
||||
|
||||
|
@ -1438,7 +1463,8 @@ file_measure_wraps(Models *models, Editing_File *file, f32 font_height, f32 *adv
|
|||
Buffer_Measure_Wrap_Params params;
|
||||
params.buffer = &file->state.buffer;
|
||||
params.wrap_line_index = file->state.wrap_line_index;
|
||||
params.adv = adv;
|
||||
params.cp_adv = cp_adv;
|
||||
params.byte_adv = byte_adv;
|
||||
params.virtual_white = file->settings.virtual_white;
|
||||
|
||||
f32 width = (f32)file->settings.display_width;
|
||||
|
@ -1468,8 +1494,9 @@ file_measure_wraps(Models *models, Editing_File *file, f32 font_height, f32 *adv
|
|||
Wrap_Indent_Pair *wrap_indent_marks = 0;
|
||||
Potential_Wrap_Indent_Pair *potential_marks = 0;
|
||||
i32 max_wrap_indent_mark = 0;
|
||||
|
||||
if (params.virtual_white && file->state.tokens_complete && !file->state.still_lexing){
|
||||
wrap_state_init(&wrap_state, file, adv);
|
||||
wrap_state_init(&wrap_state, file, cp_adv, byte_adv);
|
||||
use_tokens = 1;
|
||||
|
||||
potential_marks = push_array(part, Potential_Wrap_Indent_Pair, floor32(width));
|
||||
|
@ -1521,7 +1548,7 @@ file_measure_wraps(Models *models, Editing_File *file, f32 font_height, f32 *adv
|
|||
word_stage = 1;
|
||||
}
|
||||
else{
|
||||
f32 adv = params.adv[ch];
|
||||
f32 adv = params.cp_adv[ch];
|
||||
x += adv;
|
||||
self_x += adv;
|
||||
if (self_x > width){
|
||||
|
@ -1648,7 +1675,7 @@ file_measure_wraps(Models *models, Editing_File *file, f32 font_height, f32 *adv
|
|||
goto doublebreak_stage1;
|
||||
}
|
||||
|
||||
f32 adv = params.adv[ch];
|
||||
f32 adv = params.cp_adv[ch];
|
||||
x += adv;
|
||||
if (!first_word && x > current_width){
|
||||
emit_comment_position = 1;
|
||||
|
@ -1674,7 +1701,7 @@ file_measure_wraps(Models *models, Editing_File *file, f32 font_height, f32 *adv
|
|||
goto doublebreak_stage2;
|
||||
}
|
||||
|
||||
f32 adv = params.adv[ch];
|
||||
f32 adv = params.cp_adv[ch];
|
||||
x += adv;
|
||||
}
|
||||
still_looping = buffer_stringify_next(&stream);
|
||||
|
@ -1881,21 +1908,21 @@ file_measure_wraps(Models *models, Editing_File *file, f32 font_height, f32 *adv
|
|||
}
|
||||
|
||||
internal void
|
||||
file_measure_wraps_and_fix_cursor(Models *models, Editing_File *file, f32 font_height, f32 *adv){
|
||||
file_measure_wraps(models, file, font_height, adv);
|
||||
file_measure_wraps_and_fix_cursor(Models *models, Editing_File *file, f32 font_height, f32 *cp_adv, f32 byte_adv){
|
||||
file_measure_wraps(models, file, font_height, cp_adv, byte_adv);
|
||||
file_update_cursor_positions(models, file);
|
||||
}
|
||||
|
||||
internal void
|
||||
file_set_display_width_and_fix_cursor(Models *models, Editing_File *file, i32 display_width, f32 font_height, f32 *adv){
|
||||
file_set_width(Models *models, Editing_File *file, i32 display_width, f32 font_height, f32 *cp_adv, f32 byte_adv){
|
||||
file->settings.display_width = display_width;
|
||||
file_measure_wraps_and_fix_cursor(models, file, font_height, adv);
|
||||
file_measure_wraps_and_fix_cursor(models, file, font_height, cp_adv, byte_adv);
|
||||
}
|
||||
|
||||
internal void
|
||||
file_set_minimum_base_display_width_and_fix_cursor(Models *models, Editing_File *file, i32 minimum_base_display_width, f32 font_height, f32 *adv){
|
||||
file_set_min_base_width(Models *models, Editing_File *file, i32 minimum_base_display_width, f32 font_height, f32 *cp_adv, f32 byte_adv){
|
||||
file->settings.minimum_base_display_width = minimum_base_display_width;
|
||||
file_measure_wraps_and_fix_cursor(models, file, font_height, adv);
|
||||
file_measure_wraps_and_fix_cursor(models, file, font_height, cp_adv, byte_adv);
|
||||
}
|
||||
|
||||
//
|
||||
|
@ -1944,7 +1971,7 @@ file_create_from_string(System_Functions *system, Models *models, Editing_File *
|
|||
file->settings.font_id = font_id;
|
||||
Render_Font *font = get_font_info(font_set, font_id)->font;
|
||||
|
||||
file_measure_wraps(models, file, (f32)font->height, font->advance_data);
|
||||
file_measure_wraps(models, file, (f32)font->height, font->codepoint_advance_data, font->byte_advance);
|
||||
|
||||
file->settings.read_only = read_only;
|
||||
if (!read_only){
|
||||
|
@ -3215,7 +3242,7 @@ file_do_single_edit(System_Functions *system, Models *models, Editing_File *file
|
|||
(f32)file->settings.display_width);
|
||||
#endif
|
||||
|
||||
file_measure_wraps(models, file, (f32)font->height, font->advance_data);
|
||||
file_measure_wraps(models, file, (f32)font->height, font->codepoint_advance_data, font->byte_advance);
|
||||
|
||||
// NOTE(allen): cursor fixing
|
||||
Cursor_Fix_Descriptor desc = {};
|
||||
|
@ -3330,16 +3357,14 @@ file_do_batch_edit(System_Functions *system, Models *models, Editing_File *file,
|
|||
buffer_measure_character_starts(&file->state.buffer, file->state.character_starts, 0, file->settings.virtual_white);
|
||||
|
||||
Render_Font *font = get_font_info(models->font_set, file->settings.font_id)->font;
|
||||
file_measure_wraps(models, file, (f32)font->height, font->advance_data);
|
||||
file_measure_wraps(models, file, (f32)font->height, font->codepoint_advance_data, font->byte_advance);
|
||||
|
||||
// NOTE(allen): cursor fixing
|
||||
{
|
||||
Cursor_Fix_Descriptor desc = {};
|
||||
desc.is_batch = 1;
|
||||
desc.batch = batch;
|
||||
desc.batch_size = batch_size;
|
||||
file_edit_cursor_fix(system, models, file, layout, desc);
|
||||
}
|
||||
Cursor_Fix_Descriptor desc = {0};
|
||||
desc.is_batch = 1;
|
||||
desc.batch = batch;
|
||||
desc.batch_size = batch_size;
|
||||
file_edit_cursor_fix(system, models, file, layout, desc);
|
||||
}
|
||||
|
||||
inline void
|
||||
|
@ -3697,7 +3722,7 @@ internal void
|
|||
file_set_font(Models *models, Editing_File *file, i16 font_id){
|
||||
file->settings.font_id = font_id;
|
||||
Render_Font *font = get_font_info(models->font_set, file->settings.font_id)->font;
|
||||
file_measure_wraps_and_fix_cursor(models, file, (f32)font->height, font->advance_data);
|
||||
file_measure_wraps_and_fix_cursor(models, file, (f32)font->height, font->codepoint_advance_data, font->byte_advance);
|
||||
|
||||
Editing_Layout *layout = &models->layout;
|
||||
for (View_Iter iter = file_view_iter_init(layout, file, 0);
|
||||
|
@ -5966,7 +5991,6 @@ draw_file_loaded(View *view, i32_Rect rect, b32 is_active, Render_Target *target
|
|||
|
||||
i16 font_id = file->settings.font_id;
|
||||
Render_Font *font = get_font_info(models->font_set, font_id)->font;
|
||||
float *advance_data = font->advance_data;
|
||||
|
||||
f32 scroll_x = view->edit_pos->scroll.scroll_x;
|
||||
f32 scroll_y = view->edit_pos->scroll.scroll_y;
|
||||
|
@ -6005,7 +6029,8 @@ draw_file_loaded(View *view, i32_Rect rect, b32 is_active, Render_Target *target
|
|||
params.start_cursor = render_cursor;
|
||||
params.wrapped = wrapped;
|
||||
params.font_height = (f32)line_height;
|
||||
params.adv = advance_data;
|
||||
params.cp_adv = font->codepoint_advance_data;
|
||||
params.byte_adv = font->byte_advance;
|
||||
params.virtual_white = file->settings.virtual_white;
|
||||
params.wrap_slashes = file->settings.wrap_indicator;
|
||||
|
||||
|
@ -6162,8 +6187,7 @@ draw_file_loaded(View *view, i32_Rect rect, b32 is_active, Render_Target *target
|
|||
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);
|
||||
font_draw_glyph(target, font_id, (u8)item->glyphid, item->x0, item->y0, char_color);
|
||||
}
|
||||
prev_ind = ind;
|
||||
}
|
||||
|
@ -6194,8 +6218,7 @@ draw_text_field(Render_Target *target, View *view, i16 font_id,
|
|||
}
|
||||
|
||||
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(Render_Target *target, View *view, i16 font_id, i32_Rect rect, String s, i32 pos){
|
||||
Models *models = view->persistent.models;
|
||||
Style *style = main_style(models);
|
||||
|
||||
|
@ -6222,8 +6245,9 @@ draw_text_with_cursor(Render_Target *target, View *view, i16 font_id,
|
|||
|
||||
x = draw_string(target, font_id, part1, floor32(x), y, text_color);
|
||||
|
||||
// TODO(allen): WHAT TO DO NOW?
|
||||
cursor_rect.x0 = floor32(x);
|
||||
cursor_rect.x1 = floor32(x) + ceil32(font->advance_data[s.str[pos]]);
|
||||
cursor_rect.x1 = floor32(x) + ceil32(font->codepoint_advance_data[s.str[pos]]);
|
||||
cursor_rect.y0 = y;
|
||||
cursor_rect.y1 = y + view->line_height;
|
||||
draw_rectangle(target, cursor_rect, cursor_color);
|
||||
|
|
|
@ -28,7 +28,8 @@ struct Render_Font{
|
|||
b32 loaded;
|
||||
|
||||
Glyph_Data glyphs[256];
|
||||
f32 advance_data[256];
|
||||
f32 byte_advance;
|
||||
f32 codepoint_advance_data[256];
|
||||
i32 height, ascent, descent, line_skip;
|
||||
i32 advance;
|
||||
u32 tex;
|
||||
|
|
|
@ -116,9 +116,9 @@ font_predict_size(i32 pt_size){
|
|||
}
|
||||
|
||||
internal void
|
||||
font_draw_glyph_mono(Render_Target *target, i16 font_id, u8 character, f32 x, f32 y, f32 advance, u32 color){
|
||||
font_draw_glyph(Render_Target *target, i16 font_id, i32 type, u8 character, f32 x, f32 y, u32 color){
|
||||
Render_Piece_Combined piece;
|
||||
piece.header.type = piece_type_mono_glyph;
|
||||
piece.header.type = type;
|
||||
piece.glyph.pos.x = x;
|
||||
piece.glyph.pos.y = y;
|
||||
piece.glyph.color = color;
|
||||
|
@ -128,113 +128,111 @@ font_draw_glyph_mono(Render_Target *target, i16 font_id, u8 character, f32 x, f3
|
|||
font_set_use(target->partition, &target->font_set, font_id);
|
||||
}
|
||||
|
||||
inline void
|
||||
font_draw_glyph_mono(Render_Target *target, i16 font_id,
|
||||
u8 character, f32 x, f32 y, u32 color){
|
||||
f32 advance = (f32)get_font_info(&target->font_set, font_id)->advance;
|
||||
font_draw_glyph_mono(target, font_id, character, x, y, advance, color);
|
||||
}
|
||||
|
||||
internal void
|
||||
font_draw_glyph(Render_Target *target, i16 font_id, u8 character, f32 x, f32 y, u32 color){
|
||||
Render_Piece_Combined piece;
|
||||
piece.header.type = piece_type_glyph;
|
||||
piece.glyph.pos.x = x;
|
||||
piece.glyph.pos.y = y;
|
||||
piece.glyph.color = color;
|
||||
piece.glyph.font_id = font_id;
|
||||
piece.glyph.character = character;
|
||||
target->push_piece(target, piece);
|
||||
font_set_use(target->partition, &target->font_set, font_id);
|
||||
font_draw_glyph(target, font_id, piece_type_glyph, character, x, y, color);
|
||||
}
|
||||
|
||||
internal f32
|
||||
font_string_width(Render_Target *target, i16 font_id, char *str){
|
||||
f32 x = 0;
|
||||
draw_string_base(Render_Target *target, i16 font_id, i32 type, String str_, i32 x_, i32 y_, u32 color){
|
||||
Render_Font *font = get_font_info(&target->font_set, font_id)->font;
|
||||
f32 *advance_data = font->advance_data;
|
||||
f32 x = 0;
|
||||
|
||||
if (font){
|
||||
for (i32 i = 0; str[i]; ++i){
|
||||
u8 c = str[i];
|
||||
x += advance_data[c];
|
||||
f32 y = (f32)y_;
|
||||
x = (f32)x_;
|
||||
|
||||
f32 byte_advance = font->byte_advance;
|
||||
f32 *codepoint_advance_data = font->codepoint_advance_data;
|
||||
|
||||
u8 *str = (u8*)str_.str;
|
||||
u8 *str_end = str + str_.size;
|
||||
|
||||
for (;str < str_end;){
|
||||
u8 *byte = str;
|
||||
u32 codepoint = utf8_to_u32(&str, str_end);
|
||||
|
||||
b32 do_codepoint = false;
|
||||
b32 do_numbers = false;
|
||||
if (codepoint){
|
||||
if (codepoint >= ' ' && codepoint <= 0xFF && codepoint != 127){
|
||||
do_codepoint = true;
|
||||
}
|
||||
else{
|
||||
do_numbers = true;
|
||||
}
|
||||
}
|
||||
else{
|
||||
do_numbers = true;
|
||||
}
|
||||
|
||||
if (do_codepoint){
|
||||
if (color != 0){
|
||||
font_draw_glyph(target, font_id, type, (u8)codepoint, x, y, color);
|
||||
}
|
||||
x += codepoint_advance_data[codepoint];
|
||||
}
|
||||
else if (do_numbers){
|
||||
for (;byte < str; ++byte){
|
||||
u8_4tech n = *byte;
|
||||
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 += byte_advance;
|
||||
}
|
||||
}
|
||||
|
||||
x += byte_advance;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
return(w);
|
||||
}
|
||||
|
||||
internal f32
|
||||
draw_string(Render_Target *target, i16 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);
|
||||
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);
|
||||
return(w);
|
||||
}
|
||||
|
||||
internal f32
|
||||
draw_string_mono(Render_Target *target, i16 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);
|
||||
return(w);
|
||||
}
|
||||
|
||||
internal f32
|
||||
font_string_width(Render_Target *target, i16 font_id, String str){
|
||||
f32 x = 0;
|
||||
Render_Font *font = get_font_info(&target->font_set, font_id)->font;
|
||||
f32 *advance_data = font->advance_data;
|
||||
|
||||
if (font){
|
||||
for (i32 i = 0; i < str.size; ++i){
|
||||
u8 c = str.str[i];
|
||||
x += advance_data[c];
|
||||
}
|
||||
}
|
||||
|
||||
return(x);
|
||||
f32 w = draw_string_base(target, font_id, piece_type_glyph, str, 0, 0, 0);
|
||||
return(w);
|
||||
}
|
||||
|
||||
internal f32
|
||||
draw_string(Render_Target *target, i16 font_id,
|
||||
char *str, i32 x_, i32 y, u32 color){
|
||||
f32 x = (f32)x_;
|
||||
Render_Font *font = get_font_info(&target->font_set, font_id)->font;
|
||||
f32 *advance_data = font->advance_data;
|
||||
|
||||
if (font){
|
||||
for (i32 i = 0; str[i]; ++i){
|
||||
u8 c = str[i];
|
||||
font_draw_glyph(target, font_id, c, x, (f32)y, color);
|
||||
x += advance_data[c];
|
||||
}
|
||||
}
|
||||
|
||||
return(x);
|
||||
}
|
||||
|
||||
internal f32
|
||||
draw_string_mono(Render_Target *target, i16 font_id, char *str, f32 x, f32 y, f32 advance, u32 color){
|
||||
for (i32 i = 0; str[i]; ++i){
|
||||
u8 c = str[i];
|
||||
font_draw_glyph_mono(target, font_id, c, x, y, advance, color);
|
||||
x += advance;
|
||||
}
|
||||
|
||||
return(x);
|
||||
}
|
||||
|
||||
internal f32
|
||||
draw_string(Render_Target *target, i16 font_id, String str, i32 x_, i32 y, u32 color){
|
||||
f32 x = (f32)x_;
|
||||
Render_Font *font = get_font_info(&target->font_set, font_id)->font;
|
||||
f32 *advance_data = font->advance_data;
|
||||
|
||||
if (font){
|
||||
for (i32 i = 0; i < str.size; ++i){
|
||||
u8 c = str.str[i];
|
||||
font_draw_glyph(target, font_id, c, x, (f32)y, color);
|
||||
x += advance_data[c];
|
||||
}
|
||||
}
|
||||
|
||||
return(x);
|
||||
}
|
||||
|
||||
internal f32
|
||||
draw_string_mono(Render_Target *target, i16 font_id, String str, f32 x, f32 y, f32 advance, u32 color){
|
||||
for (i32 i = 0; i < str.size; ++i){
|
||||
u8 c = str.str[i] % 128;
|
||||
font_draw_glyph_mono(target, font_id, c, x, y, advance, color);
|
||||
x += advance;
|
||||
}
|
||||
|
||||
return(x);
|
||||
font_string_width(Render_Target *target, i16 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);
|
||||
return(w);
|
||||
}
|
||||
|
||||
// BOTTOM
|
||||
|
|
BIN
4ed_site.ctm
BIN
4ed_site.ctm
Binary file not shown.
|
@ -544,6 +544,7 @@ launch_rendering(Render_Target *target){
|
|||
|
||||
#undef ExtractStruct
|
||||
|
||||
#if 0
|
||||
internal void*
|
||||
part_alloc(i32 size, void *context){
|
||||
Partition *part = (Partition*)context;
|
||||
|
@ -552,8 +553,7 @@ part_alloc(i32 size, void *context){
|
|||
}
|
||||
|
||||
internal void
|
||||
part_free(void *ptr, void *context){
|
||||
}
|
||||
part_free(void *ptr, void *context){}
|
||||
|
||||
#define STBTT_malloc part_alloc
|
||||
#define STBTT_free part_free
|
||||
|
@ -561,34 +561,28 @@ part_free(void *ptr, void *context){
|
|||
#define STB_TRUETYPE_IMPLEMENTATION
|
||||
#include "stb_truetype.h"
|
||||
|
||||
internal i32
|
||||
stb_font_load(Partition *part,
|
||||
Render_Font *font_out,
|
||||
char *filename_untranslated,
|
||||
i32 pt_size,
|
||||
i32 tab_width,
|
||||
i32 oversample,
|
||||
b32 store_texture){
|
||||
internal b32
|
||||
stb_font_load(Partition *part, Render_Font *font_out, char *filename_untranslated, i32 pt_size, i32 tab_width, i32 oversample, b32 store_texture){
|
||||
|
||||
char space_[1024];
|
||||
String filename = make_fixed_width_string(space_);
|
||||
b32 translate_success = sysshared_to_binary_path(&filename, filename_untranslated);
|
||||
if (!translate_success) return 0;
|
||||
|
||||
i32 result = 1;
|
||||
b32 result = true;
|
||||
|
||||
stbtt_packedchar chardata[256];
|
||||
|
||||
File_Data file = sysshared_load_file(filename.str);
|
||||
|
||||
if (!file.data){
|
||||
result = 0;
|
||||
result = false;
|
||||
}
|
||||
|
||||
else{
|
||||
stbtt_fontinfo font;
|
||||
if (!stbtt_InitFont(&font, (u8*)file.data, 0)){
|
||||
result = 0;
|
||||
result = false;
|
||||
}
|
||||
else{
|
||||
memset(font_out, 0, sizeof(*font_out));
|
||||
|
@ -620,19 +614,16 @@ stb_font_load(Partition *part,
|
|||
/////////////////////////////////////////////////////////////////
|
||||
stbtt_pack_context spc;
|
||||
|
||||
if (stbtt_PackBegin(&spc, (u8*)block, tex_width, tex_height,
|
||||
tex_width, 1, part)){
|
||||
if (stbtt_PackBegin(&spc, (u8*)block, tex_width, tex_height, tex_width, 1, part)){
|
||||
stbtt_PackSetOversampling(&spc, oversample, oversample);
|
||||
if (!stbtt_PackFontRange(&spc, (u8*)file.data, 0,
|
||||
STBTT_POINT_SIZE((f32)pt_size),
|
||||
0, 128, chardata)){
|
||||
result = 0;
|
||||
if (!stbtt_PackFontRange(&spc, (u8*)file.data, 0, STBTT_POINT_SIZE((f32)pt_size), 0, 128, chardata)){
|
||||
result = false;
|
||||
}
|
||||
|
||||
stbtt_PackEnd(&spc);
|
||||
}
|
||||
else{
|
||||
result = 0;
|
||||
result = false;
|
||||
}
|
||||
/////////////////////////////////////////////////////////////////
|
||||
|
||||
|
@ -694,6 +685,7 @@ stb_font_load(Partition *part,
|
|||
|
||||
return(result);
|
||||
}
|
||||
#endif
|
||||
|
||||
// NOTE(allen): Thanks to insofaras. This is copy-pasted from some work he originally did to get free type working on Linux.
|
||||
|
||||
|
@ -826,11 +818,11 @@ font_load_freetype(Partition *part, Render_Font *rf, char *filename, i32 pt_size
|
|||
|
||||
// TODO(allen): maybe advance data should be integers for a while...
|
||||
// I require the actual values to be integers anyway... hmm...
|
||||
rf->advance_data[i] = (f32)ceil32(face->glyph->advance.x / 64.0f);
|
||||
f32 advance = (f32)ceil32(face->glyph->advance.x / 64.0f);
|
||||
rf->codepoint_advance_data[i] = advance;
|
||||
|
||||
rf->glyphs[i].exists = 1;
|
||||
|
||||
|
||||
i32 pitch = face->glyph->bitmap.pitch;
|
||||
|
||||
// write to texture atlas
|
||||
|
@ -865,40 +857,23 @@ font_load_freetype(Partition *part, Render_Font *rf, char *filename, i32 pt_size
|
|||
pen_x = ceil32(c->x1 + 1);
|
||||
}
|
||||
|
||||
// TODO(allen): advance data is still too stupid.
|
||||
// Provide an "unedited" version, then generate these
|
||||
// on the fly. Maybe later introduce a caching system or whatevs.
|
||||
f32 *adv = rf->advance_data;
|
||||
for (i32 i = 0; i < 256; ++i){
|
||||
if (i < ' ' || i == 127){
|
||||
switch (i){
|
||||
case '\n':
|
||||
adv[i] = adv[' '];
|
||||
break;
|
||||
|
||||
case '\r':
|
||||
adv[i] = adv['\\'] + adv['r'];
|
||||
break;
|
||||
|
||||
case '\t':
|
||||
adv[i] = adv[' ']*tab_width;
|
||||
break;
|
||||
|
||||
default:
|
||||
{
|
||||
int8_t d1 = (int8_t)(i/0x10), d2 = (int8_t)(i%0x10);
|
||||
char c1 = '0' + d1, c2 = '0' + d2;
|
||||
if (d1 >= 0xA){
|
||||
c1 = ('A' - 0xA) + d1;
|
||||
}
|
||||
if (d2 >= 0xA){
|
||||
c2 = ('A' - 0xA) + d2;
|
||||
}
|
||||
adv[i] = adv['\\'] + adv[c1] + adv[c2];
|
||||
}break;
|
||||
}
|
||||
}
|
||||
f32 *cp_adv = rf->codepoint_advance_data;
|
||||
cp_adv['\n'] = cp_adv[' '];
|
||||
cp_adv['\r'] = cp_adv['\\'] + cp_adv['r'];
|
||||
cp_adv['\t'] = cp_adv[' ']*tab_width;
|
||||
|
||||
f32 max_hex_advance = cp_adv['0'];
|
||||
for (u32 i = '1'; i <= '9'; ++i){
|
||||
max_hex_advance = Max(max_hex_advance, cp_adv[i]);
|
||||
}
|
||||
for (u32 i = 'a'; i <= 'f'; ++i){
|
||||
max_hex_advance = Max(max_hex_advance, cp_adv[i]);
|
||||
}
|
||||
for (u32 i = 'A'; i <= 'F'; ++i){
|
||||
max_hex_advance = Max(max_hex_advance, cp_adv[i]);
|
||||
}
|
||||
|
||||
rf->byte_advance = cp_adv['\\'] + max_hex_advance*2;
|
||||
|
||||
FT_Done_FreeType(ft);
|
||||
|
||||
|
|
|
@ -13,5 +13,7 @@ fi
|
|||
|
||||
echo "Building custom_4coders.so from $SOURCE ..."
|
||||
|
||||
SOURCE=$(readlink -f "$SOURCE")
|
||||
|
||||
g++ -I"$CODE_HOME" -Wno-write-strings -std=gnu++0x "$SOURCE" -shared -o custom_4coder.so -fPIC
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -357,6 +357,9 @@ Sys_Set_File_List_Sig(system_set_file_list){
|
|||
if (d){
|
||||
if (canon_directory_out != 0){
|
||||
u32 length = copy_fast_unsafe_cc(canon_directory_out, directory);
|
||||
if (canon_directory_out[length-1] != '/'){
|
||||
canon_directory_out[length++] = '/';
|
||||
}
|
||||
canon_directory_out[length] = 0;
|
||||
*canon_directory_size_out = length;
|
||||
}
|
||||
|
@ -2653,11 +2656,11 @@ LinuxHandleX11Events(void)
|
|||
fputs("FIXME: XBufferOverflow from LookupString.\n", stderr);
|
||||
}
|
||||
|
||||
u16 key = utf8_to_u32_unchecked(buff);
|
||||
u16 key_no_caps = key;
|
||||
u32 key = utf8_to_u32_unchecked(buff);
|
||||
u32 key_no_caps = key;
|
||||
|
||||
if(mods[MDFR_CAPS_INDEX] && status == XLookupBoth && Event.xkey.keycode){
|
||||
u8 buff_no_caps[32] = {};
|
||||
u8 buff_no_caps[32] = {0};
|
||||
Event.xkey.state &= ~(LockMask);
|
||||
|
||||
XLookupString(
|
||||
|
@ -2669,7 +2672,7 @@ LinuxHandleX11Events(void)
|
|||
);
|
||||
|
||||
if(*buff_no_caps){
|
||||
key_no_caps = utf8_to_u16_unchecked(buff_no_caps);
|
||||
key_no_caps = utf8_to_u32_unchecked(buff_no_caps);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -19,6 +19,7 @@ TYPE: 'build-target'
|
|||
# define BIND_4CODER_TESTS(context) ((void)context)
|
||||
#endif
|
||||
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
|
||||
static float
|
||||
|
@ -1344,6 +1345,27 @@ CUSTOM_COMMAND_SIG(write_explicit_enum_values){
|
|||
end_temp_memory(temp);
|
||||
}
|
||||
|
||||
CUSTOM_COMMAND_SIG(punishment){
|
||||
Theme_Color colors[4];
|
||||
colors[0].tag = Stag_Back;
|
||||
colors[1].tag = Stag_Margin;
|
||||
colors[2].tag = Stag_Margin_Hover;
|
||||
colors[3].tag = Stag_Margin_Active;
|
||||
get_theme_colors(app, colors, 4);
|
||||
|
||||
for (uint32_t i = 0; i < 4; ++i){
|
||||
int_color color = colors[i].color;
|
||||
uint8_t *c = (uint8_t*)(&color);
|
||||
c[0] = 0xFF - c[0];
|
||||
c[1] = 0xFF - c[1];
|
||||
c[2] = 0xFF - c[2];
|
||||
c[3] = 0xFF - c[3];
|
||||
colors[i].color = color;
|
||||
}
|
||||
|
||||
set_theme_colors(app, colors, 4);
|
||||
}
|
||||
|
||||
extern "C" int32_t
|
||||
get_bindings(void *data, int32_t size){
|
||||
Bind_Helper context_ = begin_bind_helper(data, size);
|
||||
|
@ -1370,6 +1392,9 @@ get_bindings(void *data, int32_t size){
|
|||
end_map(context);
|
||||
|
||||
begin_map(context, mapid_file);
|
||||
bind(context, 's', MDFR_CTRL, punishment);
|
||||
bind(context, 's', MDFR_ALT, save);
|
||||
|
||||
bind(context, 'k', MDFR_ALT, kill_rect);
|
||||
bind(context, ' ', MDFR_ALT | MDFR_CTRL, multi_line_edit);
|
||||
|
||||
|
|
|
@ -768,7 +768,7 @@ Sys_Set_File_List_Sig(system_set_file_list){
|
|||
if (canon_directory_out != 0){
|
||||
if (final_length+1 < canon_directory_max){
|
||||
memcpy(canon_directory_out, c_str_dir, final_length);
|
||||
if (char_is_slash(dir.str[dir.size-1]) && canon_directory_out[final_length-1] != '\\'){
|
||||
if (canon_directory_out[final_length-1] != '\\'){
|
||||
canon_directory_out[final_length++] = '\\';
|
||||
}
|
||||
canon_directory_out[final_length] = 0;
|
||||
|
|
Loading…
Reference in New Issue