pull request #924 - unicode symsets

Pull request from chasonr:  a symbols file with more than one set
having the unicode attribute effectively merged all unicode sets when
loading any of them.  Also, freeing unicode glyphmap entries for gems
would attempt to free some of them more than once for those that had
colors cloned from other gems.

[This new code compiles but is otherwise untested by me.]

Closes #924
This commit is contained in:
PatR
2022-11-23 12:11:24 -08:00
2 changed files with 62 additions and 19 deletions

View File

@@ -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)

View File

@@ -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);
}
}