diff --git a/4coder_custom.h b/4coder_custom.h index 7eeb88c0..09db350b 100644 --- a/4coder_custom.h +++ b/4coder_custom.h @@ -246,6 +246,8 @@ enum Hook_ID{ hook_start, hook_open_file, hook_frame, + hook_new_file, + hook_file_out_of_sync, // never below this hook_type_count }; diff --git a/4ed.cpp b/4ed.cpp index e6703c23..18ad9c85 100644 --- a/4ed.cpp +++ b/4ed.cpp @@ -3299,42 +3299,40 @@ App_Init_Sig(app_init){ i32 name_len; i32 pt_size; }; - -#define LitStr(n) n, sizeof(n)-1 int font_size = 16; if (font_size < 8) font_size = 8; Font_Setup font_setup[] = { - {LitStr("LiberationSans-Regular.ttf"), - LitStr("liberation sans"), + {literal("LiberationSans-Regular.ttf"), + literal("liberation sans"), font_size}, - {LitStr("liberation-mono.ttf"), - LitStr("liberation mono"), + {literal("liberation-mono.ttf"), + literal("liberation mono"), font_size}, - {LitStr("Hack-Regular.ttf"), - LitStr("hack"), + {literal("Hack-Regular.ttf"), + literal("hack"), font_size}, - {LitStr("CutiveMono-Regular.ttf"), - LitStr("cutive mono"), + {literal("CutiveMono-Regular.ttf"), + literal("cutive mono"), font_size}, - {LitStr("Inconsolata-Regular.ttf"), - LitStr("inconsolata"), + {literal("Inconsolata-Regular.ttf"), + literal("inconsolata"), font_size}, }; i32 font_count = ArrayCount(font_setup); - + 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; + i32 pt_size = DpiMultiplier(font_setup[i].pt_size, target->dpi); font_set_add(partition, models->font_set, file_name, name, pt_size); } @@ -3430,11 +3428,16 @@ App_Step_Sig(app_step){ time_stamp = system->file_time_stamp(make_c_str(file->name.source_path)); - // TODO(allen): This is a bit wasteful! Let's dial it in a bit. if (time_stamp > 0){ + File_Sync_State prev_sync = buffer_get_sync(file); + file->state.last_sys_write_time = time_stamp; + file->state.sync = buffer_get_sync(file); + if (file->state.last_sys_write_time != file->state.last_4ed_write_time){ - app_result.redraw = 1; + if (file->state.sync != prev_sync){ + app_result.redraw = 1; + } } } } @@ -4338,6 +4341,15 @@ App_Step_Sig(app_step){ view_set_file(view, file, models, system, models->hooks[hook_open_file], &app_links); view->map = app_get_map(models, file->settings.base_map_id); + + Hook_Function *new_file_fnc = models->hooks[hook_new_file]; + if (new_file_fnc){ + models->buffer_param_indices[models->buffer_param_count++] = file->id.id; + new_file_fnc(&app_links); + models->buffer_param_count = 0; + file->settings.is_initialized = 1; + } + #if BUFFER_EXPERIMENT_SCALPEL <= 0 if (file->settings.tokens_exist) file_first_lex_parallel(system, general, file); diff --git a/4ed_delay.cpp b/4ed_delay.cpp index 3167e5ff..4a491f65 100644 --- a/4ed_delay.cpp +++ b/4ed_delay.cpp @@ -120,14 +120,14 @@ delayed_action_repush(Delay *delay, Delayed_Action *act){ return(new_act); } -#define delayed_open(delay, ...) delayed_action_(delay, DACT_OPEN, __VA_ARGS__) -#define delayed_open_background(delay, ...) delayed_action_(delay, DACT_OPEN_BACKGROUND, __VA_ARGS__) -#define delayed_set_line(delay, ...) delayed_action_(delay, DACT_SET_LINE, __VA_ARGS__) -#define delayed_save_as(delay, ...) delayed_action_(delay, DACT_SAVE_AS, __VA_ARGS__) -#define delayed_save(delay, ...) delayed_action_(delay, DACT_SAVE, __VA_ARGS__) -#define delayed_new(delay, ...) delayed_action_(delay, DACT_NEW, __VA_ARGS__) -#define delayed_switch(delay, ...) delayed_action_(delay, DACT_SWITCH, __VA_ARGS__) -#define delayed_try_kill(delay, ...) delayed_action_(delay, DACT_TRY_KILL, __VA_ARGS__) -#define delayed_kill(delay, ...) delayed_action_(delay, DACT_KILL, __VA_ARGS__) -#define delayed_touch_file(delay, ...) delayed_action_(delay, DACT_TOUCH_FILE, __VA_ARGS__) +#define delayed_open(delay, ...) delayed_action_(delay, DACT_OPEN, ##__VA_ARGS__) +#define delayed_open_background(delay, ...) delayed_action_(delay, DACT_OPEN_BACKGROUND, ##__VA_ARGS__) +#define delayed_set_line(delay, ...) delayed_action_(delay, DACT_SET_LINE, ##__VA_ARGS__) +#define delayed_save_as(delay, ...) delayed_action_(delay, DACT_SAVE_AS, ##__VA_ARGS__) +#define delayed_save(delay, ...) delayed_action_(delay, DACT_SAVE, ##__VA_ARGS__) +#define delayed_new(delay, ...) delayed_action_(delay, DACT_NEW, ##__VA_ARGS__) +#define delayed_switch(delay, ...) delayed_action_(delay, DACT_SWITCH, ##__VA_ARGS__) +#define delayed_try_kill(delay, ...) delayed_action_(delay, DACT_TRY_KILL, ##__VA_ARGS__) +#define delayed_kill(delay, ...) delayed_action_(delay, DACT_KILL, ##__VA_ARGS__) +#define delayed_touch_file(delay, ...) delayed_action_(delay, DACT_TOUCH_FILE, ##__VA_ARGS__) #define delayed_close(delay, ...) delayed_action_(delay, DACT_CLOSE, ##__VA_ARGS__) diff --git a/4ed_file.cpp b/4ed_file.cpp index 8d8199af..e7aa13c4 100644 --- a/4ed_file.cpp +++ b/4ed_file.cpp @@ -81,6 +81,12 @@ struct Undo_Data{ b32 current_block_normal; }; +enum File_Sync_State{ + SYNC_GOOD, + SYNC_BEHIND_OS, + SYNC_UNSAVED +}; + struct Text_Effect{ i32 start, end; u32 color; @@ -122,6 +128,7 @@ struct Editing_File_State{ Text_Effect paste_effect; + File_Sync_State sync; u64 last_4ed_write_time; u64 last_4ed_edit_time; u64 last_sys_write_time; @@ -747,12 +754,6 @@ hot_directory_first_match(Hot_Directory *hot_directory, return result; } -enum File_Sync_State{ - SYNC_GOOD, - SYNC_BEHIND_OS, - SYNC_UNSAVED -}; - inline File_Sync_State buffer_get_sync(Editing_File *file){ File_Sync_State result = SYNC_GOOD; diff --git a/4ed_file_view.cpp b/4ed_file_view.cpp index 76cf22a5..477ec857 100644 --- a/4ed_file_view.cpp +++ b/4ed_file_view.cpp @@ -280,6 +280,7 @@ file_synchronize_times(System_Functions *system, Editing_File *file, char *filen file->state.last_4ed_edit_time = stamp; file->state.last_sys_write_time = stamp; } + file->state.sync = buffer_get_sync(file); } internal i32 @@ -1295,7 +1296,6 @@ view_set_file( if (file_is_ready(file)){ view_measure_wraps(system, &models->mem.general, view); view->cursor = view_compute_cursor_from_pos(view, file->state.cursor_pos); - view->reinit_scrolling = 1; } } diff --git a/4ed_metagen.cpp b/4ed_metagen.cpp index ab5dff16..69bbc78a 100644 --- a/4ed_metagen.cpp +++ b/4ed_metagen.cpp @@ -241,7 +241,7 @@ char delayed_action_specialized_bottom[] = "}\n\n"; char delayed_action_macro[] = -"#define delayed_%s(delay, ...) delayed_action_(delay, DACT_%s, __VA_ARGS__)\n"; +"#define delayed_%s(delay, ...) delayed_action_(delay, DACT_%s, ##__VA_ARGS__)\n"; char delayed_action_repush_function[] = "inline Delayed_Action*\n" diff --git a/4ed_rendering.cpp b/4ed_rendering.cpp index d4cecd53..7a5be278 100644 --- a/4ed_rendering.cpp +++ b/4ed_rendering.cpp @@ -386,33 +386,33 @@ draw_font_load(void *base_block, i32 size, Render_Font *font_out, char *filename_untranslated, i32 pt_size, - i32 tab_width){ + i32 tab_width, + i32 oversample){ char space_[1024]; String filename = make_fixed_width_string(space_); b32 translate_success = system_to_binary_path(&filename, filename_untranslated); if (!translate_success) return 0; - + i32 result = 1; Data file; file = system_load_file(filename.str); - + Partition partition_ = partition_open(base_block, size); Partition *partition = &partition_; - + stbtt_packedchar *chardata = font_out->chardata; - i32 oversample = 2; - + i32 tex_width, tex_height; tex_width = pt_size*128*oversample; tex_height = pt_size*2*oversample; void *block = push_block(partition, tex_width * tex_height); - + if (!file.data){ result = 0; } - + else{ stbtt_fontinfo font; if (!stbtt_InitFont(&font, (u8*)file.data, 0)){ @@ -421,21 +421,21 @@ draw_font_load(void *base_block, i32 size, else{ i32 ascent, descent, line_gap; f32 scale; - + stbtt_GetFontVMetrics(&font, &ascent, &descent, &line_gap); scale = stbtt_ScaleForPixelHeight(&font, (f32)pt_size); - + f32 scaled_ascent, scaled_descent, scaled_line_gap; - + scaled_ascent = scale*ascent; scaled_descent = scale*descent; scaled_line_gap = scale*line_gap; - + font_out->height = (i32)(scaled_ascent - scaled_descent + scaled_line_gap); font_out->ascent = (i32)(scaled_ascent); font_out->descent = (i32)(scaled_descent); font_out->line_skip = (i32)(scaled_line_gap); - + font_out->tex_width = tex_width; font_out->tex_height = tex_height; @@ -444,7 +444,7 @@ draw_font_load(void *base_block, i32 size, if (stbtt_PackBegin(&spc, (u8*)block, tex_width, tex_height, tex_width, 1, partition)){ stbtt_PackSetOversampling(&spc, oversample, oversample); if (stbtt_PackFontRange(&spc, (u8*)file.data, 0, - STBTT_POINT_SIZE((f32)pt_size), 0, 128, chardata)){ + STBTT_POINT_SIZE((f32)pt_size), 0, 128, chardata)){ // do nothing } else{ @@ -461,21 +461,21 @@ draw_font_load(void *base_block, i32 size, GLuint font_tex; glGenTextures(1, &font_tex); glBindTexture(GL_TEXTURE_2D, font_tex); - + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - + glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, tex_width, tex_height, 0, GL_ALPHA, GL_UNSIGNED_BYTE, block); - + font_out->tex = font_tex; glBindTexture(GL_TEXTURE_2D, 0); - + font_out->chardata['\r'] = font_out->chardata[' ']; font_out->chardata['\n'] = font_out->chardata[' ']; font_out->chardata['\t'] = font_out->chardata[' ']; font_out->chardata['\t'].xadvance *= tab_width; - + i32 max_advance = 0; for (u8 code_point = 0; code_point < 128; ++code_point){ if (stbtt_FindGlyphIndex(&font, code_point) != 0){ @@ -490,11 +490,11 @@ draw_font_load(void *base_block, i32 size, } font_out->advance = max_advance - 1; } - + } system_free_memory(file.data); } - + return result; } diff --git a/4ed_rendering.h b/4ed_rendering.h index b0fbcccd..320d4028 100644 --- a/4ed_rendering.h +++ b/4ed_rendering.h @@ -187,8 +187,12 @@ struct Render_Target{ Draw_Push_Clip *push_clip; Draw_Pop_Clip *pop_clip; Draw_Push_Piece *push_piece; + + i32 dpi; }; +#define DpiMultiplier(n,dpi) ((n) * (dpi) / 96) + inline i32_Rect rect_from_target(Render_Target *target){ return i32R(0, 0, target->width, target->height); diff --git a/TODO.txt b/TODO.txt index 0cb1297d..67d2302e 100644 --- a/TODO.txt +++ b/TODO.txt @@ -63,16 +63,17 @@ ; [X] mouse not working on interactive view ; [X] reopen effects other view too? ; [X] allen's segfaults on linux launch +; [X] open empty file bug +; [X] chronal's map setting issue ; [] indication on failure to save ; [] clean whitespace doesn't appear to be cleaning trailing whitespace anymore??? ; [] sometimes the main cursor is not the same width as the mark cursor in the same spot ; [] tab character wrong width ; [] bouncing when scrolling down ; [] miblo's off screen cursor thing +; ; [] linux save jankieness ; -; [] open empty file bug -; [] chronal's map setting issue ; ; @@ -96,10 +97,10 @@ ; [X] improve file limit (now is > 8 million I think) ; [X] get key stroke in custom callback ; [X] tab option for auto-indent +; [X] catch unsaved files on close ; -; [] File status (saved, needs saving, out of sync) +; [] file status in custom API ; [] user file bar string -; [] catch unsaved files on close ; ; [] feedback messages ; [] command meta data @@ -113,8 +114,9 @@ ; search related tech ; [X] replace word (incremental and/or in range) ; [] optimize search -; [] make search wrap around beginning/end -; [] polish for seeking +; [] allow search wrap around beginning/end +; [] improved custom API for text "streams" +; [] caps insensitivety ; ; GUI related tech ; [X] consolidate all GUI code properly diff --git a/win32_4ed.cpp b/win32_4ed.cpp index cb26fafd..94b54940 100644 --- a/win32_4ed.cpp +++ b/win32_4ed.cpp @@ -1437,14 +1437,16 @@ Win32Callback(HWND hwnd, UINT uMsg, } Font_Load_Parameters *params = win32vars.fnt.params + lParam; - + i32 oversample = DpiMultiplier(2, win32vars.target.dpi); + for (b32 success = 0; success == 0;){ success = draw_font_load(win32vars.fnt.part.base, win32vars.fnt.part.max, params->font_out, params->filename, params->pt_size, - params->tab_width); + params->tab_width, + oversample); if (!success){ Win32ScratchPartitionDouble(&win32vars.fnt.part); @@ -1893,6 +1895,9 @@ main(int argc, char **argv){ window_style |= WS_MAXIMIZE; } + // TODO(allen): not Windows XP compatible, do we care? + SetProcessDPIAware(); + HWND window_handle = {}; window_handle = CreateWindowA( window_class.lpszClassName, @@ -1911,6 +1916,14 @@ main(int argc, char **argv){ HDC hdc = GetDC(window_handle); win32vars.window_hdc = hdc; + i32 xdpi = GetDeviceCaps(hdc, LOGPIXELSX); + i32 ydpi = GetDeviceCaps(hdc, LOGPIXELSY); + + win32vars.target.dpi = xdpi; + if (win32vars.target.dpi < ydpi){ + win32vars.target.dpi = ydpi; + } + GetClientRect(window_handle, &window_rect); static PIXELFORMATDESCRIPTOR pfd = { @@ -1976,7 +1989,6 @@ main(int argc, char **argv){ } } - File_Slot file_slots[32]; sysshared_init_file_exchange(&exchange_vars, file_slots, ArrayCount(file_slots), 0);