Author Topic: Graphic Font Code  (Read 5344 times)

0 Members and 1 Guest are viewing this topic.

Offline rickclark58

  • Newbie
  • Posts: 18
    • View Profile
    • YouTube Channel
Graphic Font Code
« on: September 16, 2021, 06:55:37 pm »
This is the graphic font code that I used in FreeBasic which I have converted over to QB64. I am not that familiar with QB64 yet so any suggestions for improvement are welcome. I am using the Dwarf Fortress graphic format which is a 16x16 character grid in png format. I used png since I am not sure about transparency values in other formats.

Here is the graphic I am using: https://drive.google.com/file/d/1YHDaM1m6scBquqTFO7dUIJc7YOXxF5N1/view?usp=sharing

Code: [Select]
'Copyright 2021 Richard D. Clark

'Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"),
'to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,
'and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

'The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

'THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
'FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
'LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
'IN THE SOFTWARE.
'========================================================================================================================================================
'This code displays a graphic font. You can access the font either by character or ascii code.
Option _Explicit

'Screen and image coords.
Type coords
    x As Integer
    y As Integer
End Type
'Working consts.
Const False = 0
Const True = Not False
Const fontsize = 16
'This is the location of each character in the font.
Dim fgrid(0 To 255) As coords
Dim fhandle As Long
Dim As Integer ret, cx, cy, ic
Dim As String mystring

'Using 32 bit screen.
Screen _NewImage(640, 480, 32)
_Title "Graphic Font Demo"
'Load the font.
ret = LoadFont%("16x16.png", fontsize, fgrid(), fhandle)
If ret = False Then
    Print "Could not load font."
Else
    mystring = "Graphic Font Demo"
    cy = fontsize
    cx = (_Width(0) / 2) - ((Len(mystring) / 2) * fontsize) 'Center the string.
    PrintString mystring, cx, cy, fontsize, fgrid(), fhandle
    'Print all the characters.
    cx = 0
    cy = cy + (fontsize) * 2
    For ic = 0 To 255
        PrintByCode ic, cx, cy, fontsize, fgrid(), fhandle
        cx = cx + fontsize
        If cx + fontsize > _Width(0) Then
            cx = 0
            cy = cy + fontsize
        End If
    Next
End If


Sub PrintString (c As String, x As Integer, y As Integer, fsize As Integer, grd() As coords, handle As Long)
    Dim As Integer x1, y1, x2, y2, charw, charh, i, ch, nx, ny
    'Calculate the character width and height.
    charw = _Width(handle) / fsize
    charh = _Height(handle) / fsize
    nx = x
    ny = y
    For i = 1 To Len(c)
        ch = Asc(Mid$(c, i, 1))
        'Get the character coords.
        x1 = grd(ch).x
        x2 = grd(ch).x + charw - 1
        y1 = grd(ch).y
        y2 = grd(ch).y + charh - 1
        If nx < _Width(0) + charw Then
            _PutImage (nx, ny), handle, 0, (x1, y1)-(x2, y2)
            nx = nx + charw
        End If
    Next
End Sub

Sub PrintByCode (c As Integer, x As Integer, y As Integer, fsize As Integer, grd() As coords, handle As Long)
    Dim As Integer x1, y1, x2, y2, charw, charh
    If c >= 0 And c <= 255 Then
        'Calculate the character width and height.
        charw = _Width(handle) / fsize
        charh = _Height(handle) / fsize
        'Get the character coords.
        x1 = grd(c).x
        x2 = grd(c).x + charw - 1
        y1 = grd(c).y
        y2 = grd(c).y + charh - 1
        _PutImage (x, y), handle, 0, (x1, y1)-(x2, y2)
    End If
End Sub

'Loads the font into memory. The fonts graphic has to be square such as 16x16 characters. This is the standard Dwarf Fortress format.
Function LoadFont% (FontName As String, fsize As Integer, grd() As coords, handle As Long)
    Dim As Integer x, y, charw, charh, px, py

    handle = _LoadImage(FontName, 32)
    If handle > -2 Then
        LoadFont% = False
    Else
        'Calculate the character width and height.
        charw = _Width(handle) / fsize
        charh = _Height(handle) / fsize
        'Fill in the grid.
        px = 0
        py = 0
        For y = 0 To 15
            For x = 0 To 15
                grd(x + y * fsize).x = px
                grd(x + y * fsize).y = py
                px = px + charw
            Next
            px = 0
            py = py + charh
        Next
        LoadFont% = True
    End If
End Function
« Last Edit: September 16, 2021, 06:56:51 pm by rickclark58 »
Rick Clark

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
    • View Profile
Re: Graphic Font Code
« Reply #1 on: September 16, 2021, 07:18:12 pm »
Can you attach the 16x16.png?

Just pack it all up in a zip like this:
* Font Sheet test.zip (Filesize: 1.43 MB, Downloads: 237)
« Last Edit: September 16, 2021, 07:25:24 pm by bplus »

FellippeHeitor

  • Guest
Re: Graphic Font Code
« Reply #2 on: September 16, 2021, 07:33:49 pm »
Welcome aboard, @rickclark58 and thanks for sharing it.

Offline rickclark58

  • Newbie
  • Posts: 18
    • View Profile
    • YouTube Channel
Re: Graphic Font Code
« Reply #3 on: September 16, 2021, 08:41:15 pm »
Thank you. I am enjoying QB64 quite a bit. Trying to get up to speed on it.
Rick Clark

Offline rickclark58

  • Newbie
  • Posts: 18
    • View Profile
    • YouTube Channel
Re: Graphic Font Code
« Reply #4 on: September 16, 2021, 08:43:49 pm »
Here is the font file.
* 16x16.zip (Filesize: 8.85 KB, Downloads: 212)
Rick Clark

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
    • View Profile
Re: Graphic Font Code
« Reply #5 on: September 16, 2021, 08:59:32 pm »
Thanks

Code: QB64: [Select]
  1. _Title "WELCOME"
  2. Const xmax = 1200
  3. Const ymax = 600
  4.  
  5. Common Shared cN, pR!, pG!, pB!
  6.  
  7. Screen _NewImage(xmax, ymax, 32)
  8. mess$ = " Amazing.bas how sweet thou art... "
  9. Print mess$
  10. w = 8 * Len(mess$): h = 16
  11. Dim p(w, h)
  12. black&& = Point(0, 10)
  13. For y = 0 To h
  14.     For x = 0 To w
  15.         If Point(x, y) <> black&& Then
  16.             p(x, y) = 1
  17.         End If
  18.     Next
  19.  
  20. xo = 5: yo = 235: m = 4
  21. resetPlasma
  22.     For y = 0 To h - 1
  23.         For x = 0 To w - 1
  24.             If p(x, y) Then
  25.                 changePlasma
  26.             Else
  27.                 Color 0
  28.             End If
  29.             Line (xo + x * m, yo + y * m)-(xo + x * m + m, yo + y * m + m), , BF
  30.         Next
  31.     Next
  32.     _Limit 10
  33.     lc = lc + 1
  34.     If lc Mod 30 = 0 Then resetPlasma
  35.  
  36. Sub changePlasma ()
  37.     cN = cN + 1
  38.     Color _RGB(127 + 127 * Sin(pR! * .3 * cN), 127 + 127 * Sin(pG! * .3 * cN), 127 + 127 * Sin(pB! * .3 * cN))
  39.  
  40. Sub resetPlasma ()
  41.     pR! = Rnd ^ 2: pG! = Rnd ^ 2: pB! = Rnd ^ 2
  42.  
  43.  

Offline rickclark58

  • Newbie
  • Posts: 18
    • View Profile
    • YouTube Channel
Re: Graphic Font Code
« Reply #6 on: September 16, 2021, 10:42:26 pm »
Very cool.
Rick Clark

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
    • View Profile
Re: Graphic Font Code
« Reply #7 on: September 17, 2021, 12:17:54 pm »
@rickclark58

There is something odd about your "16x 16.png", it doesn't display in either Paint nor just clicking it in a Windows File Explorer listing. It does show in Paint 3D and there it has a glow bar along bottom row of letters.
How did this image get created?

There is so many ways to do this kind of thing...

If you just want the image that can be expanded or shrunk or even rotated by 90's you could use _PutImage. It can take any box area in image and project it to any place on screen. The image can get extremely distorted but sometimes that's perfect. This would be good practice for tiles off images too. So you could do 16x16 or 32x32 or 16x48 or any n x any m that is smaller than screen and image. Probably easier than what you have done and would be good practice. You'd store the image in a handle and make a Sub that picks and prints characters from image to screen using _PutImage not very different that what you've done.

Then there is the easy way, just pick a nice .ttf font, load it and switch to it when / where you want and print with _PrintString(topleftX, topLeftY), text$

Now if you want to mess with the colors in the print like I did in Welcome, you could collect points from the ascii characters printed on screen like your chart image. Basically using Point and storing character images in array(s) or just saving the image in a separate handle. Then print each point as a tiny rectangle so you can make wide fat letters or tall thin letters and again you have control over what color to make each rectangle.

Offline rickclark58

  • Newbie
  • Posts: 18
    • View Profile
    • YouTube Channel
Re: Graphic Font Code
« Reply #8 on: September 17, 2021, 01:25:12 pm »
It is a 32-bit png with transparency with white letters so it is hard to see in explorer. It looks fine to me. I used Paint.Net to convert from BMP to PNG. I don't need rotated text or anything like that. This is to substitute for the built-in ASCII characters. This is the format Dwarf Fortress uses. I wasn't aware of the black transparency for BMP when I did this or I probably would have used that. They have a tile repository on the DF wiki: https://dwarffortresswiki.org/Tileset_repository They have several different sizes but the standard is a 16x16 character file. I just saw the font command in the wiki. I need to look at that more.
Rick Clark

Offline rickclark58

  • Newbie
  • Posts: 18
    • View Profile
    • YouTube Channel
Re: Graphic Font Code
« Reply #9 on: September 18, 2021, 10:31:57 am »
When I originally created this code I made some templates for GIMP and Paint.Net to make my own graphics. Here are the templates in case you want to use them in your own projects. Both GIMP and Paint.Net are free.
* grtemplates.zip (Filesize: 50.86 KB, Downloads: 182)
Rick Clark

Offline rickclark58

  • Newbie
  • Posts: 18
    • View Profile
    • YouTube Channel
Re: Graphic Font Code
« Reply #10 on: September 18, 2021, 04:50:39 pm »
I case it isn't obvious, you can use this code for tilesets, as well as a graphic font. I used the templates to create tile sheets and that way I could reference each tile based on the code I had defined in the program. It is a very simple way to package graphics for a game and very simple to use.
Rick Clark

Offline SMcNeill

  • QB64 Developer
  • Forum Resident
  • Posts: 3972
    • View Profile
    • Steve’s QB64 Archive Forum
Re: Graphic Font Code
« Reply #11 on: September 18, 2021, 05:40:00 pm »
It’s also an easy way to embed fonts into a program via data statements.  Instead of a 16x16 image, just store that 16x16 data in data statements instead and then READ them back as needed.  ;)
https://github.com/SteveMcNeill/Steve64 — A github collection of all things Steve!

Offline rickclark58

  • Newbie
  • Posts: 18
    • View Profile
    • YouTube Channel
Re: Graphic Font Code
« Reply #12 on: September 18, 2021, 07:46:04 pm »
Ah yes, I have done that before. You can store all kinds of interesting stuff in a Data statement.
Rick Clark