got unicode working in the clipboard, reoganized some old stuff
parent
3515722fdb
commit
4d46aa8e97
|
@ -62,7 +62,7 @@
|
|||
#include "4ed_file_view.cpp"
|
||||
#include "4ed.cpp"
|
||||
|
||||
#include "font/4coder_font_static_functions.cpp"
|
||||
#include "4ed_font_static_functions.cpp"
|
||||
|
||||
// BOTTOM
|
||||
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
// Buffer low level operations
|
||||
//
|
||||
|
||||
#include "font/4coder_font_data.h"
|
||||
#include "4ed_font_data.h"
|
||||
#include "4coder_helper/4coder_seek_types.h"
|
||||
|
||||
typedef struct Cursor_With_Index{
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
|
||||
// TOP
|
||||
|
||||
#include "4coder_font_data.h"
|
||||
#include "4ed_font_data.h"
|
||||
|
||||
internal f32
|
||||
font_get_byte_advance(Render_Font *font){
|
|
@ -12,7 +12,7 @@
|
|||
#if !defined(FCODER_SYSTEM_INTERFACE_H)
|
||||
#define FCODER_SYSTEM_INTERFACE_H
|
||||
|
||||
#include "font/4coder_font_interface.h"
|
||||
#include "4ed_font_interface.h"
|
||||
|
||||
// types
|
||||
struct Plat_Handle{
|
||||
|
|
|
@ -12,23 +12,10 @@
|
|||
#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.
|
||||
//
|
||||
|
||||
struct Shared_Vars{
|
||||
File_Track_System track;
|
||||
void *track_table;
|
||||
u32 track_table_size;
|
||||
u32 track_node_size;
|
||||
|
||||
Partition scratch;
|
||||
};
|
||||
|
||||
global Shared_Vars shared_vars;
|
||||
|
||||
internal void
|
||||
init_shared_vars(){
|
||||
umem scratch_size = KB(128);
|
||||
|
|
|
@ -30,6 +30,17 @@ global File_Data null_file_data = {0};
|
|||
internal Sys_File_Can_Be_Made_Sig(system_file_can_be_made);
|
||||
internal Sys_Get_Binary_Path_Sig(system_get_binary_path);
|
||||
|
||||
struct Shared_Vars{
|
||||
File_Track_System track;
|
||||
void *track_table;
|
||||
u32 track_table_size;
|
||||
u32 track_node_size;
|
||||
|
||||
Partition scratch;
|
||||
};
|
||||
|
||||
global Shared_Vars shared_vars;
|
||||
|
||||
#endif
|
||||
|
||||
// BOTTOM
|
||||
|
|
|
@ -1,493 +0,0 @@
|
|||
/*
|
||||
* 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
|
||||
|
||||
|
||||
|
||||
|
|
@ -1,241 +0,0 @@
|
|||
/*
|
||||
|
||||
A series of stress tests to more quickly verify that 4coder isn't totally
|
||||
broken before I release in the future... "unit tests" perhaps, although
|
||||
I guess I don't know what the "units" are... probably just "tests".
|
||||
|
||||
Allen Webster
|
||||
18.07.2016
|
||||
|
||||
*/
|
||||
|
||||
// TOP
|
||||
|
||||
#define LOTS_OF_FILES "w:/4ed/data/lots_of_files"
|
||||
#define TEST_FILES "w:/4ed/data/test"
|
||||
|
||||
#include "4coder_default_include.cpp"
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include <intrin.h>
|
||||
#pragma intrinsic(__rdtsc)
|
||||
|
||||
typedef uint64_t DWORD64;
|
||||
|
||||
#define TEST_TIME_B(m) DWORD64 time_start = __rdtsc(), time_max = m; (void)(time_start), (void)(time_max)
|
||||
#define TEST_TIME_E() DWORD64 time_total = __rdtsc() - time_start; if (time_total > time_max) {assert(!"failed timing");}
|
||||
#define TEST_TIME_M(m) m = (float)(__rdtsc() - time_start) / time_max
|
||||
|
||||
// NOTE(allen): This testing system only verifies that everything works
|
||||
// without crashing and without blowing through a fair time budget.
|
||||
// These tests do not verify the correctness of the output.
|
||||
|
||||
CUSTOM_COMMAND_SIG(load_lots_of_files){
|
||||
// NOTE(allen): This timing restriction is based on 4GHz and 60fps
|
||||
// 4G / 60 ~= 70M Reserving most of that time for rendering and hopefully idling
|
||||
// I set the goal of 10M for all tests.
|
||||
TEST_TIME_B(10000000);
|
||||
|
||||
File_List list = get_file_list(app, literal(LOTS_OF_FILES));
|
||||
File_Info *info = list.infos;
|
||||
|
||||
char space[1024];
|
||||
String str = make_fixed_width_string(space);
|
||||
append_ss(&str, make_lit_string(LOTS_OF_FILES));
|
||||
append_s_char(&str, '/');
|
||||
int32_t size = str.size;
|
||||
|
||||
for (uint32_t i = 0; i < list.count; ++i, ++info){
|
||||
if (!info->folder){
|
||||
append_ss(&str, make_string(info->filename, info->filename_len));
|
||||
Buffer_Summary buffer = create_buffer(app, str.str, str.size,
|
||||
BufferCreate_Background);
|
||||
assert(buffer.size != 0);
|
||||
str.size = size;
|
||||
}
|
||||
}
|
||||
|
||||
free_file_list(app, list);
|
||||
|
||||
// TODO(allen): Pass this time test!
|
||||
//TEST_TIME_E();
|
||||
}
|
||||
|
||||
CUSTOM_COMMAND_SIG(reopen_test){
|
||||
// NOTE(allen): This is set to roughly one percent of the frame budget
|
||||
// based on 4GHz and 60fps
|
||||
TEST_TIME_B(700000);
|
||||
|
||||
Buffer_Summary buffer = create_buffer(app, literal(TEST_FILES "/basic.cpp"), 0);
|
||||
View_Summary view = get_active_view(app, AccessAll);
|
||||
view_set_buffer(app, &view, buffer.buffer_id, 0);
|
||||
|
||||
exec_command(app, cmdid_reopen);
|
||||
|
||||
// TODO(allen): Pass this time test!
|
||||
//TEST_TIME_E();
|
||||
}
|
||||
|
||||
CUSTOM_COMMAND_SIG(generate_stop_spots_test_data){
|
||||
Buffer_Summary buffer = create_buffer(app, literal(LOTS_OF_FILES "/4ed.cpp"), 0);
|
||||
View_Summary view = get_active_view(app, AccessAll);
|
||||
view_set_buffer(app, &view, buffer.buffer_id, 0);
|
||||
|
||||
FILE *file = fopen(TEST_FILES "/stop_spots_data", "wb");
|
||||
|
||||
if (file){
|
||||
Partial_Cursor curs;
|
||||
int32_t pos;
|
||||
|
||||
buffer_compute_cursor(app, &buffer, seek_line_char(316, 29), &curs);
|
||||
fwrite(&curs.pos, 4, 1, file);
|
||||
|
||||
for (int32_t i = 0; i < 10; ++i){
|
||||
Query_Bar bar = {0};
|
||||
bar.prompt = make_lit_string("Do something to continue the test");
|
||||
if (start_query_bar(app, &bar, 0)){
|
||||
get_user_input(app, EventAll, EventAll);
|
||||
}
|
||||
refresh_buffer(app, &buffer);
|
||||
if (buffer.tokens_are_ready){
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static Seek_Boundary_Flag flag_set[] = {
|
||||
BoundaryWhitespace,
|
||||
BoundaryToken,
|
||||
BoundaryAlphanumeric,
|
||||
BoundaryCamelCase,
|
||||
BoundaryWhitespace | BoundaryToken,
|
||||
BoundaryWhitespace | BoundaryAlphanumeric,
|
||||
BoundaryToken | BoundaryCamelCase,
|
||||
};
|
||||
|
||||
for (int32_t flag_i = 0; flag_i < ArrayCount(flag_set); ++flag_i){
|
||||
for (int32_t seek_forward = 0; seek_forward <= 1; ++seek_forward){
|
||||
pos = curs.pos;
|
||||
for (int32_t i = 0; i < 100; ++i){
|
||||
pos = buffer_boundary_seek(app, &buffer, pos, seek_forward, flag_set[flag_i]);
|
||||
fwrite(&pos, 4, 1, file);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fclose(file);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
fcheck(int32_t x, FILE *file){
|
||||
int32_t x0 = 0;
|
||||
fread(&x0, 4, 1, file);
|
||||
Assert(x == x0);
|
||||
}
|
||||
|
||||
CUSTOM_COMMAND_SIG(stop_spots_test){
|
||||
Buffer_Summary buffer = create_buffer(app, literal(LOTS_OF_FILES "/4ed.cpp"), 0);
|
||||
View_Summary view = get_active_view(app, AccessAll);
|
||||
view_set_buffer(app, &view, buffer.buffer_id, 0);
|
||||
|
||||
FILE *file = fopen(TEST_FILES "/stop_spots_data", "rb");
|
||||
|
||||
if (file){
|
||||
Partial_Cursor curs;
|
||||
int32_t pos;
|
||||
|
||||
buffer_compute_cursor(app, &buffer, seek_line_char(316, 29), &curs);
|
||||
fcheck(curs.pos, file);
|
||||
|
||||
for (int32_t i = 0; i < 10; ++i){
|
||||
Query_Bar bar = {0};
|
||||
bar.prompt = make_lit_string("Do something to continue the test");
|
||||
if (start_query_bar(app, &bar, 0)){
|
||||
get_user_input(app, EventAll, EventAll);
|
||||
}
|
||||
refresh_buffer(app, &buffer);
|
||||
if (buffer.tokens_are_ready){
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static Seek_Boundary_Flag flag_set[] = {
|
||||
BoundaryWhitespace,
|
||||
BoundaryToken,
|
||||
BoundaryAlphanumeric,
|
||||
BoundaryCamelCase,
|
||||
BoundaryWhitespace | BoundaryToken,
|
||||
BoundaryWhitespace | BoundaryAlphanumeric,
|
||||
BoundaryToken | BoundaryCamelCase,
|
||||
};
|
||||
|
||||
for (int32_t flag_i = 0; flag_i < ArrayCount(flag_set); ++flag_i){
|
||||
for (int32_t seek_forward = 0; seek_forward <= 1; ++seek_forward){
|
||||
pos = curs.pos;
|
||||
for (int32_t i = 0; i < 100; ++i){
|
||||
pos = buffer_boundary_seek(app, &buffer, pos, seek_forward, flag_set[flag_i]);
|
||||
fcheck(pos, file);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fclose(file);
|
||||
}
|
||||
}
|
||||
|
||||
CUSTOM_COMMAND_SIG(load_unicode_file){
|
||||
Buffer_Summary buffer = create_buffer(app, literal(TEST_FILES "/mod_markov.c"), 0);
|
||||
View_Summary view = get_active_view(app, AccessAll);
|
||||
view_set_buffer(app, &view, buffer.buffer_id, 0);
|
||||
|
||||
view_set_cursor(app, &view, seek_line_char(230, 25), 1);
|
||||
}
|
||||
|
||||
CUSTOM_COMMAND_SIG(edit_giant_file){
|
||||
Buffer_Summary buffer = create_buffer(app, literal(TEST_FILES "/test_large.cpp"), 0);
|
||||
View_Summary view = get_active_view(app, AccessAll);
|
||||
view_set_buffer(app, &view, buffer.buffer_id, 0);
|
||||
view_set_cursor(app, &view, seek_line_char(230, 25), 1);
|
||||
|
||||
for (int32_t i = 0; i < 600; ++i){
|
||||
Query_Bar bar = {0};
|
||||
bar.prompt = make_lit_string("Do something to continue the test");
|
||||
if (start_query_bar(app, &bar, 0)){
|
||||
get_user_input(app, EventAll, EventAll);
|
||||
}
|
||||
end_query_bar(app, &bar, 0);
|
||||
refresh_buffer(app, &buffer);
|
||||
if (buffer.tokens_are_ready){
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
buffer_replace_range(app, &buffer, 2000, 2000,
|
||||
literal("{\n//Not important at all\n}\n"));
|
||||
buffer_auto_indent(app, &buffer, 2000, 2100, 4, 0);
|
||||
}
|
||||
|
||||
CUSTOM_COMMAND_SIG(run_all_tests){
|
||||
exec_command(app, load_lots_of_files);
|
||||
exec_command(app, reopen_test);
|
||||
exec_command(app, stop_spots_test);
|
||||
exec_command(app, load_unicode_file);
|
||||
exec_command(app, edit_giant_file);
|
||||
}
|
||||
|
||||
static void
|
||||
test_get_bindings(Bind_Helper *context){
|
||||
begin_map(context, mapid_global);
|
||||
bind(context, key_f3, MDFR_NONE, run_all_tests);
|
||||
end_map(context);
|
||||
}
|
||||
|
||||
#define BIND_4CODER_TESTS(context) test_get_bindings(context)
|
||||
|
||||
#include "power/4coder_experiments.cpp"
|
||||
|
||||
|
||||
// BOTTOM
|
||||
|
|
@ -433,11 +433,7 @@ do_buildsuper(char *cdir, i32 custom_option, u32 flags){
|
|||
|
||||
case Custom_Experiments:
|
||||
{
|
||||
#if defined(IS_WINDOWS)
|
||||
copy_sc(&str, "../code/internal_4coder_tests.cpp");
|
||||
#else
|
||||
copy_sc(&str, "../code/power/4coder_experiments.cpp");
|
||||
#endif
|
||||
}break;
|
||||
|
||||
case Custom_Casey:
|
||||
|
|
|
@ -74,11 +74,9 @@
|
|||
#include "win32_utf8.h"
|
||||
|
||||
#include "4ed_file_track.h"
|
||||
#include "font/4coder_font_interface_to_os.h"
|
||||
#include "4ed_font_interface_to_os.h"
|
||||
#include "4ed_system_shared.h"
|
||||
|
||||
#include "win32_4ed_file_track.cpp"
|
||||
|
||||
//
|
||||
// Win32_Vars structs
|
||||
//
|
||||
|
@ -187,6 +185,9 @@ typedef struct Win32_Vars{
|
|||
HCURSOR cursor_arrow;
|
||||
HCURSOR cursor_leftright;
|
||||
HCURSOR cursor_updown;
|
||||
|
||||
u8 *clip_buffer;
|
||||
u32 clip_max;
|
||||
String clipboard_contents;
|
||||
b32 next_clipboard_is_self;
|
||||
DWORD clipboard_sequence;
|
||||
|
@ -1122,6 +1123,7 @@ Win32ToggleFullscreen(void){
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Clipboard
|
||||
//
|
||||
|
@ -1144,20 +1146,41 @@ Sys_Post_Clipboard_Sig(system_post_clipboard){
|
|||
}
|
||||
|
||||
internal b32
|
||||
Win32ReadClipboardContents(){
|
||||
b32 result = 0;
|
||||
win32_read_clipboard_contents(){
|
||||
b32 result = false;
|
||||
|
||||
if (IsClipboardFormatAvailable(CF_TEXT)){
|
||||
result = 1;
|
||||
if (IsClipboardFormatAvailable(CF_UNICODETEXT)){
|
||||
result = true;
|
||||
if (OpenClipboard(win32vars.window_handle)){
|
||||
HANDLE clip_data;
|
||||
clip_data = GetClipboardData(CF_TEXT);
|
||||
if (clip_data){
|
||||
win32vars.clipboard_contents.str = (char*)GlobalLock(clip_data);
|
||||
if (win32vars.clipboard_contents.str){
|
||||
win32vars.clipboard_contents.size = str_size((char*)win32vars.clipboard_contents.str);
|
||||
HANDLE clip_data = GetClipboardData(CF_UNICODETEXT);
|
||||
if (clip_data != 0){
|
||||
Partition *scratch = &shared_vars.scratch;
|
||||
Temp_Memory temp = begin_temp_memory(scratch);
|
||||
|
||||
u16 *clip_16 = (u16*)GlobalLock(clip_data);
|
||||
|
||||
if (clip_16 != 0){
|
||||
u32 clip_16_len = 0;
|
||||
for(;clip_16[clip_16_len];++clip_16_len);
|
||||
|
||||
// TODO(allen): Extend the buffer if it is too small.
|
||||
b32 error = false;
|
||||
u32 clip_8_len = (u32)utf16_to_utf8_minimal_checking(win32vars.clip_buffer, win32vars.clip_max-1, clip_16, clip_16_len, &error);
|
||||
|
||||
if (clip_8_len < win32vars.clip_max && !error){
|
||||
win32vars.clip_buffer[clip_8_len] = 0;
|
||||
|
||||
win32vars.clipboard_contents = make_string_cap(win32vars.clip_buffer, clip_8_len, win32vars.clip_max);
|
||||
}
|
||||
|
||||
GlobalUnlock(clip_data);
|
||||
}
|
||||
|
||||
if (win32vars.clipboard_contents.str){
|
||||
win32vars.clipboard_contents.size = str_size((char*)win32vars.clipboard_contents.str);
|
||||
}
|
||||
|
||||
end_temp_memory(temp);
|
||||
}
|
||||
CloseClipboard();
|
||||
}
|
||||
|
@ -1362,33 +1385,31 @@ Sys_Send_Exit_Signal_Sig(system_send_exit_signal){
|
|||
win32vars.send_exit_signal = 1;
|
||||
}
|
||||
|
||||
#include "4ed_system_shared.cpp"
|
||||
|
||||
#include "win32_4ed_fonts.cpp"
|
||||
|
||||
//
|
||||
// Linkage to Custom and Application
|
||||
//
|
||||
|
||||
internal b32
|
||||
Win32LoadAppCode(){
|
||||
b32 result = 0;
|
||||
b32 result = false;
|
||||
App_Get_Functions *get_funcs = 0;
|
||||
|
||||
win32vars.app_code = LoadLibraryA("4ed_app.dll");
|
||||
if (win32vars.app_code){
|
||||
get_funcs = (App_Get_Functions*)
|
||||
GetProcAddress(win32vars.app_code, "app_get_functions");
|
||||
get_funcs = (App_Get_Functions*)GetProcAddress(win32vars.app_code, "app_get_functions");
|
||||
}
|
||||
|
||||
if (get_funcs){
|
||||
result = 1;
|
||||
win32vars.app = get_funcs();
|
||||
result = true;
|
||||
win32vars.app = get_funcs();
|
||||
}
|
||||
|
||||
return result;
|
||||
return(result);
|
||||
}
|
||||
|
||||
#include "4ed_font_data.h"
|
||||
#include "4ed_system_shared.cpp"
|
||||
|
||||
internal void
|
||||
Win32LoadSystemCode(){
|
||||
win32vars.system.set_file_list = system_set_file_list;
|
||||
|
@ -2167,6 +2188,9 @@ WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdS
|
|||
// Misc System Initializations
|
||||
//
|
||||
|
||||
win32vars.clip_max = KB(16);
|
||||
win32vars.clip_buffer = (u8*)system_memory_allocate(win32vars.clip_max);
|
||||
|
||||
win32vars.clipboard_sequence = GetClipboardSequenceNumber();
|
||||
if (win32vars.clipboard_sequence == 0){
|
||||
system_post_clipboard(make_lit_string(""));
|
||||
|
@ -2179,7 +2203,7 @@ WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdS
|
|||
}
|
||||
}
|
||||
else{
|
||||
Win32ReadClipboardContents();
|
||||
win32_read_clipboard_contents();
|
||||
}
|
||||
|
||||
Win32KeycodeInit();
|
||||
|
@ -2360,7 +2384,7 @@ WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdS
|
|||
win32vars.next_clipboard_is_self = 0;
|
||||
}
|
||||
else{
|
||||
Win32ReadClipboardContents();
|
||||
win32_read_clipboard_contents();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2444,7 +2468,10 @@ WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdS
|
|||
return(0);
|
||||
}
|
||||
|
||||
#include "font/4coder_font_static_functions.cpp"
|
||||
#include "win32_4ed_fonts.cpp"
|
||||
|
||||
#include "win32_4ed_file_track.cpp"
|
||||
#include "4ed_font_static_functions.cpp"
|
||||
#include "win32_utf8.cpp"
|
||||
|
||||
#if 0
|
||||
|
|
|
@ -10,9 +10,9 @@
|
|||
// 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"
|
||||
#include "4ed_font_interface.h"
|
||||
#include "4ed_font_interface_to_os.h"
|
||||
#include "4ed_font_data.h"
|
||||
|
||||
struct Win32_Fonts{
|
||||
Partition part;
|
||||
|
|
Loading…
Reference in New Issue