Skip to content

Description

With the help of .NET FontManager, you can use the common type of font files, get contours of every glyph and draw them as you need. The library is rather simple and you don’t even need to know about fonts internals.

1 var fsup = new FreetypeFontSupplier(File.ReadAllBytes("arial.ttf"));
2 fsup.DrawString(graphics, 0, 0, "This is a text!", 12.0f, Brushes.Black);
font-manager

Main Functions

.NET FontManager provides low-level operations with various font formats, which include:

prod-018-pic
  • TrueType and TrueType collections,
  • OpenType and OpenType collections,
  • Type1 fonts, including Type1C,
  • CID fonts.

Technically, it works through freetype2 version 2.5 and supports all fonts from this library. Instead of playing with low C code you can work with .NET and operate with pure .NET abstractions.

Why .NET FontManager

Once working with the DTP area, you need to make certain charts, vector images and logos with a real vector format and proper pantones. Or, perhaps you simply like good charts on your mobile device without raster. In all these cases you need to make images in specific and sometimes ancient formats.

So, you need proper and high-quality fonts as well! It is not enough to make a few polygons to be sure it works and looks excellent.

But .NET does not even have support for OpenType fonts. Thereby, we decided to create our own library .NET FontManager with a number of helpful features. Once we have done the same trick dozens of times, we decided to share our code with others.

Moreover, we have API for Java as well.

When to Use .NET FontManager

Whenever you have a non-standard or commercial font, you need to think about how to work with it, how to distribute it and how to keep windows font substitution hands out of your font.

Also, you don’t need to purchase TrueType fonts. OpenType, CID fonts, Type1 hold glyphs in vector and are handled by freetype2.

Here is a simple decision: bring everything with your application, use it from your private folder and it will work in an excellent manner: the proper look, the proper feel and no interference with other fonts and programs. Easy distribution is important sometimes.

When you work with font files you know the proper font all the time, and errors in font metadata will not bring you any trouble. Just use contents and add any “font name” to it according to your needs.

How to Integrate

Technically, it works through freetype2 version 2.5 and supports all fonts from this library. Instead of playing with low C code you can work with .NET and operate with pure .NET abstractions. For example, with OxyPlot library the typical appliance will look like:

graphics

All fonts are handled by .Net FontManager and stored in SVG font format:

1
2
3
4
5
6
7
8
9
10
<defs>
    <font id="Font_2107481958">
      <font-face ascent="92.9000" descent="-25.0000" units-per-em="100" height="117.9000"
      font-style="normal" font-family="Font_2107481958" font-weight="normal" />
      <glyph unicode="0" horiz-adv-x="48.0000" d="..." />
      <glyph unicode="5" horiz-adv-x="48.0000" d="...  Z" />
      <glyph unicode="2" horiz-adv-x="48.0000" d="M 3.7 7.7 ... L 3.7 7.7 Z" />
       ...
   </font>
  </defs>

This is the typical result:

bigplane

Architecture

.NET FontManager is an intellectual wrapper over the FreeType2 open source library and it uses GPLv2 as the original library.

When creating FreetypeFontSupplier, you provide the byte array with the font contents. It might be a file from a disk or content downloaded from the Internet or a resource from your assembly. During the creation time, you provide the byte array with one of the known font formats.

During the creation process, FreetypeFontSupplier is called FreeType to parse the byte array, extract the contours and fill it as FreetypeFontSupplier.GlyphInfo hashmap. At the same time, the basic font metrics are discovered as well and become available once the FreetypeFontSupplier is created.

After the creation of FreetypeFontSupplier, FreeType is no longer used and everything is held in the memory. All computations and drawings are performed by our code, not by FreeType2. So, you don’t need to think about Cairo and other Linux-world libraries with wrappers. Once the font is parsed, all further operations are pure .NET.

If you have only CIDType2 from PDF, just extract the bytes of the font into an array and let the library work. The in-existence of certain characters might limit paints, but the known glyphs will work well. Please do not forget to extract PDF Encoding and/or CMap conversions additionally in your code, especially for the case Type0 descendants; some “optimizers” might keep only codes of the glyphs in fonts instead of normal tables. Over-optimized PDFs might be a bunch of surprises.

Samples

To start using the library, just specify the font file: private Matrix defaultMatrix = new Matrix(0.01f, 0, 0, 0.01f, 0, 0); FreetypeFontSupplier fsup = new FreetypeFontSupplier( File.ReadAllBytes(“arial.ttf”), defaultMatrix);

The default matrix is necessary to scale glyphs in a normal canvas for measurements and drawings. For example, for the SVG library, the “common size” is 100. Thus, we use 1/100 for scaling for this case. Defaults are useable for most cases, so you can leave the 2nd parameter as null.

Once a file is loaded you can compute the sizes of the text for 12pt font size:

1
2
float width = fsup.MeasureTextWidth("Text"12.0f);
    float height= fsup.GetHeight(12.0f);

or

1
SizeF sz = fsup.MeasureText("Text"12.0f);

In the same way, we can compute ascent, descent and even “units per em”.

Now we can either discover such details from the font, for example, to produce a new format (like SVG) or imply draw the text as follows:

1
2
3
fsup.DrawString(graphics, 00,
        "This\nis\na\n\text!",
        12.0f, Brushes.Black);

where (0, 0) are left/top corner of the text (ascending is added automatically so you don’t need to care about it), 12.0f is font size in points and brush is the color, hatch, gradient or texture.

In the same way, you can make an outlined text:

1
2
3
fsup.DrawOutline(graphics, 00,
        "This\nis\na\n\text!",
        12.0f, Pens.Bisque);

Sometimes you need to fill the text in the specific rectangle:

1
2
3
fsup.DrawString(graphics, 00100100,
       "This\nis\na\n\text!",
       12.0f, Brushes.Black);

The text will be auto-wrapped against the right boundary.

And the last trick is to make SVG custom font definition for specific sub-string:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
public String dumpFontGlyphs(String knownChars, String refName, float emSize)
{
    float commonSize = fsup.MatrixScale;
    StringBuilder d = new StringBuilder();
    d.Append("<font id=\"" + refName + "\">");
    d.Append("<font-face ascent=\"" +
        (commonSize * fsup.GetAscent(emSize)) + "\" descent=\"" +
        (commonSize * fsup.GetDescent(emSize)) + "\" units-per-em=\"" +
        fsup.UnitsPerEm + "\" height=\"" +
        (commonSize * fsup.GetHeight(emSize)) +
        "\" font-style=\"normal\" font-family=\"Font_" + refName +
        "\" font-weight=\"normal\"/>");
    for(int k = 0; k < knownChars.Count; ++k) {
        d.Append("<glyph unicode=\""+knownChars[k]+"\" horiz-adv-x=\"" +
            fsup.GetAdvanceX(knownChars[k]) + "\" d=\"");
        d.Append(fsup.ToSVGData(knownChars[k]));
        d.Append("\"/>");
    }
    d.Append("<font/>");
    return d.ToString();
}

This code seems tricky, but it indicates the basic principles of using the library. Every number and every curve are available through .NET FontManager, and it is easy to use it in the same way for other libraries. Just use a new API instead of the trick with sophisticated “measurers” and “renderers”. Your fonts will be always available and predictable.

Download

.NET FontManager appliances: OxyPlot charts library

For the sake of usability, we have added bindings to popular .NET libraries. One of them is OxyPlot. It works fast and has a very good architecture allowing you to add a few additional options. Certainly, we have added not only fonts support but SVG output as well; which means we have added SVG Colors (with icc-color(#CMYK,) profile) and fonts. All patches (oxyplot-final.patch) and patched library source (oxyplot-develop-patched.zip) with binaries (OxyPlot-SvgNet-bin.zip) are available.

.NET FontManager appliances: SvgNet

Unlike the charts library, SvgNet is an open-source code supporting drawings to SVG. Logos, simple boxes and other vectorized stuff are there. For OxyPlot we have added certain code to handle custom fonts and improve the colors. Unfortunately, due to GDI API limits, we cannot inherit System.Drawing.Font and supply our derived implementation instead of the standard one (Microsoft like sealed classes even in cases it should not be sealed). So, we have added a few more DrawString() calls for SVGGraphics implementation as well as in the interface. We have no possibility to follow Microsoft's contract for Graphics class. All patches (svgnet-final.patch) and patched library (SvgNet-master-patched.zip) with binaries (OxyPlot-SvgNet-bin.zip) are available. .NET FontManager library source (dotNET-FontManager-sources.zip). This library is provided “AS IS” under the terms of the GPLv3. In case you need it under another (for example, commercial) license, please contact us using the contact form below. Commercial support is available as well.

You can request any specific features you need — order our custom software development services, fast and cost-effective.

Need a Similar Solution?

Related Products

DbFS.NET

DbFS.NET is a high-level abstraction and implementation, which supports files (with versions and branches) in MS SQL database.

Learn more

GSpread.NET

GSpread.NET is a fast and easy to use library designed for working with Google Spreadsheets by using the well-known API from Microsoft Excel.

Learn more

ASP.NET MVC Modules

Open source MVC framework for .NET to enable packing multiple resources, including views, icons, scripts, etc. in one DLL.

Learn more

This site uses technical cookies and allows the sending of 'third-party' cookies. By continuing to browse, you accept the use of cookies. For more information, see our Privacy Policy.