Archive for the 'Level: ABC' Category

A Trick to Render Outlined Text

Sunday, February 11th, 2007

In the last few years I found myself in need to render a font outlined to increase readability or to comply with UI requirements.
In both cases I had a non-outlined font, I had no choice of picking a different one, and I had to render it outlined.

To give you example, I had to render a font like this:

fontnormal.jpg

Outlined, like this:

fontoutlined.jpg

If you are not too concerned about rendering speed (in my case, it wasn’t an issue), the trick I used to accomplish this is astonishingly simple, and very effective. You just need to render the font 5 times in different positions; 4 times with the color of the outline, and one time with the color of the body of the text.

Assuming that you want the body of the text starting at position (x,y) on the screen, the algorithm is:

A) Select the outline color.
1) Draw the text at (x+1,y)
2) Draw the text at (x-1,y)
3) Draw the text at (x,y+1)
4) Draw the text at (x,y-1)
B) Select the font body color
5) Draw the text at (x,y)

Here is an example of the results you get after each draw, numbered as in the above steps. In the example the color of the outline is BLACK, and the color of the body of the text is RED. I also added a background with a color similar to color of the body of the text, to show how outlining can increase readability in cases where you don’t know what the color of the background is (like in cases where the background could be any image).

fontdemo1.jpg

To make it even clearer for you I did the same thing but this time I rendered the body of the text in gray after each steps 1,2,3 and 4. This way it becomes very clear how the outline is constructed, with each draw, around the body of the text:

fontdemo2.jpg

In Java, a very simple example of a method that does exactly what described looks like:

public void drawTextOutlined(Graphics g,
                            String text,
                            int x, int y,
                            Color cOutline,
                            Color cBody) {
   g.setColor(cOutline);
   g.drawString(text, x+1, y);
   g.drawString(text, x-1, y);
   g.drawString(text, x, y+1);
   g.drawString(text, x, y-1);
   g.setColor(cBody);
   g.drawString(text, x, y);
}

Variations:

This method of outlining can be used with pretty much anything that you can render in a given color; it doesn’t have to be only text. In some cases it can even be expanded to images. It’s somewhat of a long story, but if anybody cares I can post about that as well.

There are also many variations based on the same concept. For example you can draw the outline rendering the text in the outline color at positions (x+1,y+1) (x+1,y-1) (x-1,y+1) (x-1,y-1) with similar results. You can also try drawing the outline with only two renderings of the text in the outline color, at positions (x+1,y+1) (x-1,y-1) or (x-1,y-1) (x+1,y+1), saving two text renderings and obtaining OK results in most cases.

I prefer the variations presented here, which gave me the best results in the situations I had, but feel free to experiment. There are cases where different variations might give you better results.

Hope you’ll find this helpful.

When You Miss The Case

Wednesday, January 31st, 2007

One rainy day you write some code in C++, and compile it with no errors. It might just work, you hope. You run it and it just doesn’t do what it should be doing. You debug it, look at it, think about it, tweak it… but… nothing! You try to understand. The code is there. Only a few lines, doing something that doesn’t seem right.

[Am I going mad?]

typedef enum
{
	FIRST_ONE,
	SECOND_ONE,
	THIRD_ONE
} T_states;

int main()
{
	T_states x=FIRST_ONE;

	switch(x)
	{
		FIRST_ONE:
			printf("First one! Yeah.n");
			break;
		SECOND_ONE:
		THIRD_ONE:
			printf("Second or third one?n");
                        break;
		default:
			printf("None of them!n");
                        break;
	}
	return 0;
}

…you find yourself kneeling down in front of your desk with your fists ready to smash the screen… then… with your amazement… you figure it out… you completely missed the case… Bad words associated with the compiler pop to mind.

There are mistakes that you never made, and that you’d never think you would make. When you do make them, you just don’t see them, because everything looks so innocent and normal… except… that you missed the darn case…

Yep, the code above compiles just fine. No errors, at least not with VS and with another embedded compiler I’ve compiled it with. In fact, it is perfectly syntactically valid code. Evil, but valid.

When you run this code it prints “None of them!”. Yep. You missed the case!!!! (the “case” keywords before the constants inside the switch).

The compiler takes “FIRST_ONE”, “SECOND_ONE” and “THIRD_ONE” as goto labels, and doesn’t complain. Everything compiles. Obviously when you run it, the execution runs straight to the default case.

Never miss a case, especially when you are tired!! :)