• Advertisement

Archived

This topic is now archived and is closed to further replies.

Font engines

This topic is 6553 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

How do you do your font engines? I''ve been working on one this weekend and what I''ve come up with this far is: 1. Load a bitmap file to a surface containing the font gfx 2. Load a .fnt file (contains a RECT for every font character to specify where the font is on the bitmap 3. Draw the font by getting the character from a character list (using 87 characters), getting the RECT for the font bitmap and drawing it on the specified destination RECT Are there any faster/better ways of doing this? I want it to be fast and flexible. ============================ Daniel Netz, Sentinel Design "I'm not stupid, I'm from Sweden" - Unknown

Share this post


Link to post
Share on other sites
Advertisement
That''s essentially the way I''m doing it, though I''ve combined the rect information and the bitmap data into a single file. The only other difference is that my fonts can have as many (or as few) characters as you wish (I set it up so that it can do DBCS and Unicode if necessary) to make it easier to do different character sets, or limit the amount of memory it''s taking up in the case that I''m only going to do numbers or other similar character limiting tasks.

Another way to do fonts is to use windows fonts and get a DC for a surface and draw your text to the surface (and then save the surface if you intend to use it more than once). The biggest disadvantage to this (other than possible speed issues) is that your fonts tend to look like Windows (or operating system) fonts.



Mark Fassett
Laughing Dragon Entertainment
http://www.laughing-dragon.com

Share this post


Link to post
Share on other sites
The way you''re doing it seems to be as fast and flexible as any other way I have seen. At least if you''re putting all of these RECTs in an array that can be indexed by character value.

As I''m sure you know it isn''t very funny create the .fnt file in a text editor though. But if you haven''t created a font editor you can use the following way of creating the font file.

I assume fixed size font because if it isn''t this way will not work.

In your font file you can specify the size of each character and then give some strings of characters that give the layout of the characters. Here''s an example of the font file


8 8 // Width and Height
"abcdefghijkl"
"mnopqrstuvwx"
"yz0123456789"
"ABCDEFGHIJKL"
"MNOPQRSTUVWX"
"YZ+-=*/''_ "


When the file is loaded the position of each character is calculated by it''s position in the strings, for example ''a'' would be placed at (0,0) and ''J'' at (80,24).

Share this post


Link to post
Share on other sites
LaughingD: One other disadvantage of using DrawText() or TextOut() besides the speed is that you have to install the font on the system, thus letting the computer owner use it as they please.

I''ve thought about merging the font descriptor file with the bitmap data, but I''m using DirectX7 for VB and I''m not that good with binary files yet.

"As I''m sure you know it isn''t very funny create the .fnt file in a text editor though" - I though of making a DirectDraw font editor to define the RECT of the font character, but I won''t be doing alot of fonts, so I created a program that saves the RECT you specify for the character. That''s easier than doing it in a text editor, also keeps your data intact and saves alot of time from doing a full featured font editor.

As it is now, I lookup every character from my character list, since it doesn''t feature the whole ASCII table (only the ones I will be needing), so it''s quite slow, but I''m thinking of doing a "transparent" function that saves the string converted to the character list values instead, saving the time it takes to look them up. Another way is to create another surface and only draw the font once, to save time.

============================
Daniel Netz, Sentinel Design
"I'm not stupid, I'm from Sweden" - Unknown

Share this post


Link to post
Share on other sites
One thing I forgot. How the heck do you scale the fonts?
When I tested my font drawing function yesterday I couldn''t scale it by one pixel without it looking skewed.
But I guess you can''t do much about that when using DirectDraw since the scaling functions are built in, right?

============================
Daniel Netz, Sentinel Design
"I'm not stupid, I'm from Sweden" - Unknown

Share this post


Link to post
Share on other sites
You say you don''t use the whole ASCII character set. That is fine and normal. You can still use the character value to index into a list though. Just build an array of 128 entries and then only fill in the characters you are using. As you''re using 87 characters you''re only wasting 41 entries, which is certainly affordable in regards to the increase of speed and ease of use, as you don''t need to make your own stringformat.

DDraw automatically scales bitmaps when the destination and source rectangles in Blt() are of different sizes. However, DDraw can only do point filtering, as opposed to bilinear filtering, which will make the font look extremely bad for scaling with fractional values.

Share this post


Link to post
Share on other sites
Actually I''ve created my own character list, an array of 87 characters I use, but maybe it would be faster to do as you said though, since you don''t have to loop through the character list to get the character.

But I think creating a list of character list values and privately store it in the font engine class would make it faster, since you tend to display fonts every loop and draw them to the target surface, or as I said in my previous postings, drawing the font string to a new surface and blit that one to save some time.

Thanks for your help though, I was just afraid my structure would be a bad structure, but it seems like it''s what most people use.

============================
Daniel Netz, Sentinel Design
"I'm not stupid, I'm from Sweden" - Unknown

Share this post


Link to post
Share on other sites
I do not use bitmaps for my fonts. I use somewhat of a compiled font that only holds the pixels that are drawn. The problem with using the bitmap and rect is that there is a lot of data that is not needed; aka the pixels that are masked out of the font. What I do is something along these lines:

#define NUMBER_OF_FONTS 128

struct BIT_XY {
char x, y;
};

struct FONT_STRUCT {
short n_size;
BIT_XY* data;
FONT_STRUCT() : size(0), data(NULL) // c++ only???
{}
~FONT_STRUCT()
{
if (data) delete[] data;
}
};

struct FONTGROUP_STRUCT {
FONT_STRUCT font[NUMBER_OF_FONTS];
};

Each FONT_STRUCT holds a n_size (short) and a data pointer (BIT_XY*). When my program creates the FONTGROUP_STRUCT, is reads a file with NUMBER_OF_FONTS fonts in it. Then for each font it reads the n_size, allocate data (new BIT_XY[n_size] (if n_size > 0)) then reads in n_size BIT_XY structs into the data.

Then when my program wants to write a char, I call:
(psuedo)
PutChar(x_offset,y_offset)
for i = 0 to n_size
placebit(x_offset + font.data.x,y_offset +
font.data[i].y)
next i

Thus drawing the only bits needed, with no mask required, and some memory saved. It is a win - win situation.

This code is a rough sketch of the idea, but you get it. If you would like a code example in DirectDraw (640x400x8) in C++, email me (look at my profile)

Share this post


Link to post
Share on other sites
Spiff, I don''t scale the fonts. If I need a new size, I have to use a "different" font. So I guess they are not really fonts at all. Why do I do it this way? Because I generally don''t need more than three or four different type faces/sizes for the whole game.

I also use an array to store the characters so I can map the character code directly to the character in the array. Using a list will be much slower, especially if you do lots of text, and your average character lookup ends up in the middle. You could adjust this somewhat by putting most often used characters at the front of the list, but it still wouldn''t be as fast as using an array. Like Spellbound said, I think the speed vs size tradeoff for wasting unused character slots definitely comes out on the speed side as the winner.

Mark Fassett
Laughing Dragon Entertainment
http://www.laughing-dragon.com

Share this post


Link to post
Share on other sites
If you do need to scale the fonts, make sure the stored font bmp is the largest size you''ll use in the game. Scaling down looks much nicer than scaling up. You probably already knew that, though Of course, that would waste some memory, but that''s less memory than loading in several different bmps for the different sizes.

Good Luck!


- null_pointer

Share this post


Link to post
Share on other sites
Ok, thanks for your help, people.

One more question though. I would like to specify the color of the text too without creating alot of surfaces for every color. How can I easily change the color of what I''m blitting? (preferably without anything but DirectDraw)

============================
Daniel Netz, Sentinel Design
"I'm not stupid, I'm from Sweden" - Unknown

Share this post


Link to post
Share on other sites
If you're using DX, there was as similar question a while ago:


I wonder how they did it

I think they eventually decided to do the color conversions at run-time. Oh no! Mithrandir's pics are gone. Maybe you could ask him to send them to you -- they're really good illustrations of the task.

Good Luck!


- null_pointer


Edited by - null_pointer on 3/14/00 8:09:51 AM

Share this post


Link to post
Share on other sites
i won't get into the nuts and bolts of it, but this is the font i use :


you might recognize it, it's the default font from mirc32 (fixedsys), but it does the job for me. having 256 elements allows you to customize the fonts for non-standard characters you want to include in your game, lets say a heart or an odd looking arrow. these can be part of the font itself. you would put these in the 128 to 255 portion of the image, so they dont disturb the ASCII portion.

the way i have it, you can make it a monochrome display (with transparent background like in the image) or have it drawn as a normal sprite so that the characters can be comprised of more than one color.

this works really well for me, i just need to call one function to load the font, and another to display text:

font_id = FONT_LoadFont("fixedsys.pcx", etc etc);
font_id2 = FONT_LoadFont("anotherfont.pcx", etc etc);
FONT_GotoXY(font_id, 100, 100);
FONT_Print(font_id, "HP: %d MP: %d", hitpoints, magicpoints);

Edited by - foofightr on 3/14/00 2:10:22 PM

Share this post


Link to post
Share on other sites
and this is the 8x8 BIOS font:


and a 6x4 font i drew myself!


These look really tiny in desktop of 1024x768, but they look fine in fullscreen 640x480. (ok well the 6x4 looks tiny in any resolution except 320x200)

Sorry if it sounds like I''m tooting my own horn, but I really like my font system :D

Share this post


Link to post
Share on other sites
I think there is a better way to do colored text than the alpha blending scheme in the above thread. Since text only requires 2 colors (the text and transparency) you could accomplish the same thing with 2 sets of transparent blits.

1) Create a temp surface to hold your entire message and fill it with the color you want the text to be.

2) Blit the characters from your font file to the temp surface with *black* as the transparent color. This will give you a message that is the right color, surrounded by magenta.

3) Blit the message to the back buffer, but this time use the magenta as the transparent color.

This should still work for black text since the first blit will do practically nothing (you could optimize this part, but it shouldn''t matter too much) so you don''t even have to have 2 special colors to do the 2 transparent blits!

Hope this helps.

Share this post


Link to post
Share on other sites
When you scale a font up, it looks very pixelated. That''s OK for some bitmaps, but text just looks bad that way.

When you scale a font down, important parts end up not being drawn. A scaled-down E may look like F or L, depending on the scale. This is assuming you don''t anti-alias it, but of course AA is very slow.

~CGameProgrammer( );

Share this post


Link to post
Share on other sites

  • Advertisement