ttf examples on 64-bit systems?

External libraries (GTK, GSL, SDL, Allegro, OpenGL, etc) questions.
Post Reply
N3trunn3r
Posts: 110
Joined: Feb 14, 2008 15:48

ttf examples on 64-bit systems?

Post by N3trunn3r »

Are there any new true type font examples for writing whole words/strings?
FreeType2 or Cairo, either would work for me.

In the past I used "FreeType2 library test, by jofers" but this one seems to be broken now. Fonts don't draw properly and I even get malloc errors.

examples/graphics/FreeType/drawstr.bas doesn't work either (black screen).

I'm on Linux 64-bit (Debian 10), FreeBASIC-1.07.1.
paul doe
Moderator
Posts: 1733
Joined: Jul 25, 2017 17:22
Location: Argentina

Re: ttf examples on 64-bit systems?

Post by paul doe »

Here's one example that uses both Cairo and FreeType to load and render fonts:

Code: Select all

#include once "inc/cairo/cairo.bi"
#include once "inc/freetype2/freetype.bi"

'' The FB headers don't contain this prototype
extern "C"
  declare function _
    cairo_ft_font_face_create_for_ft_face ( as FT_Face, as long ) as cairo_font_face_t ptr
end extern

'' Convenience
type FreeType
  public:
    declare constructor()
    declare destructor()
    
    declare operator _
      cast() as FT_Library
    
  private:
    as FT_Library _
      _library
end type

constructor FreeType()
  FT_Init_FreeType( @_library )
end constructor

destructor FreeType()
  FT_Done_FreeType( _library )
end destructor

operator FreeType.cast() as FT_Library
  return( _library )
end operator

dim as integer _
  aWidth => 800, _
  aHeight => 600

'' Set a screen mode
screenRes( aWidth, aHeight, 32 )

'' Create a surface (in this case, we'll use the screen buffer)
var surface => _
  cairo_image_surface_create_for_data( _
    screenPtr(), _
    CAIRO_FORMAT_ARGB32, _
    aWidth, aHeight, _
    aWidth * sizeOf( ulong ) )

'' Create a Cairo context
var context => cairo_create( surface )

'' Load FreeType to use as a font backend
var ft => FreeType()

'' Load a font with FreeType
dim as FT_Face _
  ftface

/'
  BE WELL AWARE:
  
  Only OpenType fonts are correctly handled. This seems to be a bug in
  Cairo. If you pass Cairo a FreeType face created from a TrueType font
  ** THE PROGRAM WILL CRASH **.
'/
FT_New_Face( ft, "BebasKai.otf", 0, @ftface )

'' And pass it to Cairo to create a Cairo font face
var _
  cface => cairo_ft_font_face_create_for_ft_face( ftface, 0 )

cairo_set_font_face( context, cface )
cairo_set_font_size( context, 160 )

dim as string _
  text => "Hello world!"

'' Get the text extents and center it
dim as cairo_text_extents_t extents
cairo_text_extents( context, text, @extents )

dim as single _
  x => ( aWidth - extents.width ) / 2 - extents.x_bearing, _
  y => ( aHeight - extents.height ) / 2 - extents.y_bearing

screenLock()
  cairo_set_source_rgba( context, 1.0, 1.0, 1.0, 1.0 )
  cairo_paint( context )
  
  cairo_move_to( context, x, y )
  cairo_set_source_rgba( context, 0.2, 0.2, 0.2, 1.0 )
  cairo_show_text( context, text )
  
  cairo_surface_flush( surface )
screenUnlock()

'' Cleanup
cairo_destroy( context )
cairo_surface_destroy( surface )

cairo_font_face_destroy( cface )
FT_Done_Face( ftface )

sleep()
Result should be:
Image
TJF
Posts: 3809
Joined: Dec 06, 2009 22:27
Location: N47°, E15°
Contact:

Re: ttf examples on 64-bit systems?

Post by TJF »

Hi N3trunn3r!

On 64 bit systems take care sending a proper stride value to function cairo_image_surface_create_for_data():

Code: Select all

#DEFINE CAIRO_HAS_PDF_SURFACE 1
#DEFINE CAIRO_HAS_PS_SURFACE 1
#DEFINE CAIRO_HAS_SVG_SURFACE 1

#INCLUDE ONCE "cairo/cairo.bi"
#INCLUDE ONCE "cairo/cairo-pdf.bi"
#INCLUDE ONCE "cairo/cairo-ps.bi"
#INCLUDE ONCE "cairo/cairo-svg.bi"

    '{612, 792},     /* HPDF_PAGE_SIZE_LETTER */
    '{612, 1008},    /* HPDF_PAGE_SIZE_LEGAL */
    '{841.89, 1199.551},    /* HPDF_PAGE_SIZE_A3 */
    '{595.276, 841.89},     /* HPDF_PAGE_SIZE_A4 */
    '{419.528, 595.276},     /* HPDF_PAGE_SIZE_A5 */
    '{708.661, 1000.63},     /* HPDF_PAGE_SIZE_B4 */
    '{498.898, 708.661},     /* HPDF_PAGE_SIZE_B5 */
    '{522, 756},     /* HPDF_PAGE_SIZE_EXECUTIVE */
    '{288, 432},     /* HPDF_PAGE_SIZE_US4x6 */
    '{288, 576},     /* HPDF_PAGE_SIZE_US4x8 */
    '{360, 504},     /* HPDF_PAGE_SIZE_US5x7 */
    '{297, 684}      /* HPDF_PAGE_SIZE_COMM10 */

CONST SCR_W = 595.276
CONST SCR_H = 841.89

SUB links(BYVAL c AS cairo_t PTR, BYVAL x AS DOUBLE, BYVAL y AS DOUBLE, BYREF t AS STRING)
  cairo_move_to(c, x, y)
  cairo_show_text(c, t)
END SUB

SUB mitte(BYVAL c AS cairo_t PTR, BYVAL x AS DOUBLE, BYVAL y AS DOUBLE, BYVAL b AS DOUBLE, BYREF t AS STRING)
  DIM AS cairo_text_extents_t extents
  cairo_text_extents (c, t, @extents)
  cairo_move_to (c, x + b/2-(extents.width/2 + extents.x_bearing), y)
  cairo_show_text(c, t)
END SUB

SUB rechts(BYVAL c AS cairo_t PTR, BYVAL x AS DOUBLE, BYVAL y AS DOUBLE, BYVAL b AS DOUBLE, BYREF t AS STRING)
  DIM AS cairo_text_extents_t extents
  cairo_text_extents (c, t, @extents)
  cairo_move_to(c, x + b - extents.width - extents.x_bearing, y)
  cairo_show_text(c, t)
END SUB

' Bild aufbauen und ausgeben
SUB build_page(BYVAL cs AS cairo_surface_t PTR)
  DIM AS cairo_t PTR c = cairo_create(cs)
  DIM AS STRING t, Page_Title = "Gedichte - ihr Wichte!"
  DIM AS DOUBLE x = 50, y = 50, b = SCR_W - 100

  cairo_rectangle(c, 0.0, 0.0, SCR_W, SCR_H)
  cairo_set_source_rgb(c, 1.0, 1.0, 1.0)
  cairo_fill(c)

  cairo_set_source_rgb(c, 0.0, 0.0, 0.0)
  cairo_set_line_width(c, 0.5)
  cairo_rectangle(c, x, y + 10, b, SCR_H - 110)
  cairo_stroke(c)

  cairo_select_font_face(c, "Arial", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_NORMAL)
  cairo_set_font_size(c, 24.0)
  mitte(c, x, y, b, Page_Title)

  cairo_select_font_face (c, "Times", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_NORMAL)
  cairo_set_font_size (c, 16.0)

  y = 100 : mitte(c, x, y, b, "Das Meer ist weit, das Meer ist blau,")
  y += 20 : mitte(c, x, y, b, "im Wasser schwimmt ein Kabeljau.")
  y += 20 : mitte(c, x, y, b, "Da kümmt ein Hai von ungefähr,")
  y += 20 : mitte(c, x, y, b, "ich glaub von links, ich weiß nicht mehr -")
  y += 20 : mitte(c, x, y, b, "verschlingt den Fisch mit Haut und Haar,")
  y += 20 : mitte(c, x, y, b, "das ist zwar traurig, aber wahr.")
  y += 20 : mitte(c, x, y, b, "Das Meer ist weit, das Meer ist blau,")
  y += 20 : mitte(c, x, y, b, "im Wasser schwimmt kein Kabeljau.")

  y = 400 : links(c, x, y, "Als sie den Ritter Fibs im Jahr")
  y += 20 : links(c, x, y, "elfhundertsiebenzehn gebahr,")
  y += 20 : links(c, x, y, "zog die Mama dem kleinen Mann,")
  y += 20 : links(c, x, y, "als erstes eine Rüstung an,")
  y += 20 : links(c, x, y, "die sie des nachts und oft ermüdet,")
  y += 20 : links(c, x, y, "für ihn gelötet und geschmiedet,")
  y += 20 : links(c, x, y, "damit er gegen allerlei,")
  y += 20 : links(c, x, y, "Gefahren wohl gerüstet sei.")
  cairo_select_font_face (c, "Times", CAIRO_FONT_SLANT_ITALIC, CAIRO_FONT_WEIGHT_BOLD)
  y += 30 : links(c, x, y, "Schlußfolgerung:")
  cairo_select_font_face (c, "Times", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_NORMAL)
  y += 20 : links(c, x, y, "Die Rüstung muß, ist man noch klein,")
  y += 20 : links(c, x, y, "besonders unten rostfrei sein.")

  y = 618 : rechts(c, x, y, b, "Hinter den Gardinen sehen")
  y += 20 : rechts(c, x, y, b, "wir erstaunt Sardinen gehen.")
  cairo_select_font_face (c, "Times", CAIRO_FONT_SLANT_ITALIC, CAIRO_FONT_WEIGHT_NORMAL)
  y += 30 : rechts(c, x, y, b, "Nach dem Sturmtief")
  y += 20 : rechts(c, x, y, b, "stand der Turm schief.")
  cairo_select_font_face (c, "Times", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_NORMAL)
  y += 30 : rechts(c, x, y, b, "Hast du zu viel Geld da liegen")
  y += 20 : rechts(c, x, y, b, "kauf dir Hühnchen, laß sie fliegen.")
  cairo_select_font_face (c, "Times", CAIRO_FONT_SLANT_ITALIC, CAIRO_FONT_WEIGHT_NORMAL)
  y += 30 : rechts(c, x, y, b, "Bist Du des Lebens nicht mehr froh,")
  y += 20 : rechts(c, x, y, b, "so stürze Dich in H2O.")

  cairo_show_page(c)
  cairo_destroy(c)
END SUB

' Schreibt eine PDF-Datei
SUB write_pdf(BYREF fname AS STRING)
  DIM AS cairo_surface_t PTR cs = cairo_pdf_surface_create(fname, SCR_W, SCR_H)
  build_page(cs)
  cairo_surface_flush(cs)
  cairo_surface_destroy(cs)
END SUB

' Schreibt eine PS-Datei
SUB write_ps(BYREF fname AS STRING)
  DIM AS cairo_surface_t PTR cs = cairo_ps_surface_create(fname, SCR_W, SCR_H)
  build_page(cs)
  cairo_surface_flush(cs)
  cairo_surface_destroy(cs)
END SUB

' Schreibt eine SVG-Datei
SUB write_svg(BYREF fname AS STRING)
  DIM AS cairo_surface_t PTR cs = cairo_svg_surface_create(fname, SCR_W, SCR_H)
  build_page(cs)
  cairo_surface_flush(cs)
  cairo_surface_destroy(cs)
END SUB

' Gibt Bild auf Schirm aus
SUB write_screen()
  DIM AS INTEGER S_W = INT(SCR_W) + 1, S_H = INT(SCR_H) + 1
  SCREENRES S_W, S_H, 32
  SCREENLOCK
  VAR stride = cairo_format_stride_for_width(CAIRO_FORMAT_ARGB32,S_W)
  DIM AS cairo_surface_t PTR cs = _
         cairo_image_surface_create_for_data(SCREENPTR, _
                                             CAIRO_FORMAT_ARGB32, S_W, _
                                             S_H, stride)
  build_page(cs)
  SCREENUNLOCK
END SUB


' Hauptprogramm / main program

'write_pdf("t3.pdf")
'write_ps("t3.ps")
'write_svg("t3.svg")
write_screen()
SLEEP
badidea
Posts: 2591
Joined: May 24, 2007 22:10
Location: The Netherlands

Re: ttf examples on 64-bit systems?

Post by badidea »

N3trunn3r wrote:examples/graphics/FreeType/drawstr.bas doesn't work either (black screen).
Change:

Code: Select all

Dim As UInteger Ptr p = CPtr(UInteger Ptr, ScreenPtr()) + (y * SCREEN_W) + x
To:

Code: Select all

Dim As ULong Ptr p = CPtr(ULong Ptr, ScreenPtr()) + (y * SCREEN_W) + x
And I had to change the font location:

Code: Select all

'Const TTF_FONT = "/usr/share/fonts/truetype/ttf-dejavu/DejaVuSans.ttf"
Const TTF_FONT = "/usr/share/fonts/truetype/dejavu/DejaVuSans.ttf"
And you should get this:
Image
Ubuntu Mate 18.04, fbc 1.07.1 64-bit
N3trunn3r
Posts: 110
Joined: Feb 14, 2008 15:48

Re: ttf examples on 64-bit systems?

Post by N3trunn3r »

AH wonderful! Thanks everyone :)
Post Reply