.NET FontManager SamplesFontManager

.NET FontManager 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 contents 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 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 array and let the library work. The in-existence of the 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.

.NET FontManager 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 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:

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

or

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:

fsup.DrawString(graphics, 0, 0, 
        "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:

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

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

 fsup.DrawString(graphics, 0, 0, 100, 100,
        "This\nis\na\n\text!", 
        12.0f, Brushes.Black);

The text will be auto-wrapped against right boundary.

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

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.