pythoncoder wrote:v923z wrote:I was wondering, how much memory overhead a dictionary adds...
That's an interesting technique: I didn't realise
convert could do that. How are you dealing with the issue of alignment?
I am not sure I see what you mean: if it is the vertical alignment of fonts (i.e., the baseline of characters), then the bitmap produced by convert is automatically aligned.
pythoncoder wrote:
My code aims to produce, given a nominal font size, a set of bitmaps with the vertical alignment pre-computed. This is for performance reasons: the aim is that rendering should be fast and simple. The alternative approach is to store the metrics with each glyph and figure out the positioning at render time. While this is probably OK for small displays, it may be too slow for large ones capable of displaying substantial amounts of text.
I believe, what I have is pretty similar to yours: each character is in a field of fixed height, and its position inside that field is stored in the bytearray itself, so no extra computation is required at run time. I don't think it would make too much sense to chop off the white spaces below and above the characters, and store the size of that as extra. If you look at the output of draw_string in the notebook, you can see that the characters are properly aligned.
pythoncoder wrote:While I appreciate the flexibility of using a dict, again there may be a performance issue: a dict lookup is likely to be slower than handling two levels of indirection, although I haven't tested this.
This is absolutely true, though I would mention that the rendering itself is orders of magnitude slower than the lookup, so it doesn't really matter.
pythoncoder wrote:As for RAM use, this can be fixed with frozen bytecode. My solution produces bytes objects which are immutable. This means that they can be accessed in place, consuming almost no RAM. A dict is mutable, so even if you freeze the bytecode, the runtime will pull the dict into RAM (because Python allows you to change its contents).
I have figured that the dictionary is rather expensive. If I take 32-pt FreeSans fonts for 80 standard characters, I consume something like 30 kB of RAM, while the actual data is only 7.3kB, and the frozen bytecode takes up something like 20 kB.
One has to add, though, that here I am talking about the costs of carrying the whole class, which contains the dictionary, plus the height function. However, the class can't probably be so expensive. I don't think that there is too much difference between
Code: Select all
def height():
return 32
font = {'1': b'\x00....'}
and
Code: Select all
class Font(object):
def __init__(self):
self.font = {'1': b'\x00....'}
def height():
return 32
while the first form becomes somewhat problematic, if one has to use two kinds of fonts at the same time: you'll never know whose height the function height() returns...