Font for graphical LCD

Let's talk about anything related to the 6502 microprocessor.
Post Reply
User avatar
Druzyek
Posts: 367
Joined: 12 May 2014
Contact:

Font for graphical LCD

Post by Druzyek »

I finally got a 128x64 graphical LCD working with a 6507 an 6532 for my calculator project. The LCD doesn't have a font built in. Does anyone know if there is a 5x8 one in the Public Domain I can use? According to what I've read, a "bitmapped typeface" cannot be copyrighted but it can be patented.
User avatar
Agumander
Posts: 129
Joined: 17 Jul 2018
Location: Long Island, NY
Contact:

Re: Font for graphical LCD

Post by Agumander »

What characters do you need?
User avatar
GARTHWILSON
Forum Moderator
Posts: 8774
Joined: 30 Aug 2002
Location: Southern California
Contact:

Re: Font for graphical LCD

Post by GARTHWILSON »

If 5x8 does not include the blank column separating characters, you could just copy what all the intelligent character LCDs use, shown near the top of the displays page of the 6502 primer. If you want something smaller, to get more characters in since it's a pretty small display, see if https://www.hpcalc.org/hp49/utils/fonts/ helps. There are lots of fonts there.
http://WilsonMinesCo.com/ lots of 6502 resources
The "second front page" is http://wilsonminesco.com/links.html .
What's an additional VIA among friends, anyhow?
User avatar
Rob Finch
Posts: 465
Joined: 29 Dec 2002
Location: Canada
Contact:

Re: Font for graphical LCD

Post by Rob Finch »

There is VB source code for a primitive font (glyph) editor which has been used to develop fonts for a FPGA based display controller here:
https://github.com/robfinch/Cores/tree/ ... /GlyphEdit
It is pretty primitive but works enough to create fonts. It can handle just about any font size up to 32x32.
User avatar
Druzyek
Posts: 367
Joined: 12 May 2014
Contact:

Re: Font for graphical LCD

Post by Druzyek »

Agumander wrote:
What characters do you need?
Just the standard ones from ! to ~ which includes upper and lowercase, numbers, and the most common punctuation and symbols.
GARTHWILSON wrote:
If 5x8 does not include the blank column separating characters, you could just copy what all the intelligent character LCDs use, shown near the top of the displays page of the 6502 primer. If you want something smaller, to get more characters in since it's a pretty small display, see if https://www.hpcalc.org/hp49/utils/fonts/ helps. There are lots of fonts there.
Thanks! What is the copyright situation on those though? If the character set for those intelligent displays is in the public domain, I haven't been able to find mention of it yet.
User avatar
Rob Finch
Posts: 465
Joined: 29 Dec 2002
Location: Canada
Contact:

Re: Font for graphical LCD

Post by Rob Finch »

They have some fonts at OpenGameArt.org. The licensing is usually okay. Author typically just want a note to the origin. I have used images from that source before.
barnacle
Posts: 1831
Joined: 19 Jan 2004
Location: Potsdam, DE
Contact:

Re: Font for graphical LCD

Post by barnacle »

Here's one I generated years ago. It's in a bit of an odd format for historical reasons... It's intended for a 128 x 64 LCD/OLED display, which tend to use a memory map where the 128 columns go right to left and 8 rows of eight pixels go top to bottom; bit zero of the memory is the highest. On that display dimension, it gives four rows of twenty-three columns.

The font is six pixels wide by sixteen pixels high, stored as five pixels wide (there isn't a lot of point wasting space by storing the blanks) and doesn't have an characters below the space. Ten bytes per character; odd bytes along the line are the bottom half of the character and even bytes are the top half. In both cases, bit zero is at the top.

This is a larger font than the one requested by the OP but it's available for any use - including playing with it to change it.

Neil

Code: Select all

const uint8_t fonts[960] = {
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 	// ' '
	0x00, 0x00, 0x00, 0x00, 0x0B, 0xF8, 0x00, 0x00, 0x00, 0x00, 	// '!'
	0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 	// '"'
	0x02, 0x20, 0x0F, 0xF8, 0x02, 0x20, 0x0F, 0xF8, 0x02, 0x20, 	// '#'
	0x04, 0x60, 0x08, 0x90, 0x1F, 0xF8, 0x09, 0x10, 0x06, 0x20, 	// '$'
	0x06, 0x10, 0x01, 0x28, 0x04, 0x90, 0x0A, 0x40, 0x04, 0x30, 	// '%'
	0x07, 0x30, 0x08, 0xC8, 0x09, 0x30, 0x06, 0x00, 0x09, 0x00, 	// '&'
	0x00, 0x00, 0x00, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x00, 0x00, 	// '''
	0x00, 0x00, 0x00, 0x00, 0x0F, 0xF8, 0x10, 0x04, 0x00, 0x00, 	// '('
	0x00, 0x00, 0x00, 0x00, 0x10, 0x04, 0x0F, 0xF8, 0x00, 0x00, 	// ')'
	0x01, 0x10, 0x00, 0xA0, 0x03, 0xF8, 0x00, 0xA0, 0x01, 0x10, 	// '*'
	0x01, 0x00, 0x01, 0x00, 0x07, 0xC0, 0x01, 0x00, 0x01, 0x00, 	// '+'
	0x00, 0x00, 0x2C, 0x00, 0x1C, 0x00, 0x00, 0x00, 0x00, 0x00, 	// ','
	0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 	// '-'
	0x0C, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 	// '.'
	0x0C, 0x00, 0x03, 0x00, 0x00, 0xC0, 0x00, 0x38, 0x00, 0x00, 	// '/'
	0x07, 0xF0, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x07, 0xF0, 	// '0'
	0x00, 0x00, 0x00, 0x10, 0x00, 0x10, 0x0F, 0xF8, 0x00, 0x00, 	// '1'
	0x0C, 0x10, 0x0A, 0x08, 0x09, 0x08, 0x08, 0x88, 0x08, 0x70, 	// '2'
	0x04, 0x10, 0x08, 0x08, 0x08, 0x88, 0x08, 0x88, 0x07, 0x70, 	// '3'
	0x03, 0x00, 0x02, 0xC0, 0x02, 0x30, 0x0F, 0xF8, 0x02, 0x00, 	// '4'
	0x04, 0xF8, 0x08, 0x48, 0x08, 0x48, 0x08, 0x48, 0x07, 0x88, 	// '5'
	0x07, 0xF0, 0x08, 0x88, 0x08, 0x88, 0x08, 0x88, 0x07, 0x10, 	// '6'
	0x00, 0x08, 0x0E, 0x08, 0x01, 0x88, 0x00, 0x68, 0x00, 0x18, 	// '7'
	0x07, 0x70, 0x08, 0x88, 0x08, 0x88, 0x08, 0x88, 0x07, 0x70, 	// '8'
	0x04, 0x70, 0x08, 0x88, 0x08, 0x88, 0x08, 0x88, 0x07, 0xF0, 	// '9'
	0x0C, 0xC0, 0x0C, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 	// ':'
	0x00, 0x00, 0x2C, 0xC0, 0x1C, 0xC0, 0x00, 0x00, 0x00, 0x00, 	// ';'
	0x01, 0x00, 0x02, 0x80, 0x04, 0x40, 0x08, 0x20, 0x00, 0x00, 	// '<'
	0x02, 0x80, 0x02, 0x80, 0x02, 0x80, 0x02, 0x80, 0x02, 0x80, 	// '='
	0x08, 0x20, 0x04, 0x40, 0x02, 0x80, 0x01, 0x00, 0x00, 0x00, 	// '>'
	0x00, 0x10, 0x00, 0x08, 0x0B, 0x08, 0x00, 0x88, 0x00, 0x70, 	// '?'
	0x01, 0xE0, 0x02, 0x10, 0x04, 0xC8, 0x05, 0x28, 0x02, 0xF0, 	// '@'
	0x0F, 0x00, 0x02, 0xE0, 0x02, 0x18, 0x02, 0xE0, 0x0F, 0x00, 	// 'A'
	0x0F, 0xF8, 0x08, 0x88, 0x08, 0x88, 0x08, 0x88, 0x07, 0x70, 	// 'B'
	0x07, 0xF0, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x04, 0x10, 	// 'C'
	0x0F, 0xF8, 0x08, 0x08, 0x08, 0x08, 0x04, 0x10, 0x03, 0xE0, 	// 'D'
	0x0F, 0xF8, 0x08, 0x88, 0x08, 0x88, 0x08, 0x08, 0x00, 0x00, 	// 'E'
	0x0F, 0xF8, 0x00, 0x88, 0x00, 0x88, 0x00, 0x08, 0x00, 0x00, 	// 'F'
	0x07, 0xF0, 0x08, 0x08, 0x08, 0x88, 0x04, 0x88, 0x0F, 0x90, 	// 'G'
	0x0F, 0xF8, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x0F, 0xF8, 	// 'H'
	0x00, 0x00, 0x0F, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 	// 'I'
	0x06, 0x00, 0x08, 0x00, 0x08, 0x00, 0x07, 0xF8, 0x00, 0x00, 	// 'J'
	0x0F, 0xF8, 0x00, 0xC0, 0x01, 0x20, 0x02, 0x10, 0x0C, 0x08, 	// 'K'
	0x0F, 0xF8, 0x08, 0x00, 0x08, 0x00, 0x08, 0x00, 0x08, 0x00, 	// 'L'
	0x0F, 0xF8, 0x00, 0x70, 0x01, 0x80, 0x00, 0x70, 0x0F, 0xF8, 	// 'M'
	0x0F, 0xF8, 0x00, 0x30, 0x00, 0xC0, 0x03, 0x00, 0x0F, 0xF8, 	// 'N'
	0x07, 0xF0, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x07, 0xF0, 	// 'O'
	0x0F, 0xF8, 0x00, 0x88, 0x00, 0x88, 0x00, 0x88, 0x00, 0x70, 	// 'P'
	0x07, 0xF0, 0x08, 0x08, 0x0A, 0x08, 0x0C, 0x08, 0x17, 0xF0, 	// 'Q'
	0x0F, 0xF8, 0x00, 0x88, 0x00, 0x88, 0x00, 0x88, 0x0F, 0x70, 	// 'R'
	0x04, 0x70, 0x08, 0x88, 0x08, 0x88, 0x08, 0x88, 0x07, 0x10, 	// 'S'
	0x00, 0x08, 0x00, 0x08, 0x0F, 0xF8, 0x00, 0x08, 0x00, 0x08, 	// 'T'
	0x07, 0xF8, 0x08, 0x00, 0x08, 0x00, 0x08, 0x00, 0x07, 0xF8, 	// 'U'
	0x00, 0x38, 0x03, 0xC0, 0x0C, 0x00, 0x03, 0xC0, 0x00, 0x38, 	// 'V'
	0x00, 0xF8, 0x0F, 0x00, 0x00, 0xE0, 0x0F, 0x00, 0x00, 0xF8, 	// 'W'
	0x0E, 0x38, 0x01, 0x40, 0x00, 0x80, 0x01, 0x40, 0x0E, 0x38, 	// 'X'
	0x00, 0x38, 0x00, 0x40, 0x0F, 0x80, 0x00, 0x40, 0x00, 0x38, 	// 'Y'
	0x0C, 0x08, 0x0B, 0x08, 0x08, 0x88, 0x08, 0x68, 0x08, 0x18, 	// 'Z'
	0x00, 0x00, 0x1F, 0xFC, 0x10, 0x04, 0x00, 0x00, 0x00, 0x00, 	// '['
	0x00, 0x00, 0x00, 0x38, 0x00, 0xC0, 0x03, 0x00, 0x0C, 0x00, 	// '\'
	0x00, 0x00, 0x10, 0x04, 0x1F, 0xFC, 0x00, 0x00, 0x00, 0x00, 	// ']'
	0x00, 0x10, 0x00, 0x08, 0x00, 0x04, 0x00, 0x08, 0x00, 0x10, 	// '^'
	0x10, 0x00, 0x10, 0x00, 0x10, 0x00, 0x10, 0x00, 0x10, 0x00, 	// '_'
	0x00, 0x08, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 	// '`'
	0x06, 0x00, 0x09, 0x40, 0x09, 0x40, 0x09, 0x40, 0x0F, 0x80, 	// 'a'
	0x0F, 0xF8, 0x08, 0x40, 0x08, 0x40, 0x08, 0x40, 0x07, 0x80, 	// 'b'
	0x07, 0x80, 0x08, 0x40, 0x08, 0x40, 0x08, 0x40, 0x04, 0x80, 	// 'c'
	0x07, 0x80, 0x08, 0x40, 0x08, 0x40, 0x08, 0x40, 0x0F, 0xF8, 	// 'd'
	0x07, 0x80, 0x09, 0x40, 0x09, 0x40, 0x09, 0x40, 0x05, 0x80, 	// 'e'
	0x0F, 0xF0, 0x00, 0x48, 0x00, 0x48, 0x00, 0x48, 0x00, 0x10, 	// 'f'
	0x27, 0x80, 0x28, 0x40, 0x28, 0x40, 0x28, 0x40, 0x1F, 0xC0, 	// 'g'
	0x0F, 0xF8, 0x00, 0x80, 0x00, 0x40, 0x00, 0x40, 0x0F, 0x80, 	// 'h'
	0x00, 0x00, 0x00, 0x00, 0x0F, 0xC8, 0x00, 0x00, 0x00, 0x00, 	// 'i'
	0x20, 0x00, 0x20, 0x00, 0x1F, 0xC8, 0x00, 0x00, 0x00, 0x00, 	// 'j'
	0x0F, 0xF8, 0x01, 0x00, 0x02, 0x80, 0x04, 0x40, 0x08, 0x00, 	// 'k'
	0x00, 0x00, 0x00, 0x00, 0x0F, 0xF8, 0x00, 0x00, 0x00, 0x00, 	// 'l'
	0x0F, 0xC0, 0x00, 0x40, 0x0F, 0x80, 0x00, 0x40, 0x0F, 0x80, 	// 'm'
	0x0F, 0xC0, 0x00, 0x80, 0x00, 0x40, 0x00, 0x40, 0x0F, 0x80, 	// 'n'
	0x07, 0x80, 0x08, 0x40, 0x08, 0x40, 0x08, 0x40, 0x07, 0x80, 	// 'o'
	0x3F, 0xC0, 0x08, 0x40, 0x08, 0x40, 0x08, 0x40, 0x07, 0x80, 	// 'p'
	0x07, 0x80, 0x08, 0x40, 0x08, 0x40, 0x08, 0x40, 0x3F, 0xC0, 	// 'q'
	0x0F, 0xC0, 0x00, 0x80, 0x00, 0x40, 0x00, 0x40, 0x00, 0x00, 	// 'r'
	0x04, 0x80, 0x09, 0x40, 0x0A, 0x40, 0x04, 0x80, 0x00, 0x00, 	// 's'
	0x07, 0xF0, 0x08, 0x40, 0x08, 0x40, 0x00, 0x00, 0x00, 0x00, 	// 't'
	0x07, 0xC0, 0x08, 0x00, 0x08, 0x00, 0x04, 0x00, 0x0F, 0xC0, 	// 'u'
	0x00, 0xC0, 0x03, 0x00, 0x0C, 0x00, 0x03, 0x00, 0x00, 0xC0, 	// 'v'
	0x01, 0xC0, 0x0E, 0x00, 0x01, 0xC0, 0x0E, 0x00, 0x01, 0xC0, 	// 'w'
	0x0C, 0xC0, 0x03, 0x00, 0x03, 0x00, 0x0C, 0xC0, 0x00, 0x00, 	// 'x'
	0x20, 0x00, 0x23, 0xC0, 0x1C, 0x00, 0x04, 0x00, 0x03, 0xC0, 	// 'y'
	0x0C, 0x40, 0x0A, 0x40, 0x09, 0x40, 0x08, 0xC0, 0x00, 0x00, 	// 'z'
	0x00, 0x00, 0x00, 0x80, 0x0F, 0x78, 0x10, 0x04, 0x00, 0x00, 	// '{'
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0xF8, 0x00, 0x00, 	// '|'
	0x00, 0x00, 0x10, 0x04, 0x0F, 0x78, 0x00, 0x80, 0x00, 0x00, 	// '}'
	0x00, 0x10, 0x00, 0x08, 0x00, 0x04, 0x00, 0x08, 0x00, 0x10, 	// '~'
	0x00, 0x38, 0x00, 0x44, 0x00, 0x44, 0x00, 0x44, 0x00, 0x38, 	// 'degree'
	};
User avatar
commodorejohn
Posts: 299
Joined: 21 Jan 2016
Location: Placerville, CA
Contact:

Re: Font for graphical LCD

Post by commodorejohn »

If you're genuinely concerned about copyright/license issues, I'd just get a tile editor of the sort that homebrew game developers and ROM hackers use and roll one up yourself. It's really not difficult (I can do one in half an hour, and at 5x8 fixed-pitch it's not like you need to know much about typography,) and you can do it exactly to your taste, within the limits of the format.

5x8 on a 128px screen does seem like a bit of an odd choice to me. Depending on how many columns you really feel you need, 6x8 or 8x8 would probably be a little more comfortable.
User avatar
Michael
Posts: 633
Joined: 13 Feb 2013
Location: Michigan, USA

Re: Font for graphical LCD

Post by Michael »

May I ask which display you're using, please? Is it one of the tiny 0.96" or 1.3" type?

Cheerful regards...
User avatar
Druzyek
Posts: 367
Joined: 12 May 2014
Contact:

Re: Font for graphical LCD

Post by Druzyek »

commodorejohn wrote:
If you're genuinely concerned about copyright/license issues, I'd just get a tile editor of the sort that homebrew game developers and ROM hackers use and roll one up yourself.
This is what I ended up doing with MS Paint and a Python script. Thanks for the suggestion.
Quote:
5x8 on a 128px screen does seem like a bit of an odd choice to me. Depending on how many columns you really feel you need, 6x8 or 8x8 would probably be a little more comfortable.
Hmm, maybe 6x8 is what I mean then since the letter is five pixels wide and I'm not counting the one pixel space between letters.
Quote:
May I ask which display you're using, please? Is it one of the tiny 0.96" or 1.3" type?
Do you mean one of the little OLED displays from China? I have some of those to play with but haven't tested them out yet. For this I'm using an LCD: https://www.crystalfontz.com/product/cf ... ule-128x64
User avatar
drogon
Posts: 1671
Joined: 14 Feb 2018
Location: Scotland
Contact:

Re: Font for graphical LCD

Post by drogon »

Druzyek wrote:
Quote:
May I ask which display you're using, please? Is it one of the tiny 0.96" or 1.3" type?
Do you mean one of the little OLED displays from China? I have some of those to play with but haven't tested them out yet. For this I'm using an LCD: https://www.crystalfontz.com/product/cf ... ule-128x64
Looks exactly like this one I used on a Pi some time back:

https://www.youtube.com/watch?v=JBtS35qPmeo

and while I don't put up any text in that video, I do have some fonts I've used on it (and others like that in the past)

This is a nice, generic 8x8 font I have used in the past:

https://unicorn.drogon.net/font.h

This is a variable width one, condensed down to 5 high and 4 or 5 wide (ie. variable width) which I designed for the Pimoroni Scroll pHAT for the Pi:

https://unicorn.drogon.net/scrollPhatFont.h

It needs code support to check the width of each character which is stored left-shifted in a byte, 5 bytes long. so needs 5 bytes per character rather than 8. My code checks the width by scanning each of the 5 bytes for the right-most set bit - starting at bit 0 (rightmost) and working towards bit 7 (left most), so characters like double quote get worked out correctly.

Also this:

https://unicorn.drogon.net/font_acorn_8x8.h

is a font I've tweaked based on the Acorn font in the BBC Micro. It's an 8x8 font and in quite interesting as most of the vertical lines (e.g. in ! and others) are doubled. This was an intentional design by Sophie Wilson who designed it (and the Beeb, ARM, etc.) to cater for PAL video so the font was visible in an 80-column mode on a UK TV at the time. (640x256 pixel resolution). There is an article online about this somewhere which I read a while back but the link to it escapes me right now.

The biggest headache is storing the data in ROM on a 6502 - a 'basic' 64 character font in an 8x8 format needs 512 bytes of ROM space - which may or may not be an issue, but you can cut it down to just (say) uppercase only and pack to 7 bytes if you really need to save space.

-Gordon
--
Gordon Henderson.
See my Ruby 6502 and 65816 SBC projects here: https://projects.drogon.net/ruby/
Post Reply