Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

drawChar should let you specify a different font #120

Open
joshgoebel opened this issue Mar 1, 2016 · 13 comments
Open

drawChar should let you specify a different font #120

joshgoebel opened this issue Mar 1, 2016 · 13 comments

Comments

@joshgoebel
Copy link
Collaborator

http://community.arduboy.com/t/adding-font-and-removing-arduboy-font/855/3

Probably should make this easier. Providing a custom font isn't that unusual of a thing to want to do. The question is how to do this without getting both fonts linked or requiring you to always set the font after startup.

Easy enough to have a setFont(ptr)...

@MLXXXp
Copy link
Collaborator

MLXXXp commented Mar 1, 2016

Easy enough to have a setFont(ptr)...

I think it's acceptable to require you to specify the font after startup, even if it's the supplied built-in default font.

As far as font definitions and handling go, we should consider switching to the way the SparkFun MicroView Library does it:

The start of the array itself contains a header which gives the width, height, starting character, number of characters and font map width(?). This allows any size font. Also, since the starting character and number of characters are given, you can define just a (contiguous) subset of the entire 256 characters. For subsets, asking to print any character outside the range just does nothing.

We'd have to decide if we wanted to keep the font size capability, which allows you to increase the size of a given font.

We could "borrow" the drawChar() function, and the other font support functions, from this library. We could also "borrow" their fonts, if desired.

@joshgoebel
Copy link
Collaborator Author

To me a full font rendering engine with different faces/sizes starts to sound like an external library perhaps.

@MLXXXp
Copy link
Collaborator

MLXXXp commented Mar 1, 2016

To me a full font rendering engine with different faces/sizes starts to sound like an external library perhaps.

I was thinking it should be a separate library even with the simple drawChar() and support functions that we have now.

@joshgoebel
Copy link
Collaborator Author

Separate class or separate library? I really want to avoid the urge to make this much more complex (than swapping out fixed sized font) but I do think it's pretty important that our base library have some simply way to throw characters/strings at the screen - doesn't that seem like pretty core functionality?

@joshgoebel
Copy link
Collaborator Author

Even the font is weird cause it feels like maybe that's a printing concept but right now drawing concerns (and therefor font) would be a graphics concern. Grrrr. :-)

@joshgoebel
Copy link
Collaborator Author

Also, since the starting character and number of characters are given, you can define just a (contiguous) subset of the entire 256 characters

This is a great idea but staging to get complex. setFont and a default 1 character font with a funny character in case people forget to set font? A tiny Arduboy? A smiley? A frownie? I guess a 1 character font kind of implies adding the ability to have at least a COUNT of characters at a minimum. Grrrr.

I'm not sure what is best here, not enough people using text IMHO.

The minimum I'd like to do is allow user to pass in a custom font without having to completely recode drawChar.

@joshgoebel
Copy link
Collaborator Author

Default font or "build your own" or "use this great font lib" isn't completely terrible asnwer.

@MLXXXp
Copy link
Collaborator

MLXXXp commented Mar 2, 2016

Default font or "build your own" or "use this great font lib" isn't completely terrible asnwer.

Sounds good to me.

@MLXXXp
Copy link
Collaborator

MLXXXp commented Mar 2, 2016

I'd just like to state this here, in case someone reviewing this conversation decides to create a font rendering engine based on the SparkFun MicroView Library.

With this library, you can define a font to be a subset of the full 255 characters, but it must be a contiguous range. If you wanted to have a font that contains a character far from the rest of your desired range, then you have to extend the range to include all the characters in between. For example, if you wanted a font that was upper case only, but also contained all of the symbols including "{", "|" and "}" you would still have to include lower case, because upper case is before lower case and those symbols are after lower case.

One solution would be to add those symbols at the end of your block, and use whatever characters happened to be there to display them. E.g. "{" = "a", "|" = "b", "}" = "c". However, to display something like {HELLO} you would need to use print("aHELLOc"); instead of print("{HELLO}");. Also, if at some point you wanted to switch to a different font that included lower case, aHELLOc would actually be printed.

The solution I would use would be to add a mapping table within the font or in a separate array (within the font would probably be better, either after the header or at the end). The first byte of the table would be the number of entries. The remainder would be pairs of bytes with the first byte being the actual character number and the second byte being the charater that it should be mapped to.

To map the above characters the table would be:

3, // The number of table entries
'{', 'a',
'|', 'b',
'}', 'c'

In the library, drawChar() would

  • Check if the character is in range, as it does now.

  • If not, instead of just returning, check if the character is one of the first bytes of the pairs in mapping table.

  • If so, display the character who's value is the second byte.

  • If not, return as before.

    Essentially, this allows you to create a font that contains any subset (not only contiguous) of the full set, and still be able to switch to a complete font.

Of course, unless the library had additional information and checking, if you tried to do print("aHELLOc"); you would get {HELLO} but since "a" and "c" aren't supported by that font, the sketch shouldn't be trying to use them.

Continuing with the above example, if you wanted the font to accept lower case characters but display them as upper case, you could just extend the mapping table with:

'a', 'A',
'b', 'B',
'c', 'C',
// ...
'z', 'Z'

@joshgoebel
Copy link
Collaborator Author

We need to start coming up with great suggestions for a "full kit"... ArduboyLib + ArduboyExtra + [what music] + [what font] + ????. So when someone says "how can i do cool dont" we have more to say than "write your own code".

@MLXXXp
Copy link
Collaborator

MLXXXp commented Mar 3, 2016

We need to start coming up with great suggestions for a "full kit"

Well, if someone wants to start a discussion and list of what this "full kit" would be, and how it would function, you can add my previous comment there.

@joshgoebel
Copy link
Collaborator Author

I think this would be better:

ranges = {
{"az","A."},
}}

Much shorter and I bet the code would weigh in at less than 26*2 bytes.

@MLXXXp
Copy link
Collaborator

MLXXXp commented Mar 3, 2016

Much shorter and I bet the code would weigh in at less than 26*2 bytes.

Sure, and even more so if your sketch used more than one font with lower to upper translation. But that's a single special case. Would that syntax be useful for anything but lower to upper case?

It may be better to keep my table format and just add another flag byte in the header, with a bit in it indicating "translate lower to upper". Other bits in that flag byte might be useful for other purposes, such as indicating how many pixels of inter-character spacing to add to the height and width.

Another use I envisioned for the mapping table would be for a decimal numeric only font (including floats), consisting of 0-9 + - . E e and space. The block would be 0-9 and the rest would be individually remapped. In this case, my table, with pairs of bytes, would be smaller than yours, with pairs of strings (because of the null terminators).

P.S. Another change I would make would be to have unsupported characters print as a space, instead of being ignored. Or better, print a checkerboard or some other pattern that indicates an unsupported character.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants