using iText.IO.Font; using iText.IO.Font.Otf; using iText.Kernel.Font; using iText.Layout.Element; using iText.Layout.Properties; using iText.Layout.Renderer; using System; namespace Elwig.Documents { public class KernedParagraph : Paragraph { public KernedParagraph(float fontSize) : base() { SetFontKerning(FontKerning.YES); SetFixedLeading(fontSize); SetFontSize(fontSize); } public KernedParagraph(string text, float fontSize) : base(text) { SetFontKerning(FontKerning.YES); SetFixedLeading(fontSize); SetFontSize(fontSize); } public KernedParagraph(Text text, float fontSize) : base(text) { SetFontKerning(FontKerning.YES); SetFixedLeading(fontSize); SetFontSize(fontSize); } public override KernedParagraph Add(ILeafElement element) { if (element is Text t) { t.SetFontKerning(FontKerning.YES); t.SetNextRenderer(new KerningTextRenderer(t)); } base.Add(element); return this; } public override Paragraph Add(IBlockElement element) { base.Add(element); return this; } public class KerningTextRenderer(Text textElement) : TextRenderer(textElement) { public override IRenderer GetNextRenderer() { return new KerningTextRenderer((Text)modelElement); } public override void ApplyOtf() { PdfFont font; try { font = GetPropertyAsFont(Property.FONT); } catch (InvalidCastException) { return; } if (strToBeConverted != null) { SetProcessedGlyphLineAndFont(TextPreprocessingUtil.ReplaceSpecialWhitespaceGlyphs(font.CreateGlyphLine(strToBeConverted), font), font); } if (otfFeaturesApplied || text.GetStart() >= text.GetEnd()) { return; } if (GetProperty(Property.FONT_KERNING, (FontKerning?)FontKerning.NO) == FontKerning.YES) { ApplyKerning(font.GetFontProgram(), text); } otfFeaturesApplied = true; } private static void ApplyKerning(FontProgram font, GlyphLine text) { for (int i = 1; i < text.Size(); i++) { var kerning = font.GetKerning(text.Get(i - 1), text.Get(i)); if (kerning != 0) { text.Set(i - 1, new Glyph(text.Get(i - 1), 0, 0, kerning, 0, 0)); } } } } } }