Recent

Author Topic: Small question about fonts  (Read 8885 times)

DiCri

  • Full Member
  • ***
  • Posts: 151
  • My goal : Build a game
    • http://manueldicriscito.altervista.org/DinoLand.zip
Small question about fonts
« on: September 02, 2016, 12:06:36 pm »
Is it possible to pick up text fonts from images? I see some program do it and so i'd like to know how to do. Thank you!
I'm a game developer.. Now studying..
Go download my game:
http://manueldicriscito.altervista.org/DinoLand.zip

marcov

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 8780
  • FPC developer.
Re: Small question about fonts
« Reply #1 on: September 02, 2016, 12:11:24 pm »
Fonts for non GUI purposes (Games and opengl/directx environments in general like e.g. in maps of navigation devices) are often stored in images.

These are specially crafted for the purpose though, and the fonts are often not very scalable (limited range).

There are some ways to improve that (e.g. signed distance fonts, see signed distance fonts in lazarus thread), but in remains a special purpose technology.

Thaddy

  • Hero Member
  • *****
  • Posts: 10516
Re: Small question about fonts
« Reply #2 on: September 02, 2016, 01:12:24 pm »
Is it possible to pick up text fonts from images? I see some program do it and so i'd like to know how to do. Thank you!
Well, Marco has a good pointer for you, but there are also other possibilities:
Often a game font is included as a resource bitmap. You can read out that resource bitmap, save it and examine its layout with a resource explorer and an image editor.
Many times it is a bitmap of say 250x250 pixels dived up in equal sized characters. You can then simply refer to a small square index x,y in the big square and map it to a character.
This is all pretty easy to do and a good excersice. Of course these are fixed sized fonts, but in games that is often the case (Starting from Doom and the likes).
« Last Edit: September 02, 2016, 01:15:09 pm by Thaddy »

marcov

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 8780
  • FPC developer.
Re: Small question about fonts
« Reply #3 on: September 02, 2016, 01:22:57 pm »
The term you sometimes see used is fontmap. Note that the actual font is the bitmap with the font PLUS some metadata where to find which letter in the bitmap.

Signed distance fonts (as in my demo) are the same principle, but instead of a pixel value, a signed distance of every pixel to the closest edge of the character is used.

This allows the character to be drawn with some hardware-accelerated scaling and anti-aliasing.

For software based fontrendering, often the freetype library is used.

Handoko

  • Hero Member
  • *****
  • Posts: 3850
  • My goal: build my own game engine using Lazarus
Re: Small question about fonts
« Reply #4 on: September 02, 2016, 05:34:38 pm »
@Manu12x

There are several possibilities to use fonts on games. The most common and I think also the easiest is using Resource Bitmap as explained by Thaddy. It uses no any special technology, just RenderyCopy to copy part of the big image as you've just learned some days ago:
http://forum.lazarus.freepascal.org/index.php/topic,33837.msg220282.html

The tricky part is how to know the X, Y, W, H values for each of the characters. If it is fixed-width font, you can easily do calculation to get the X value. If it is variable-width font, you have to store each of the characters' width.

The more 'hi-tech' one is the one explained by marcov. I never really tried it, I've just tried to understand the concept. Wow, impressive - that what I only can say.

The other trick is what I used on my GLVisualComponents. I am too lazy to draw nor generate the font. When the program starts, it will automatically draw the large characters from a-z, A-Z, 0-9 and some symbols using default font, and stores them into memory along with width of each characters. When the font need to be used, it will automatically scaled down to the necessary size (because I use OpenGL).

My trick has its advantages, that are to dismiss the use of external file (the Resourse Bitmap) and the font style follows the default of the theme on the computer. The disadvantage is the font style maybe boring and not looking good for certain games.

Usually,  game designers draw their own fonts. But if you're a lazy bone (like me  ::)) here is a good site can be used to generated your font bitmap:
http://cooltext.com/

DiCri

  • Full Member
  • ***
  • Posts: 151
  • My goal : Build a game
    • http://manueldicriscito.altervista.org/DinoLand.zip
Re: Small question about fonts
« Reply #5 on: September 03, 2016, 02:20:22 pm »
@Manu12x

There are several possibilities to use fonts on games. The most common and I think also the easiest is using Resource Bitmap as explained by Thaddy. It uses no any special technology, just RenderyCopy to copy part of the big image as you've just learned some days ago:
http://forum.lazarus.freepascal.org/index.php/topic,33837.msg220282.html

The tricky part is how to know the X, Y, W, H values for each of the characters. If it is fixed-width font, you can easily do calculation to get the X value. If it is variable-width font, you have to store each of the characters' width.

The more 'hi-tech' one is the one explained by marcov. I never really tried it, I've just tried to understand the concept. Wow, impressive - that what I only can say.

The other trick is what I used on my GLVisualComponents. I am too lazy to draw nor generate the font. When the program starts, it will automatically draw the large characters from a-z, A-Z, 0-9 and some symbols using default font, and stores them into memory along with width of each characters. When the font need to be used, it will automatically scaled down to the necessary size (because I use OpenGL).

My trick has its advantages, that are to dismiss the use of external file (the Resourse Bitmap) and the font style follows the default of the theme on the computer. The disadvantage is the font style maybe boring and not looking good for certain games.

Usually,  game designers draw their own fonts. But if you're a lazy bone (like me  ::)) here is a good site can be used to generated your font bitmap:
http://cooltext.com/
I already know that website.. i used it for creating logo images. I know that i can use RenderCopy, but if i want to draw text like "hello" i don't know how to divide this word and pick up the letters from the image.. Not only bmp but i see PNG too..
I'm a game developer.. Now studying..
Go download my game:
http://manueldicriscito.altervista.org/DinoLand.zip

DiCri

  • Full Member
  • ***
  • Posts: 151
  • My goal : Build a game
    • http://manueldicriscito.altervista.org/DinoLand.zip
Re: Small question about fonts
« Reply #6 on: September 03, 2016, 02:25:28 pm »
I know no one can understand me.
I'm a game developer.. Now studying..
Go download my game:
http://manueldicriscito.altervista.org/DinoLand.zip

Handoko

  • Hero Member
  • *****
  • Posts: 3850
  • My goal: build my own game engine using Lazarus
Re: Small question about fonts
« Reply #7 on: September 03, 2016, 02:46:39 pm »
I know no one can understand me.

The problem is we don't know how much you know about Pascal programming. So we just pointed out the basic things and we thought you will understand how to do it. Rendering text from a font bitmap file actually isn't the thing a newbie programmer should try. Because you want to do it, so we thought you already have good knowlegde about Pascal.

Okay, here I explained in more detail.

But before I start, I want to know have you already known how to do these things:
- Using array in Pascal
- Read image from file and save it to memory buffer
- Using graphics editing software to generate a font bitmap

Please answer me, before I move to detail of showing text using font bitmap.

Handoko

  • Hero Member
  • *****
  • Posts: 3850
  • My goal: build my own game engine using Lazarus
Re: Small question about fonts
« Reply #8 on: September 03, 2016, 07:38:29 pm »
.... No reply?

Ok, I'm starting to explain now.


Using array in Pascal

You need to use array to store each of the font pictures copied from the loaded image. To do it, first load the font bitmap (or image), then perform some calculations and copy the rectangular size of the single character from the font image and store it in a array.

The array to store the font pictures is declared like this:
Code: [Select]
var
  MyFonts: array[1..something] of PSDL_Texture;
Note: something is the characters count in your font image.

But as I remember, you ever said you haven't learn array from your school, so I will tried to avoid the using of array.

Read image from file and save it to memory buffer

I guess you already know how to do it. I won't explain this topic.

Using graphics editing software to generate a font bitmap

This is not a programming thing, so I skip the process about how I draw the font image using Gimp. You can simply use the image I provide.

In the font image provided, I use:
- 30 pixels width for each character
- 30 pixels height for each character
- I intentionally draw the rectangle so you can have the idea of the size
- It consist only: a..z, A..Z, 0..9

Some useful links (for beginners only):
https://en.wikipedia.org/wiki/ASCII
http://wiki.freepascal.org/Mod
http://www.freepascal.org/docs-html/rtl/system/length.html
http://www.freepascal.org/docs-html/rtl/system/ord.html
http://wiki.freepascal.org/Div

As usual, I do not provide working codes. You have to learn from my code and write your own. And it is not optimized and has not tested. This code provided here is to give you the idea how to use font image.

I do not use SDL, so any SDL experts please correct my code if I write something wrong.

Code: [Select]
procedure WriteText(R: PSDL_Renderer; X, Y: Integer; const S: string);
var
  i: Integer;
  CurrentChar: Char;
  FontPos: Integer;
  SourceRect, DestinationRect: PSDL_Rect;
begin
  for i := 1 to Length(S) do begin

    // Get the font position of the character
    FontPos := 0;
    CurrentChar := S[i];
    if (CurrentChar >= 'a') and (CurrentChar <= 'z') then
      FontPos := ord(C) - 96; // ASCII value of 'a' is 97
    if (CurrentChar >= 'A') and (CurrentChar <= 'Z') then
      FontPos := ord(C) - 64 + 26; // ASCII value of 'A' is 65
    if (CurrentChar >= '0') and (CurrentChar <= '9') then
      FontPos := ord(C) - 47 + 52; // ASCII value of '0' is 48

    // Render it if the character can be found in the font image
    if (FontPos > 0) then begin
      with SourceRect do begin
        y := (FontPos div 10) * 30; // 30 is the height of the font
        x := ((FontPos-1) mod 10) * 30; // 30 is the width of the font
        w := 30;
        h := 30;
      end;
      with DestinationRect do begin
        x := i * 30;
        w := 30;
        h := 30;
      end;
      DestinationRect.y := Y;
      SDL_RenderCopy(R, LoadedFontTexture, SourceRect, DestinationRect);
      end;
    end;

end;

Further improvement:
- You can add more characters, symbols, etc
- The font in this font image looks ugly, you should decrease its width
- You should remove the rectangles (horizontal and vertical lines)
- Variable-width fonts usually will look better, but to draw it more things are needed to be performed
- It can be optimized for speed
« Last Edit: September 03, 2016, 08:01:25 pm by Handoko »

DiCri

  • Full Member
  • ***
  • Posts: 151
  • My goal : Build a game
    • http://manueldicriscito.altervista.org/DinoLand.zip
Re: Small question about fonts
« Reply #9 on: September 04, 2016, 12:05:14 pm »
No reply because i was offline.. but that example is what i was searching for!! In these days i will release my game and so you can see ( with source code ) how much i know programming with Pascal.. Thanks
I'm a game developer.. Now studying..
Go download my game:
http://manueldicriscito.altervista.org/DinoLand.zip

DiCri

  • Full Member
  • ***
  • Posts: 151
  • My goal : Build a game
    • http://manueldicriscito.altervista.org/DinoLand.zip
Re: Small question about fonts
« Reply #10 on: September 05, 2016, 05:45:50 pm »
.... No reply?

Ok, I'm starting to explain now.


Using array in Pascal

You need to use array to store each of the font pictures copied from the loaded image. To do it, first load the font bitmap (or image), then perform some calculations and copy the rectangular size of the single character from the font image and store it in a array.

The array to store the font pictures is declared like this:
Code: [Select]
var
  MyFonts: array[1..something] of PSDL_Texture;
Note: something is the characters count in your font image.

But as I remember, you ever said you haven't learn array from your school, so I will tried to avoid the using of array.

Read image from file and save it to memory buffer

I guess you already know how to do it. I won't explain this topic.

Using graphics editing software to generate a font bitmap

This is not a programming thing, so I skip the process about how I draw the font image using Gimp. You can simply use the image I provide.

In the font image provided, I use:
- 30 pixels width for each character
- 30 pixels height for each character
- I intentionally draw the rectangle so you can have the idea of the size
- It consist only: a..z, A..Z, 0..9

Some useful links (for beginners only):
https://en.wikipedia.org/wiki/ASCII
http://wiki.freepascal.org/Mod
http://www.freepascal.org/docs-html/rtl/system/length.html
http://www.freepascal.org/docs-html/rtl/system/ord.html
http://wiki.freepascal.org/Div

As usual, I do not provide working codes. You have to learn from my code and write your own. And it is not optimized and has not tested. This code provided here is to give you the idea how to use font image.

I do not use SDL, so any SDL experts please correct my code if I write something wrong.

Code: [Select]
procedure WriteText(R: PSDL_Renderer; X, Y: Integer; const S: string);
var
  i: Integer;
  CurrentChar: Char;
  FontPos: Integer;
  SourceRect, DestinationRect: PSDL_Rect;
begin
  for i := 1 to Length(S) do begin

    // Get the font position of the character
    FontPos := 0;
    CurrentChar := S[i];
    if (CurrentChar >= 'a') and (CurrentChar <= 'z') then
      FontPos := ord(C) - 96; // ASCII value of 'a' is 97
    if (CurrentChar >= 'A') and (CurrentChar <= 'Z') then
      FontPos := ord(C) - 64 + 26; // ASCII value of 'A' is 65
    if (CurrentChar >= '0') and (CurrentChar <= '9') then
      FontPos := ord(C) - 47 + 52; // ASCII value of '0' is 48

    // Render it if the character can be found in the font image
    if (FontPos > 0) then begin
      with SourceRect do begin
        y := (FontPos div 10) * 30; // 30 is the height of the font
        x := ((FontPos-1) mod 10) * 30; // 30 is the width of the font
        w := 30;
        h := 30;
      end;
      with DestinationRect do begin
        x := i * 30;
        w := 30;
        h := 30;
      end;
      DestinationRect.y := Y;
      SDL_RenderCopy(R, LoadedFontTexture, SourceRect, DestinationRect);
      end;
    end;

end;

Further improvement:
- You can add more characters, symbols, etc
- The font in this font image looks ugly, you should decrease its width
- You should remove the rectangles (horizontal and vertical lines)
- Variable-width fonts usually will look better, but to draw it more things are needed to be performed
- It can be optimized for speed
Ok i tried your code and it doesn't works correctly, writing alphabet : "ABCDEFGHITLMNO.." and so i fixed it adding this
Code: Pascal  [Select][+][-]
  1. var hy : integer;
  2. ...
  3. If FontPos < 21 then hy := 11 else
  4. If FontPos mod 10 = 0 then hy:=11 else
  5. hy := 10;
  6.  
  7.  

And i modified this

Code: Pascal  [Select][+][-]
  1.  
  2. If FontPos > 0 then
  3.   Begin
  4.   With SourceRect^ do
  5.     begin
  6.       Y := ( FontPos div hy ) * 30;
  7.       X:= ( (FontPos -1) mod 10) * 30;
  8. ...
  9.  

And so now it works!
I'm a game developer.. Now studying..
Go download my game:
http://manueldicriscito.altervista.org/DinoLand.zip

Handoko

  • Hero Member
  • *****
  • Posts: 3850
  • My goal: build my own game engine using Lazarus
Re: Small question about fonts
« Reply #11 on: September 05, 2016, 06:41:21 pm »
I haven't test my code, it can contain some bugs.

And so now it works!

Glad to know you can fix it and make it work.

Programming is fun. You don't simply copy/paste and use it. But you read the code, fix and improve it. You now have the basic code to use font image, you can make further improvements and save the code for reusing in the future.

Some suggestions:
- Add more characters and symbols
- Try other more cool fonts
- You can improve it to become spritesheet, even further: sprite animation

You have known the basic, but the usability and possibilities is endless.

Sprite animation can be done using similar trick of font image technique, just add some more calculations.

You can find some free spritesheets here:
http://opengameart.org/content/various-walkcycle-8-characters
http://opengameart.org/content/platformer-art-deluxe
http://opengameart.org/content/platflormer-asset-pack-1
http://opengameart.org/users/ctatz
http://opengameart.org/content/simple-broad-purpose-tileset

Have fun!

DiCri

  • Full Member
  • ***
  • Posts: 151
  • My goal : Build a game
    • http://manueldicriscito.altervista.org/DinoLand.zip
Re: Small question about fonts
« Reply #12 on: September 05, 2016, 11:19:45 pm »
I haven't test my code, it can contain some bugs.

And so now it works!

Glad to know you can fix it and make it work.

Programming is fun. You don't simply copy/paste and use it. But you read the code, fix and improve it. You now have the basic code to use font image, you can make further improvements and save the code for reusing in the future.

Some suggestions:
- Add more characters and symbols
- Try other more cool fonts
- You can improve it to become spritesheet, even further: sprite animation

You have known the basic, but the usability and possibilities is endless.

Sprite animation can be done using similar trick of font image technique, just add some more calculations.

You can find some free spritesheets here:
http://opengameart.org/content/various-walkcycle-8-characters
http://opengameart.org/content/platformer-art-deluxe
http://opengameart.org/content/platflormer-asset-pack-1
http://opengameart.org/users/ctatz
http://opengameart.org/content/simple-broad-purpose-tileset

Have fun!
The most difficult i find in programming is creating automatic calculations like in your code, so i take a few hours to understand it, but.. Ok i should see the meaning of sprite😂
I'm a game developer.. Now studying..
Go download my game:
http://manueldicriscito.altervista.org/DinoLand.zip

DiCri

  • Full Member
  • ***
  • Posts: 151
  • My goal : Build a game
    • http://manueldicriscito.altervista.org/DinoLand.zip
Re: Small question about fonts
« Reply #13 on: September 05, 2016, 11:58:45 pm »

Sprite animation can be done using similar trick of font image technique, just add some more calculations.

You can find some free spritesheets here:
http://opengameart.org/content/various-walkcycle-8-characters
http://opengameart.org/content/platformer-art-deluxe
http://opengameart.org/content/platflormer-asset-pack-1
http://opengameart.org/users/ctatz
http://opengameart.org/content/simple-broad-purpose-tileset

Have fun!
OOOHh sprite sheet.. But i already know it, I always use it in my game. For example try to download my beta game http://manueldicriscito.altervista.org/DinoLand.zip and in Resources folder there are the images (sprite sheet ).
The only thing i learned in this topic is "lenght(string)" and "string" because i didn't knew these functions. I already know how to use spritesheets, i repeat please try to download my small game ( 5MB ) ( no source code but i will upload it ) and see how much is my knowledge in Pascal programming.. ok, Bye
I'm a game developer.. Now studying..
Go download my game:
http://manueldicriscito.altervista.org/DinoLand.zip

Handoko

  • Hero Member
  • *****
  • Posts: 3850
  • My goal: build my own game engine using Lazarus
Re: Small question about fonts
« Reply #14 on: September 06, 2016, 05:28:21 am »
I have downloaded your game. But it can't run, it said:
Quote
This application has failed to start because SDL2.dll was not found. Re-installing the application may fix this problem.

Before you use a library, you have to read the documentation about how to deploy it. Most libraries including GTK, QT and SDL require the programmer to manually provides the runtime files.

If I'm not wrong, certain versions of SDL now allow static linking, which will make the deployment easier. You may need to learn what is static linking and dynamic linking, and how to do it.

The need to include runtime files is one of the reasons that I avoid to use ready-to-use graphics/game engines. I prefer to write my own using OpenGL (which is installed by default on most OSes). Most the programs I wrote are portable, no need to include extra files, only 1 single executable that can copy and run. Even when it needs extra files (config, data, etc), it will auto generate on its first run.

Writing portable app is an art.
It's more challenging but it's fun.
« Last Edit: September 06, 2016, 05:40:54 am by Handoko »

 

TinyPortal © 2005-2018