Cross-platform C SDK logo

Cross-platform C SDK

Typography fonts

❮ Back
Next ❯
This page has been automatically translated using the Google Translate API services. We are working on improving texts. Thank you for your understanding and patience.

Functions

Font*font_create (...)
Font*font_system (...)
Font*font_monospace (...)
Font*font_with_style (...)
Font*font_copy (...)
voidfont_destroy (...)
bool_tfont_equals (...)
real32_tfont_regular_size (void)
real32_tfont_small_size (void)
real32_tfont_mini_size (void)
const char_t*font_family (...)
real32_tfont_size (...)
real32_tfont_height (...)
uint32_tfont_style (...)
voidfont_extents (...)
bool_tfont_exists_family (...)
ArrPt(String)*font_installed_families (void)
void*font_native (...)

Typography fonts are graphic objects (files) that contain the characters and symbols we see on a monitor. We remember that a Unicode string only stores the character codes (codepoints) without any information on how they should be drawn. The graph associated with a character is known as glyph and, in a font file, there are as many glyphs as codepoints can represent the typography. The matching between codepoints and their corresponding glyphs is carried out by the operating system graphic sub-system (Listing 1) (Figure 1).

Listing 1: Drawing a text string.
1
2
3
4
Font *font = font_create("Comic Sans MS" 28, 0);
draw_font(ctx, font);
draw_text(ctx, "Hello World", 200, 250);
font_destroy(&font);
Graph that relationships Unicode characters with glyphs and fonts.
Figure 1: Text representation: codepoints + glyphs.

1. Create fonts

When displaying texts on graphic interfaces it is necessary to establish a typography, otherwise the system would not know how to render it. There will always be some fount defined by default, but we can change it when customizing the appearance of our texts.

The most representative feature of a typeface design is the family to which it belongs (font family) (Figure 2). Each computer has a series of families installed that do not have to coincide with those incorporated in another machine. This is an important fact to keep in mind since, for portability, we should not assume that a certain typeface family will be present on all machines that run the program. Sentences like:

1
Font *font = font_create("Comic Sans MS", 28, 0);

they will not be completely portable, since we are not sure that the Comic Sans MS typeface is installed in all computers. We have two alternatives to guarantee the existence of a certain font:

Hello World text written using different fonts.
Figure 2: Different typographic families.
  • Use font_system to get the default font of the operating system. It will always be available but its appearance will be different according to operating system.
  • Use font_regular_size to get the default size for buttons and other controls.
  • Use font_installed_families to obtain the list of families installed in the machine and choose the one that best suits our purposes.

2. System font

As we just mentioned, there is always a default font associated with the window environment and that, in a way, gives part of its personality. Using this font guarantees us the correct integration of our program in all the systems where it runs, making our code totally portable (Figure 3). Interface controls like Button or Label have the system font of regular size associated by default. The correspondence of font_system in the different systems is:

  • Segoe UI: Windows Vista, 7, 8, 10.
  • Tahoma: Windows XP.
  • San Francisco: macOS Mojave, High Sierra, Sierra, Mac OSX El Capitan.
  • Helvetica Neue: Mac OSX Yosemite.
  • Lucida Grande: Mac OSX Mavericks, Mountain Lion, Lion, Snow Leopard.
  • Ubuntu: Linux Ubuntu.
  • Piboto: Linux Raspbian.
  • Capture the same application on different systems, using the default font.
    Figure 3: Use of the system font.

In addition to the system font we have another default monospace font available (Figure 4). These typefaces mimic old typewriters, where all characters occupy the same space. Usually used for technical documents or source code files.

  • Use font_monospace to create a generic monospace typography.
  • Comparison of a proportional source and monospace.
    Figure 4: Proportional font (variable width) and monospace (fixed width).

3. Font characteristics

In addition to the family, we can adjust the size and style of the font. The size refers to the average height (in pixels) of the characters that make up the typeface, where margins and displacements in relation to the baseline are not taken into account (Figure 5). The total height of a line of text is known as cell height and, as a general rule, it will be somewhat larger than the char height font size.

Character height in a font.
Figure 5: Character height (char height = font size).

We can also change the style of the text, setting its attributes through the parameter style combining the values of fstyle_t (Figure 6).

3.1. Size in points

By default, the font size is expressed in pixels, but can be changed by adding ekFPOINTS to the style parameter. This unit is related to paper fonts. Here is the DPI (dots per inch) concept that indicates the amount of isolated ink drops that a printing device can emit per metric inch. In typography the criterion of 72 DPI's is established, therefore, the size of a point is approximately 0.35mm. In this way it is easy to calculate the font size from the points: 12pt=4.2mm, 36pt=12.7mm or 72pt=25.4mm (1 inch). This is the unit used in word processors, which already work based on a print page size. The problem comes when we want to represent sources expressed in points on a screen, since there is no exact correspondence between pixels and millimeters. The final pixel size depends on the resolution and physical size of the monitor. A conversion agreement between pixels and inches is required, which results in the term PPI (pixels per inch). Traditionally, in Windows systems 96 PPI is established while in Apple iMac it is 72 PPI. This causes the fonts expressed in points to be 33% larger in Windows (Figure 7). Also in the Microsoft system it is possible to configure the PPI by the user, which adds more uncertainty about the final size of the texts on the screen.

Sharing between size in pixels and size in points.
Figure 7: Unit ekFPOINTS is not advisable for screens.

4. Bitmap and Outline fonts

In the first computers typographies were created as raster graphics Bitmap Fonts (Figure 8). Each character fitted a fixed-sized cell where those pixels that made it were marked. The biggest problem is that they don't scale well. As the text on the screen grows larger, the jagged effect of the pixels becomes apparent.

Extension of a bitmap font, where the jagged effect is appreciated.
Figure 8: Bitmap fonts.

In 1982 Adobe launched the PostScript format that included those known as Outline Fonts (Figure 9). This format contains a geometric description of each symbol based on Bezier lines and curves. In this way the pixelated effect of the bitmap is avoided, since when the character is scaled, the pixels that compose it are re-computed in a process known as rasterization. In the late 80's Apple launches the TrueType format and sells a license to Microsoft that incorporates it in Windows 3.1, opening the door of the mass market to vector sources. Today all systems work with scalable fonts, having the clearest representatives in TrueType and OpenType.

Scaling an outline font (vector).
Figure 9: Outline fonts, on which TrueType and OpenType formats are based.

5. Unicode and glyphs

Unicode is a very large table. In version 11 (June 2018) there are 137,374 codepoints registered and this number grows with each new revision of the standard. If the application needs special symbols (above the BMP-Basic Multilingual Plane) we must make sure that the selected fonts contain glyphs for them. To see the relationship between codepoints and glyphs we can use the BabelMap application (Figure 10), and within it the Font Analysis option. From a Unicode block, it will show those installed sources that include glyphs for that range. In macOS we have a similar application called Character Viewer and in Ubuntu another one called Character Map.

Application that shows the glyphs included in each typeface.
Figure 10: BabelMap Font Analysis gives us information about the glyphs included in each typeface.
❮ Back
Next ❯

font_create ()

Create a font.

Font*
font_create(const char_t *family,
            const real32_t size,
            const uint32_t style);
family

Typographic family. Eg: "Arial", "Times New Roman", etc.

size

Font size. Default in pixels. Use ekFPOINTS in style to change the unit.

style

Operation OR | over the fields of the fstyle_t structure. Eg: ekFBOLD | ekFITALIC.

Return

The font.


font_system ()

Create a font, with the system default family.

Font*
font_system(const real32_t size,
            const uint32_t style);
size

Font size. Default in pixels. Use ekFPOINTS in style to change the unit.

style

Operation OR | over the fields of the fstyle_t structure. Eg: ekFBOLD | ekFITALIC.

Return

The font.


font_monospace ()

Create a font, with the default system mono-space family.

Font*
font_monospace(const real32_t size,
               const uint32_t style);
size

Font size. Default in pixels. Use ekFPOINTS in style to change the unit.

style

Operation OR | over the fields of the fstyle_t structure. Eg: ekFBOLD | ekFITALIC.

Return

The font.


font_with_style ()

Create a copy of an existing font, changing the style.

Font*
font_with_style(const Font *font,
                const uint32_t style);
font

Original font.

style

Operation OR | over the fields of the fstyle_t structure. Eg: ekFBOLD | ekFITALIC.

Return

A copy of font with another style.


font_copy ()

Create an exact copy of a font.

Font*
font_copy(const Font *font);
font

Source font.

Return

The copy of font.

Remarks

Fonts are immutable objects. Copying really means increasing an internal counter without cloning the object. However, the application must destroy the copy with font_destroy just like those created with any other constructor.


font_destroy ()

Destroy the font.

void
font_destroy(Font **font);
font

The font. Will be set to NULL after destruction.


font_equals ()

Compare two fonts. They are considered equal if they have the same family, size and style.

bool_t
font_equals(const Font *font1,
            const Font *font2);
font1

First font to compare.

font2

Second font to compare.

Return

TRUE if they are the same, FALSE if not.


font_regular_size ()

Get the default font size for interface controls.

real32_t
font_regular_size(void);

Return

The default size in pixels.


font_small_size ()

Get the small font size by default for interface controls.

real32_t
font_small_size(void);

Return

The size in pixels.

Remarks

This size is slightly smaller than that obtained by font_regular_size.


font_mini_size ()

Get the default mini font size for interface controls.

real32_t
font_mini_size(void);

Return

The size in pixels.

Remarks

This size is slightly smaller than that obtained by font_small_size.


font_family ()

Get the font type family.

const char_t*
font_family(const Font *font);
font

The font.

Return

The typographic family in UTF8.


font_size ()

Get the font size.

real32_t
font_size(const Font *font);
font

The font.

Return

The size. The units depend on the parameter style.


font_height ()

Get the height of the cell or line of text with this font.

real32_t
font_height(const Font *font);
font

The font.

Return

Cell height.


font_style ()

Get the font style.

uint32_t
font_style(const Font *font);
font

The font.

Return

The style. Combination of fstyle_t structure values. Eg: ekFBOLD | ekFITALIC.


font_extents ()

Gets the size in pixels of a text string, based on the font.

void
font_extents(const Font *font,
             const char_t *text,
             const real32_t refwidth,
             real32_t *width,
             real32_t *height);
font

The font.

text

The text string to size.

refwidth

Maximum width of the text box.

width

Text box width.

height

Text box height.


font_exists_family ()

Check if a typeface family is installed in the operating system.

bool_t
font_exists_family(const char_t *family);
family

UTF8 string with family name, terminated in a null character '\0'.

Return

TRUE if the family exists, FALSE if not.


font_installed_families ()

Get a list with the names of all the typographic families installed in the operating system.

ArrPt(String)*
font_installed_families(void);
1
2
3

Return

Array of String with the names of the families, arranged alphabetically. It must be destroyed with arrpt_destroy.


font_native ()

Gets the font in the native format of each platform.

void*
font_native(const Font *font);
font

The font.

Return

The native font. HFONT in Windows, PangoFontDescription in Linux and NSFont in macOS.

❮ Back
Next ❯