diff --git a/src/symbols.c b/src/symbols.c index 0b517addd..6867bb425 100644 --- a/src/symbols.c +++ b/src/symbols.c @@ -7,6 +7,7 @@ static void savedsym_add(const char *, const char *, int); static struct _savedsym *savedsym_find(const char *, int); +void purge_custom_entries(enum graphics_sets which_set); extern const uchar def_r_oc_syms[MAXOCLASSES]; /* drawing.c */ @@ -332,6 +333,10 @@ clear_symsetentry(int which_set, boolean name_too) free((genericptr_t) g.symset[which_set].name); g.symset[which_set].name = (char *) 0; } +#ifdef ENHANCED_SYMBOLS + free_all_glyphmap_u(); + purge_custom_entries(which_set); +#endif } boolean symset_is_compatible(enum symset_handling_types handling, unsigned long wincap2) @@ -462,7 +467,11 @@ parse_sym_line(char *buf, int which_set) symp = match_sym(buf); if (!symp && buf[0] == 'G' && buf[1] == '_') { #ifdef ENHANCED_SYMBOLS - is_glyph = match_glyph(buf); + if (g.chosen_symset_start) { + is_glyph = match_glyph(buf); + } else { + is_glyph = TRUE; /* report error only once */ + } #else enhanced_unavailable = TRUE; #endif @@ -608,7 +617,9 @@ parse_sym_line(char *buf, int which_set) } #ifdef ENHANCED_SYMBOLS } else { - glyphrep_to_custom_map_entries(buf, &glyph); + if (g.chosen_symset_start) { + glyphrep_to_custom_map_entries(buf, &glyph); + } #endif } } @@ -1047,7 +1058,6 @@ struct customization_detail *find_matching_symset_customization( enum graphics_sets which_set); struct customization_detail *find_display_urep_customization( const char *customization_name, int glyphidx, enum graphics_sets which_set); -void purge_custom_entries(enum graphics_sets which_set); extern glyph_map glyphmap[MAX_GLYPH]; static void shuffle_customizations(void); @@ -1058,11 +1068,11 @@ apply_customizations_to_symset(enum graphics_sets which_set) struct customization_detail *details; if (g.symset[which_set].handling == H_UTF8 - && g.sym_customizations[UNICODESET].count - && g.sym_customizations[UNICODESET].details) { + && g.sym_customizations[which_set].count + && g.sym_customizations[which_set].details) { /* These UTF-8 customizations get applied to the glyphmap array, not to symset entries */ - details = g.sym_customizations[UNICODESET].details; + details = g.sym_customizations[which_set].details; while (details) { gm = &glyphmap[details->content.urep.glyphidx]; (void) set_map_u(gm, @@ -1080,18 +1090,51 @@ apply_customizations_to_symset(enum graphics_sets which_set) static void shuffle_customizations(void) { - int i; - struct unicode_representation *tmp_u[2][NUM_OBJECTS]; + static const int offsets[2] = { GLYPH_OBJ_OFF, GLYPH_OBJ_PILETOP_OFF }; + int j; - for (i = 0; i < NUM_OBJECTS; i++) { - tmp_u[0][i] = - glyphmap[objects[i].oc_descr_idx + GLYPH_OBJ_OFF].u; - tmp_u[1][i] = - glyphmap[objects[i].oc_descr_idx + GLYPH_OBJ_PILETOP_OFF].u; - } - for (i = 0; i < NUM_OBJECTS; i++) { - glyphmap[i + GLYPH_OBJ_OFF].u = tmp_u[0][i]; - glyphmap[i + GLYPH_OBJ_PILETOP_OFF].u = tmp_u[1][i]; + for (j = 0; j < SIZE(offsets); j++) { + glyph_map *obj_glyphs = glyphmap + offsets[j]; + int i; + struct unicode_representation *tmp_u[NUM_OBJECTS]; + int duplicate[NUM_OBJECTS]; + + for (i = 0; i < NUM_OBJECTS; i++) { + duplicate[i] = -1; + } + for (i = 0; i < NUM_OBJECTS; i++) { + int idx = objects[i].oc_descr_idx; + + /* + * Shuffling gem appearances can cause the same oc_descr_idx to + * appear more than once. Detect this condition and ensure that + * each pointer points to a unique allocation. + */ + if (duplicate[idx] >= 0) { + /* Current structure already appears in tmp_u */ + struct unicode_representation *other = tmp_u[duplicate[idx]]; + + tmp_u[i] = (struct unicode_representation *) alloc(sizeof *tmp_u[i]); + *tmp_u[i] = *other; + if (other->utf8str != NULL) { + tmp_u[i]->utf8str = (uint8 *) dupstr((const char *) other->utf8str); + } + } else { + tmp_u[i] = obj_glyphs[idx].u; + if (obj_glyphs[idx].u != NULL) { + duplicate[idx] = i; + obj_glyphs[idx].u = NULL; + } + } + } + for (i = 0; i < NUM_OBJECTS; i++) { + /* Some glyphmaps may not have been transferred */ + if (obj_glyphs[i].u != NULL) { + free(obj_glyphs[i].u->utf8str); + free(obj_glyphs[i].u); + } + obj_glyphs[i].u = tmp_u[i]; + } } } @@ -1112,7 +1155,7 @@ purge_custom_entries(enum graphics_sets which_set) { struct symset_customization *gdc = &g.sym_customizations[which_set]; struct customization_detail *details = gdc->details, *next; - if (details) { + while (details) { next = details->next; if (gdc->custtype == custom_ureps) { if (details->content.urep.u.utf8str) diff --git a/src/utf8map.c b/src/utf8map.c index fbffe18b7..35e390fbb 100644 --- a/src/utf8map.c +++ b/src/utf8map.c @@ -65,7 +65,7 @@ to_custom_symset_entry_callback(int glyph, struct find_struct *findwhat) (findwhat->color != 0L) ? findwhat->color : 0L); #endif add_custom_urep_entry(known_handling[H_UTF8], glyph, - uval, utf8str, findwhat->color, UNICODESET); + uval, utf8str, findwhat->color, g.symset_which_set); } }