Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

Led Font Creator with Scrolling Display

0.00/5 (No votes)
18 Sep 2008 1  
A led display with a character editor

Sample Image of the control

Sample Image of the control

Introduction

With this control, I try to solve a problem common to all of us who do not have English as our native language. All led, lcd, seven segments controls I have seen so far do not support more than the 7 bit ASCII character set. So for all of us that would like to have our own specific character or symbol, I have added a character editor. I was inspired by another led control by Liu Xia A Fine-looking Segmented LED Control from where I also borrowed a few things like ISupportInitialize.

Background

There are some quite nice, free led fonts on the Internet like Ozone by Andreas Nylin and AI pointe by Ritchie Ned Hansel. Al pointe uses a 5x7 matrix, a nice light font, and Ozone uses a bolder 6x8 matrix. Have a look and get some inspiration to create your own font. Feel free to use anything between 4x4 (never tried) and 8x8, 5x7, 6x10 or anything that multiplies to 64 or less.

The matrix is stored in a ulong that holds up to 64 bits.

Font samples

Using the Code

This control has just a few specific public properties, two to change the appearance of the font, and three for scrolling. Besides that, you can of course change ForeColor and BackColor, which also support transparency. The font you create is stored in a Dictionary key=char, value=bits and saved to an XML file in your Documents directory using:

Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments) + "\\LedFont.xml";

This is because the file is needed in design mode as well as in run time, explained in Points of Interest. The file created contains the characters and their binary matrix as a ulong, e.g. character char="A" bits="227873781661662" which translates to “0000 0000 0000 0000 1100 1111 0011 1111 1111 1111 1100 1111 0011 1111 1101 1110” in binary.
If you read from the right, you can match bit by bit in the editor starting from the upper left corner.
It is also possible to change the layout of the matrix, currently 6x8, by changing the constants HSEGMENTS and VSEGMENTS.
But be sure to make a backup of your previous font file before that and start with a new one, or else if the matrix doesn't comply with your font, it will be scrambled.
As the font isn't a bitmap, it's freely resizable and so far I have tested a 16 pixel high and up to 120 pixel high font. Of course the bigger it is, the higher will be the CPU load.

I have included a LedFont.xml with capital letters and numbers if you would like to get started.
Just remember to copy this file to your documents folder.

Sample Image of the editor

The editor

Binary matrix

The binary matrix

Public Properties

  • SegmentSpace - Space between segments in percent of segment size
  • CharSpace - Space between characters in percent of character size
  • Scroll - true or false, to scroll or not to scroll
  • ScrollDelay - Delay in milliseconds between movements
  • ScrollStep - Scroll by pixel or segment

Public Methods

  • public bool FindChar(char chr)

    Checks if character exists in dictionary

  • public void AddChar(char chr, ulong bits)

    Adds a character to dictionary, replaces old one if it exists

  • public void RemoveChar(char chr)

    Removes character if it exists in dictionary

  • public ulong GetValue(char chr)

    Gets value for a character

  • public ArrayList GetKeys()

    Gets a list of characters in dictionary

  • public void DrawChar(ulong bits, Graphics g, Rectangle rect)

    Draws a single char to the graphics object within a specified rectangle

  • public void DrawString(string str, Graphics g, Rectangle rect)

    Draws a string to the graphics object within a specified rectangle

Normally you don't use these methods directly as that is done by the Text property, which itself calls the DrawString method. The DrawString method is called when the Text property is changed, size changed, colors changed and spaces changed. DrawChar uses the ulong bits by masking of a bit at a time and painting the led if not zero.

public void DrawString(string str, Graphics g, Rectangle rect)
{
	ulong bits;

	if (str != null && str.Length > 0)
	{
		int width = Convert.ToInt32(this.Height / VSEGMENTS * HSEGMENTS);
		// position for next character		
		int pos = (int) (width + width * charSpace);	

		for (int i = 0; i < str.Length; i++)
		{
			segDict.TryGetValue(str[i], out bits);
			rect = new Rectangle(pos * i, 0, width, rect.Height);
			DrawChar(bits, g, rect);
		}
	}
}

public void DrawChar(ulong bits, Graphics g, Rectangle rect)
{
	g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;

	float size = rect.Height / VSEGMENTS;       	// height and width makes a square
	float space = (size * segmentSpace) / 2;    	// space between segments

	using (SolidBrush segmentBrush = new SolidBrush(ForeColor))
	{
		for (int y = 0; y < VSEGMENTS; y++)         // vertical row
		{
			for (int x = 0; x < HSEGMENTS; x++)     // horizontal row
			{
				if ((bits & 1) != 0)// if bit 1 is set, fill segment
				{
					RectangleF segmentRect = 
                                                  new RectangleF(rect.X + x * size, 
                                                                 y * size, size, size);
					// do not inflate to zero
					if ((space * 2) < size)         
						segmentRect.Inflate
							(-space, -space);
						g.FillEllipse(segmentBrush, 
								segmentRect);
				}
				// roll bits to the right
				bits = bits >> 1;                   
			}
		}
	}
}

Points of Interest

I discovered one thing while using an XML file for storing character definitions. To use the file in design mode which I have to, I could not use the common Application.StartupPath, as you usually do when storing data, because in design mode that path changed to Visual Studio's directory! The simplest solution was to use the documents folder to make it available in both modes, but feel free to change that. Another thing is that System.Timer.Timer and Windows.Forms.Timer is quite inaccurate. That makes timer ticks vary depending on what else the computer does. I also couldn't get a lower tick rate than 15 milliseconds on my mediocre computer.

History

  • 17th September, 2008: Initial version

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here