robhagemans / monobit

Tools for working with monochrome bitmap fonts
MIT License
208 stars 11 forks source link

py: export as python byte array #9

Closed pluess closed 2 years ago

pluess commented 2 years ago

I added the the possibility to export python code. It's a modified copy of the c export.

Unfortunately I did not manage to read the generated python code again. But I don't know if that's necessary.

ernst@Schamgar ~/Dropbox/Source/python/monobit
[632] : python3 convert.py c64-german.draw c64_german.py
INFO: Loading `c64-german.draw` on `.` as hexdraw
INFO: Saving `c64_german.py` on `.` as Python source.
ernst@Schamgar ~/Dropbox/Source/python/monobit
[635] : python3 convert.py --debug c64_german.py c64_german.c
DEBUG: Opening file `c64_german.py` for mode 'r'.
DEBUG: Exiting <Stream name='c64_german.py' mode='r'> with reference count 0.
DEBUG: Opening DirContainer container `.` for 'r'.
DEBUG: Opening file `c64_german.py` for mode 'r'.
INFO: Loading `c64_german.py` on `.` as Python source
DEBUG: Exiting <Stream name='c64_german.py' mode='r'> with reference count 0.
DEBUG: Exiting <DirContainer name='.' mode='r'> with reference count 0.
ERROR: load_py() missing 1 required keyword-only argument: 'identifier'
Traceback (most recent call last):
  File "/Users/ernst/Dropbox/Source/python/monobit/monobit/storage.py", line 63, in open_location
    with open_container(stream, mode, overwrite=overwrite) as container:
  File "/Users/ernst/Dropbox/Source/python/monobit/monobit/containers.py", line 45, in open_container
    container_type = _identify_container(file, mode, overwrite)
  File "/Users/ernst/Dropbox/Source/python/monobit/monobit/containers.py", line 65, in _identify_container
    raise ContainerFormatError('Expected container format, got non-container stream.')
monobit.containers.ContainerFormatError: Expected container format, got non-container stream.

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/Users/ernst/Dropbox/Source/python/monobit/convert.py", line 92, in <module>
    pack = monobit.load(infile, format=args.from_, **loader_args.pick(args))
  File "/Users/ernst/Dropbox/Source/python/monobit/monobit/storage.py", line 81, in load
    return _load_from_file(stream, container, format, **kwargs)
  File "/Users/ernst/Dropbox/Source/python/monobit/monobit/storage.py", line 90, in _load_from_file
    fonts = loader(instream, where, **kwargs)
  File "/Users/ernst/Dropbox/Source/python/monobit/monobit/scripting.py", line 35, in _scriptable_func
    result = func(*args, **kwargs)
TypeError: load_py() missing 1 required keyword-only argument: 'identifier'
ernst@Schamgar ~/Dropbox/Source/python/monobit
robhagemans commented 2 years ago

Thanks, this is a useful addition! A few issues:

pluess commented 2 years ago

I refactored the c an python output into one common method and also took the other comments into account.

pluess commented 2 years ago

About commit https://github.com/robhagemans/monobit/pull/9/commits/5310d7d7d84c91275967b734d44a2bc8146ffce4 You are right. My fix is incomplete and most likely entierly in the wrong place.

I converted https://github.com/robhagemans/hoard-of-bitfonts/blob/master/acorn/saa5050.draw to python:

python3 convert.py --overwrite saa5050.draw saa5050.py
INFO: Loading `saa5050.draw` on `.` as hexdraw
INFO: Saving `saa5050.py` on `.` as Python source.

The resulting bytes in the python code do not look right to me (see saa5050.py) . The font is 6 pixels wide. To fit into one byte they are right padded with zeros.

If you look at the second line in saa5050.py you see some 0x10 (0b00010000) of the second character. This adds two bits to the font and makes a 8x8 out of a 6x8 font.

So

21:
    ------
    ---#--
    ---#--
    ---#--
    ---#--
    ---#--
    ------
    ---#--
    ------
    ------

is actually converted into

21:
    --------
    ---#----
    ---#----
    ---#----
    ---#----
    ---#----
    --------
    ---#----
    --------
    --------

If this is really a bug and not me having wrong expectations, then this should probably be fixed while reading the draw file and not when writing the c or python file.

robhagemans commented 2 years ago

Thanks! I need to have a play with the PR but this looks right. Though I'll probably remove the typing hints as elsewhere I use annotations specifically to support the script interface so having them here for typing clashes a bit.

Re the padding, I don't think it's a bug, just a limitation of this particular storage format which by design has little internal structure and no metadata. Storing a font in this way is always going to limit you to integer multiples of 8 pixels for the width; the width itself is not encoded in the font. So you can either left-pad or right-pad, either way you're left with two additional empty columns. I don't think it's worth trying to somehow encode the width in some way, that would just make things more complicated and less generic. It would be up to whoever uses the c or python code to store and use the metadata they need alongside the bitmap.

robhagemans commented 2 years ago

This has been merged.