--- vtfontcvt.c (版本 315489) +++ vtfontcvt.c (工作副本) @@ -217,13 +217,13 @@ uint8_t *p; unsigned int i, subline; - if (dwidth != width && dwidth != width * 2) - errx(1, "Bitmap with unsupported width %u!", dwidth); + if (dwidth > width * 2) + errx(1, "Character too wide %u!", dwidth); /* Move pixel data right to simplify splitting double characters. */ line >>= (howmany(dwidth, 8) * 8) - dwidth; - for (i = dwidth / width; i > 0; i--) { + for (i = howmany(dwidth, width); i > 0; i--) { p = (i == 2) ? right : left; subline = line & ((1 << width) - 1); @@ -251,10 +251,16 @@ size_t length; uint8_t bytes[wbytes * height], bytes_r[wbytes * height]; unsigned int curchar = 0, dwidth = 0, i, line; + int bb_x = 0, bb_y = 0, bb_w = width, bb_h = height, line_y; + int font_w = width, font_h = height, font_x = 0, font_y = 0; while ((ln = fgetln(fp, &length)) != NULL) { ln[length - 1] = '\0'; + if (strncmp(ln, "FONTBOUNDINGBOX ", 16) == 0) { + sscanf(ln + 16, "%d %d %d %d", &font_w, &font_h, &font_x, &font_y); + } + if (strncmp(ln, "ENCODING ", 9) == 0) { curchar = atoi(ln + 9); } @@ -263,20 +269,41 @@ dwidth = atoi(ln + 7); } + if (strncmp(ln, "BBX ", 4) == 0) { + sscanf(ln + 4, "%d %d %d %d", &bb_w, &bb_h, &bb_x, &bb_y); + } + if (strncmp(ln, "BITMAP", 6) == 0 && (ln[6] == ' ' || ln[6] == '\0')) { - for (i = 0; i < height; i++) { + bzero(bytes, sizeof(bytes)); + bzero(bytes_r, sizeof(bytes_r)); + + for (i = 0; ; i++) { if ((ln = fgetln(fp, &length)) == NULL) errx(1, "Unexpected EOF!"); + if (strncmp(ln, "ENDCHAR", 7) == 0) { + break; + } + line_y = height + font_y - bb_h - bb_y + i; + if ((line_y < 0) || ((unsigned int)line_y >= height)) { + continue; + } + + if (bb_x > 0) { + line >>= bb_x; + } else { + line <<= -bb_x; + } + ln[length - 1] = '\0'; sscanf(ln, "%x", &line); - if (parse_bitmap_line(bytes + i * wbytes, - bytes_r + i * wbytes, line, dwidth) != 0) + if (parse_bitmap_line(bytes + line_y * wbytes, + bytes_r + line_y * wbytes, line, dwidth) != 0) return (1); } if (add_char(curchar, map_idx, bytes, - dwidth == width * 2 ? bytes_r : NULL) != 0) + dwidth > width ? bytes_r : NULL) != 0) return (1); } }