---
title: "Working with Font Registry"
canonical: https://www.graphicsmill.com/docs/gm/working-with-font-registry.htm
product: "Graphics Mill"
---

# Working with Font Registry
 
A **font registry** is the set of fonts that Graphics Mill can use. When you draw text, every font name in the text is looked up in a font registry. If the font is not there, the text cannot be drawn. So a font registry decides which fonts your output uses and how font names are resolved.
 
Font registries are represented by the following classes:
 
- [FontRegistry](https://www.graphicsmill.com/docs/gm/T_Aurigma_GraphicsMill_Drawing_FontRegistry.htm.md) is the base class. It lets you look fonts up and create [Font](https://www.graphicsmill.com/docs/gm/T_Aurigma_GraphicsMill_Drawing_Font.htm.md) objects.
- [FontRegistry.Installed](https://www.graphicsmill.com/docs/gm/P_Aurigma_GraphicsMill_Drawing_FontRegistry_Installed.htm.md) is a read-only registry with the fonts installed in the operating system. It is created on first use and shared by the whole application.
- [CustomFontRegistry](https://www.graphicsmill.com/docs/gm/T_Aurigma_GraphicsMill_Drawing_CustomFontRegistry.htm.md) is a registry that you fill yourself. You can add and remove fonts, add aliases, choose how conflicts are resolved, and handle missing fonts.

Many classes take a font registry. The most common one is [Graphics.FontRegistry](https://www.graphicsmill.com/docs/gm/P_Aurigma_GraphicsMill_Drawing_Graphics_FontRegistry.htm.md). Others are [ImageGenerator.FontRegistry](https://www.graphicsmill.com/docs/gm/P_Aurigma_GraphicsMill_ImageGenerator_FontRegistry.htm.md), [GraphicsContainerRasterizer.FontRegistry](https://www.graphicsmill.com/docs/gm/P_Aurigma_GraphicsMill_GraphicsContainerRasterizer_FontRegistry.htm.md), and [SvgReader.FontRegistry](https://www.graphicsmill.com/docs/gm/P_Aurigma_GraphicsMill_Codecs_SvgReader_FontRegistry.htm.md). Methods that measure text, such as [Text.GetBlackBox(FontRegistry, Single, Single)](https://www.graphicsmill.com/docs/gm/M_Aurigma_GraphicsMill_Drawing_Text_GetBlackBox_3_185e8a92.htm.md), take a registry as a parameter. Use the same registry for measuring and for drawing. Otherwise the text can be measured with one font and drawn with another.
 
This topic covers the following:
 
- Supported Font Formats
- Choosing a Font Registry
- Font Names
- Font Aliases
- Large Font Sets and Collisions
- Missing Fonts and Missing Glyphs
- Font Cache

## Supported Font Formats
  
Graphics Mill supports vector fonts in the following formats:
 
- OpenType (`.otf`)
- TrueType (`.ttf`)
- PostScript Type 1 (`.pfb`)

Bitmap fonts, such as Windows `.fon` fonts, are not supported. An attempt to add one throws [UnsupportedFontException](https://www.graphicsmill.com/docs/gm/T_Aurigma_GraphicsMill_UnsupportedFontException.htm.md). Font collections (`.ttc` files) are not supported either.
 
## Choosing a Font Registry
  
By default, **Graphics.FontRegistry** is the **FontRegistry.Installed** registry. This is convenient for a quick start. However, the installed fonts depend on the machine. A font can be missing on a server or in a container. Two machines can have different versions of the same font. As a result, the same template can produce different output on different machines.
 
We recommend using a **CustomFontRegistry** if you do not want to rely on installed fonts. Add the fonts that your application ships with, and assign the registry to every object that draws or measures text:
 
```csharp
using (var fontRegistry = new CustomFontRegistry())
using (var bitmap = new Bitmap(500, 100, PixelFormat.Format24bppRgb, RgbColor.White))
using (var graphics = bitmap.GetGraphics())
{
    // Register only the fonts your application ships with.
    // Add returns one result for each font in the file.
    var comic = fontRegistry.Add(@"C:\Windows\Fonts\comic.ttf").First();
    fontRegistry.Add(@"C:\Windows\Fonts\comicbd.ttf");

    Console.WriteLine("{0}: {1}", comic.PostscriptName, comic.Status);

    // Graphics looks fonts up only in its own registry.
    graphics.FontRegistry = fontRegistry;

    DrawLine(graphics, comic.PostscriptName, "Dedicated font registry", 60);

    bitmap.Save(@"Images\Output\DedicatedFontRegistry.png");
}
```
 ![Text drawn with a font from a dedicated font registry](https://www.graphicsmill.com/docs/gm/DedicatedFontRegistry.png) 
You can add a font from a file with [CustomFontRegistry.Add(String)](https://www.graphicsmill.com/docs/gm/M_Aurigma_GraphicsMill_Drawing_CustomFontRegistry_Add_1_bb3a7a4f.htm.md), or from a stream with [CustomFontRegistry.Add(Stream)](https://www.graphicsmill.com/docs/gm/M_Aurigma_GraphicsMill_Drawing_CustomFontRegistry_Add_1_bca7c9fe.htm.md). A stream is useful when fonts are kept in a database or in cloud storage. The registry copies the font data, so you can dispose the stream right after the call. When you add a font from a file, the registry keeps the path and reads the file again when the font is first used. Do not delete or change the file while the registry uses it.
 
If you need both the installed fonts and your own fonts, call [CustomFontRegistry.Merge(FontRegistry)](https://www.graphicsmill.com/docs/gm/M_Aurigma_GraphicsMill_Drawing_CustomFontRegistry_Merge_1_1d836bf2.htm.md) to copy the installed fonts into your registry first, and then add your fonts.
 
**Important** 
[Graphics](https://www.graphicsmill.com/docs/gm/T_Aurigma_GraphicsMill_Drawing_Graphics.htm.md) looks fonts up only in its own registry. A font that you added to another registry stays invisible to it.
 
## Font Names
  
A font can be identified in two ways:
 
- **Postscript name**, for example *TimesNewRomanPS-BoldMT*. This is a single string that identifies one font. Text styles, such as [CharStyle](https://www.graphicsmill.com/docs/gm/T_Aurigma_GraphicsMill_Drawing_CharStyle.htm.md), refer to fonts by postscript name. Templates created in Adobe applications store postscript names too.
- **Family and style**, for example *Times New Roman* and *Bold*. This is the name that people see in font menus. Use it when a user picks a font in your UI.

Both systems are needed, and a font registry keeps them consistent. Each postscript name resolves to one font, and each family and style pair resolves to one font. The following members work with both systems:
 
- [FontRegistry.CreateFont](https://www.graphicsmill.com/docs/gm/O_T_Aurigma_GraphicsMill_Drawing_FontRegistry_CreateFont.htm.md) creates a **Font** by postscript name or by family and style.
- [FontRegistry.Contains](https://www.graphicsmill.com/docs/gm/O_T_Aurigma_GraphicsMill_Drawing_FontRegistry_Contains.htm.md) checks whether a font is registered.
- [FontRegistry.TryGetPostscriptName(String, String, String@)](https://www.graphicsmill.com/docs/gm/M_Aurigma_GraphicsMill_Drawing_FontRegistry_TryGetPostscriptName_3_bbad2053.htm.md) returns the postscript name for a family and style pair. It does not throw an exception if there is no such font.
- [FontRegistry.Families](https://www.graphicsmill.com/docs/gm/P_Aurigma_GraphicsMill_Drawing_FontRegistry_Families.htm.md) and [FontRegistry.GetFontStyles(String)](https://www.graphicsmill.com/docs/gm/M_Aurigma_GraphicsMill_Drawing_FontRegistry_GetFontStyles_1_bb3a7a4f.htm.md) list the families and their styles. This is useful for filling a font menu.
- [FontRegistry.Fonts](https://www.graphicsmill.com/docs/gm/P_Aurigma_GraphicsMill_Drawing_FontRegistry_Fonts.htm.md) lists every registered font as a [FontInfo](https://www.graphicsmill.com/docs/gm/T_Aurigma_GraphicsMill_Drawing_FontInfo.htm.md) with its postscript name, family, style, and aliases.

Font names are not case sensitive, and leading and trailing spaces are ignored. So *ArialMT*, *arialmt*, and *ARIALMT* are the same font. The same rule applies to aliases and to family and style names.
 
The following snippet looks up the same font in different ways:
 
```csharp
using (var fontRegistry = new CustomFontRegistry())
{
    fontRegistry.Add(@"C:\Windows\Fonts\timesbd.ttf");

    // The same font by its postscript name and by its family and style.
    var byPostscriptName = fontRegistry.CreateFont("TimesNewRomanPS-BoldMT", 20, 72, 72);
    var byFamilyAndStyle = fontRegistry.CreateFont("Times New Roman", "Bold", 20, 72, 72);

    Console.WriteLine(byPostscriptName.PostscriptName == byFamilyAndStyle.PostscriptName);

    // Get the postscript name for a family and style without an exception.
    string postscriptName;

    if (fontRegistry.TryGetPostscriptName("Times New Roman", "Bold", out postscriptName))
        Console.WriteLine("Times New Roman Bold is {0}", postscriptName);

    // Names are not case sensitive.
    Console.WriteLine(fontRegistry.Contains("timesnewromanps-boldmt"));

    // List the registered fonts.
    foreach (var fontInfo in fontRegistry.Fonts)
    {
        Console.WriteLine("{0} = {1} {2}", fontInfo.PostscriptName, fontInfo.Family, fontInfo.Style);
    }
}
```
 
**Note** 
**CreateFont** takes the resolution of the target image. It must match the resolution of the **Graphics** object that draws the text. It is often easier to call [Graphics.CreateFont(String, Single)](https://www.graphicsmill.com/docs/gm/M_Aurigma_GraphicsMill_Drawing_Graphics_CreateFont_2_1dbfa9fa.htm.md), which uses the registry and the resolution of that **Graphics** object.
 
## Font Aliases
  
An **alias** is an extra name for a registered font. It works everywhere a postscript name works. Aliases are useful in the following cases:
 
- A template refers to a font by a name that differs from the real postscript name of your font file.
- A font was renamed in a newer version, but old documents still use the old name.
- You want to use stable names in your templates, such as *BrandHeadline*, and change the actual font later.

To add an alias to a registered font, call [CustomFontRegistry.AddFontAlias(String, String)](https://www.graphicsmill.com/docs/gm/M_Aurigma_GraphicsMill_Drawing_CustomFontRegistry_AddFontAlias_2_f3570541.htm.md). To remove it, call [CustomFontRegistry.RemoveFontAlias(String, String)](https://www.graphicsmill.com/docs/gm/M_Aurigma_GraphicsMill_Drawing_CustomFontRegistry_RemoveFontAlias_2_f3570541.htm.md). The original postscript name remains valid. [FontInfo.Aliases](https://www.graphicsmill.com/docs/gm/P_Aurigma_GraphicsMill_Drawing_FontInfo_Aliases.htm.md) lists the aliases of a font.
 
```csharp
using (var fontRegistry = new CustomFontRegistry())
using (var bitmap = new Bitmap(500, 100, PixelFormat.Format24bppRgb, RgbColor.White))
using (var graphics = bitmap.GetGraphics())
{
    var postscriptName = fontRegistry.Add(@"C:\Windows\Fonts\comicbd.ttf").First().PostscriptName;

    // A template refers to the font as "BrandHeadline".
    fontRegistry.AddFontAlias(postscriptName, "BrandHeadline");
    fontRegistry.AddFontAlias(postscriptName, "BrandTitle");

    foreach (var alias in fontRegistry.Fonts.First().Aliases)
    {
        Console.WriteLine("Alias: {0}", alias);
    }

    graphics.FontRegistry = fontRegistry;

    DrawLine(graphics, "BrandHeadline", "Drawn with an alias", 60);

    bitmap.Save(@"Images\Output\FontAlias.png");
}
```
 ![Text drawn with a font alias](https://www.graphicsmill.com/docs/gm/FontAlias.png) 
An alias must be unique in the registry. If an alias already refers to a different font, adding it throws **DuplicateFontAliasException**. Aliases are not case sensitive, so *Brand* and *BRAND* are the same alias. This exception is thrown regardless of the collision policies described below. An alias is an explicit instruction, so the registry never ignores it silently.
 
## Large Font Sets and Collisions
  
Real font libraries often contain fonts with conflicting names. This is especially common when customers upload their own fonts. Typical problems are:
 
- **Identical copies** of the same font under different file names.
- **The same postscript name for different fonts.** For example, some font families use one postscript name for all styles, or two vendors publish different fonts under the same name.
- **The same family and style for different postscript names.** For example, the OpenType and TrueType versions of one font can have different postscript names.

A **CustomFontRegistry** resolves these conflicts in [CustomFontRegistry.Add](https://www.graphicsmill.com/docs/gm/O_T_Aurigma_GraphicsMill_Drawing_CustomFontRegistry_Add.htm.md) and [CustomFontRegistry.Merge](https://www.graphicsmill.com/docs/gm/O_T_Aurigma_GraphicsMill_Drawing_CustomFontRegistry_Merge.htm.md). A font with exactly the same content as an already registered font is always skipped. For other conflicts, two properties define what happens:
 
|  Property |  Values |
| --- | --- |
 |  [CustomFontRegistry.PostscriptNameCollisionPolicy](https://www.graphicsmill.com/docs/gm/P_Aurigma_GraphicsMill_Drawing_CustomFontRegistry_PostscriptNameCollisionPolicy.htm.md) defines what happens when a different font already has the same postscript name. Its type is [PostscriptNameCollisionPolicy](https://www.graphicsmill.com/docs/gm/T_Aurigma_GraphicsMill_Drawing_PostscriptNameCollisionPolicy.htm.md). |  **Skip** (default) keeps the registered font and ignores the new one.<br> <br>**Replace** removes the registered font and adds the new one.<br> <br>**Throw** throws **DuplicatePostscriptNameException**. |
 |  [CustomFontRegistry.FamilyStyleCollisionPolicy](https://www.graphicsmill.com/docs/gm/P_Aurigma_GraphicsMill_Drawing_CustomFontRegistry_FamilyStyleCollisionPolicy.htm.md) defines what happens when a font with a different postscript name already has the same family and style. Its type is [FamilyStyleCollisionPolicy](https://www.graphicsmill.com/docs/gm/T_Aurigma_GraphicsMill_Drawing_FamilyStyleCollisionPolicy.htm.md). |  **AddAlias** (default) does not add the new font. Its postscript name becomes an alias of the registered font, so both names still work.<br> <br>**Skip** does not add the new font. Its postscript name does not resolve to any font.<br> <br>**Replace** removes the registered font and adds the new one.<br> <br>**Throw** throws **DuplicateFamilyStyleException**. |
 
With the default values, adding a font never throws an exception because of a conflict. Every name that could be resolved before the call can still be resolved after it.
 
**Add** and **Merge** return a collection of [FontAddResult](https://www.graphicsmill.com/docs/gm/T_Aurigma_GraphicsMill_Drawing_FontAddResult.htm.md) objects, one for each font. The [FontAddResult.Status](https://www.graphicsmill.com/docs/gm/P_Aurigma_GraphicsMill_Drawing_FontAddResult_Status.htm.md) property tells you what happened. Its type is [FontAddStatus](https://www.graphicsmill.com/docs/gm/T_Aurigma_GraphicsMill_Drawing_FontAddStatus.htm.md). [FontAddResult.PostscriptName](https://www.graphicsmill.com/docs/gm/P_Aurigma_GraphicsMill_Drawing_FontAddResult_PostscriptName.htm.md) is always the postscript name of the font you added. [FontAddResult.ConflictingPostscriptName](https://www.graphicsmill.com/docs/gm/P_Aurigma_GraphicsMill_Drawing_FontAddResult_ConflictingPostscriptName.htm.md) is the registered font it conflicted with.
 
|  Status |  Meaning |
| --- | --- |
 |  **Added** |  The font was added. |
 |  **AlreadyPresent** |  A font with the same content is already registered. Nothing changed. |
 |  **Replaced** |  The conflicting font was removed, and this font was added. |
 |  **Aliased** |  The font was not added. Its postscript name is now an alias of the conflicting font. |
 |  **SkippedPostscriptConflict** |  The font was not added because a different font has the same postscript name. |
 |  **SkippedFamilyStyleConflict** |  The font was not added because a different font has the same family and style. |
 
The following snippet loads a folder of fonts and reports the fonts that were not added as is:
 
```csharp
using (var fontRegistry = new CustomFontRegistry())
{
    // These are the default values.
    fontRegistry.PostscriptNameCollisionPolicy = PostscriptNameCollisionPolicy.Skip;
    fontRegistry.FamilyStyleCollisionPolicy = FamilyStyleCollisionPolicy.AddAlias;

    foreach (var path in Directory.GetFiles(@"C:\Windows\Fonts", "*.ttf"))
    {
        try
        {
            foreach (var result in fontRegistry.Add(path))
            {
                switch (result.Status)
                {
                    case FontAddStatus.Added:
                    case FontAddStatus.AlreadyPresent:
                        break;

                    case FontAddStatus.Aliased:
                        Console.WriteLine("{0} now resolves to {1}", result.PostscriptName, result.ConflictingPostscriptName);
                        break;

                    default:
                        Console.WriteLine("{0} was not added: {1}, conflicts with {2}",
                            result.PostscriptName, result.Status, result.ConflictingPostscriptName);
                        break;
                }
            }
        }
        catch (FontException ex)
        {
            Console.WriteLine("{0}: cannot load the font. {1}", path, ex.Message);
        }
    }
}
```
 
### Font Exceptions
 
All font exceptions are derived from [FontException](https://www.graphicsmill.com/docs/gm/T_Aurigma_GraphicsMill_FontException.htm.md). An exception thrown by **CustomFontRegistry.Add(String)**, **Merge**, or **AddFontAlias** never changes the registry. **Merge** checks all fonts before it adds any of them.
 
|  Exception |  When it is thrown |
| --- | --- |
 |  [DuplicatePostscriptNameException](https://www.graphicsmill.com/docs/gm/T_Aurigma_GraphicsMill_DuplicatePostscriptNameException.htm.md) |  A different font has the same postscript name, and the postscript name policy is **Throw**. The [Conflicts](https://www.graphicsmill.com/docs/gm/P_Aurigma_GraphicsMill_DuplicatePostscriptNameException_Conflicts.htm.md) property lists the conflicts. |
 |  [DuplicateFamilyStyleException](https://www.graphicsmill.com/docs/gm/T_Aurigma_GraphicsMill_DuplicateFamilyStyleException.htm.md) |  A different font has the same family and style, and the family and style policy is **Throw**. After **Merge**, the [Conflicts](https://www.graphicsmill.com/docs/gm/P_Aurigma_GraphicsMill_DuplicateFamilyStyleException_Conflicts.htm.md) property lists every conflict, not only the first one. |
 |  [DuplicateFontAliasException](https://www.graphicsmill.com/docs/gm/T_Aurigma_GraphicsMill_DuplicateFontAliasException.htm.md) |  An alias already refers to a different font. It is thrown regardless of the policies. |
 |  [AmbiguousFontCollisionException](https://www.graphicsmill.com/docs/gm/T_Aurigma_GraphicsMill_AmbiguousFontCollisionException.htm.md) |  The family and style of the new font belong to one registered font, and its postscript name belongs to another one. No policy can resolve both conflicts, so it is thrown regardless of the policies. |
 |  **UnsupportedFontException** |  The font format is not supported. |
 |  [FontMissingException](https://www.graphicsmill.com/docs/gm/T_Aurigma_GraphicsMill_FontMissingException.htm.md) |  A font cannot be found when you create a font object or draw text. See Missing Fonts and Missing Glyphs. |
 |  **FontException** |  Other font problems, for example a damaged font file. |
 
The following snippet uses the **Throw** policies to reject a set of uploaded fonts if any of them conflicts with the fonts already registered:
 
```csharp
using (var fontRegistry = new CustomFontRegistry())
{
    fontRegistry.Merge(FontRegistry.Installed);

    fontRegistry.PostscriptNameCollisionPolicy = PostscriptNameCollisionPolicy.Throw;
    fontRegistry.FamilyStyleCollisionPolicy = FamilyStyleCollisionPolicy.Throw;

    try
    {
        // All conflicts are checked before any font is added.
        // If there is a conflict, the registry does not change.
        fontRegistry.Merge(uploadedFonts);
    }
    catch (DuplicatePostscriptNameException ex)
    {
        foreach (var conflict in ex.Conflicts)
        {
            Console.WriteLine("{0} conflicts with {1}", conflict.PostscriptName, conflict.ExistingPostscriptName);
        }
    }
    catch (DuplicateFamilyStyleException ex)
    {
        foreach (var conflict in ex.Conflicts)
        {
            Console.WriteLine("{0} conflicts with {1}", conflict.PostscriptName, conflict.ExistingPostscriptName);
        }
    }
}
```
 
## Missing Fonts and Missing Glyphs
  
When Graphics Mill needs a font, the registry searches for it in the following order:
 
1. The font name, as described in Font Names.
2. The fonts in [FontRegistry.FallbackFonts](https://www.graphicsmill.com/docs/gm/P_Aurigma_GraphicsMill_Drawing_FontRegistry_FallbackFonts.htm.md). The first registered font from this list is used instead of the missing font.
3. The [CustomFontRegistry.FontMissing](https://www.graphicsmill.com/docs/gm/E_Aurigma_GraphicsMill_Drawing_CustomFontRegistry_FontMissing.htm.md) event. If the handler adds the font, the search is repeated once.

If the font is still not found, **FontMissingException** is thrown. The search runs both when you create a **Font** object and when you draw or measure text.
 
**Note** 
Fallback fonts are checked before the event. If **FallbackFonts** contains a registered font, the **FontMissing** event is never raised.
 
### Fallback Fonts
 
The **FallbackFonts** collection is a list of postscript names. It is used in two cases:
 
- **A font is missing.** The first registered fallback font replaces it.
- **A glyph is missing.** The font exists, but it has no glyph for some characters. For example, many Latin fonts have no Chinese, Japanese, or Korean characters. These characters are drawn with a fallback font that has them.

Names in the list that are not registered are ignored. When you remove a font from the registry, it is also removed from the list.
 
```csharp
using (var fontRegistry = new CustomFontRegistry())
using (var bitmap = new Bitmap(500, 160, PixelFormat.Format24bppRgb, RgbColor.White))
using (var graphics = bitmap.GetGraphics())
{
    fontRegistry.Add(@"C:\Windows\Fonts\arial.ttf");
    fontRegistry.Add(@"C:\Windows\Fonts\malgun.ttf");

    // Arial has no Korean glyphs. They are taken from Malgun Gothic.
    fontRegistry.FallbackFonts.Add("MalgunGothic");

    graphics.FontRegistry = fontRegistry;

    DrawLine(graphics, "ArialMT", "Hello, \uC548\uB155\uD558\uC138\uC694", 60);

    // UnknownFont is not registered, so the first fallback font is used instead.
    DrawLine(graphics, "UnknownFont", "Missing font", 120);

    bitmap.Save(@"Images\Output\FontFallback.png");
}
```
 ![Missing glyphs and a missing font replaced by a fallback font](https://www.graphicsmill.com/docs/gm/FontFallback.png) 
### FontMissing Event
 
The **FontMissing** event lets you load fonts on demand. For example, you can load a font from a font storage only when a template really uses it. The event is available only in **CustomFontRegistry**. The [FontMissingEventArgs](https://www.graphicsmill.com/docs/gm/T_Aurigma_GraphicsMill_Drawing_FontMissingEventArgs.htm.md) contain the [FontMissingEventArgs.PostscriptName](https://www.graphicsmill.com/docs/gm/P_Aurigma_GraphicsMill_Drawing_FontMissingEventArgs_PostscriptName.htm.md) of the missing font and the [FontMissingEventArgs.FontRegistry](https://www.graphicsmill.com/docs/gm/P_Aurigma_GraphicsMill_Drawing_FontMissingEventArgs_FontRegistry.htm.md) to add the font to:
 
```csharp
var fontRegistry = new CustomFontRegistry();

fontRegistry.FontMissing += (sender, e) =>
{
    // For example, a font storage keeps each font in a file named after its postscript name.
    var path = System.IO.Path.Combine("Fonts", e.PostscriptName + ".ttf");

    if (File.Exists(path))
        e.FontRegistry.Add(path);
};

using (var bitmap = new Bitmap(500, 100, PixelFormat.Format24bppRgb, RgbColor.White))
using (var graphics = bitmap.GetGraphics())
{
    graphics.FontRegistry = fontRegistry;

    try
    {
        DrawLine(graphics, "ComicSansMS", "Loaded on demand", 60);
    }
    catch (FontMissingException ex)
    {
        Console.WriteLine(ex.Message);
    }
}

fontRegistry.Dispose();
```
 
## Font Cache
  
Before a font can be used for drawing, its file must be parsed. Parsing takes time, so each registry keeps a cache of parsed fonts:
 
- The cache belongs to a registry instance. Registries do not share it.
- A font is parsed when it is first used, not when it is added. This keeps **Add** fast.
- A new registry, including a registry filled with **Merge**, starts with an empty cache. However, it shares the font data with the source registry and does not copy it.
- When you remove a font or clear the registry, the parsed font is removed from the cache.

The data of fonts added from streams is kept in memory for the lifetime of the registry. Fonts added from files are read from disk when they are parsed.
 
## See Also
  
### Reference
 
- [FontRegistry Class](https://www.graphicsmill.com/docs/gm/T_Aurigma_GraphicsMill_Drawing_FontRegistry.htm.md)
- [CustomFontRegistry Class](https://www.graphicsmill.com/docs/gm/T_Aurigma_GraphicsMill_Drawing_CustomFontRegistry.htm.md)
- [FontAddResult Class](https://www.graphicsmill.com/docs/gm/T_Aurigma_GraphicsMill_Drawing_FontAddResult.htm.md)
- [FontInfo Class](https://www.graphicsmill.com/docs/gm/T_Aurigma_GraphicsMill_Drawing_FontInfo.htm.md)
- [Font Class](https://www.graphicsmill.com/docs/gm/T_Aurigma_GraphicsMill_Drawing_Font.htm.md)
- [FontException Class](https://www.graphicsmill.com/docs/gm/T_Aurigma_GraphicsMill_FontException.htm.md)

### Manual
 
- [Working with the Text Class](https://www.graphicsmill.com/docs/gm/working-with-text-class.htm.md)
- [Drawing Simple Text Objects](https://www.graphicsmill.com/docs/gm/advanced-drawing-text.htm.md)
- [Formatted Text](https://www.graphicsmill.com/docs/gm/advanced-formatted-text.htm.md)
