FreeBSD Bugzilla – Attachment 193447 Details for
Bug 228288
[patch] usr.bin/vtfontcvt/vtfontcvt.c: added support big font width, detect .bdf font size and etc
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Help
|
New Account
|
Log In
Remember
[x]
|
Forgot Password
Login:
[x]
[patch]
patch
vtfontcvt.c.diff (text/plain), 10.64 KB, created by
Dmitry Wagin
on 2018-05-16 08:34:54 UTC
(
hide
)
Description:
patch
Filename:
MIME Type:
Creator:
Dmitry Wagin
Created:
2018-05-16 08:34:54 UTC
Size:
10.64 KB
patch
obsolete
>--- usr.bin/vtfontcvt/vtfontcvt.c.orig >+++ usr.bin/vtfontcvt/vtfontcvt.c >@@ -44,11 +44,13 @@ > #include <string.h> > #include <unistd.h> > >-#define VFNT_MAPS 4 >-#define VFNT_MAP_NORMAL 0 >-#define VFNT_MAP_NORMAL_RH 1 >-#define VFNT_MAP_BOLD 2 >-#define VFNT_MAP_BOLD_RH 3 >+#define VFNT_MAPS 4 >+#define VFNT_MAP_NORMAL 0 >+#define VFNT_MAP_NORMAL_RIGHT 1 >+#define VFNT_MAP_BOLD 2 >+#define VFNT_MAP_BOLD_RIGHT 3 >+#define VFNT_MAXGLYPHS 131072 >+#define VFNT_MAXDIMENSION 128 > > static unsigned int width = 8, wbytes, height = 16; > >@@ -63,10 +65,10 @@ > TAILQ_HEAD(glyph_list, glyph); > static SLIST_HEAD(, glyph) glyph_hash[FONTCVT_NHASH]; > static struct glyph_list glyphs[VFNT_MAPS] = { >- TAILQ_HEAD_INITIALIZER(glyphs[0]), >- TAILQ_HEAD_INITIALIZER(glyphs[1]), >- TAILQ_HEAD_INITIALIZER(glyphs[2]), >- TAILQ_HEAD_INITIALIZER(glyphs[3]), >+ TAILQ_HEAD_INITIALIZER(glyphs[0]), >+ TAILQ_HEAD_INITIALIZER(glyphs[1]), >+ TAILQ_HEAD_INITIALIZER(glyphs[2]), >+ TAILQ_HEAD_INITIALIZER(glyphs[3]), > }; > static unsigned int glyph_total, glyph_count[4], glyph_unique, glyph_dupe; > >@@ -79,13 +81,13 @@ > > TAILQ_HEAD(mapping_list, mapping); > static struct mapping_list maps[VFNT_MAPS] = { >- TAILQ_HEAD_INITIALIZER(maps[0]), >- TAILQ_HEAD_INITIALIZER(maps[1]), >- TAILQ_HEAD_INITIALIZER(maps[2]), >- TAILQ_HEAD_INITIALIZER(maps[3]), >+ TAILQ_HEAD_INITIALIZER(maps[0]), >+ TAILQ_HEAD_INITIALIZER(maps[1]), >+ TAILQ_HEAD_INITIALIZER(maps[2]), >+ TAILQ_HEAD_INITIALIZER(maps[3]), > }; > static unsigned int mapping_total, map_count[4], map_folded_count[4], >- mapping_unique, mapping_dupe; >+ mapping_unique, mapping_dupe; > > static void > usage(void) >@@ -103,6 +105,7 @@ > > if ((m = malloc(size)) == NULL) > errx(1, "memory allocation failure"); >+ > return (m); > } > >@@ -137,7 +140,7 @@ > struct mapping *mp_bold, *mp_normal, *mp_temp; > unsigned normal_map_idx = map_idx - VFNT_MAP_BOLD; > >- assert(map_idx == VFNT_MAP_BOLD || map_idx == VFNT_MAP_BOLD_RH); >+ assert(map_idx == VFNT_MAP_BOLD || map_idx == VFNT_MAP_BOLD_RIGHT); > mp_normal = TAILQ_FIRST(&maps[normal_map_idx]); > TAILQ_FOREACH_SAFE(mp_bold, &maps[map_idx], m_list, mp_temp) { > while (mp_normal->m_char < mp_bold->m_char) >@@ -153,6 +156,7 @@ > free(mp_bold); > mapping_dupe++; > } >+ > return (0); > } > >@@ -183,6 +187,10 @@ > SLIST_INSERT_HEAD(&glyph_hash[hash], gl, g_hash); > > glyph_unique++; >+ >+ if (glyph_unique > VFNT_MAXGLYPHS) >+ errx(1, "Too large number of glyphs %u!", glyph_unique); >+ > return (gl); > } > >@@ -201,8 +209,7 @@ > return (1); > if (bytes_r != NULL) { > gl = add_glyph(bytes_r, map_idx + 1, 0); >- if (add_mapping(gl, curchar, >- map_idx + 1) != 0) >+ if (add_mapping(gl, curchar, map_idx + 1) != 0) > return (1); > } > } >@@ -211,60 +218,79 @@ > > > static int >-parse_bitmap_line(uint8_t *left, uint8_t *right, unsigned int line, >+parse_bitmap_line(uint8_t *left, uint8_t *right, uint8_t *line, > unsigned int dwidth) > { >- uint8_t *p; >- unsigned int i, subline; >+ unsigned int s, i; > >- if (dwidth != width && dwidth != width * 2) >- errx(1, "Bitmap with unsupported width %u!", dwidth); >+ s = wbytes * 8 - width; > >- /* Move pixel data right to simplify splitting double characters. */ >- line >>= (howmany(dwidth, 8) * 8) - dwidth; >+ memcpy(left, line, wbytes); >+ *(left + wbytes - 1) &= 0xFF << s; > >- for (i = dwidth / width; i > 0; i--) { >- p = (i == 2) ? right : left; >- >- subline = line & ((1 << width) - 1); >- subline <<= (howmany(width, 8) * 8) - width; >- >- if (wbytes == 1) { >- *p = subline; >- } else if (wbytes == 2) { >- *p++ = subline >> 8; >- *p = subline; >- } else { >- errx(1, "Unsupported wbytes %u!", wbytes); >+ if (dwidth > width) { /* Double-width character. */ >+ for (i = 0; i < wbytes; i++) { >+ *(right + i) = *(line + wbytes + i - 1) << (8 - s); >+ *(right + i) |= *(line + wbytes + i) >> s; > } >- >- line >>= width; >+ *(right + wbytes - 1) &= 0xFF << s; > } > > return (0); > } > >+static void >+set_width(int v) >+{ >+ if (v < 1 || v > VFNT_MAXDIMENSION) >+ errx(1, "invalid width %d", v); >+ width = v; >+ wbytes = howmany(width, 8); >+} >+ >+static void >+set_height(int v) >+{ >+ if (v < 1 || v > VFNT_MAXDIMENSION) >+ errx(1, "invalid height %d", v); >+ height = v; >+} >+ > static int > parse_bdf(FILE *fp, unsigned int map_idx) > { > char *ln; > size_t length; >- uint8_t bytes[wbytes * height], bytes_r[wbytes * height]; >- unsigned int curchar = 0, dwidth = 0, i, line; >+ uint8_t *bytes = NULL, *bytes_r = NULL, *line = NULL; >+ unsigned int curchar = 0, dwidth = 0, dwbytes = 0, i, j; >+ int rv = 0; > > while ((ln = fgetln(fp, &length)) != NULL) { > ln[length - 1] = '\0'; > >- if (strncmp(ln, "ENCODING ", 9) == 0) { >+ if (sscanf(ln, "FONTBOUNDINGBOX %u %u", &width, &height)) { >+ if (bytes != NULL) >+ errx(1, "malformed input: " >+ "FONTBOUNDINGBOX tag after font data"); >+ set_width(width); >+ set_height(height); >+ } else if (strncmp(ln, "ENCODING ", 9) == 0) { > curchar = atoi(ln + 9); >- } >- >- if (strncmp(ln, "DWIDTH ", 7) == 0) { >+ } else if (strncmp(ln, "DWIDTH ", 7) == 0) { > dwidth = atoi(ln + 7); >- } >- >- if (strncmp(ln, "BITMAP", 6) == 0 && >+ dwbytes = howmany(dwidth, 8); >+ if (dwidth != width && dwidth != width * 2) >+ errx(1, "Bitmap with unsupported width %u!", >+ dwidth); >+ } else if (strncmp(ln, "BITMAP", 6) == 0 && > (ln[6] == ' ' || ln[6] == '\0')) { >+ if (bytes == NULL) { >+ bytes = xmalloc(wbytes * height); >+ bytes_r = xmalloc(wbytes * height); >+ line = xmalloc(wbytes * 2); >+ } >+ if (dwidth == 0) >+ errx(1, "malformed input: Bitmap without DWIDTH!"); > /* > * Assume that the next _height_ lines are bitmap > * data. ENDCHAR is allowed to terminate the bitmap >@@ -277,44 +303,49 @@ > ln[length - 1] = '\0'; > if (strcmp(ln, "ENDCHAR") == 0) { > memset(bytes + i * wbytes, 0, >- (height - i) * wbytes); >+ (height - i) * wbytes); > memset(bytes_r + i * wbytes, 0, >- (height - i) * wbytes); >+ (height - i) * wbytes); > break; > } >- sscanf(ln, "%x", &line); >- if (parse_bitmap_line(bytes + i * wbytes, >- bytes_r + i * wbytes, line, dwidth) != 0) >- return (1); >+ if (strlen(ln) < dwbytes * 2) >+ errx(1, "malformed input: Broken bitmap, character %u!", >+ curchar); >+ for (j = 0; j < dwbytes; j++) { >+ unsigned int val; >+ if (sscanf(ln + j * 2, "%2x", &val) == 0) >+ break; >+ *(line + j) = (uint8_t) val; >+ } >+ rv = parse_bitmap_line(bytes + i * wbytes, >+ bytes_r + i * wbytes, line, dwidth); >+ if (rv != 0) >+ goto out; > } > >- if (add_char(curchar, map_idx, bytes, >- dwidth == width * 2 ? bytes_r : NULL) != 0) >- return (1); >+ rv = add_char(curchar, map_idx, bytes, >+ dwidth != width ? bytes_r : NULL); >+ if (rv != 0) >+ goto out; >+ dwidth = 0; > } > } > >- return (0); >-} >+out: >+ free(bytes); >+ free(bytes_r); >+ free(line); > >-static void >-set_width(int w) >-{ >- >- if (w <= 0 || w > 128) >- errx(1, "invalid width %d", w); >- width = w; >- wbytes = howmany(width, 8); >+ return (rv); > } > > static int > parse_hex(FILE *fp, unsigned int map_idx) > { > char *ln, *p; >- char fmt_str[8]; > size_t length; >- uint8_t *bytes = NULL, *bytes_r = NULL; >- unsigned curchar = 0, i, line, chars_per_row, dwidth; >+ uint8_t *bytes = NULL, *bytes_r = NULL, *line = NULL; >+ unsigned int curchar = 0, dwidth, dwbytes, i, j, chars_per_row; > int rv = 0; > > while ((ln = fgetln(fp, &length)) != NULL) { >@@ -323,7 +354,7 @@ > if (strncmp(ln, "# Height: ", 10) == 0) { > if (bytes != NULL) > errx(1, "malformed input: Height tag after font data"); >- height = atoi(ln + 10); >+ set_height(atoi(ln + 10)); > } else if (strncmp(ln, "# Width: ", 9) == 0) { > if (bytes != NULL) > errx(1, "malformed input: Width tag after font data"); >@@ -332,36 +363,48 @@ > if (bytes == NULL) { > bytes = xmalloc(wbytes * height); > bytes_r = xmalloc(wbytes * height); >+ line = xmalloc(wbytes * 2); > } >+ > /* ln is guaranteed to have a colon here. */ > p = strchr(ln, ':') + 1; >+ > chars_per_row = strlen(p) / height; >- dwidth = width; >- if (chars_per_row / 2 > (width + 7) / 8) >- dwidth *= 2; /* Double-width character. */ >- snprintf(fmt_str, sizeof(fmt_str), "%%%ux", >- chars_per_row); >+ if (chars_per_row < wbytes * 2) >+ errx(1, "malformed input: Broken bitmap, character %06x.", curchar); >+ dwidth = width * 2; >+ dwbytes = howmany(dwidth, 8); >+ if (chars_per_row < dwbytes * 2 || dwidth <= 8) { >+ dwidth = width; /* Single-width character. */ >+ dwbytes = wbytes; >+ } > > for (i = 0; i < height; i++) { >- sscanf(p, fmt_str, &line); >- p += chars_per_row; >- if (parse_bitmap_line(bytes + i * wbytes, >- bytes_r + i * wbytes, line, dwidth) != 0) { >- rv = 1; >- goto out; >+ for (j = 0; j < dwbytes; j++) { >+ unsigned int val; >+ if (sscanf(p + j * 2, "%2x", &val) == 0) >+ break; >+ *(line + j) = (uint8_t) val; > } >+ rv = parse_bitmap_line(bytes + i * wbytes, >+ bytes_r + i * wbytes, line, dwidth); >+ if (rv != 0) >+ goto out; >+ p += dwbytes * 2; > } > >- if (add_char(curchar, map_idx, bytes, >- dwidth == width * 2 ? bytes_r : NULL) != 0) { >- rv = 1; >+ rv = add_char(curchar, map_idx, bytes, >+ dwidth != width ? bytes_r : NULL); >+ if (rv != 0) > goto out; >- } > } > } >+ > out: > free(bytes); > free(bytes_r); >+ free(line); >+ > return (rv); > } > >@@ -383,6 +426,7 @@ > else > rv = parse_bdf(fp, map_idx); > fclose(fp); >+ > return (rv); > } > >@@ -496,9 +540,9 @@ > > if (write_glyphs(fp) != 0 || > write_mappings(fp, VFNT_MAP_NORMAL) != 0 || >- write_mappings(fp, 1) != 0 || >+ write_mappings(fp, VFNT_MAP_NORMAL_RIGHT) != 0 || > write_mappings(fp, VFNT_MAP_BOLD) != 0 || >- write_mappings(fp, 3) != 0) { >+ write_mappings(fp, VFNT_MAP_BOLD_RIGHT) != 0) { > perror(filename); > fclose(fp); > return (1); >@@ -548,7 +592,7 @@ > int > main(int argc, char *argv[]) > { >- int ch, val, verbose = 0; >+ int ch, verbose = 0; > > assert(sizeof(struct file_header) == 32); > assert(sizeof(struct file_mapping) == 8); >@@ -556,16 +600,13 @@ > while ((ch = getopt(argc, argv, "h:vw:")) != -1) { > switch (ch) { > case 'h': >- val = atoi(optarg); >- if (val <= 0 || val > 128) >- errx(1, "Invalid height %d", val); >- height = val; >+ height = atoi(optarg); > break; > case 'v': > verbose = 1; > break; > case 'w': >- set_width(atoi(optarg)); >+ width = atoi(optarg); > break; > case '?': > default: >@@ -578,7 +619,8 @@ > if (argc < 2 || argc > 3) > usage(); > >- wbytes = howmany(width, 8); >+ set_width(width); >+ set_height(height); > > if (parse_file(argv[0], VFNT_MAP_NORMAL) != 0) > return (1); >@@ -592,7 +634,7 @@ > } > number_glyphs(); > dedup_mapping(VFNT_MAP_BOLD); >- dedup_mapping(VFNT_MAP_BOLD_RH); >+ dedup_mapping(VFNT_MAP_BOLD_RIGHT); > fold_mappings(0); > fold_mappings(1); > fold_mappings(2);
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 228288
: 193447 |
194017