PDF::Bu...tManager(3)

πŸ’– PDF::Builder::FontManager β€” aka PDF::Bu...tManager(3) πŸ’–

Hiii bestie, welcome to the font corner of the PDF::Builder universe πŸŽ€ this is PDF::Builder::FontManager, and she is literally the one managing the entire font library for PDF::Builder. No cap, she runs the whole closet. πŸ‘‘


✨ NAME ✨

PDF::Builder::FontManager β€” Managing the font library for PDF::Builder πŸ¦‹


🌸 SYNOPSIS 🌸

Okay so these routines don't come find you, you go to them β€” they're called from the PDF::Builder class itself (peep get_font(), add_font() methods, iykyk).

# core fonts come preloaded
# Add new a new font face and variants
my $rc = $pdf->add_font(
    'face' => $unique_face_name,  # font family, e.g., Times
    'type' => 'core',             # note that core fonts preloaded
    'style' => 'serif',           # also sans-serif, script (cursive),
                                  #  and symbol
    'width' => 'proportional',    # also constant
    'settings' => { 'encode' => $encoding },
    # note that these are actual core font names rather than file paths
    'file' => { 'roman'       => 'Times-Roman',
                'italic'      => 'Times-Italic',
                'bold'        => 'Times-Bold',
                'bold-italic' => 'Times-BoldItalic' },
                # for non-core these would be the actual file paths
                # prefixed with font search paths
);
$rc = $pdf->add_font(
    'face' => 'DejaVuSans',       # Deja Vu  sans serif family
    'type' => 'ttf',              # otf uses 'ttf'
    'style' => 'sans-serif',
    'width' => 'proportional',
    'settings' => { 'encode' => 'utf8' },
    # the defined font paths will be prepended to find the actual path
    'file' => { 'roman'       => 'DejaVuSans.ttf',
                'italic'      => 'DejaVuSans-Oblique.ttf',
                'bold'        => 'DejaVuSans-Bold.ttf',
                'bold-italic' => 'DejaVuSans-BoldOblique.ttf' }
);

Some of the global data, which can be reset via the font_settings() method β€” think of these as the ✨vibes✨ the system defaults to when you don't say otherwise:

  • default-face: initialized to Times-Roman (core), used if you start formatting text without explicitly setting a face, or inheriting one
  • default-serif: initialized to Times-Roman (core), used if you want a "generic" serif typeface
  • default-sansserif: initialized to Helvetica (core), used if you want a "generic" sans-serif typeface
  • default-constant: initialized to Courier (core), used if you want a "generic" constant-width typeface
  • default-script: NOT initialized (no default), used if you want a "generic" script (cursive) typeface
  • default-symbol initialized to Symbol (core), used if you want a "generic" symbol typeface
  • font-paths: C:/Windows/Fonts for Windows systems for TTF, other types are in non-standard paths, and for non-Windows, anything goes πŸ™ˆ

Usage of get_font() is to specify the face and variants, and then each time, specify italic and bold to be on or off. If the desired file is not yet opened, it will be, and the $font returned. If the font was already created earlier, the saved $font will be returned. (She remembers, she's efficient like that πŸ’…)

my $font = $pdf->get_font(
     'face' => 'Times',
     'italic' => 0,     # desire Roman (upright)
     'bold' => 0,       # desire medium weight
);
# if $font is undef, we have a problem...
$text->font($font, $font_size);
$text->...  # use this font (medium weight Times-Roman core font)
$font = $pdf->get_font('italic' => 1);
$text->...  # switched to italic
$font = $pdf->get_font('italic' => 0);
$text->...  # back to Roman (upright) text

πŸ’… METHODS πŸ’…

🫢 new

PDF::Builder::FontManager->new(%opts)

This is called from Builder.pm's new(). Currently there are no options selectable (sorry babe, nothing to toggle yet 😭). It will set up the font manager system and preload it with the core fonts. Various defaults will be set for the face (core Times-Roman), serif face (core Times-Roman), sans-serif face (core Helvetica), constant width (fixed pitch) face (core Courier), and a symbol font (core Symbol). There is no default for a script (cursive) font unless you set one using the font_settings() method. πŸ‘‘

πŸŽ€ font_settings

@list = $pdf->font_settings()  # Get

$pdf->font_settings(%info)  # Set

Get or set some information about fonts, particularly the fonts to be used for "generic" purposes.

"Get" returns a list (array) of the default font face name, the default generic serif face, the default generic sans-serif face, the default generic constant width face, the default generic symbol face, and the default generic script (cursive) face. It is possible for an element to be undefined (e.g., the generic script face is "undef"). πŸ’€

"Set" changes one or more default settings:

'font' => face to use for the default font face (initialized to Times)
'serif' => face to use for the generic serif face (initialized to Times)
'sans-serif' => face to use for the generic sans serif face
                (initialized to Helvetica)
'constant' => face to use for the generic constant width face
              (initialized to Courier)
'script' => face to use for the generic script face (uninitialized)
'symbol' => face to use for the generic symbol face
            (initialized to Symbol)

🌈 add_font_path

$rc = $pdf->add_font_path("a directory path", %opts)

This method adds one search path to the list of paths to search. In the get_font() method, each defined search path will be prepended to the "file" entry (except for core fonts) in turn, until the font file is found. However, if the "file" entry starts with / or ./ or ../, it will be used alone. A "file" entry starting with .../ is a special case, which is turned into ../ before the search path is prepended. This permits you to give a search path that you expect to move up one or more directories. 🧚

The font path search list always includes the current directory (.), and is initialized in "Builder.pm" as @font_path. For the Windows operating system, "/Windows/Fonts" usually contains a number of TTF fonts that come standard with Windows, so it is added by default. Anything else, including all Linux (and other non-Windows operating systems), will have to be added depending on your particular system. Some common places are:

Windows (NOTE: use / and not \\ in Windows paths!). Linux systems may or may not handle spaces in directory names gracefully!

/Windows/Fonts
/WinNT/Fonts
/Program Files/MikTex 2.9/fonts/type1/urw/bookman (URW Bookman for MikTex)
/Program Files (x86)/MikTex 2.9/fonts/type1/urw/bookman (older versions)
/Program Files/Adobe/Acrobat DC/Resource/CIDFont (Adobe Reader fonts)
GhostScript may have its own directories

Note that directory names with spaces (e.g., "/Program Files") may not play nice with some Linux systems, so they are not included by default. 🫠

Linux, etc.

/usr/share/fonts (common base)
/usr/local/share/fonts (common base)
/usr/share/fonts/dejavu-sans-fonts  (Deja Vu Sans TTF specifically)
/usr/share/fonts/truetype/ttf-dejavu
/usr/share/fonts/truetype/dejavu
/usr/lib/defoma/gs.d/devs/fonts   (GhostScript?)
/usr/share/fonts/type1/gsfonts    (GhostScript PS)
/usr/share/X11/fonts/urw-fonts    (URW PS)

Third-party application installations, such as Adobe's Acrobat Reader, may be a source of installed fonts, too. πŸ‘€

A return code of 0 means the path was successfully added, while 1 means there was a problem encountered (and a message was issued).

No options are currently defined.

πŸ’œ add_font

$rc = add_font(%info)

Add a new font entry (by face and variants) to the Font Manager's list of known fonts. Slay, new font just dropped. ✨

%info items to be defined:

face => 'face name'

This should be a unique string to identify just one entry in the Font Manager fonts table. I.e., you should not have two "Times" (one a core font and the other a TTF font). Give them different names (face names are case sensitive, so 'Times' is different from 'times'). The "face" name is used to retrieve the desired font.

The default core font face names (Times, Helvetica, Courier, Symbol, ZapfDingbats, Georgia, Verdana, Trebuchet, Wingdings, Webdings), as well as class names current, default, serif, sans-serif, constant, script, symbol, -external- are reserved and should not be used for user-added faces. They may be redefined at your discretion. The MS Windows core extension BankGothic is currently not added to the core fonts automatically. -external- may or may not be defined, and should not be used by user code.

Note that use of Windows extension "core" fonts (Georgia, Verdana, Trebuchet, Wingdings, and Webdings) expect those fonts to be installed on platforms if they are used, and a (hopefully) close substitution will be attempted if not. These fonts are normally available on Windows platforms, but may not be available on non-Windows platforms. Use (create PDFs specifying them) at your own risk. 😭

type => 'type string'

This tells which Builder font routine to use to load the font. The allowed entries are:

core

This is a core font, and is loaded via the CoreFont() routine. Note that the core fonts are automatically preloaded (including additional ones on Windows systems), so you should not need to explicitly load any core fonts (at least, the 14 basic ones). All PDF installation are supposed to include these 14 basic core fonts, but the precise actual file type may vary among installations, and substitutions may be made (so long as the metrics match). Currently, core fonts are limited to single byte encodings.

On Windows systems, there are an additional 14 core fonts which are normally loaded. These are Georgia, Verdana, Trebuchet, Wingdings, and Webdings faces. Use caution if making use of these additional core fonts, as non-Windows systems may not include them without explicit manual installation of these fonts. These fonts may be safe to use if you know that all your PDF readers will be running on Windows systems. Finally, PDF::Builder includes metrics for Bank Gothic, but this is not automatically loaded into the core set, as it is not clear whether all Windows systems actually include this font.


  • ttf β€” bestie, this is a TrueType (.ttf) or OpenType (.otf) font, and you load it with ttfont(). Right now it's the ONLY type that can do multibyte (like utf8) encodings, plus it also does single-byte encodings like Latin-1. It's also the only font type that plays nice with HarfBuzz::Shaper. πŸ’… Lots of systems ship a bunch of TTF fonts, but unlike core fonts, none of them get auto-loaded by the PDF::Builder Font Manager β€” you have to explicitly load them via add_font(). No cap.
  • type1 β€” this one's a PostScript (Type1) font, loaded with psfont(). It used to be everywhere, but ngl it's pretty rare today, mostly bodied by the way more capable TTF format. Some systems might have a few Type1 fonts kicking around, but Windows, for example, normally comes with none. No Type1 fonts are auto-loaded by the PDF::Builder Font Manager, so you must explicitly load them via add_font().

It assumes the font metrics file (.afm or .pfm) has the same base file name as the glyph file (.pfa or .pfb), lives in the same directory, and either can work with either. If you need a different directory, a different base name, or a specific metrics file to pair with a specific glyph file β€” let us know so we can add that functionality. Otherwise you'll need to go straight to the psfont() method to specify those different paths.

  • cjk β€” an East Asian (Chinese-Japanese-Korean) type font, loaded with the cjkfont() method. Heads up though: CJK fonts have never been well supported by PDF::Builder, and they depend on some pretty old (obsolete) features and external files (.cmap and .data). Our suggestion? Instead of going straight to CJK files, first try directly using the (usually) TTF files in TTF format. Few systems come with CJK fonts installed. No CJK fonts are auto-loaded by the PDF::Builder Font Manager β€” explicit add_font() loading only. ✨
  • bdf β€” an Adobe Bitmap Distribution Format font, loaded with the bdfont() method. It's a very old bitmapped format, dating all the way back to the early days of the X11 system. Unlike the filled smooth outlines most modern fonts use, BDF's are a coarse grid of on/off pixels. πŸ‘€ Please be kind to your readers and use this format sparingly β€” like, only for chapter titles or headings! Few systems come with BDF fonts installed any more. No BDF fonts are auto-loaded by the PDF::Builder Font Manager, and must be explicitly loaded via add_font().
  • settings => { 'encode' => string, ... } β€” a whole little collection of any other settings, flags, etc. that this particular font type accepts. Peep the POD for "corefont", "ttfont", etc., per type, for the allowable entries. The important one is the encoding, which you'll need to specify if you use any characters beyond basic ASCII. πŸ”€

Currently, all fonts can use any single-byte encoding you want (the default is CP-1252). Only TTF type fonts (which includes OTF and CJK fonts) can currently specify a multibyte encoding like utf8. And yeah β€” the text data you pass to text routines must conform to the given encoding. You're not forced to use the same encoding for all defined fonts, but if you want to mix-and-match encodings, it's on you to define your text using the encoding specified for that particular font you're using!

Also note, in particular, when you use entities: (if numeric) they're given in the Unicode number. When you go out of the single byte range (x00-xFF), results are unpredictable if you give an entity that doesn't fall within the encoding's range! And check your results for Unicode points within the range x80-xFF if you're using utf8 encoding. 🫢

  • style => 'styling' β€” this specifies the styling of the font: serif, sans-serif, constant (constant width, aka fixed pitch), script (cursive), or symbol (non-alphabetic). It has no effect on how a font is loaded or used, but it might be useful to you for defining a generic style font. πŸ’–
  • width => 'relative widths' β€” right now, proportional (variable width) and constant (constant width) can be specified. Again, it has no effect on how a font is loaded or used, but it may be useful for defining a generic style font. 🌸
  • file => {anonymous hash of source files} β€” this is the one that tells the Font Manager where to actually find the font file. πŸ”

Various font paths get tried from the "font_path" list to find an actual file. TrueType and OpenType fonts ('type'=>'ttf') may instead be given as a "Font::TTF::Font" object β€” like one extracted from a TTC (TrueType Collection) file, one per "file" ('roman', 'italic', etc.). In a dump of the FontManager tables (dump_font_tables()), these show up as a file "name" of "Font::TTF::Font=HASH(....)". Other ways of specifying TTC fonts are expected to be added in the future. πŸ‘‘

For core fonts, it's the standard name rather than a file (and remember β€” they're preloaded πŸŽ€). For all other types, it lists from one to four of these variants:

  • roman => 'path to Roman' β€” the "Roman" or "regular" posture variant of the font. Almost all available fonts include a Roman (normal, upright posture) variant at normal (medium) weight.
  • italic => 'path to Italic' β€” the "Italic", "slanted", or "oblique" posture variant. Most available fonts include an italic variant at normal (medium) weight.
  • bold => 'path to Bold' β€” the "Bold" or "heavy" variant. Most available fonts include a bold (heavy weight) variant with normal (Roman) posture.
  • bold-italic => 'path to BoldItalic' β€” the "Bold" and "Italic" variant. Many available fonts include a bold (heavy weight) variant with italic posture.
  • symbol => 'path to Symbol' β€” for symbol type fonts (non-alphabetic), instead of risking confusion by reusing the "roman" term, the "symbol" term is used to specify what's usually the only variant of a symbol font. It's possible there are bold, italic, and even bold-italic variants of a symbol file, but if so, they are not currently supported.

You can give the entire path of the font's source file as an absolute path if you want. But fr fr, it's usually less typing to use add_font_path() to specify a list of font directories to search, and only give the name (and maybe a subdirectory) for the path here in add_font(). πŸ¦‹


🌟 get_font 🌟

@current = $pdf->get_font()  # Get

$font = $pdf->get_font(%info)  # Set

Okay so if you pass no parameters at all (@current = $pdf->get_font()), you get a list (array) back giving you the current font setting: face name, italic flag 0/1, bold flag 0/1, type ('core', 'ttf', etc.), a hash reference of settings like the encoding ('utf8', etc.), style value, width value, and an array reference (list) of variants (roman, bold, etc.). And if no font has been explicitly set yet, the current font is just the default font. πŸ’β€β™€οΈ

If you give at least one parameter (the %info hash), the font manager will try to discover the appropriate font (from within the font list), load it if it hasn't been already, and return the $font value. If undef comes back, there was an error.

%info fields:

  • face => face name string β€” this is the font family (face) name, loaded up with the core fonts (e.g., Times), or via "$pdf->add_font()" calls. You can also request the current font face, the default face, the serif generic serif face, the sans-serif generic sans-serif face, the constant generic constant width face, or the script generic script (cursive) face (if defined). 🌈

If you give the "face" entry, the other settings ("italic", "bold", etc.) are not reset, unless it's impossible to use the existing setting. If you don't give the "face" entry, the current entry gets updated (bold, italic switched on/off, etc.). And you can always explicitly give current to make it clear in your code that you don't want to change the face.

  • italic => flag β€” requests use of the italic (slanted, oblique) variant of the font, in either the current face ("face" not given in this call) or the new face. The value is 0 or 1 for "off" (Roman/upright posture) and "on" (italic posture). πŸ’«
  • bold => flag β€” requests use of the bold (heavy weight) variant, in either the current face ("face" not given in this call) or the new face. The value is 0 or 1 for "off" (medium weight) and "on" (heavy weight). πŸ’ͺ

🌟 get_external_font 🌟

$rc = $pdf->get_external_font($text)

If the user has already defined a font outside of "FontManager", in the $text text context, this call lets you retrieve it as the current font, named -external-. If no font has been defined already, nothing changes and the return code is 1. πŸ“

If "$text->{' font'}" has been defined, that font gets stored in the internal cache (as an "already read" font) in a new "-external-" font, and it becomes the current font. The return code is 0. ✨

If there's no existing preloaded font, nothing happens and the return code is 1.

This is a way for those using "markdown" formatting to define the font used, as an alternative to using "'style'=>'body { font-family: ... '" to define the body font. πŸ’œ


🌟 dump_font_tables 🌟

$pdf->dump_font_tables()

Print (to STDOUT) all the Font Manager font information on hand. Simple as that, bestie. πŸ’€


And that's a wrap on this page, babes! πŸŽ€ It came to you from perl v5.42.0, dated 2026-01-17, and it's the PDF::Bu...tManager(3) manual page. Go forth and font responsibly. πŸ’…βœ¨

πŸ“¦ where this page comes from