Skip to content

Setting TextState.Font via FontRepository.FindFont yields different results based on overload #73

@daeghanelkin

Description

@daeghanelkin

Describe the bug

I'm trying to use the DejaVu Sans Mono font with an Italic style within a PDF that I'm generating, and when rendering text that's had it's TextState.Font assigned via the FontRepository.FindFont method, the resulting text differs based on the method overload that was used.

If the FontRespository.FindFont(string) method is used in conjunction with assigning a font style directly to TextState.FontStyle, the rendered text will be double italicized. If the FontRespository.FindFont(string, FontStyles) method is used, it correctly styles the font.

This only appears to be an issue with the italicized version of DejaVu Sans Mono, something I'm assuming may be a result of their font naming choice of Oblique instead of Italic. I tested with Liberation Mono and it renders the font's as expected. Based on some of the properties/fields I was able to inspect in the debugger, I'm assuming there's some kind of special handling around the DejaVu font, as there aren't any differences in the text state that I can see.

To Reproduce

using System.Reflection;

using Aspose.Pdf;
using Aspose.Pdf.Printing;
using Aspose.Pdf.Text;

internal class Program
{
    private static void Main()
    {
        // Set license
        FontIssue();
    }

    private static void FontIssue()
    {
        Document document = new();
        Page page = document.Pages.Add();
        page.SetPageSize(InchToPoint(PaperSizes.Letter.Width / 100d), InchToPoint(PaperSizes.Letter.Height / 100d));
        string[] fontNames = ["LiberationMono", "DejaVuSansMono"];
        FontStyles[] fontStyles = [FontStyles.Italic, FontStyles.Bold];
        foreach ((string fontName, FontStyles fontStyle) in fontNames.SelectMany(fontName => fontStyles.Select(fontStyle => (fontName, fontStyle))))
        {
            TextState textStateA = new()
            {
                Font = FontRepository.FindFont(fontName, fontStyle)
            };
            page.Paragraphs.Add(CreateTextFragment("A", textStateA));
            page.Paragraphs.Add(new TextFragment("\n"));
            TextState textStateB = new()
            {
                Font = FontRepository.FindFont(fontName),
                FontStyle = fontStyle
            };
            page.Paragraphs.Add(CreateTextFragment("B", textStateB));
            page.Paragraphs.Add(new TextFragment("\n"));
        }
        document.Save("font-repository-font-style-differences.pdf");

        static double InchToPoint(double inch)
        {
            return inch * 72d;
        }

        static TextFragment CreateTextFragment(string type, TextState textState)
        {
            TextFragment textFragment = new(
                string.Format(
                    "({0}) {1} - {2} - This is some test text.",
                    type,
                    textState.Font.FontName,
                    textState.FontStyle
                )
            );
            textFragment.TextState.ApplyChangesFrom(textState);
            textFragment.TextState.FontSize = 10;
            Console.WriteLine(
                "({0}) {1} - {2} {{ IsFontStyleSet: {3}, Obfuscated FontStyles field: {4} }}",
                type,
                textFragment.TextState.Font.FontName,
                textFragment.TextState.FontStyle,
                typeof(TextState)
                    .GetProperty("IsFontStyleSet", BindingFlags.NonPublic | BindingFlags.Instance)?
                    .GetValue(textState) ?? throw new Exception("IsFontStyleSet property not found"),
                typeof(TextState)
                    .GetField("#=z3kFiMxvIYg4k1v1UJsBKNsw=", BindingFlags.NonPublic | BindingFlags.Instance)?
                    .GetValue(textState) ?? throw new Exception("Obfuscated FontStyles field not found")
            );
            return textFragment;
        }
    }
}

In the console, this yields:

(A) Liberation Mono Italic - Italic { IsFontStyleSet: False, Obfuscated FontStyles field: Regular }
(B) Liberation Mono Italic - Italic { IsFontStyleSet: True, Obfuscated FontStyles field: Italic }
(A) Liberation Mono Bold - Bold { IsFontStyleSet: False, Obfuscated FontStyles field: Regular }
(B) Liberation Mono Bold - Bold { IsFontStyleSet: True, Obfuscated FontStyles field: Bold }
(A) DejaVu Sans Mono Oblique - Italic { IsFontStyleSet: False, Obfuscated FontStyles field: Regular }
(B) DejaVu Sans Mono Oblique - Italic { IsFontStyleSet: True, Obfuscated FontStyles field: Italic }
(A) DejaVu Sans Mono Bold - Bold { IsFontStyleSet: False, Obfuscated FontStyles field: Regular }
(B) DejaVu Sans Mono Bold - Bold { IsFontStyleSet: True, Obfuscated FontStyles field: Bold }

See the attached PDF for the results of the rendering.

Expected behavior

The TextStyle reflects an italicized font, but does not render as an italicized version of an already italicized font.

System information:

OS: Linux - Debian Bookworm (dev container)
Versions:

  • Aspose.Pdf.Drawing: 25.7.0
  • .NET: 9.0.303

Additional information

My company is a paid customer.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions