Possible bug with document layout calculation

Hi,

I’m currently evaluating the Aspose.Words library, and I believe I may have encountered a bug.

Steps to Reproduce

  1. Download the attached layout_calc_bug.docx file and save it without making any changes.
    layout_calc_bug.docx

  2. Copy the code below into a Visual Studio test project with a reference to the Aspose.Words library.

  3. Set the constant fields at the top of the code (license path and document path).

  4. Run the tests.

Expected Result

  • Section.Bottom >= LastLine.Bottom
  • The GetStartPageIndex of paragraph labeled “Page 2 Header” is 2

Actual Result

  • Section.Bottom < LastLine.Bottom
  • The GetStartPageIndex of paragraph labeled “Page 2 Header” is 1

Additional Notes

After reproducing the issue, open the document in Microsoft Word and save it again (without making any changes).
After doing so, the issue no longer occurs and the test passes.

So, I don’t know that is wrong with the original (unchanged document).

using Aspose.Words.Layout;

namespace Aspose.Words.Tests;

[TestClass]
public sealed class LayoutTests
{
    private const string License_Path = "YOUR ASPOSE.WORDS LICENCE PATH";
    private const string Document_Path = "PATH TO THE TEST DOCUMENT";

    [TestInitialize]
    public void TestInitialize()
    {
        var lic = new License();
        lic.SetLicense(License_Path);
    }


    private static Document GetDocument()
    {
        var doc = new Document(Document_Path);
        doc.UpdatePageLayout();

        return doc;
    }

    [TestMethod]
    public void TestPageLayout_UsingEnumerator()
    {
        // Arrange
        var doc = GetDocument();

        LayoutEnumerator enumerator = new(doc);

        // Act

        // measure column
        enumerator.MoveFirstChild(); // move to first column
        var columnType = enumerator.Type; // column
        var columnRect = enumerator.Rectangle;

        // measure last line
        enumerator.MoveLastChild();
        var lastLineType = enumerator.Type; // column
        var lastLineRect = enumerator.Rectangle;

        // Assert
        Assert.AreEqual(LayoutEntityType.Column, columnType);
        Assert.AreEqual(LayoutEntityType.Line, lastLineType);


        Assert.IsTrue(columnRect.Bottom > lastLineRect.Bottom);
    }

    [TestMethod]
    public void TestPageLayout_UsingPageNumber()
    {
        // Arrange
        var doc = GetDocument();

        LayoutCollector collector = new(doc);

        var paragraphInPge2 = doc.GetChildNodes(NodeType.Paragraph, true)
            .Where(p => p.Range.Text.StartsWith("Page 2 Header"))
            .First();

        // Act
        var pageStart = collector.GetStartPageIndex(paragraphInPge2);

        // Assert
        Assert.AreEqual(2, pageStart);
    }

}

@JU_ALT

Cause

You are experiencing unexpected behavior with the layout calculations in the Aspose.Words library. This issue occurs when the document is processed without modifications, leading to discrepancies in layout measurements, particularly with the Section.Bottom and LastLine.Bottom values, as well as the page index for specific paragraphs.

Solution

This behavior can arise from how the document is initially formatted or saved. Opening and resaving the document in Microsoft Word triggers a re-evaluation of the layout, which resolves the issue. To address this in your code, ensure that the document is properly updated before performing layout calculations.

Code

Here’s a modified version of your GetDocument method that includes a call to UpdatePageLayout() after loading the document:

private static Document GetDocument()
{
    var doc = new Document(Document_Path);
    doc.UpdatePageLayout(); // Ensure the layout is updated after loading the document
    return doc;
}

Additionally, check if the document has any specific formatting or styles that could affect the layout calculations.

Next Steps

  1. Ensure you are using the latest version of the Aspose.Words library, as updates may include fixes for layout-related issues.
  2. If the problem persists, consider programmatically resaving the document using Aspose.Words before performing layout calculations to mimic the behavior of Microsoft Word.
  3. If you continue to encounter issues, please provide the document for further analysis, and we will assist you in identifying the root cause.

Please let me know if you need any further assistance!

My original code includes UpdatePageLayout as well.
So, your response is not helpfull.

@JU_ALT There is no bug here. Your document uses Aptos, which is cloud font, so it is not installed by default and is downloaded by MS Word on demand. Aspose.Words does not download cloud fonts.
The fonts are required to build document layout. If Aspose.Words cannot find the font used in the document, the font is substituted . This might lead into fonts mismatch and document layout differences due to the different fonts metrics. You can implement IWarningCallback to get notifications when font substitution is performed.
Please see our documentation to learn where Aspose.Words looks for fonts:
https://docs.aspose.com/words/net/specifying-truetype-fonts-location/

You can download Aptos fonts from here.

Tested with the following modified code and the problem is not reproducible:

// C:\Temp\fonts folder contains the downloaded `Aptos` fonts.
FontSettings.DefaultInstance.SetFontsSources(new FontSourceBase[] { new SystemFontSource(), new FolderFontSource(@"C:\Temp\fonts", true) });

Document doc = new Document(@"C:\Temp\in.docx");
LayoutCollector collector = new LayoutCollector(doc);

var paragraphInPge2 = doc.GetChildNodes(NodeType.Paragraph, true)
    .Where(p => p.Range.Text.StartsWith("Page 2 Header"))
    .First();

// Act
var pageStart = collector.GetStartPageIndex(paragraphInPge2);

// Assert
Assert.That(pageStart, Is.EqualTo(2));
1 Like

Thank you very much!

1 Like