Bug 205707

Summary: Improve parsing of BDFs by vtfontcvt
Product: Base System Reporter: Mikhail Teterin <mi>
Component: binAssignee: freebsd-bugs mailing list <bugs>
Status: New ---    
Severity: Affects Only Me CC: dmitry.wagin, emaste, henry.hu.sh
Priority: --- Keywords: patch, vt
Version: 10.2-STABLE   
Hardware: Any   
OS: Any   
Attachments:
Description Flags
Allow BDF-characters to have less than 16 rows
none
Allow BDF-characters to appear out of order
none
read character size from BBX entry
none
read FONTBOUNDINGBOX and BBX, handle other DWIDTH
none
fix x-position handling
none
More complex patch none

Description Mikhail Teterin freebsd_committer 2015-12-30 00:12:56 UTC
Created attachment 164832 [details]
Allow BDF-characters to have less than 16 rows

The current implementation is somewhat naive in assuming, the bitmaps will always contain exactly 16 rows. The assumption is not verified resulting in cryptic failure messages trying to parse a 8x13 font, for example.

The attached patch fixes this -- it parses the hex rows until it encounters the ENDCHAR-keyword or reads the 16 rows (the hard-coded constant currently in place).

This allows me to convert the KOI8-U font (koi8x13.bdf) from the x11-fonts/geminifonts port. Not that the result is very useful -- presumably, because non-UTF locales aren't supported yet.
Comment 1 Mikhail Teterin freebsd_committer 2015-12-30 00:17:35 UTC
Created attachment 164833 [details]
Allow BDF-characters to appear out of order

I made these changes locally, because the utility kept rejecting my font with the "Bad ordering" error. Although it turned out, the error was bogus and due simply to the misparsing addressed by the other patch, these hunks may still be useful in case a BDF with misordered characters is encountered by someone else.
Comment 2 Ed Maste freebsd_committer 2015-12-30 02:25:11 UTC
> The current implementation is somewhat naive in assuming, the bitmaps will always contain exactly 16 rows. The assumption is not verified resulting in cryptic failure messages trying to parse a 8x13 font, for example.

Note that you can specify the height and width with -h and -w, but I agree that it's a bit silly to require it to be specified, and we should provide a useful error message if parsing fails.
Comment 3 Mikhail Teterin freebsd_committer 2015-12-30 06:33:53 UTC
(In reply to Ed Maste from comment #2)
> we should provide a useful error message if parsing fails.

Well, my changes make the function accept arbitrary number of rows UP TO the height. I don't know, if BDF-format allows different characters in the same file to have different heights, but with my patch the utility will be better prepared to handle such cases...
Comment 4 Ed Maste freebsd_committer 2016-03-28 14:13:07 UTC
Created attachment 168728 [details]
read character size from BBX entry
Comment 5 Ed Maste freebsd_committer 2016-03-28 14:18:39 UTC
(In reply to Mikhail Teterin from comment #3)

> I don't know, if BDF-format allows different characters in the same file to
> have different heights, but with my patch the utility will be better prepared
> to handle such cases...

I agree that a cryptic error message is unacceptable.

However, in the case of just stopping upon ENDCHAR the result with a 13 row .bdf will still be a 16x8 .fnt font that has the final 3 rows empty. This is probably not what is desired.

I've attached a patch that might be part of the solution - reading the height and width from the BBX entry in the font.

It doesn't fully work with koi8x13.bdf because most glyphs are 13x8 but there is one 9x6 and one 13x9.
Comment 6 Henry Hu 2017-03-18 20:35:05 UTC
Created attachment 180939 [details]
read FONTBOUNDINGBOX and BBX, handle other DWIDTH

I tried to convert fonts in x11-fonts/wqy (an open source Chinese bitmap font) for use with vt. The original fonts are in pcf, I used https://github.com/ganaware/pcf2bdf to convert them to bdf.

I found that the original assumptions in the code have several problems:
* Assuming DWIDTH = width or width * 2
Actually there can be varying widths. For wqy, there are DWIDTH between 2-13 for the 10pt font, and 2-12 for the 9pt font.
* Assuming number of lines in the bitmap == height
Actually it usually equals to the height in the BBX line.

This patch fixes the problems by:
* Read the FONTBOUNDINGBOX line.
This gives us the baseline position. If offset_y in this line is -3, we need to reserve 3 lines at the bottom.
* Read the BBX line.
The offset_x and offset_y information in this line tells us where to position the glyph. For example, if offset_y == -2, the font should be positioned 2 lines below the baseline.
* Position the glyph at the correct place.
The starting line is calculated by:
    line_y = height + font_y - bb_h - bb_y + i;
The font's baseline (bottom) is height + font_y, the glyph's baseline is height + font_y - bb_y.

The font generated by this patch is used successfully with the wqy font on the vt terminal to display chinese characters. There seems to be problems for alphabet characters which are double-width (the 'W' in wqy font), so the working configuration requires a width of at least 10 pixels.
Comment 7 Henry Hu 2017-03-18 22:25:06 UTC
Created attachment 180943 [details]
fix x-position handling

The previous patch has some problems in deciding the x-position of the character.

The input line seems to have howmany(bb_w, 8) bytes. The bitmap is aligned to the left, and occupies the left bb_w bits.
The first shift moves the bitmap to the right, now it's right aligned to bit 0.
The parse_bitmap_line() function seems to assume that the glyph occupies the top dwidth bits. To put the character at bb_x position, the number of bits at right is howmany(dwidth, 8) * 8 - bb_x - bb_w.
Comment 8 Dmitry Wagin 2018-06-27 09:02:16 UTC
Created attachment 194668 [details]
More complex patch

Added support all font width, improve parsing of BDFs (FONT, FONTBOUNDINGBOX, BBX etc)
Comment 9 Dmitry Wagin 2018-06-27 09:02:53 UTC
*** Bug 228288 has been marked as a duplicate of this bug. ***