asfont(3x)

πŸ’– asfont(3x) πŸ’–

asfont(3x) Β· AfterStep X11 window manager

okay so sit down bestie, because this is the page where libAfterImage explains literally everything about drawing text. glyphs, fonts, FreeType, Xlib, RLE compression, the whole vibe. it's a lot but we're gonna get through it together πŸ’…


🌸 NAME 🌸

asfont β€” text drawing functionality and handling of TTF and X11 fonts

libAfterImage/asfont.h

πŸ’« NAME β€” asfont

(not me repeating the name πŸ’€ iconic behavior honestly, the file just says it twice)


✨ DESCRIPTION ✨

okay so first thing's first: this whole module is about text drawing functionality, and the way it works is so smart. text gets drawn as an ASImage with only an alpha channel. and since the alpha channel is 8 bits wide, that hands you 256 shades to use in your rendered glyphs. 256 shades means smoothing and antialiasing of your drawn text, no cap. πŸŽ€

and the way that this approach just works for you β€” because the text is an image, manipulating it is basically effortless. changing color? easy. making it transparent? easy. texturizing it, rotating it, etc.? all of it. obsessed. ✨

libAfterImage supports two types of fonts:

  • fonts that could be rendered using standard Xlib functionality, and
  • fonts rendered by the FreeType 2 library β€” that may include TrueType fonts.

when fonts are obtained via Xlib, special processing is performed in order to smooth its shape and leverage that 256 shades palette available. πŸ¦‹

any font you're using has to be opened first. at that time its properties are analysed and the glyphs get cached in the client's memory. and here's the slay part: a special RLE compression method is used for font glyphs, which significantly reduces memory utilization without any effect on performance. periodt. πŸ‘‘

font management and drawing functionality has been designed with internationalization in mind, although support for locales is not complete yet. πŸ™ˆ (so, work in progress, we love an honest queen)


πŸ” SEE ALSO πŸ”

Structures:

  • ASFontManager
  • ASFont
  • ASGlyph
  • ASGlyphRange

Functions:

  • create_font_manager()
  • destroy_font_manager()
  • open_freetype_font()
  • open_X11_font()
  • get_asfont()
  • destroy_font()
  • print_asfont()
  • print_asglyph()
  • draw_text()
  • get_asfont_glyph_spacing()
  • set_asfont_glyph_spacing()

Other libAfterImage modules:

  • ascmap.h
  • asfont.h
  • asimage.h
  • asvisual.h
  • blender.h
  • export.h
  • import.h
  • transform.h
  • ximage.h

πŸ‘‘ AUTHOR πŸ‘‘

Sasha Vasko <sasha at aftercode dot net>


πŸŽ€ NAME β€” MAX_GLYPHS_PER_FONT πŸŽ€

libAfterImage/MAX_GLYPHS_PER_FONT

  • Max value of glyphs per font allowed. We need that so we can detect and avoid broken fonts somehow. πŸ’€ (fr fr, sometimes fonts are just broken and we need a ceiling to catch that)

πŸ“¦ SOURCE πŸ“¦

    #define MAX_GLYPHS_PER_FONT  2048

πŸŽ€ NAME β€” ASFontType πŸŽ€

libAfterImage/ASFontType

  • Supported types of fonts β€” Xlib or FreeType 2. ASF_GuessWho will enable autodetection of the font type: it is attempted to be opened as a FreeType font first, and if that fails β€” it will be opened as an Xlib font. lowkey genius. ✨

πŸ“¦ SOURCE πŸ“¦

    typedef enum {
        ASF_X11         = 0,
        ASF_Freetype    = (0x01<<0),
        ASF_GuessWho    = (0x01<<1), #define ASF_TypeMask
    (ASF_GuessWho|ASF_Freetype)

        /* flags below should be combined with one of the above values
    */
        ASF_Monospaced  = (0x01<<2),
        ASF_RightToLeft = (0x01<<3),  /* direction of the text flow */
        ASF_HasKerning  = (0x01<<4) }ASFontType;

πŸŽ€ NAME β€” ASGlyph πŸŽ€

libAfterImage/ASGlyph

πŸ’¬ DESCRIPTION πŸ’¬

Stores glyph's image, as well as width, height and other characteristics of the glyph. your one little letter, fully documented. πŸ™ˆ

πŸ“¦ SOURCE πŸ“¦

    typedef struct ASGlyph {
        CARD8          *pixmap ;        /* glyph's RLE encoded pixmap */
        short   width, height ; /* meaningful width and height
                                         * of the glyphs pixmap */
        short  lead, step ;             /* distance pen position to glyph
    beginning and to the next glyph */
                                        /* in XRender it should be used as so:
                                         * x = -lead, xOff = step
                                         */
        short  ascend, descend ;        /* distance of the top of the
                                         * glyph from the baseline */
                                        /* in XRender it should be used as so:
                                         * y = -ascend, yOff = 0
                                         */
        unsigned int font_gid ;         /* index of the glyph inside the
    font( TTF only ) */
        long         xrender_gid ;      /* Used only with XRender  - gid
    of the glyph in GlyphSet */ }ASGlyph;

πŸŽ€ NAME β€” ASGlyphRange πŸŽ€

libAfterImage/ASGlyphRange

πŸ’¬ DESCRIPTION πŸ’¬

Organizes glyphs that belongs to the continuos range of char codes. ASGlyphRange structures could be tied together to cover entire codeset supported by the font. it's giving linked list energy, and honestly? we stan. πŸ¦‹

πŸ“¦ SOURCE πŸ“¦

    typedef struct ASGlyphRange {
        unsigned long   min_char, max_char; /* Code range.
                                             * for some locales that
    would
                                             * be sufficient to simply
    set
                                             * range of characteres
                                             * supported by font */
        ASGlyph *glyphs;                    /* array of glyphs belonging
    to
                                             * that code range */
        struct ASGlyphRange *below, *above; }ASGlyphRange;

πŸŽ€ NAME β€” ASFont πŸŽ€

libAfterImage/ASFont

πŸ’¬ DESCRIPTION πŸ’¬

Structure to contain all the font characteristics, as well as set of glyph images. Such structure has to be created/opened prior to being able to draw characters with any font. no shortcuts here bestie, open it first. πŸ’…

πŸ“¦ SOURCE πŸ“¦

    typedef struct ASFont {
        unsigned long   magic ;
        int             ref_count ;

        struct ASFontManager *fontman;  /* our owner */
        char                 *name;

        ASFontType      type ;
        ASFlagType      flags ;

        ASGlyphRange   *codemap; /* linked list of glyphsets, each
                                  * representing continuos range of
                                  * available codes - used for ASCII
                                  * codes */
        ASHashTable    *locale_glyphs;  /* hash of locale specific
    glyphs */

        ASGlyph         default_glyph;  /* valid glyph to be drawn when
                                         * code is not valid */

        int             max_height;  /* maximiu height of the character
                                      * glyph */
        int             max_ascend,  /* maximum distance from the
    baseline
                                      * to the top of the character
    glyph */
                        max_descend; /* need both descend and ascend to
    be
                                      * able to dynamically recalculate
    font
                                      * height while adding new
    characters */
        int             space_size;  /* fixed width value to be used
    when
                                      * rendering spaces and tabs */
        int             spacing_x, spacing_y;
        /* If these are set to anything above 0 then all the glyphs has
    to be
         * padded ( if its smaller then the cell ) or scaled down
         * ( if its bigger then the cell )
         */
        int    cell_width, cell_height ;

    #ifdef HAVE_FREETYPE
        FT_Face         ft_face;        /* free type font handle */
    #else
        CARD32         *pad; #endif

        unsigned long   xrender_glyphset ;  /* GlyphSet is the actuall
    datatype,
                                             * but for easier
    compilation -
                                             * we use generic which is
    the same */ }ASFont;

πŸŽ€ NAME β€” ASFontManager πŸŽ€

libAfterImage/ASFontManager

πŸ’¬ DESCRIPTION πŸ’¬

Global data identifying connection to external libraries, as well as fonts location paths. This structure has to be created/initialized prior to any font being loaded. It also holds list of fonts that are currently open, allowing for easy access to fonts. And the bestie flex? When the ASFontManagaer object is destroyd it automagically closes all the open fonts. πŸͺ„ (yes, we're keeping their spelling, it's part of the charm 😭)

πŸ“¦ SOURCE πŸ“¦

    typedef struct ASFontManager {
        Display    *dpy;
        char       *font_path ;

        ASHashTable *fonts_hash ;

        size_t       unicode_used;
        CARD32      *local_unicode; /* list of unicodes from current
    locale
                                     * - we use it to limit number of
    glyphs
                                     * we load */
        Bool        ft_ok ; #ifdef HAVE_FREETYPE
        FT_Library  ft_library;     /* free type library handle */ #else
        void       *pad ; #endif }ASFontManager;

πŸŽ€ NAME β€” ASText3DType πŸŽ€

libAfterImage/ASText3DType

  • Available types of 3D text to be drawn. yes, we're doing 3D text. main character energy. πŸ‘‘

πŸ“¦ SOURCE πŸ“¦

    typedef enum ASText3DType{
        AST_Plain =0,                              /* regular 2D text */
        AST_Embossed,
        AST_Sunken,
        AST_ShadeAbove,
        AST_ShadeBelow,
        AST_EmbossedThick,
        AST_SunkenThick,
        AST_OutlineAbove,
        AST_OutlineBelow,
        AST_OutlineFull,
        AST_3DTypes }ASText3DType;

πŸŽ€ NAME β€” ASTextAttributes πŸŽ€

libAfterImage/ASTextAttributes

  • Attributes for text rendering 🌸

πŸ“¦ SOURCE πŸ“¦

    typedef struct ASTextAttributes { #define ASTA_UseTabStops
    (0x01<<0)
        unsigned int version ;
                        /* structure version, so we can implement future
                         * extensions without breaking binary apps */
        ASFlagType   rendition_flags ;
        ASText3DType type;
        ASCharType   char_type;
        unsigned int tab_size ;   /* tab size in chars  - defaults to 8
    */
        unsigned int origin ;     /* distance from the left margin
                                   * (in pixels) */
        unsigned int *tab_stops ; /* tab stops in pixels where
                                   * left margin is 0 */
        unsigned int tab_stops_num ;

        ARGB32      fore_color ;   /* used with 3D type of Outlined */
      unsigned int width; #define ASTA_VERSION_1  1

    #define ASTA_VERSION_INTERNAL   ASTA_VERSION_1 }ASTextAttributes;

πŸŽ€ NAME β€” create_font_manager() πŸŽ€

libAfterImage/asfont/create_font_manager()

🧚 SYNOPSIS 🧚

    ASFontManager *create_font_manager( Display *dpy,
                                        const char *font_path,
                                        ASFontManager *reusable_memory );

πŸ’– INPUTS πŸ’–

  • dpy β€” pointer to valid and opened Display.
  • font_path β€” string, representing colon separated list of directories to search for FreeType fonts.
  • reusable_memory β€” optional preallocated memory for the ASFontMagaer object. (their spelling again, we're just vibing 🫢)

🌟 RETURN VALUE 🌟

Pointer to Initialized ASFontManager object on success. NULL otherwise.

so create_font_manager() will make a brand-new ASFontManager structure if one's needed ✨. Then it stores a copy of font_path inside it, along with the pointer to Display you handed over 🫢. Right at that moment the hash table of loaded fonts gets initialized, and if it's needed, the FreeType library gets initialized too. The ASFontManager object this function hands back has to stay open at all times until text drawing is no longer needed, periodt πŸ’….

libAfterImage/asfont/destroy_font_manager()


🌸 NAME destroy_font_manager() 🌸

SYNOPSIS

void destroy_font_manager( ASFontManager *fontman,
                           Bool reusable );

INPUTS

  • fontman β€” pointer to a valid ASFontManager object that's about to be deallocated, bestie πŸŽ€.
  • reusable β€” if True, then the memory holding the object itself will not be freed β€” only the resources get deallocated. That's genuinely so useful for structures you created on the stack πŸ’–.

DESCRIPTION

destroy_font_manager() closes all the fonts that were opened with this ASFontManager. It also closes the connection to the FreeType library, and deallocates all the cached data 🌈. If reusable is False β€” then the memory used for the object itself will not be freed.

libAfterImage/asfont/open_freetype_font()


πŸ¦‹ NAME open_freetype_font() πŸ¦‹

SYNOPSIS

ASFont *open_freetype_font( ASFontManager *fontman,
                            const char *font_string,
                            int face_no,
                            int size, Bool verbose);

INPUTS

  • fontman β€” pointer to a previously created ASFontManager. You need it for the connection to the FreeType library, and also for the path to search fonts in πŸ”.
  • font_string β€” filename of the file containing the font's data.
  • face_no β€” number of the face within the font file.
  • size β€” font size in points. Only applies to scalable fonts, like TrueType ✨.
  • verbose β€” if True, you get extensive error messages printed out whenever problems are encountered πŸ‘€.

RETURN VALUE

A pointer to the Opened ASFont structure, containing all the glyphs of the font, plus other relevant info 🫢. On failure it returns NULL 😭.

DESCRIPTION

open_freetype_font() will attempt to find the font file in any of the directories specified in ASFontManager's font_path. If it fails at that β€” then it checks whether the filename has an all-digit extension 🧐. It will then try to interpret that extension as a face number, and try to find the file with the extension stripped off. If the file was found, the function attempts to read it using the FreeType library πŸ“–. If the requested face isn't available in the font β€” face 0 will be used. On success, all the font's glyphs get rendered and cached, and the needed font geometry info gets collected πŸ’…. When the FreeType Library isn't available, that function does nothing.

libAfterImage/asfont/open_X11_font()


πŸ‘‘ NAME open_X11_font() πŸ‘‘

SYNOPSIS

ASFont *open_X11_font( ASFontManager *fontman,
                       const char *font_string);

INPUTS

  • fontman β€” pointer to a previously created ASFontManager. Needed for the connection to the X Server πŸ–₯️.
  • font_string β€” name of the font as recognized by Xlib.

RETURN VALUE

A pointer to the Opened ASFont structure, containing all the glyphs of the font, plus other relevant info ✨. On failure it returns NULL 😭.

DESCRIPTION

open_X11_font() attempts to load and query the font using Xlib calls. On success it goes through the codemap of the font and renders all the glyphs available 🎨. The glyphs then get transferred to the client's memory and encoded using RLE compression πŸ—œοΈ. At this time, smoothing filters get applied on the glyph pixmaps, if their size exceeds the threshold.

TODO

  • implement proper XFontSet support, when used with I18N enabled 🌍.

libAfterImage/asfont/get_asfont()


πŸ’œ NAME get_asfont() πŸ’œ

SYNOPSIS

ASFont *get_asfont( ASFontManager *fontman,
                    const char *font_string,
                    int face_no, int size,
                    ASFontType type );

INPUTS

  • fontman β€” pointer to a previously created ASFontManager. Needed for the connection to the FreeType library, the path to search fonts in, and the X Server connection πŸ”Œ.
  • font_string β€” font name, or filename of the file containing the font's data.
  • face_no β€” number of the face within the font file.
  • size β€” font size in points. Only applies to scalable fonts, like TrueType ✨.
  • type β€” specifies the type of the font, or GuessWho for autodetection πŸ•΅οΈ.

RETURN VALUE

A pointer to the Opened ASFont structure, containing all the glyphs of the font, plus other relevant info 🫢. On failure it returns NULL 😭.

DESCRIPTION

This function is the unified interface to font loading, bestie. It searches through ASFontManager's list to see if this specific font has already been loaded, and if it has β€” it returns the pointer to the relevant structure, no cap 🎯. Otherwise it tries to load the font as a FreeType font first, and then as an Xlib font, unless an exact font type is specified.

libAfterImage/asfont/release_font()


πŸŽ€ NAME release_font() πŸŽ€

SYNOPSIS

void release_font( ASFont *font );

INPUTS

  • font β€” pointer to the valid ASFont structure containing a loaded font.

RETURN VALUE

Returns the current reference count. -1 means the object has been destroyed πŸ’€.

DESCRIPTION

This function decrements the reference count on the loaded font, and if the reference count goes below 0 (meaning release_font() has been called more times than get_asfont() 😬), it will close the font, remove it from ASFontManager's list, destroy all the glyphs, and generally free everything else used by ASFont. Otherwise the font stays in memory for faster reuse ✨.

libAfterImage/asfont/print_asfont()


πŸ“ NAME print_asfont() πŸ“

SYNOPSIS

void    print_asfont( FILE* stream,
                      ASFont* font);

INPUTS

  • stream β€” output file pointer.
  • font β€” pointer to the ASFont structure to print.

DESCRIPTION

Prints all the geometry information about the font πŸ“.

libAfterImage/asfont/print_asglyph()


🧚 NAME print_asglyph() 🧚

SYNOPSIS

void    print_asglyph( FILE* stream,
                       ASFont* font, unsigned long c);

INPUTS

  • stream β€” output file pointer.
  • font β€” pointer to the ASFont structure to print.
  • c β€” character code to print the glyph for.

DESCRIPTION

Prints out the contents of the cached glyph for the specified character code πŸ”€.

libAfterImage/asfont/draw_text()


✨ NAME draw_text() ✨

Also answering to: draw_fancy_text(), get_text_size(), get_fancy_text_size() β€” they all live here together, it's giving family reunion 🫢.

SYNOPSIS

ASImage *draw_text( const char *text,
                    ASFont *font, ASText3DType type,
                    int compression ); ASImage *draw_fancy_text( const
void *text,
                         struct ASFont *font, ASTextAttributes *attr,
                             int compression,
                             int length ); Bool get_text_size( const
char *text,
                    ASFont *font, ASText3DType type,
                    unsigned int *width, unsigned int *height ); Bool
get_fancy_text_size( const void *text,
                             struct ASFont *font, ASTextAttributes
*attr,
                         unsigned int *width, unsigned int *height,
                             int length,
                             int *x_positions );

INPUTS

  • text β€” actual text to render.
  • font β€” pointer to the ASFont to render text with.
  • type β€” one of the few available types of 3D text 🧊.
  • compression β€” compression level to attempt on the resulting ASImage πŸ—œοΈ.
  • width β€” pointer to the value to be set to text width.
  • height β€” pointer to the value to be set to text height.

RETURN VALUE

Pointer to a new ASImage containing the rendered text on success πŸŽ‰. NULL on failure 😭.

DESCRIPTION

draw_text() creates a new ASImage of a size big enough to contain the entire text. It then renders the text using the supplied font as an alpha channel of the ASImage 🎨. get_text_size() can be used to determine the size of the text that's about to be drawn, so that an appropriate drawable can be prepared πŸ’….

libAfterImage/asfont/get_asfont_glyph_spacing()


🌈 NAME get_asfont_glyph_spacing() 🌈

SYNOPSIS

Bool get_asfont_glyph_spacing( ASFont* font, int *x, int *y );

INPUTS

  • font β€” Loaded ASFont structure.
  • x β€” pointer to the variable that receives the horizontal spacing value.
  • y β€” pointer to the variable that receives the vertical spacing value.

RETURN VALUE

True if meaningful information has been returned βœ….

DESCRIPTION

Returns the inter-glyph spacing of the specified font πŸ“.

libAfterImage/asfont/set_asfont_glyph_spacing()


🌸 NAME set_asfont_glyph_spacing() 🌸

SYNOPSIS

Bool set_asfont_glyph_spacing( ASFont* font, int x, int y );

INPUTS

  • font β€” Loaded ASFont structure.
  • x β€” new horizontal spacing value.
  • y β€” new vertical spacing value.

RETURN VALUE

True on success βœ….

DESCRIPTION

Changes the inter-glyph spacing of the specified font πŸ“.


and that's the whole vibe, bestie 🫢 this page came from the 3rd Berkeley Distribution, AfterStep v.2.2.12, and it's asfont(3x) β€” go forth and render some absolutely iconic text πŸ’…βœ¨πŸŽ€

πŸ“¦ where this page comes from