📄 remap.c
字号:
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
};
static unsigned char hdigits[32] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x03,
0x7e, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
};
#define isdigok(m, d) (m[(d) >> 3] & (1 << ((d) & 7)))
static unsigned short
my_atous(unsigned char *s, unsigned char **end, int base)
{
unsigned short v;
unsigned char *dmap;
if (s == 0 || *s == 0)
return 0;
/*
* Make sure the radix is something recognizable. Default to 10.
*/
switch (base) {
case 8: dmap = odigits; break;
case 16: dmap = hdigits; break;
default: base = 10; dmap = ddigits; break;
}
/*
* Check for the special hex prefix.
*/
if (*s == '0' && (*(s + 1) == 'x' || *(s + 1) == 'X')) {
base = 16;
dmap = hdigits;
s += 2;
}
for (v = 0; isdigok(dmap, *s); s++)
v = (v * base) + a2i[(int) *s];
if (end != 0)
*end = s;
return v;
}
/********************************************************************
*
* Routines to load, unload, and use mapping tables to remap BDF fonts
* during generation by otf2bdf.
*
********************************************************************/
/*
* Strings used to store the registry and encoding values specified
* in the mapping table.
*/
static char *registry;
static char *encoding;
/*
* Trie node structure.
*/
typedef struct {
unsigned short key; /* Key value. */
unsigned short val; /* Data for the key. */
unsigned long sibs; /* Offset of siblings from trie beginning. */
unsigned long kids; /* Offset of children from trie beginning. */
} node_t;
/*
* The trie used for remapping codes.
*/
static node_t *nodes;
static unsigned long nodes_size = 0;
static unsigned long nodes_used = 0;
/*
* Gets the next available node in the trie.
*/
static unsigned long
getnode(unsigned short key)
{
unsigned long loc;
node_t *np;
if (nodes_used == nodes_size) {
if (nodes_size == 0)
nodes = (node_t *) malloc(sizeof(node_t) << 7);
else
nodes = (node_t *) realloc((char *) nodes, sizeof(node_t) *
(nodes_size + 128));
np = nodes + nodes_size;
nodes_size += 128;
(void) memset((char *) np, 0, sizeof(node_t) << 7);
}
loc = nodes_used++;
np = nodes + loc;
np->kids = np->sibs = 0;
np->key = key;
return loc;
}
/*
* Inserts a node in the trie.
*/
static void
trie_insert(unsigned short key, unsigned short val)
{
unsigned long i, n, t, l;
unsigned short codes[2];
/*
* Convert the incoming key into two codes to make the trie lookup more
* efficient.
*/
codes[0] = (key >> 8) & 0xff;
codes[1] = key & 0xff;
for (i = t = 0; i < 2; i++) {
if (nodes[t].kids == 0) {
n = getnode(codes[i]);
nodes[t].kids = n;
t = n;
} else if (nodes[nodes[t].kids].key == codes[i])
t = nodes[t].kids;
else if (nodes[nodes[t].kids].key > codes[i]) {
n = getnode(codes[i]);
nodes[n].sibs = nodes[t].kids;
nodes[t].kids = n;
t = n;
} else {
t = nodes[t].kids;
for (l = t; nodes[t].sibs && nodes[t].key < codes[i]; ) {
l = t;
t = nodes[t].sibs;
}
if (nodes[t].key < codes[i]) {
n = getnode(codes[i]);
nodes[t].sibs = n;
t = n;
} else if (nodes[t].key > codes[i]) {
n = getnode(codes[i]);
nodes[n].sibs = t;
nodes[l].sibs = n;
t = n;
}
}
}
/*
* Set the value in the leaf node.
*/
nodes[t].val = val;
}
/*
* List used by the routine that parses the map lines.
*/
static list_t list;
/*
* Routine to parse each line of the mapping file.
*/
static int
add_mapping(unsigned char *line, unsigned long linelen, unsigned long lineno,
void *client_data)
{
unsigned short key, val;
/*
* Split the line into parts separted by one or more spaces or tabs.
*/
splitline((unsigned char *) " \t+", line, linelen, &list);
/*
* Check to see if the line starts with one of the keywords.
*/
if (memcmp((char *) list.field[0], "REGISTRY", 8) == 0) {
/*
* Collect the XLFD CHARSET_REGISTRY value.
*/
if (registry != 0)
free((char *) registry);
if ((val = strlen((char *) list.field[1])) == 0)
registry = 0;
else {
registry = (char *) malloc(val + 1);
(void) memcpy(registry, (char *) list.field[1], val + 1);
}
return 0;
}
if (memcmp((char *) list.field[0], "ENCODING", 8) == 0) {
/*
* Collect the XLFD CHARSET_ENCODING value.
*/
if (encoding != 0)
free((char *) encoding);
if ((val = strlen((char *) list.field[1])) == 0)
encoding = 0;
else {
encoding = (char *) malloc(val + 1);
(void) memcpy(encoding, (char *) list.field[1], val + 1);
}
return 0;
}
/*
* Get the second field value as the key (the Unicode value). Always
* assume the values are in hex.
*/
key = my_atous(list.field[1], 0, 16);
val = my_atous(list.field[0], 0, 16);
trie_insert(key, val);
return 0;
}
/********************************************************************
*
* API for mapping table support.
*
********************************************************************/
int
otf2bdf_load_map(FILE *in)
{
unsigned long lineno;
/*
* Allocate some nodes initially.
*/
if (nodes_size == 0) {
nodes = (node_t *) malloc(sizeof(node_t) << 7);
nodes_size = 128;
}
/*
* Reset the trie in case more than one gets loaded for some reason.
*/
if (nodes_size > 0)
(void) memset((char *) nodes, 0, sizeof(node_t) * nodes_size);
nodes_used = 1;
return scanlines(fileno(in), add_mapping, 0, &lineno);
}
/*
* Routine that deallocates the mapping trie.
*/
void
otf2bdf_free_map(void)
{
if (registry != 0)
free((char *) registry);
if (encoding != 0)
free((char *) encoding);
registry = encoding = 0;
if (list.size > 0)
free((char *) list.field);
list.size = list.used = 0;
if (nodes_size > 0)
free((char *) nodes);
nodes_size = nodes_used = 0;
}
/*
* The routine that actually remaps the code by looking it up in the trie.
*/
int
otf2bdf_remap(unsigned short *code)
{
unsigned long i, n, t;
unsigned short c, codes[2];
/*
* If no mapping table was loaded, then simply return the code.
*/
if (nodes_used == 0)
return 1;
c = *code;
codes[0] = (c >> 8) & 0xff;
codes[1] = c & 0xff;
for (i = n = 0; i < 2; i++) {
t = nodes[n].kids;
if (t == 0)
return 0;
for (; nodes[t].sibs && nodes[t].key != codes[i]; t = nodes[t].sibs);
if (nodes[t].key != codes[i])
return 0;
n = t;
}
*code = nodes[n].val;
return 1;
}
void
otf2bdf_remap_charset(char **registry_name, char **encoding_name)
{
if (registry_name != 0)
*registry_name = registry;
if (encoding_name != 0)
*encoding_name = encoding;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -