| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408 |
- /*
- bdf_map.c
-
- select and map glyphs
-
- Syntax:
- maplist := <mapcmd> { "," <mapcmd> }
- mapcmd := <default> | <maprange> | <exclude>
- default := "*"
- maprange := <range> [ ">" <num> ]
- exclude := "~" <range>
- kern_exclude := "x" <range>
- range := <num> [ "-" <num> ]
- num := <hexnum> | <decnum>
- hexnum := "$" <hexdigit> { <hexdigit> }
- decnum := <decdigit> { <decdigit> }
- decdigit := "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9"
- hexdigit := "a" | "b" | "c" | "d" | "e" | "f" | "A" | "B" | "C" | "D" | "E" | "F" | <decdigit>
-
- { }: zero, one ore more
- [ ]: zero or once
- |: alternative
-
- */
- #include "bdf_font.h"
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <sys/types.h>
- #include <sys/stat.h>
- #include <unistd.h>
- static long range_from;
- static long range_to;
- static int is_exclude;
- static int is_kern_exclude;
- static long map_to;
- static void skip_space(const char **s)
- {
- for(;;)
- {
- if ( **s == '\0' )
- break;
- if ( **s > ' ' )
- break;
- (*s)++;
- }
- }
- static long get_dec(const char **s)
- {
- long v = 0;
- for(;;)
- {
- if ( (**s) >= '0' && (**s) <= '9' )
- {
- v*=10;
- v+= (**s)-'0';
- (*s)++;
- }
- else
- {
- break;
- }
- }
- skip_space(s);
- return v;
- }
- static long get_hex(const char **s)
- {
- long v = 0;
- for(;;)
- {
- if ( (**s) >= '0' && (**s) <= '9' )
- {
- v*=16;
- v+= (**s)-'0';
- (*s)++;
- }
- else if ( (**s) >= 'a' && (**s) <= 'f' )
- {
- v*=16;
- v+= (**s)-'a'+10;
- (*s)++;
- }
- else if ( (**s) >= 'A' && (**s) <= 'F' )
- {
- v*=16;
- v+= (**s)-'A'+10;
- (*s)++;
- }
- else
- {
- break;
- }
- }
- skip_space(s);
- return v;
- }
- static long get_num(const char **s)
- {
- if ( (**s) != '$' )
- return get_dec(s);
- (*s)++;
- skip_space(s);
- return get_hex(s);
- }
- static long get_mul(const char **s)
- {
- long v;
- v = get_num(s);
- while ( (**s) == '*' )
- {
- (*s)++;
- skip_space(s);
- v *= get_num(s);
- }
- return v;
- }
- static long get_add(const char **s)
- {
- long v;
- v = get_mul(s);
- while ( (**s) == '+' )
- {
- (*s)++;
- skip_space(s);
- v += get_mul(s);
- }
- return v;
- }
- static long get_addsub(const char **s)
- {
- long v;
- int op;
- v = get_mul(s);
- while ( (**s) == '+' || (**s) == '-' )
- {
- op = **s;
- (*s)++;
- skip_space(s);
- if ( op == '+' )
- v += get_mul(s);
- else
- v -= get_mul(s);
- }
- return v;
- }
- static void get_range(const char **s)
- {
- range_from = get_add(s);
- if ( **s != '-' )
- {
- range_to = range_from;
- }
- else
- {
- (*s)++;
- skip_space(s);
- range_to = get_add(s);
- }
- }
- static void map_cmd(const char **s)
- {
- if ( **s == '*' )
- {
- range_from = 32;
- range_to = 255;
- map_to = 32;
- is_exclude = 0;
- is_kern_exclude = 0;
-
- (*s)++;
- skip_space(s);
- }
- else if ( **s == '~' )
- {
- is_exclude = 1;
- map_to = 0; /*will be ignored */
-
- (*s)++;
- skip_space(s);
- get_range(s);
-
- }
- else if ( **s == 'x' )
- {
- is_kern_exclude = 1;
- map_to = 0; /*will be ignored */
-
- (*s)++;
- skip_space(s);
- get_range(s);
- }
- else
- {
- is_exclude = 0;
- get_range(s);
- map_to = range_from;
- if ( **s == '>')
- {
- (*s)++;
- skip_space(s);
- map_to = get_addsub(s);
- }
- }
- }
- void bf_map_cmd(bf_t *bf, const char **s)
- {
- int i;
- bg_t *bg;
- static int is_log_disabled_for_single_glyphs = 0;
-
- if ( **s == ',' || **s == '\0' )
- return;
-
- map_cmd(s);
-
- if ( range_from != range_to )
- {
- bf_Log(bf, "Map: exclude=%d from=%ld/$%lx to=%ld/$%lx map=%ld/$%lx", is_exclude, range_from, range_from, range_to, range_to, map_to, map_to);
- }
- else if ( is_log_disabled_for_single_glyphs == 0 )
- {
- bf_Log(bf, "Map: exclude=%d from=%ld/$%lx to=%ld/$%lx map=%ld/$%lx (further single glyph logs disabled)", is_exclude, range_from, range_from, range_to, range_to, map_to, map_to);
- is_log_disabled_for_single_glyphs = 1;
- }
-
-
- for( i = 0; i < bf->glyph_cnt; i++ )
- {
- bg = bf->glyph_list[i];
- if ( bg->encoding >= range_from && bg->encoding <= range_to )
- {
- if ( is_kern_exclude != 0 )
- {
- bg->is_excluded_from_kerning = 1;
- }
- else
- {
- if ( is_exclude != 0 )
- {
- bg->map_to = -1;
- }
- else
- {
- bg->map_to = bg->encoding - range_from + map_to;
- }
- }
- }
- }
-
- }
- void bf_map_list(bf_t *bf, const char **s)
- {
- int i;
- bg_t *bg;
-
- /* exclude everything first */
- for( i = 0; i < bf->glyph_cnt; i++ )
- {
- bg = bf->glyph_list[i];
- bg->map_to = -1;
- }
-
- /* process the mapping list list */
- skip_space(s);
- for(;;)
- {
- bf_map_cmd(bf, s);
- if ( **s != ',' )
- break;
- (*s)++;
- skip_space(s);
- }
- }
- void bf_Map(bf_t *bf, const char *map_cmd_list)
- {
- if ( strlen(map_cmd_list) < 1024 )
- bf_Log(bf, "Map: map_cmd_list='%s'", map_cmd_list);
- bf_map_list(bf, &map_cmd_list);
- }
- int bf_MapFile(bf_t *bf, const char *map_file_name)
- {
- struct stat buf;
- char *s;
- FILE *fp;
- if ( map_file_name == NULL )
- return 1;
- if ( map_file_name[0] == '\0' )
- return 1;
-
-
- if ( stat(map_file_name, &buf) != 0 )
- return 0;
- fp = fopen(map_file_name, "r");
- if ( fp == NULL )
- return 0;
- s = malloc(buf.st_size+1);
- if ( s == NULL )
- return 0;
- if ( fread(s, buf.st_size, 1, fp) != 1 ) {
- free(s);
- return 0;
- }
- s[buf.st_size] = '\0';
- fclose(fp);
- bf_Map(bf, s);
- free(s);
- return 1;
- }
- /* add all characters in utf8 text file to font */
- int bf_Utf8File(bf_t *bf, const char *utf8_file_name) {
- static const int utf8_verbose = 0;
- struct stat buf;
- FILE *fp;
- int byte = 0;
- uint32_t code = 0;
- int more_bytes = 0;
- int utf8_errs = 0;
- int i;
- bg_t *bg;
- if (utf8_file_name == NULL)
- return 1;
- if (utf8_file_name[0] == '\0')
- return 1;
- if (stat(utf8_file_name, &buf) != 0)
- return 0;
- fp = fopen(utf8_file_name, "r");
- if (fp == NULL)
- return 0;
- while ((byte = getc(fp)) != EOF) {
- code = 0;
- more_bytes = 0;
- if (byte <= 0x7F) {
- code = byte;
- more_bytes = 0;
- } else if ((byte & 0xE0) == 0xC0) {
- code = byte & 0x1F;
- more_bytes = 1;
- } else if ((byte & 0xF0) == 0xE0) {
- code = byte & 0x0F;
- more_bytes = 2;
- } else if ((byte & 0xF8) == 0xF0) {
- code = byte & 0x07;
- more_bytes = 3;
- } else if ((byte & 0xFC) == 0xF8) {
- code = byte & 0x03;
- more_bytes = 4;
- } else if ((byte & 0xFE) == 0xFC) {
- code = byte & 0x01;
- more_bytes = 5;
- } else {
- if (utf8_verbose)
- printf("? 0x%X\r\n", byte);
- utf8_errs++;
- continue;
- }
- while (more_bytes > 0) {
- byte = getc(fp);
- if (byte == EOF)
- break;
- if ((byte & 0xC0) != 0x80) {
- utf8_errs++;
- break;
- }
- code = (code << 6) | (byte & 0x3F);
- --more_bytes;
- }
- if (more_bytes == 0) {
- /* find glyph in font */
- for (i = 0; i < bf->glyph_cnt; i++) {
- bg = bf->glyph_list[i];
- if (bg->encoding == code) {
- if (utf8_verbose)
- printf("glyph found: 0x%X\r\n", code);
- bg->map_to = bg->encoding;
- break;
- }
- }
- if (utf8_verbose && (i == bf->glyph_cnt))
- printf("glyph not found: 0x%X\r\n", code);
- }
- }
- if (utf8_errs != 0)
- printf("%u utf8 errors\r\n", utf8_errs);
- fclose(fp);
- return 1;
- }
|