Skip to content

Commit fdfba1a

Browse files
Merge pull request #857 from AvaloniaUI/luke-embedded-fonts-update
Rewrite custom fonts page
2 parents 54eb499 + 05e7847 commit fdfba1a

File tree

1 file changed

+107
-50
lines changed

1 file changed

+107
-50
lines changed

docs/guides/styles-and-resources/how-to-use-fonts.md

Lines changed: 107 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -3,21 +3,31 @@ id: how-to-use-fonts
33
title: How To Use Custom Fonts
44
---
55

6-
Customizing your Avalonia application with unique fonts can add a distinctive look and feel. This guide will walk you through the process of integrating custom fonts into your Avalonia application.
6+
Customizing your Avalonia application with unique fonts can add a distinctive look and feel. This guide explains how to integrate custom fonts into your Avalonia application.
77

8-
<GitHubSampleLink title="Google Fonts" link="https://github.com/AvaloniaUI/AvaloniaUI.QuickGuides/tree/main/GoogleFonts"/>
8+
## Using a custom font as a static resource
99

10-
## Add Your Custom Font to the Project
10+
### Clone the Google Fonts sample
1111

12-
Before you can use a custom font, you need to include it in your project.
12+
Start by cloning our [Google Fonts sample project](https://github.com/AvaloniaUI/AvaloniaUI.QuickGuides/tree/main/GoogleFonts). This project includes files for the [Nunito](https://fonts.google.com/specimen/Nunito) font, which we will be using throughout this guide.
1313

14-
In this guide, we will be using a font called [Nunito](https://fonts.google.com/specimen/Nunito) which is already stored in our application resources under `avares://GoogleFonts/Assets/Fonts`.
14+
### Add your custom font to the project
1515

16-
Ensure that the fonts have the build property set to `AvaloniaResource`.
16+
Before you can use a custom font, you must include it in your project.
1717

18-
## Declare Your Font in Application Resources
18+
Open **GoogleFonts.csproj** in the sample project you cloned. You can see that the `Assets` directory has already been set as an `AvaloniaResource`. This ensures that fonts in the directory are correctly built at runtime.
1919

20-
In your Avalonia application, open your `App.xaml` file and include your custom font inside `<Application.Resources>`. Assign it a key, which you will use to reference it in your application. In this case, we have assigned the key `NunitoFont`.
20+
Resources in this directory can be accessed through `avares://GoogleFonts/Assets/Fonts`.
21+
22+
```xml title="GoogleFonts.csproj"
23+
<AvaloniaResource Include="Assets\**" />
24+
```
25+
26+
### Declare your font in application resources
27+
28+
1. In your Avalonia application, open `App.axaml`.
29+
2. Include your custom font inside the `<Application.Resources>` tag.
30+
3. Assign it a key to use as reference in your application. In this case, we have assigned the key `NunitoFont`.
2131

2232
```xml title="App.axaml"
2333
<Application xmlns="https://github.com/avaloniaui"
@@ -27,20 +37,21 @@ In your Avalonia application, open your `App.xaml` file and include your custom
2737
<Application.Styles>
2838
<FluentTheme />
2939
</Application.Styles>
30-
// highlight-start
40+
// highlight-start
3141
<Application.Resources>
3242
<FontFamily x:Key="NunitoFont">avares://GoogleFonts/Assets/Fonts#Nunito</FontFamily>
3343
</Application.Resources>
34-
// highlight-end
44+
// highlight-end
3545
</Application>
3646
```
3747

38-
## Use Your Custom Font
39-
Once your font is declared in your application resources, you can use it in your application.
48+
### Apply your custom font
4049

41-
To reference your custom font, use the `FontFamily` attribute with the `StaticResource` markup extension. You need to pass the key of the declared font as the parameter. In this case, `NunitoFont` is the key for our custom font.
50+
Once your font is declared in the application resources, you can use it in your application.
4251

43-
Here's an example of how to apply our custom `Nunito` font to a `TextBlock`:
52+
To reference your custom font, use the `FontFamily` attribute with the `StaticResource` markup extension. Pass the key of the declared font as the parameter, which in this case is `NunitoFont`.
53+
54+
In the below example, the text displayed in the `TextBlock` control is now size 70, and uses the Nunito font.
4455

4556
```xml
4657
<TextBlock Text="{Binding Greeting}"
@@ -49,73 +60,119 @@ Here's an example of how to apply our custom `Nunito` font to a `TextBlock`:
4960
HorizontalAlignment="Center" VerticalAlignment="Center"/>
5061
```
5162

52-
In the above example, the `TextBlock` control will use the `Nunito` font that we declared in our application resources. The text bound to the `TextBlock` will now appear in the `Nunito` font at the specified font size of 70.
63+
The `FontFamily` attribute can be applied to any control with the `FontFamily` property, meaning you can use your custom font throughout your application.
64+
65+
---
5366

54-
Remember that the `FontFamily` attribute can be applied to any control that has the `FontFamily` property, meaning you can use your custom font throughout your application.
67+
## Creating an embedded font collection
5568

56-
And that's it! You've successfully integrated a custom font into your Avalonia application. Now you can add a unique touch to your application's UI with the fonts of your choice.
69+
### About embedded font collections
5770

58-
## Adding a Font to the Font Collection
71+
`EmbeddedFontCollection` provides a way to add fonts to your application as a collection, so that you can use them without a reference to a static resource.
5972

60-
The `EmbeddedFontCollection` provides an easy way to add fonts to your application's collection of fonts without requiring a reference to a resource when using them. For example, instead of setting the `FontFamily` to `{StaticResource NunitoFont}`, you can simply reference the name of the font family directly.
73+
For example, instead of setting the font family to `{StaticResource NunitoFont}`, as described in the previous section, you can reference the font family as `#Nunito`.
6174

6275
```xml
6376
<TextBlock
6477
Text="{Binding Greeting}"
6578
FontSize="70"
66-
FontFamily="Nunito"
79+
// highlight-start
80+
FontFamily="fonts:MyFonts#Nunito"
81+
// highlight-end
6782
HorizontalAlignment="Center" VerticalAlignment="Center" />
6883
```
6984

70-
This requires additional setup on application construction, but it removes the need to remember a unique resource key when authoring your controls.
85+
This requires additional setup, but removes the need to use a unique resource key when authoring your controls.
7186

72-
### Defining a Font Collection
87+
### Defining a font collection
7388

74-
First, we need to define a collection of fonts by specifying the font family name and the directory in which the font files reside.
89+
These instructions continue with the [Google Fonts sample project](https://github.com/AvaloniaUI/AvaloniaUI.QuickGuides/tree/main/GoogleFonts) you used in the [previous section](#using-a-custom-font-as-a-static-resource).
7590

76-
```csharp title="InterFontCollection.cs"
77-
public sealed class InterFontCollection : EmbeddedFontCollection
91+
1. (Optional) In the **App.axaml** file, delete the `NunitoFont` application resource. It is no longer needed. ~~`<FontFamily x:Key="NunitoFont">avares://GoogleFonts/Assets/Fonts#Nunito</FontFamily>`~~
92+
2. Open the **Program.cs** file.
93+
3. At the top of the file, add the declaration `using Avalonia.Media.Fonts;`
94+
95+
```csharp
96+
using Avalonia;
97+
using System;
98+
// highlight-start
99+
using Avalonia.Media.Fonts;
100+
// highlight-end
101+
```
102+
103+
4. Above the `Program` class, add a new class to create the `EmbeddedFontCollection`. In this example, we have named it `MyFontCollection`.
104+
105+
```csharp
106+
public sealed class MyFontCollection : EmbeddedFontCollection
78107
{
79-
public InterFontCollection() : base(
80-
new Uri("fonts:Inter", UriKind.Absolute),
81-
new Uri("avares://Avalonia.Fonts.Inter/Assets", UriKind.Absolute))
108+
public MyFontCollection() : base(
109+
new Uri("fonts:MyFonts", UriKind.Absolute),
110+
new Uri("avares://GoogleFonts/Assets/Fonts", UriKind.Absolute))
82111
{
83112
}
84113
}
85114
```
86115

87-
Here, `Inter` is the name of the font family and `avares://Avalonia.Fonts.Inter/Assets` is the resource locator for the directory containing the font files. The actual names of the font files are not significant since the `EmbeddedFontCollection` will search every file in the given directory and only load those fonts with the given font family name.
116+
This class acts as a resource locator for the directory containing the custom font files. Here, the directory is `avares://GoogleFonts/Assets/Fonts`, and it is accessed with the key `fonts:MyFonts`.
88117

89-
For more information on how to create a resource locator, see [Assets](/docs/basics/user-interface/assets) for a primer on including assets in your project.
118+
For more information on how to create a resource locator, see [Assets](/docs/basics/user-interface/assets).
90119

91-
### Adding the Font Collection
120+
### Adding the font collection to the app
92121

93-
Next, we need to add this font collection to the application. This can be done by using `AppBuilder.ConfigureFonts` to configure the `FontManager` to include your fonts on application construction.
122+
Next, we need to add `MyFontCollection` to the application.
123+
124+
1. Continue working in the file **Program.cs**.
125+
2. Within the Avalonia configuration code, i.e. the code portion starting `public static AppBuilder BuildAvaloniaApp()`, use `AppBuilder.ConfigureFonts` to configure a font manager that includes the font collection when the app is constructed.
126+
127+
Your `class Program` should now look something like this:
94128

95129
```csharp title="Program.cs"
96-
public static class Program
97-
{
98-
[STAThread]
99-
public static void Main(string[] args) =>
100-
BuildAvaloniaApp()
130+
class Program
131+
{
132+
[STAThread]
133+
public static void Main(string[] args) => BuildAvaloniaApp()
101134
.StartWithClassicDesktopLifetime(args);
102135

103-
public static AppBuilder BuildAvaloniaApp() =>
104-
AppBuilder.Configure<App>()
105-
.UsePlatformDetect()
136+
public static AppBuilder BuildAvaloniaApp()
137+
=> AppBuilder.Configure<App>()
138+
.UsePlatformDetect()
139+
.ConfigureFonts(fontManager =>
140+
{
141+
fontManager.AddFontCollection(new MyFontCollection());
142+
})
143+
.LogToTrace();
144+
}
145+
```
146+
147+
### Applying a font from the font collection
148+
149+
1. Open the file **MainWindow.axaml**.
150+
2. Update the `FontFamily` attribute of the `TextBlock` to use `FontFamily="fonts:MyFonts#Nunito"`.
151+
152+
```xml title="MainWindow.axaml"
153+
<TextBlock Text="{Binding Greeting}"
154+
FontSize="70"
106155
// highlight-start
107-
.ConfigureFonts(fontManager =>
108-
{
109-
fontManager.AddFontCollection(new InterFontCollection());
110-
})
156+
FontFamily="fonts:MyFonts#Nunito"
111157
// highlight-end
112-
.LogToTrace();
113-
}
158+
HorizontalAlignment="Center" VerticalAlignment="Center"/>
114159
```
115160

116-
### Creating Font Packages
161+
3. Build and run the app. Confirm the text is displayed in Nunito font.
162+
163+
The `FontFamily` value `fonts:MyFonts#Nunito` acts as a URI for the font file resource in your **Assets** folder. Its format is `{scheme}:{collection-key}#{font-family-name}`. In this case, the directory indicated by `fonts:MyFonts` is `/GoogleFonts/Assets/Fonts`, and the target font family, as marked by the `#` symbol, is `Nunito`.
164+
165+
`EmbeddedFontCollection` searches every file in the specified directory and loads files with the target font family name.
166+
167+
Your font collection can contain many font families and font files. To switch to another font within the **Assets** folder, change the `FontFamily` value to the desired font, e.g. `fonts:MyFonts#ComicSans`.
168+
169+
---
170+
171+
## Pre-built font packages
172+
173+
The [`Avalonia.Fonts.Inter`](https://github.com/AvaloniaUI/Avalonia/tree/master/src/Avalonia.Fonts.Inter) package is an example of a pre-built font package that contains fonts you can utilize across multiple projects. The fonts in the package can be accessed with a single method call in your app configuration file.
117174

118-
The [`Avalonia.Fonts.Inter`](https://github.com/AvaloniaUI/Avalonia/tree/master/src/Avalonia.Fonts.Inter) package shows how you can create a separate project to contain one or many fonts that you might use in multiple projects. Once you have created and published a project similar to this, using the font becomes as simple as appending a method call to your application construction.
175+
If you wish to use the Inter font as included in the `Avalonia.Fonts.Inter` NuGet package, you can install the package and add `.WithInterFont()` to your Avalonia configuration code.
119176

120177
```csharp title="Program.cs"
121178
public static class Program
@@ -135,6 +192,6 @@ public static class Program
135192
}
136193
```
137194

138-
## Which Fonts Are Supported?
195+
## Which fonts are supported?
139196

140-
Most TrueType (`.ttf`) and OpenType (`.otf`, `.ttf`) fonts are supported. However, some font features, such as "Variable fonts" are not currently supported (see: [Issue #11092](https://github.com/AvaloniaUI/Avalonia/issues/11092)).
197+
Most TrueType (`.ttf`) and OpenType (`.otf`, `.ttf`) fonts are supported. However, some font features, such as "Variable fonts" are not currently supported (See [Issue #11092](https://github.com/AvaloniaUI/Avalonia/issues/11092)).

0 commit comments

Comments
 (0)