New vector font... #2536
Replies: 48 comments
-
Posted at 2020-05-13 by NebbishHacker I'd like to take a stab at the font design. Is there an average number of points per character I should try to target? As an aside, the work MaBecker's been doing on Hershey fonts looks pretty darn nifty. That would definitely be the better looking solution if it can be made performant enough. |
Beta Was this translation helpful? Give feedback.
-
Posted at 2020-05-13 by @gfwilliams That would be awesome! Well, the current vector font averages ~30 points each for the 95 available characters. If we could do that it'd roughly halve the size, but hopefully we could get a bit under. Just a note about making the fonts after sleeping on it - actually what I've done for holes in the SVG above (using one poly and going across and back to make a hole) probably isn't the best and it's a pain to work with. I think it'd be better to just use two polys and when possible try and get them so that each polygon didn't turn into multiple scanlines (eg. I'm a bit on the fence about Hershey - maybe the performance isn't too big a deal. The issue IMO is when you get to the middle-ground of 2px wide lines where it'll look quite rough using a filled polygon. Higher sizes can be made to work well. If you're interested I had a quick go at Hershey rendering by mapping the line into one big polygon: espruino/Espruino#1702 (comment) I guess that could be an option - there are still a few edge cases to work out on it though.Attachments: |
Beta Was this translation helpful? Give feedback.
-
Posted at 2020-05-13 by NebbishHacker
I made some sample characters in a few different styles. The top two rows are as smooth as I could manage given the limitations of the grid, averaging 20 points per characters. The next two rows are a bit more angular, averaging ~17 points per character. The last two rows are as minimal as I could manage, averaging ~15 points per character. I'd be personally inclined to go with the first style, since it scales up nicely and still stays significantly under the ~30 points per character of the original font, but I'd be curious to know what other people think. (This is using the single poly per character method - if I break it up into multiple polys that'll inflate the point count a little bit)Attachments: |
Beta Was this translation helpful? Give feedback.
-
Posted at 2020-05-13 by NebbishHacker And here's the above characters rendered on the Bangle.js, using my svg2bangle tool. At 2x scale they generally look pretty good, but at 1x scale it gets a bit quirky. Part of the issue is that fillPoly doesn't preserve symmetry - the same pattern of points doesn't produce the same pattern of pixels when mirrored vertically or horizontally. Here's the emulator link: https://www.espruino.com/ide/emulator.html?gist=c6dcac546c7247108f7c2255251d6c03
On the flipside, with the hershey fonts people can always tweak the line thickness until it looks good to them. With a regular poly font you get no such freedom.Attachments: |
Beta Was this translation helpful? Give feedback.
-
Posted at 2020-05-13 by @gfwilliams Wow, thank you! Those look awesome! Yes, personally I prefer the first option too...
I guess from my point of view if you were willing to put in the huge amount of work to do nice fonts, this would be a nice easy way of improving vector fonts as it basically slots into what's there already. It'd be faster too. The Hershey stuff is still going to take a bit of work to get rendering correctly, but I guess it might be more flexible when it's done? It'll still need a bunch of work (export to SVG then re-import) to add some missing symbols too. |
Beta Was this translation helpful? Give feedback.
-
Posted at 2020-05-18 by NebbishHacker Here's my go at the full font, covering the ASCII range. I tried to break things up in such a way as to avoid the scanline issue, so there's more individual shapes than would otherwise be necessary. Let me know if there's any modifications or additions you would like me to make :)Attachments: |
Beta Was this translation helpful? Give feedback.
-
Posted at 2020-05-18 by NebbishHacker And for the sake of completeness, here it is rendered in the emulator. I doubt the 1x scale results are ever going to look quite as good as a handcrafted pixel font, since the rasterization algorithm has to deal with things like pixels that are perfectly subdivided by an edge. That said, I think it'll definitely look better if fillPoly can be improved. Some notable quirks:
The 2x and up results look pretty good, though, which I assume is the more important use case.Attachments: |
Beta Was this translation helpful? Give feedback.
-
Posted at 2020-05-18 by @gfwilliams Wow, those look absolutely amazing - thank you! I'll see about pulling that in to Espruino. The poly rendering is difficult - it seems for most graphics work you fill up to the top left pixels, but then one pixel in on the bottom right (to stop overdraw when two polys touch) but I'm not sure if that's actually what we want, as I'm pretty sure when I tried it the result was pretty bad. edit: filed an issue for it at espruino/Espruino#1824 so I remember to get this done very soon. Most of today is going to be spent packing Bangles I'm afraid! |
Beta Was this translation helpful? Give feedback.
-
Posted at 2020-05-18 by @MaBecker Very smoth - great job @nebbishhacker! Can you please add some additional chars like |
Beta Was this translation helpful? Give feedback.
-
Posted at 2020-05-18 by @gfwilliams There was a bit of a discussion on espruino/Espruino#1702 (comment) about hard-coding the extra characters - basically just have a bunch of stuff that goes above the letters. I'm happy to have a poke around at those though. I could re-use the same mapping to handle the lack of chars in the default 4x6 font too. What do you think we should do about defining the width of each character? Maybe if I add a vertical red line in the SVG by each character or something like that, I can pick it out when generating the font file. |
Beta Was this translation helpful? Give feedback.
-
Posted at 2020-05-18 by NebbishHacker
I think that's exactly what you want in this case, where you have shapes you want to be able to scale up and down without affecting their proportions. Including the bottom right pixel effectively makes things a pixel larger than they should be, which can be a big difference at small sizes. It might help to think of the coordinates as specifying grid locations between the pixels, rather than the pixels themselves. |
Beta Was this translation helpful? Give feedback.
-
Posted at 2020-05-18 by NebbishHacker I think special casing the diacretics makes a lot of sense, especially since I didn't leave enough space above the letters to fit them in properly. 😐 For the width of each character, could you just find the rightmost point and base it on that? Although I guess that would mean hardcoding the width of the space. |
Beta Was this translation helpful? Give feedback.
-
Posted at 2020-05-18 by @MaBecker
Yes that would be nice and handle exactly what's needed for other languages as well. |
Beta Was this translation helpful? Give feedback.
-
Posted at 2020-05-18 by @gfwilliams
Yes, totally - that would be easier if it worked out ok. It'd save a bunch of space too. |
Beta Was this translation helpful? Give feedback.
-
Posted at 2020-05-19 by @gfwilliams New vector font is now in a branch at https://github.com/espruino/Espruino/compare/new_vector_font?expand=1 I still have to fix the font scaling, but it looks amazing - and takes up 1/4 of the memory! Thanks @nebbishhacker - this is amazing. Can't wait to get it into the Bangle.js firmware :) |
Beta Was this translation helpful? Give feedback.
-
Posted at 2020-05-22 by @MaBecker GREAT WORK Can please take a look at the R: the line that make a P to a R could be wider The Attachments: |
Beta Was this translation helpful? Give feedback.
-
Posted at 2020-05-22 by NebbishHacker I'm afraid I can't make the angled line on the R thicker without making it entirely too thick, due to the limitation of the grid. The small s was really tricky to design on the grid. I've attached a version that's a bit thinner and arguably more rounded, but I'm not really sure if I like it more... it ends up looking kind of slanted or skewed to me.Attachments: |
Beta Was this translation helpful? Give feedback.
-
Posted at 2020-05-22 by @MaBecker Ok, so it's all because sticking to the grid - I understand - thanks. |
Beta Was this translation helpful? Give feedback.
-
Posted at 2020-05-23 by @MaBecker
Which is 16x16 at the moment, so a switch to 32x32 or 28x36 would allow more curved and thicker/thinner chars - correct? |
Beta Was this translation helpful? Give feedback.
-
Posted at 2020-05-23 by @gfwilliams
Yes, but it also then means you can't fit X and Y into one byte :) @nebbishhacker that's great, thanks! yes, we could move to a 14x18 grid if you think that'd make more sense for the characters? Seems like quite a bit of work and maybe stuff like 'W' would be a bit too tricky then? |
Beta Was this translation helpful? Give feedback.
-
Posted at 2020-05-23 by @gfwilliams New version should be committed now! (although not live in the emulator) |
Beta Was this translation helpful? Give feedback.
-
Posted at 2020-05-23 by NebbishHacker W and @ would have to be squished a bit, but I think everything else would fit as is. Mostly I just want to make a few things like the parentheses sit a bit higher. In any case, I'll experiment a bit more to see if it seems like a change worth making. I was also pondering if it might be better in the long run to include all the accented characters directly. Pros:
Cons:
On a related note, would it make sense to store the font in a compressed form? It has a lot of small repeated elements so I think it should compress fairly well, but I guess compression would make it harder to index into it and access individual characters. |
Beta Was this translation helpful? Give feedback.
-
Posted at 2020-05-26 by @gfwilliams Well, if you're willing to spend the time redoing the fonts then I'd be happy to include them in a 14x18 grid. In terms of the accented chars, it's a trade-off since the extra code needed for them takes up quite a lot of space too. When it was pretty much just chars 33-127 doing it in code definitely made sense - but yes, now it's definitely less of a sure thing. For compression, it's a point but I think decompressing each time might make it too slow. I guess it could decompress it to RAM only when |
Beta Was this translation helpful? Give feedback.
-
Posted at 2020-05-26 by @MaBecker Now there is
What about scaling x and y wise plus kerning?
|
Beta Was this translation helpful? Give feedback.
-
Posted at 2020-05-26 by @gfwilliams It's an idea, but maybe not right now :) it doesn't fit in easily with how font size is stored at the moment, and I'm also planning to deprecate |
Beta Was this translation helpful? Give feedback.
-
Posted at 2020-05-26 by @MaBecker
Good point, I am looking forward to your solution.
|
Beta Was this translation helpful? Give feedback.
-
Posted at 2020-05-27 by NebbishHacker After a bit more fiddling, I've decided that it's not worth changing the grid just for the minor tweaks I was considering.
By my math directly including the accented chars would take up a bit over a kilobyte. I'm guessing the extra code likely takes up less space than that? |
Beta Was this translation helpful? Give feedback.
-
Posted at 2020-05-27 by @gfwilliams
I just checked and it's 440 bytes. So not as small as you might think. Not having it would be a lot easier for sure. There might be things we could do to reduce the size of the font in memory too (like another way to store the end of polys, and maybe when fillPoly works better we can get then polygons more complex) |
Beta Was this translation helpful? Give feedback.
-
Posted at 2021-03-30 by Numerist I'm using the vector font. How frequently are there revisions of it, if any? |
Beta Was this translation helpful? Give feedback.
-
Posted at 2021-04-06 by @gfwilliams Not often - it shouldn't change much. There was a big change ~6 months ago when @nebbishhacker massively improved it (and the amount of characters supported) but now I'd expect it to be pretty stable. |
Beta Was this translation helpful? Give feedback.
-
Posted at 2020-05-12 by @gfwilliams
Hi! Recently we've been really pushing up against the limits of what we can fit in Bangle.js's firmware (not helped by ~90k of Tensorflow!). One of the big blobs that takes up space in Bangle.js is actually the vector font (5kB), and I've been itching to try and find a way to improve it as it doesn't look great at the moment.
There's an issue on GitHub open for it at espruino/Espruino#1721
But basically it boils down to:
Use a Hershey font
These are old-school vector fonts designed for plotters. It seems they could be packed into about a 1.5kB of flash, and would scale down really nicely. The gotcha is we'd need a way to draw lines bigger than 1 pixel wide, and they won't render very quickly because it's not easy to fill large areas.
Design our own vector font
I'm imagining a filled font where each character was:
We could just have an SVG file and a write a script to extract the data from it.
I'd tried to export existing fonts, but we're pretty limited in what we can get in such a small footprint (see the GitHub issue) so I think we need something that embraces the limitations (ie polygons rather than smooth).
Would anyone be up for giving this a try? I uploaded my rough and ready test SVG file here - I reckon something in that form would be great - realistically for now it only needs to be the top half as well.
Attachments:
Beta Was this translation helpful? Give feedback.
All reactions