4coder/4ed_style.cpp

631 lines
20 KiB
C++

/*
* Mr. 4th Dimention - Allen Webster
*
* 28.08.2015
*
* Styles for 4coder
*
*/
// TOP
struct P4C_Page_Header{
i32 size;
u32 id;
};
#define P4C_STYLE_ID COMPOSE_ID('s', 't', 'y', 'l')
struct Style_Page_Header{
i32 version;
i32 count;
};
struct Style_Main_Data_v1{
u32 back_color;
u32 margin_color;
u32 margin_active_color;
u32 cursor_color;
u32 at_cursor_color;
u32 highlight_color;
u32 at_highlight_color;
u32 mark_color;
u32 default_color;
u32 comment_color;
u32 keyword_color;
u32 constant_color;
u32 special_character_color;
u32 highlight_junk_color;
u32 highlight_white_color;
u32 paste_color;
Interactive_Style file_info_style;
};
struct Style_File_Format_v1{
i32 name_size;
char name[24];
i32 font_name_size;
char font_name[24];
Style_Main_Data_v1 main;
};
struct Style_Main_Data_v2{
u32 back_color;
u32 margin_color;
u32 margin_active_color;
u32 cursor_color;
u32 at_cursor_color;
u32 highlight_color;
u32 at_highlight_color;
u32 mark_color;
u32 default_color;
u32 comment_color;
u32 keyword_color;
u32 str_constant_color;
u32 char_constant_color;
u32 int_constant_color;
u32 float_constant_color;
u32 bool_constant_color;
u32 preproc_color;
u32 include_color;
u32 special_character_color;
u32 highlight_junk_color;
u32 highlight_white_color;
u32 paste_color;
Interactive_Style file_info_style;
};
struct Style_File_Format_v2{
i32 name_size;
char name[24];
i32 font_name_size;
char font_name[24];
Style_Main_Data_v2 main;
};
struct Style_Main_Data_v3{
u32 back_color;
u32 margin_color;
u32 margin_hover_color;
u32 margin_active_color;
u32 cursor_color;
u32 at_cursor_color;
u32 highlight_color;
u32 at_highlight_color;
u32 mark_color;
u32 default_color;
u32 comment_color;
u32 keyword_color;
u32 str_constant_color;
u32 char_constant_color;
u32 int_constant_color;
u32 float_constant_color;
u32 bool_constant_color;
u32 preproc_color;
u32 include_color;
u32 special_character_color;
u32 highlight_junk_color;
u32 highlight_white_color;
u32 paste_color;
Interactive_Style file_info_style;
};
struct Style_File_Format_v3{
i32 name_size;
char name[24];
i32 font_name_size;
char font_name[24];
Style_Main_Data_v3 main;
};
struct Style_Main_Data{
u32 back_color;
u32 margin_color;
u32 margin_hover_color;
u32 margin_active_color;
u32 cursor_color;
u32 at_cursor_color;
u32 highlight_color;
u32 at_highlight_color;
u32 mark_color;
u32 default_color;
u32 comment_color;
u32 keyword_color;
u32 str_constant_color;
u32 char_constant_color;
u32 int_constant_color;
u32 float_constant_color;
u32 bool_constant_color;
u32 preproc_color;
u32 include_color;
u32 special_character_color;
u32 highlight_junk_color;
u32 highlight_white_color;
u32 paste_color;
u32 undo_color;
u32 result_link_color;
u32 related_link_color;
u32 error_link_color;
u32 warning_link_color;
Interactive_Style file_info_style;
};
struct Style_File_Format_v4{
i32 name_size;
char name[24];
i32 font_name_size;
char font_name[24];
Style_Main_Data main;
};
enum Style_Color_Tag{
STAG_BAR_COLOR,
STAG_BAR_ACTIVE_COLOR,
STAG_BAR_BASE_COLOR,
STAG_BAR_POP1_COLOR,
STAG_BAR_POP2_COLOR,
STAG_BACK_COLOR,
STAG_MARGIN_COLOR,
STAG_MARGIN_HOVER_COLOR,
STAG_MARGIN_ACTIVE_COLOR,
STAG_CURSOR_COLOR,
STAG_AT_CURSOR_COLOR,
STAG_HIGHLIGHT_COLOR,
STAG_AT_HIGHLIGHT_COLOR,
STAG_MARK_COLOR,
STAG_DEFAULT_COLOR,
STAG_COMMENT_COLOR,
STAG_KEYWORD_COLOR,
STAG_STR_CONSTANT_COLOR,
STAG_CHAR_CONSTANT_COLOR,
STAG_INT_CONSTANT_COLOR,
STAG_FLOAT_CONSTANT_COLOR,
STAG_BOOL_CONSTANT_COLOR,
STAG_PREPROC_COLOR,
STAG_INCLUDE_COLOR,
STAG_SPECIAL_CHARACTER_COLOR,
STAG_HIGHLIGHT_JUNK_COLOR,
STAG_HIGHLIGHT_WHITE_COLOR,
STAG_PASTE_COLOR,
STAG_UNDO_COLOR,
STAG_NEXT_UNDO_COLOR,
STAG_RESULT_LINK_COLOR,
STAG_RELATED_LINK_COLOR,
STAG_ERROR_LINK_COLOR,
STAG_WARNING_LINK_COLOR,
// never below this
STAG_COUNT
};
struct Style_Color_Specifier{
u32 tag;
u32 color;
};
struct Style_File_Format{
i32 name_size;
char name[24];
i32 font_name_size;
char font_name[24];
i32 color_specifier_count;
};
struct Style{
char name_[24];
String name;
Render_Font *font;
Style_Main_Data main;
bool32 font_changed;
};
struct Style_Library{
Style styles[64];
i32 count, max;
};
struct Font_Set{
Render_Font *fonts;
i32 count, max;
};
internal void
style_copy(Style *dst, Style *src){
*dst = *src;
dst->name.str = dst->name_;
}
internal void
style_set_name(Style *style, String name){
i32 count = ArrayCount(style->name_);
style->name_[count - 1] = 0;
style->name = make_string(style->name_, 0, count - 1);
copy(&style->name, name);
}
internal Render_Font*
font_set_extract(Font_Set *fonts, char *name, i32 size){
String n = make_string(name, size);
i32 count = fonts->count;
Render_Font *result = 0;
Render_Font *font = fonts->fonts;
for (i32 i = 0; i < count; ++i, ++font){
if (match(n, font->name)){
result = font;
break;
}
}
return result;
}
internal void
style_form_convert(Style_File_Format_v2 *o, Style_File_Format_v1 *i){
o->name_size = i->name_size;
memcpy(o->name, i->name, i->name_size);
o->font_name_size = i->font_name_size;
memcpy(o->font_name, i->font_name, i->font_name_size);
o->main.back_color = i->main.back_color;
o->main.margin_color = i->main.margin_color;
o->main.margin_active_color = i->main.margin_active_color;
o->main.cursor_color = i->main.cursor_color;
o->main.at_cursor_color = i->main.at_cursor_color;
o->main.highlight_color = i->main.highlight_color;
o->main.at_highlight_color = i->main.at_highlight_color;
o->main.mark_color = i->main.mark_color;
o->main.default_color = i->main.default_color;
o->main.comment_color = i->main.comment_color;
o->main.keyword_color = i->main.keyword_color;
o->main.str_constant_color = i->main.constant_color;
o->main.char_constant_color = i->main.constant_color;
o->main.int_constant_color = i->main.constant_color;
o->main.float_constant_color = i->main.constant_color;
o->main.bool_constant_color = i->main.constant_color;
o->main.include_color = i->main.constant_color;
o->main.preproc_color = i->main.default_color;
o->main.special_character_color = i->main.special_character_color;
o->main.highlight_junk_color = i->main.highlight_junk_color;
o->main.highlight_white_color = i->main.highlight_white_color;
o->main.paste_color = i->main.paste_color;
o->main.file_info_style = i->main.file_info_style;
}
internal void
style_form_convert(Style_File_Format_v3 *o, Style_File_Format_v2 *i){
o->name_size = i->name_size;
memcpy(o->name, i->name, i->name_size);
o->font_name_size = i->font_name_size;
memcpy(o->font_name, i->font_name, i->font_name_size);
o->main.back_color = i->main.back_color;
o->main.margin_color = i->main.margin_color;
o->main.margin_active_color = i->main.margin_active_color;
o->main.margin_hover_color = color_blend(i->main.margin_color, .5f, i->main.margin_active_color);
o->main.cursor_color = i->main.cursor_color;
o->main.at_cursor_color = i->main.at_cursor_color;
o->main.highlight_color = i->main.highlight_color;
o->main.at_highlight_color = i->main.at_highlight_color;
o->main.mark_color = i->main.mark_color;
o->main.default_color = i->main.default_color;
o->main.comment_color = i->main.comment_color;
o->main.keyword_color = i->main.keyword_color;
o->main.str_constant_color = i->main.str_constant_color;
o->main.char_constant_color = i->main.char_constant_color;
o->main.int_constant_color = i->main.int_constant_color;
o->main.float_constant_color = i->main.float_constant_color;
o->main.bool_constant_color = i->main.bool_constant_color;
o->main.include_color = i->main.include_color;
o->main.preproc_color = i->main.preproc_color;
o->main.special_character_color = i->main.special_character_color;
o->main.highlight_junk_color = i->main.highlight_junk_color;
o->main.highlight_white_color = i->main.highlight_white_color;
o->main.paste_color = i->main.paste_color;
o->main.file_info_style = i->main.file_info_style;
}
internal void
style_form_convert(Style_File_Format_v4 *o, Style_File_Format_v3 *i){
o->name_size = i->name_size;
memcpy(o->name, i->name, i->name_size);
o->font_name_size = i->font_name_size;
memcpy(o->font_name, i->font_name, i->font_name_size);
o->main.back_color = i->main.back_color;
o->main.margin_color = i->main.margin_color;
o->main.margin_hover_color = i->main.margin_hover_color;
o->main.margin_active_color = i->main.margin_active_color;
o->main.cursor_color = i->main.cursor_color;
o->main.at_cursor_color = i->main.at_cursor_color;
o->main.highlight_color = i->main.highlight_color;
o->main.at_highlight_color = i->main.at_highlight_color;
o->main.mark_color = i->main.mark_color;
o->main.default_color = i->main.default_color;
o->main.comment_color = i->main.comment_color;
o->main.keyword_color = i->main.keyword_color;
o->main.str_constant_color = i->main.str_constant_color;
o->main.char_constant_color = i->main.char_constant_color;
o->main.int_constant_color = i->main.int_constant_color;
o->main.float_constant_color = i->main.float_constant_color;
o->main.bool_constant_color = i->main.bool_constant_color;
o->main.include_color = i->main.include_color;
o->main.preproc_color = i->main.preproc_color;
o->main.special_character_color = i->main.special_character_color;
o->main.highlight_junk_color = i->main.highlight_junk_color;
o->main.highlight_white_color = i->main.highlight_white_color;
o->main.paste_color = i->main.paste_color;
o->main.undo_color = i->main.paste_color ^ 0x00FFFFFF;
o->main.file_info_style = i->main.file_info_style;
o->main.file_info_style.bar_active_color = i->main.file_info_style.bar_color;
}
inline u32*
style_index_by_tag(Style *s, u32 tag){
u32 *result = 0;
switch (tag){
case STAG_BAR_COLOR: result = &s->main.file_info_style.bar_color; break;
case STAG_BAR_ACTIVE_COLOR: result = &s->main.file_info_style.bar_active_color; break;
case STAG_BAR_BASE_COLOR: result = &s->main.file_info_style.base_color; break;
case STAG_BAR_POP1_COLOR: result = &s->main.file_info_style.pop1_color; break;
case STAG_BAR_POP2_COLOR: result = &s->main.file_info_style.pop2_color; break;
case STAG_BACK_COLOR: result = &s->main.back_color; break;
case STAG_MARGIN_COLOR: result = &s->main.margin_color; break;
case STAG_MARGIN_HOVER_COLOR: result = &s->main.margin_hover_color; break;
case STAG_MARGIN_ACTIVE_COLOR: result = &s->main.margin_active_color; break;
case STAG_CURSOR_COLOR: result = &s->main.cursor_color; break;
case STAG_AT_CURSOR_COLOR: result = &s->main.at_cursor_color; break;
case STAG_HIGHLIGHT_COLOR: result = &s->main.highlight_color; break;
case STAG_AT_HIGHLIGHT_COLOR: result = &s->main.at_highlight_color; break;
case STAG_MARK_COLOR: result = &s->main.mark_color; break;
case STAG_DEFAULT_COLOR: result = &s->main.default_color; break;
case STAG_COMMENT_COLOR: result = &s->main.comment_color; break;
case STAG_KEYWORD_COLOR: result = &s->main.keyword_color; break;
case STAG_STR_CONSTANT_COLOR: result = &s->main.str_constant_color; break;
case STAG_CHAR_CONSTANT_COLOR: result = &s->main.char_constant_color; break;
case STAG_INT_CONSTANT_COLOR: result = &s->main.int_constant_color; break;
case STAG_FLOAT_CONSTANT_COLOR: result = &s->main.float_constant_color; break;
case STAG_BOOL_CONSTANT_COLOR: result = &s->main.bool_constant_color; break;
case STAG_PREPROC_COLOR: result = &s->main.preproc_color; break;
case STAG_INCLUDE_COLOR: result = &s->main.include_color; break;
case STAG_SPECIAL_CHARACTER_COLOR: result = &s->main.special_character_color; break;
case STAG_HIGHLIGHT_JUNK_COLOR: result = &s->main.highlight_junk_color; break;
case STAG_HIGHLIGHT_WHITE_COLOR: result = &s->main.highlight_white_color; break;
case STAG_PASTE_COLOR: result = &s->main.paste_color; break;
case STAG_UNDO_COLOR: result = &s->main.undo_color; break;
case STAG_RESULT_LINK_COLOR: result = &s->main.result_link_color; break;
case STAG_RELATED_LINK_COLOR: result = &s->main.related_link_color; break;
case STAG_ERROR_LINK_COLOR: result = &s->main.error_link_color; break;
case STAG_WARNING_LINK_COLOR: result = &s->main.warning_link_color; break;
}
return result;
}
internal Style_File_Format*
style_format_for_use(Font_Set *fonts, Style *out, Style_File_Format *style){
out->name = make_string(out->name_, 0, ArrayCount(out->name_) - 1);
out->name_[ArrayCount(out->name_) - 1] = 0;
copy(&out->name, style->name);
out->font = font_set_extract(fonts, style->font_name, style->font_name_size);
i32 spec_count = style->color_specifier_count;
Style_Color_Specifier *spec = (Style_Color_Specifier*)(style + 1);
for (i32 i = 0; i < spec_count; ++i, ++spec){
u32 *color = style_index_by_tag(out, spec->tag);
if (color) *color = spec->color;
}
#if 0 // TODO(allen): when new colors are introduced, derive them here.
for (u32 i = 0; i < STAG_COUNT; ++i){
u32 *color = style_index_by_tag(out, i);
if (color && (*color >> 24) == 0){
switch (i){
}
}
}
#endif
return (Style_File_Format*)(spec);
}
inline void
style_format_for_use(Font_Set *fonts, Style *out, Style_File_Format_v4 *style){
out->name = make_string(out->name_, 0, ArrayCount(out->name_) - 1);
out->name_[ArrayCount(out->name_) - 1] = 0;
copy(&out->name, style->name);
out->font = font_set_extract(fonts, style->font_name, style->font_name_size);
out->main = style->main;
}
inline void
style_format_for_use(Font_Set *fonts, Style *out, Style_File_Format_v1 *style){
Style_File_Format_v2 form2;
Style_File_Format_v3 form3;
Style_File_Format_v4 form;
style_form_convert(&form2, style);
style_form_convert(&form3, &form2);
style_form_convert(&form, &form3);
style_format_for_use(fonts, out, &form);
}
inline void
style_format_for_use(Font_Set *fonts, Style *out, Style_File_Format_v2 *style){
Style_File_Format_v3 form3;
Style_File_Format_v4 form;
style_form_convert(&form3, style);
style_form_convert(&form, &form3);
style_format_for_use(fonts, out, &form);
}
inline void
style_format_for_use(Font_Set *fonts, Style *out, Style_File_Format_v3 *style){
Style_File_Format_v4 form;
style_form_convert(&form, style);
style_format_for_use(fonts, out, &form);
}
internal b32
style_library_import(System_Functions *system,
char *filename, Font_Set *fonts, Style *out, i32 max,
i32 *count_opt, i32 *total_opt = 0){
b32 result = 1;
Data file = system->load_file(filename);
Style_Page_Header *h = 0;
if (!file.data){
result = 0;
}
else{
void *cursor = file.data;
i32 to_read = 0;
{
P4C_Page_Header *h = (P4C_Page_Header*)cursor;
if (h->id != P4C_STYLE_ID){
result = 0;
goto early_exit;
}
cursor = h+1;
}
h = (Style_Page_Header*)cursor;
to_read = h->count;
cursor = h+1;
if (total_opt) *total_opt = to_read;
if (to_read > max) to_read = max;
if (count_opt) *count_opt = to_read;
switch (h->version){
case 1:
{
Style_File_Format_v1 *in = (Style_File_Format_v1*)cursor;
for (i32 i = 0; i < to_read; ++i){
style_format_for_use(fonts, out++, in++);
}
}break;
case 2:
{
Style_File_Format_v2 *in = (Style_File_Format_v2*)cursor;
for (i32 i = 0; i < to_read; ++i){
style_format_for_use(fonts, out++, in++);
}
}break;
case 3:
{
Style_File_Format_v3 *in = (Style_File_Format_v3*)cursor;
for (i32 i = 0; i < to_read; ++i){
style_format_for_use(fonts, out++, in++);
}
}break;
case 4:
{
Style_File_Format *in = (Style_File_Format*)cursor;
for (i32 i = 0; i < to_read; ++i){
in = style_format_for_use(fonts, out++, in);
}
}break;
default: result = 0; break;
}
early_exit:
system->free_file(file);
}
return result;
}
internal b32
style_library_add(Style_Library *library, Style *style){
b32 result = 0;
i32 count = library->count;
String my_name = style->name;
Style *ostyle = library->styles;
Style *out = 0;
// TODO(allen): hashtable for name lookup?
for (i32 i = 0; i < count; ++i, ++ostyle){
if (match(my_name, ostyle->name)){
out = ostyle;
break;
}
}
if (!out && count < library->max){
out = library->styles + library->count++;
}
if (out){
style_copy(out, style);
result = 1;
}
return result;
}
internal Style_File_Format*
style_format_for_file(Style *style, Style_File_Format *out){
Render_Font *font = style->font;
out->name_size = style->name.size;
memcpy(out->name, style->name.str, ArrayCount(out->name));
out->font_name_size = font->name.size;
memcpy(out->font_name, font->name.str, ArrayCount(out->font_name));
Style_Color_Specifier *spec = (Style_Color_Specifier*)(out + 1);
i32 count = 0;
for (u32 i = 0; i < STAG_COUNT; ++i){
u32 *color = style_index_by_tag(style, i);
if (color){
spec->tag = i;
spec->color = *color;
++count;
++spec;
}
}
out->color_specifier_count = count;
return (Style_File_Format*)spec;
}
internal void
style_library_export(System_Functions *system, char *filename, Style **styles, i32 count){
i32 size = count*(sizeof(Style_File_Format) + STAG_COUNT*sizeof(Style_Color_Specifier)) +
sizeof(P4C_Page_Header) + sizeof(Style_Page_Header);
void *data = system->get_memory(size);
void *cursor = data;
{
P4C_Page_Header *h = (P4C_Page_Header*)cursor;
h->size = size - sizeof(P4C_Page_Header);
h->id = P4C_STYLE_ID;
cursor = h+1;
}
{
Style_Page_Header *h = (Style_Page_Header*)cursor;
h->version = 4;
h->count = count;
cursor = h+1;
}
Style_File_Format *out = (Style_File_Format*)cursor;
Style **in = styles;
for (i32 i = 0; i < count; ++i){
out = style_format_for_file(*in++, out);
}
system->save_file(filename, data, size);
system->free_memory(data);
}
// BOTTOM