Font library?

General FreeBASIC programming questions.
Torahteen
Posts: 91
Joined: Jul 15, 2005 15:58
Contact:

Font library?

Post by Torahteen »

'Tis me again :D. Anyone know of a library for FreeBasic that allows me to print a special text font anywhere on the screen? I want to be able to have different fonts, sizes, and styles if possible.
jofers
Posts: 1525
Joined: May 27, 2005 17:18

Post by jofers »

Actually, I was just working on such a thing :)

Code: Select all

Option Explicit

#include "windows.bi"
#include "externs.bi"

Enum FontOptionsEnum
    Bold = &b1
    Italic = &b10
    Underline = &b100
    StrikeThrough = &b1000
    AntiAliased = &b10000
End Enum

Declare Function FormatMessage Alias "FormatMessageA" (ByVal dwFlags As DWORD, ByVal lpSource As LPCVOID, ByVal dwMessageId As DWORD, ByVal dwLanguageId As DWORD, ByVal lpBuffer As LPTSTR, ByVal nSize As DWORD, ByVal Arguments As Any Ptr) As DWORD
Declare Function PrintFont(ByVal x As Integer, ByVal y As Integer, ByVal Text As String, ByVal TextColor As uInteger, ByVal ReturnSprite As Integer = 0) As Integer
Declare Function SetFont(ByVal FontName As String = "Arial", ByVal FontSize As uInteger = 12, ByVal FontOptions As uInteger = 0) As HFONT

Declare Function InitTTF As Integer


'Set Screen Mode
ScreenRes 640, 480, 32

Dim Shared BitmapV4Header As BitmapV4Header
Dim Shared MemBMP As HBITMAP
Dim Shared MemDC As HDC
Dim Shared MemSprite As Any Ptr
Dim As Byte PixVal

Dim As Integer x, y
For y = 0 To 479
    For x = 0 To 639
        Pset(x, y), Rgb((x Xor y) Shr 4 + 184, (x Xor y) Shr 4 + 184, (x Xor y) Shr 4 + 184)
    Next x
Next y


InitTTF

SetFont "Arial", 15
PrintFont 10, 20, "The Quick Brown Fox Jumped Over The Lazy Red Dog", Rgb(255, 0, 0)
SetFont "Times New Roman", 20, Bold
PrintFont 20, 60, "The Quick Brown Fox Jumped Over The Lazy Red Dog", Rgb(0, 128, 0)

SetFont "Comic Sans MS", 25, Italic
PrintFont 30, 120, "The Quick Brown Fox Jumped Over The Lazy Red Dog", Rgb(0, 0, 255)
SetFont "Courier New", 30, Bold Or Italic Or Underline
PrintFont 20, 180, "The Quick Brown Fox Jumped Over The Lazy Red Dog", Rgb(128, 128, 0)
SetFont "Symbol", 40
PrintFont 10, 260, "The Quick Brown Fox Jumped Over The Lazy Red Dog", Rgb(255, 128, 0)
SetFont "Impact", 50
PrintFont 20, 350, "The Quick Brown Fox Jumped Over The Lazy Red Dog", Rgb(0, 0, 128)

Sleep

Function InitTTF As Integer
    Dim BitmapPalette As LOGPALETTE Ptr
    
    ' Set up BitmapV4Header for ARGB:
    With BitmapV4Header
        .bV4Size = SizeOf(BitmapV4Header)
        .bV4Width = FB_Mode->Width
        .bV4Height = -FB_Mode->Height
        .bV4Planes = 1
        .bV4BitCount = 32
        .bV4V4Compression = BI_BITFIELDS
        .bV4SizeImage = FB_Mode->Width * FB_Mode->Height * 4
        .bV4XPelsPerMeter = 1
        .bV4YPelsPerMeter = 1
        .bV4ClrUsed = 0
        .bV4ClrImportant = 0
    End With    
    
    ' Create Memory Bitmap
    MemDC = CreateCompatibleDC( GetDC(FB_Win32.Wnd))
    MemBMP = CreateCompatibleBitmap( GetDC(FB_Win32.Wnd), FB_Mode->Width, FB_Mode->Height)
    
    SelectObject MemDC, MemBMP
    
    SetBkColor MemDC, Rgb(0, 0, 0)
    SetBkMode(MemDC, TRANSPARENT)
    
    PrintFont -10, -10, ".", Rgb(0, 0, 0)
    
    If cInt(MemDC) And cInt(MemBMP) Then Return TRUE
End Function

Function SetFont(ByVal FontName As String = "Arial", ByVal FontSize As uInteger = 12, ByVal FontOptions As uInteger = 0) As HFONT
    Dim nHeight As uInteger
    Dim nWidth As uInteger
    Dim nEscapement As uInteger
    Dim nOrientation As uInteger
    Dim fnWeight As uInteger
    Dim fdwItalic As uInteger
    Dim fdwUnderline As uInteger
    Dim fdwStrikeOut As uInteger
    Dim fdwCharSet As uInteger
    Dim fdwOutputPrecision As uInteger
    Dim fdwClipPrecision As uInteger
    Dim fdwQuality As uInteger
    Dim fdwPitchAndFamily As uInteger
    
    Dim hFont As HFONT
    Dim hDC As HDC
    
    hDC = GetDC(FB_Win32.Wnd)
    nHeight = -MulDiv(FontSize, GetDeviceCaps(hDC, LOGPIXELSY), 72)' "pt" sized
    nWidth = 0

    nEscapement = NULL
    nOrientation = NULL
    If FontOptions And Bold Then fnWeight = 700 Else fnWeight = 100
    If FontOptions And Italic Then fdwItalic = TRUE
    If FontOptions And Underline Then fdwUnderline = TRUE
    If FontOptions And StrikeThrough Then fdwStrikeOut = TRUE
    
    fdwQuality = ANTIALIASED_QUALITY
    fdwCharSet = NULL
    fdwOutputPrecision = NULL
    fdwClipPrecision = NULL
    fdwQuality = NULL
    fdwPitchAndFamily = NULL
    
    hFont = CreateFont(             _
        nHeight,                    _
        nWidth,                     _
        nEscapement,                _
        nOrientation,               _
        fnWeight,                   _
        fdwItalic,                  _
        fdwUnderline,               _
        fdwStrikeOut,               _
        fdwCharSet,                 _
        fdwOutputPrecision,         _
        fdwClipPrecision,           _
        fdwQuality,                 _
        fdwPitchAndFamily,          _
        StrPtr(FontName)            _
    )
    
    DeleteObject SelectObject(MemDC, hFont)
    
    Return hFont
End Function

Function PrintFont(ByVal x As Integer, ByVal y As Integer, ByVal Text As String, ByVal TextColor As uInteger, ByVal ReturnSprite As Integer = 0) As Integer
    Dim TextSize As SIZE
    Dim Sprite As Any Ptr
    Dim SpriteData As uByte Ptr
    Dim NewSprite As uByte Ptr
    Dim NewRect As RECT
    Dim As Integer cx, cy
    
    'Calculate Width And Height
    GetTextExtentPoint32 MemDC, StrPtr(Text), Len(Text), @TextSize
    If TextSize.cx + x > FB_Mode->Width Then TextSize.cx = FB_Mode->Width - x
    If TextSize.cy + y > FB_Mode->Height Then TextSize.cy = FB_Mode->Height - y
    
    Sprite = ImageCreate(TextSize.cx, TextSize.cy)

    NewRect.Right = TextSize.cx
    NewRect.Bottom = TextSize.cy
    
    Get (x, y)-(x + TextSize.cx -1, y + TextSize.cy - 1), Sprite
    
    'Copy To Sprite
    With BitmapV4Header
        .bV4Width = TextSize.cx
        .bV4Height = -TextSize.cy
        .bV4SizeImage = TextSize.cx * TextSize.cy * 4
    End With
    
    SetDIBits MemDC, MemBMP, 0, TextSize.cy, Sprite + 4, cPtr(BITMAPINFO Ptr, @BITMAPV4HEADER), DIB_RGB_COLORS
   
    SetTextColor MemDC, TextColor
    DrawText MemDC, StrPtr(Text), Len(Text), @NewRect, NULL
    
    GetDIBits MemDC, MemBMP, 0, TextSize.cy, Sprite + 4, cPtr(BITMAPINFO Ptr, @BITMAPV4HEADER), DIB_RGB_COLORS
    
    If ReturnSprite = 0 Then
        'PUT On Screen
        Put (x, y), Sprite, PSET
        
        ImageDestroy Sprite
    Else
        Return cInt(Sprite)
    End If
End Function
However, it's kind of slow, because Windows GDI is very, very painful:
1) You HAVE to draw to either "DC"s or these rediculous DIB sections that are a pain to use. So I have to c

2) There is no way to turn Anti-aliasing *off* on Windows XP, even with NONANTIALIASING_QUALITY off. So unless you want a pink haze, you have to GET the background, SetDIBits it to a memory DC, Draw the text, GetDIBits it back to a sprite, and then PUT it back on the screen, so that's four sprite blitting/getting routines just to display a line of text.

Buuuuuut, it works well thus far. You need to have FB 0.15b. You also need a copy of "externs.bi", which you can find on my post about using menus with gfxlib in the tips and tricks section.



...

Someone desparately needs to make a library wrapper for FreeType2 :) I'm too dumb/lazy and my time is about to run out again (test week coming up).
Torahteen
Posts: 91
Joined: Jul 15, 2005 15:58
Contact:

Post by Torahteen »

Oh... I forgot to mention, it needs to be DOS compatible
Shadowwolf
Posts: 341
Joined: May 27, 2005 7:01
Location: Canada
Contact:

Post by Shadowwolf »

hmmm best bet would be to look around at a few QB archive sites in misc sections for a TTF reader that can read true type font files.

or some kind of vector font reader.

in any case you will most likely have to port the code your self unless the dos port has a GFX lib and you luck out and find a reader that uses pure QB then you might not have to port the code and simply rip it.
jofers
Posts: 1525
Joined: May 27, 2005 17:18

Post by jofers »

No. There were no QB TTF libraries. The closest thing was a vector font UGL had that also had a utility to convert TTFs. In DOS your best bet is anything that used the FreeType1 port, althought I don't know of any wrapper libraries that were meant for DOS. I believe there was also an Allegro extension called AllegFont that could be used to display TTF fonts, however.

Honestly? For DOS I would use bitmap fonts. I mean, TTF is overkill for anything that isn't an application.
Shadowwolf
Posts: 341
Joined: May 27, 2005 7:01
Location: Canada
Contact:

Post by Shadowwolf »

no i'm shure i saw a TTF reader before back in 2000 i think i saw it at the old neozones file archive.
Torahteen
Posts: 91
Joined: Jul 15, 2005 15:58
Contact:

Post by Torahteen »

Is neozones still up? It doesn't appear to be.
Shadowwolf
Posts: 341
Joined: May 27, 2005 7:01
Location: Canada
Contact:

Post by Shadowwolf »

it is and it isn't the. the new domain is www.neobasic.net but the file achive is long gone.

and i have already look to see if i could find the TTF reader but i couldn't else where on other file achives.


although you might try a the old Dos C community if any group would have some code to pull off what you want that community would. you could compile what ever you find to a lib then use it from FB dos.
jofers
Posts: 1525
Joined: May 27, 2005 17:18

Post by jofers »

I vaguely recall something that read a bit off the header of a TTF file, but something that not only reads the individual glyphs but renders them seems a little improbable for any real-mode dos program, not just QBasic.

Your best bet looks like this, Torahteen:
http://kd.lab.nig.ac.jp/glyph-keeper/introduction.html

You'd have to port the headers yourself, change the file names so they are DOS 8.3 length, find a FreeType binary for DOS and then use Allegro for graphics, but it claims to work on DOS if you do that.
Torahteen
Posts: 91
Joined: Jul 15, 2005 15:58
Contact:

Post by Torahteen »

Does anyone know how a True Type Font file works?
jofers
Posts: 1525
Joined: May 27, 2005 17:18

Post by jofers »

A font file is a collection of glyphs, which for truetypes anyways, are a set of points representing line segments and curves for each supported character. I would highly NOT reccomend trying to write your own TTF loader, though. While possible, it's difficult, and pointless if you just want to view text in your program. Use a premade library such as FreeType or use a bitmap, and I would go with the latter.
Torahteen
Posts: 91
Joined: Jul 15, 2005 15:58
Contact:

Post by Torahteen »

Yeah, I'm gonna just use b-saved files. I was mostly wondering how I would go about making one font be multiple sizes, but I guess it ain't happening.
cha0s
Site Admin
Posts: 5319
Joined: May 27, 2005 6:42
Location: USA
Contact:

Post by cha0s »

by scaling your images, i'd assume ;p (dont ask me HOW to do that)
D.J.Peters
Posts: 8586
Joined: May 28, 2005 3:28
Contact:

Post by D.J.Peters »

dumbledore
Posts: 680
Joined: May 28, 2005 1:11
Contact:

Post by dumbledore »

Torahteen wrote:Oh... I forgot to mention, it needs to be DOS compatible
Post Reply