peterhinch / micropython-font-to-py

A Python 3 utility to convert fonts to Python source capable of being frozen as bytecode
MIT License
368 stars 67 forks source link

Support for BDF files #31

Closed enigmaniac closed 3 years ago

enigmaniac commented 3 years ago

Add support to convert bitmap BDF fonts to micropython fonts. Makes it possible to use BDF bitmap fonts developped for other embedded architectures, eg https://github.com/olikraus/u8g2/wiki/fntlistall

peterhinch commented 3 years ago

Three comments.

Firstly the BDF format is over 30 years old and obsolescent. I think if we are going to support bitmapped font files we should also support its replacement, PCF.

Secondly I think the handling of height is not ideal. With a bitmapped font the height is encoded in the file. Having the user specify a height makes no sense. I think the height arg should be ignored, with the height always being retrieved from the file as you do when height==0.

Finally I'm not keen on the use of the get_dimensions method. I am not a fonts guru. The iterative approach to determining height is a part of my code which I'd love to rewrite if some expert showed me a way. Also the iterative determination of max_ascent and max_descent. I can't help feeling that (for scalable fonts) there is a better way.

For bitmaps the dimensions are encoded in the file. Determining max_ascent etc does not require iterating through the character set: it is in the file header. There must be a more efficient way to determine these dimensions. Perhaps an alternative get_bitmap_dimensions method could be devised for BDF and PCF files. This would have the additional advantage of remaining unchanged should I rewrite get_dimensions.

enigmaniac commented 3 years ago

Thanks Peter! Some additional thoughts / rationale on design choices:

PCF: Should be easy enough, as PCF is supported natively in FreeType. I started with BDF, since this still seems like the default for bitmap fonts used in other embedded projects, and my original objective was to be able to leverage the many smaller-sized bitmap fonts already available. I'll play around with adding PCF support soon.

Height handling: I'd originally planned to ignore the height as suggested. But BDF (and PCF) fonts can actually have multiple sizes embedded in a single file. This height = 0 approach allows for both automated selection of the first available size, but also for the user to specify an alternate size. Otherwise there wouldn't be any way to access other sizes. I should probably do some validation to make sure the size specified by the user is actually available. Will add that.

get_dimensions: Yes, this deserves its own approach for bitmap files. Not a font expert either, but I'll play around with it. Am I correct that the key outputs are self.height self._max_ascent (for baseline setting), and max_width ?

peterhinch commented 3 years ago

Also self._max_descent.

peterhinch commented 3 years ago

I've pushed a first pass at this. No docs yet, but font_to_py now accepts .PCF or .BDF files. Height should be specified as 0: any other value will be ignored and produce a warning message. I'd be glad of any comments. Dimensions are retrieved from the file and are currently printed out as a debugging aid.

Thank you for this very worthwhile suggestion. At small sizes these hand crafted bitmaps work very much better than scaled TTF or ODF files. The thought of supporting them in this way hadn't occurred to me but it seems straightforward and so far has produced good results.

peterhinch commented 3 years ago

I've now pushed an update to master (with updated docs) so I think we can close this. Thanks again for the ideas: these tiny bitmapped fonts work very nicely on my displays.