/// <summary>
/// Calculate the kerning between two glyphs
/// </summary>
/// <param name="g1">The first glyph</param>
/// <param name="g2">The second glyph</param>
/// <param name="lim1">The first glyph limits</param>
/// <param name="lim2">The second glyph limits</param>
/// <param name="config">The kerning configuration to use</param>
/// <param name="font">The glyph's <see cref="IFont"/></param>
/// <returns>The x coordinate kerning offset</returns>
private static int Kerning(QFontGlyph g1, QFontGlyph g2, XLimits[] lim1, XLimits[] lim2, QFontKerningConfiguration config, IFont font)
{
// Use kerning information from the font if it exists
if (font != null && font.HasKerningInformation)
{
return(font.GetKerning(g1.Character, g2.Character));
}
// Otherwise, calculate our own kerning
int yOffset1 = g1.YOffset;
int yOffset2 = g2.YOffset;
int startY = Math.Max(yOffset1, yOffset2);
int endY = Math.Min(g1.Rect.Height + yOffset1, g2.Rect.Height + yOffset2);
int w1 = g1.Rect.Width;
int worstCase = w1;
//TODO - offset startY, endY by yOffset1 so that lim1[j-yOffset1] can be written as lim1[j], will need another var for yOffset2
for (int j = startY; j < endY; j++)
{
worstCase = Math.Min(worstCase, w1 - lim1[j - yOffset1].Max + lim2[j - yOffset2].Min);
}
worstCase = Math.Min(worstCase, g1.Rect.Width);
worstCase = Math.Min(worstCase, g2.Rect.Width);
//modify by character kerning rules
CharacterKerningRule kerningRule = config.GetOverridingCharacterKerningRuleForPair("" + g1.Character + g2.Character);
switch (kerningRule)
{
case CharacterKerningRule.Zero:
return(1);
case CharacterKerningRule.NotMoreThanHalf:
return(1 - (int)Math.Min(Math.Min(g1.Rect.Width, g2.Rect.Width) * 0.5f, worstCase));
}
return(1 - worstCase);
}