Closed Jcook65 closed 4 years ago
Have a look at the FontMapper class:
https://github.com/toptensoftware/RichTextKit/blob/master/Topten.RichTextKit/FontMapper.cs
You can provide your own implementation this (it's just one method that maps an IStyle to a typeface) and plug it in by either setting FontMapper.Default or setting the font mapper on the individual text blocks you're using.
For reference, here's some sample code from one of my projects that show how to do this:
using SkiaSharp;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Topten.RichTextKit;
namespace Topten.GuiKit
{
/// <summary>
/// Handles mapping of font family names to SKTypefaces
/// </summary>
public class FontMapper : Topten.RichTextKit.FontMapper
{
/// <summary>
/// Loads a private font from a stream
/// </summary>
/// <param name="stream">The stream to load from</param>
/// <param name="familyName">An optional family name to override the font's built in name</param>
/// <returns>True if the font was successully loaded</returns>
public static bool LoadPrivateFont(System.IO.Stream stream, string familyName=null)
{
var tf = SKTypeface.FromStream(stream);
if (tf == null)
return false;
var qualifiedName = familyName ?? tf.FamilyName;
if (tf.FontSlant != SKFontStyleSlant.Upright)
// if (tf.IsItalic)
{
qualifiedName += "-Italic";
}
// Get a list of typefaces with this family
if (!_customFonts.TryGetValue(qualifiedName, out var listFonts))
{
listFonts = new List<SKTypeface>();
_customFonts[qualifiedName] = listFonts;
}
// Add to the list
listFonts.Add(tf);
return true;
}
/// <summary>
/// Map a RichTextKit style to an SKTypeface
/// </summary>
/// <param name="style">The style</param>
/// <param name="ignoreFontVariants">True to ignore variants (super/subscript)</param>
/// <returns>The mapped typeface</returns>
public override SKTypeface TypefaceFromStyle(IStyle style, bool ignoreFontVariants)
{
// Work out the qualified name
var qualifiedName = style.FontFamily;
if (style.FontItalic)
qualifiedName += "-Italic";
// Look up custom fonts
List<SKTypeface> listFonts;
if (_customFonts.TryGetValue(qualifiedName, out listFonts))
{
// Find closest weight
return listFonts.MinBy(x => Math.Abs(x.FontWeight - style.FontWeight));
}
// Do default mapping
return base.TypefaceFromStyle(style, ignoreFontVariants);
}
/// <summary>
/// Maps a GuiKit font to a SKTypeface
/// </summary>
/// <param name="font">The font to map</param>
/// <returns>A mapped SKTypeface</returns>
public static SKTypeface MapFontToSKTypeface(Font font)
{
// Look up custom fonts
List<SKTypeface> listFonts;
if (_customFonts.TryGetValue(font.FamilyName, out listFonts))
{
return listFonts.MinBy(x => Math.Abs(x.FontWeight - font.Weight));
}
// Skia's family name mapper seems to map apple system font
// to a very bold version SF. Remap it...
var name = font.FamilyName;
if (font.FamilyName == ".AppleSystemUIFont" && !font.Bold)
{
name = "San Francisco";
}
// Default...
return SKTypeface.FromFamilyName(name, (SKFontStyleWeight)font.Weight, 0, SKFontStyleSlant.Upright);
}
static FontMapper()
{
// Install self as the default RichTextKit font mapper
Topten.RichTextKit.FontMapper.Default = new FontMapper();
}
// Constructor
private FontMapper()
{
}
static Dictionary<string, List<SKTypeface>> _customFonts = new Dictionary<string, List<SKTypeface>>();
}
}
I have a custom Typeface that I am using for text in my application. For painting text with
SKPaint
I can set the Typeface from an custom font that I load into aSKTypeface
object. I can't seem to find a way to do that for aStyle
in the RichTextKit sinceStyle.FontFamily
only takes a string. I have tried usingSKTypeface.FamilyName
but the style doesn't seem to recognize it since it is a custom font. Is there a way to do this? I have looked around but I can't seem to find anywhere that this is referenced. If it isn't possible could someone point me to a list of acceptable values forStyle.FontFamily
?