Aspose.Words for Java 21.12 Release Notes

Major Features

There are 83 improvements and fixes in this regular monthly release. The most notable are:

  • Implemented ability to get OOXML of content control.
  • Implemented loading previously saved font search cache to speed up the font cache initialization process upon rendering.
  • Added recognition of non-standard footnotes in PDF documents during the import workflow.
  • Implemented support for ‘Allow Latin text to wrap in the middle of a word’ feature
  • Implemented workaround for SkiaSharp bug, which causes application crash on Linux when new SkiaSharp 2.80.3 is used.

Full List of Issues Covering all Changes in this Release (Reported by Java Users)

KeySummaryCategory
WORDSJAVA-2658WindowsNativeCall methods used after repackagingNew Feature
WORDSJAVA-2664Callback implementation for CharsetDecoderNew Feature
WORDSJAVA-2620FileCorruptedException occurs for a DOCX with embedded gigantic image.Bug
WORDSJAVA-2635Surrogate pair character causes wrong reading of char array.Bug
WORDSNET-22923DOCX to PDF: Differences in generated output filesBug
WORDSNET-22922Exporting highlighted paragraphs to PDFBug
WORDSNET-22961DOCX to HTML conversion throws System.NullReferenceExceptionBug
WORDSNET-22971DOC to PDF conversion issue - new line in wrong placeBug
WORDSNET-22977IndexOutOfBoundsException when setting alternate text on the shapeBug
WORDSNET-22972getBoundsWithEffects returns 0 width and 0 heightBug
WORDSNET-22670Wrong text commented after comparing DOCX filesBug
WORDSNET-22480DOCX to PDF conversion issue with hidden bookmarkBug
WORDSNET-22862Chart conversion issue upon converting to PDFBug
WORDSNET-19833IndexOutOfRangeException is thorwn while saving DOCX to PDFBug
WORDSNET-22895Insert SVG with special characters in Text fails to render in output DOCX and PDFBug
WORDSNET-18902Size of SVG images are not displayed correctlyBug
WORDSNET-22976DOCX to PDF: Inserted image has different dimensionsBug

Full List of Issues Covering all Changes in this Release (Reported by .NET Users)

KeySummaryCategory
WORDSNET-22409Requesting feature to get OOXML of content controlNew Feature
WORDSNET-22278Add a possibility to cache FontSearchInfos in a file and then load itNew Feature
WORDSNET-22892Add loading progress notification upon Markdown loadingNew Feature
WORDSNET-22811Implement Fill.SetImage() methodNew Feature
WORDSNET-16511Path gradient fill of rotated shape is rendered incorrectlyBug
WORDSNET-22564Comments for Content controls are messed up after cloneBug
WORDSNET-20192Curved lines of SmartArt render are rendered incorrectly in output PDFBug
WORDSNET-22907DrawingML textbox position and text orientation is changed after updating page layoutBug
WORDSNET-23049Too big font size when notes are written on the page bordersBug
WORDSNET-22916Image is lost after DOCX to PDF conversionBug
WORDSNET-22917Opening MHT file encoded quoted-printable hangs indefinitelyBug
WORDSNET-23048Text was skipped because of incorrect ClippingBounds calculationBug
WORDSNET-20056Document comparison result issue if comments are there in documentBug
WORDSNET-22192DOCX to HTML and Back to DOCX conversion loses the footer page number alignmentBug
WORDSNET-23021NullReferenceException at CSJ2K’s FileBitstreamReaderAgent..ctorBug
WORDSNET-23020NullReferenceException at CSJ2K’s readBox()Bug
WORDSNET-22928ArgumentNullException: Value cannot be null. (Parameter ‘buffer’) with SkiaSharp 20.8.3 in DockerBug
WORDSNET-22780Shape is shifted when renderingBug
WORDSNET-22782System.ArgumentOutOfRangeException is raised while exporting into Markdown formatBug
WORDSNET-22946Incorrect position calculation for East Asian characters in MathTextElementBug
WORDSNET-22949draft2digital.com shows exception for EPUB generated by Aspose.WordsBug
WORDSNET-22958System.ArgumentNullException with SkiaSharp 20.8.3 in DockerBug
WORDSNET-22406System.InvalidOperationException is thrown when DOCX is saved to HTMLBug
WORDSNET-22850Convert docx to PDF radar chart missing category labels and incorrect scaleBug
WORDSNET-22968System.IO.FileLoadException while loading PDFBug
WORDSNET-22969PDF to DOCX - content is missingBug
WORDSNET-22967Variables declared in document header when using LINQ are not working in document bodyBug
WORDSNET-22970PDF to DOCX - extra content addedBug
WORDSNET-22974XmlException while saving to FOPCBug
WORDSNET-22934Missing font fallback settings for the Geometric Shapes Extended Unicode blockBug
WORDSNET-22960Comment ranges are lost after comparing documentsBug
WORDSNET-22980FileCorruptedException is thrown upon loading RTF documentBug
WORDSNET-22906Rich text content control is not visible when the SetMapping function is usedBug
WORDSNET-22978Unexpected behavior of UpdateFields()Bug
WORDSNET-23060Duplicated letters in words after the conversionBug
WORDSNET-22988DOCX to PDF/a: Empty ‘P’ tag added to outputBug
WORDSNET-22877Unable to set bit depth of output TIFF imageBug
WORDSNET-23047NotImplementedException: Security handler is not implemented for V=5, R=6Bug
WORDSNET-23050NullReferenceException when a PDF file has empty cross-reference streamBug
WORDSNET-23061NullReferenceException at TableOfContentsTabStorage.NumberIsIncreasingBug
WORDSNET-23062InvalidOperationException: Subtype must be present in a Font resourceBug
WORDSNET-22839Infinite loop in FloaterOverlapResolver due to shape with zero heightBug
WORDSNET-22743Build logical structure for layout graphicsBug
WORDSNET-23065InvalidOperationException: Pdf corrupt. Reference with Obj #12. Gen #0  does not point to a valid indirect objectBug
WORDSNET-22955TOC in document prevents replacements with Range.Replace below the TOC if IgnoreFields = TrueBug
WORDSNET-23139System.InvalidOperationException: Collection was modifiedBug
WORDSNET-23140InvalidOperationException: Footnotes are only allowed inside the main text of the documentBug
WORDSNET-23150Rotated PathGradient shapes inside group are rendered incorrectlyBug
WORDSNET-22875DOCX to PDF conversion issue with hyperlinkBug
WORDSNET-22876Conversion issue with hyperlink upon converting to PDFBug
WORDSNET-22874WML to PDF conversion issue with hyperlinkBug
WORDSNET-22931Sigma is rendered as S in EQ FieldBug
WORDSNET-22723Word to PDF Conversion loses space and linesBug
WORDSNET-23158FileCorruptedException is thrown while loading DOCBug
WORDSNET-22886Extra characters are added in output after DOCX to PDF conversionBug
WORDSNET-22791Setting mapping creates corrupted outputBug
WORDSNET-22881RTF to HTML - System.ArgumentNullExceptionBug
WORDSNET-23051DivideByZeroException in TextCorrectionService if language is incorrectBug
WORDSNET-23165Text of Field’s code part is exported into Markdown formatBug
WORDSNET-22903Some SVG symbols look distortedBug
WORDSNET-23028NullReferenceException at CSJ2K’s FileFormatReader.readFileFormatBug
WORDSNET-22198Text position is changed after DOCX to PDF conversionBug
WORDSNET-22795Incorrect rendering of Chinese fontBug
WORDSNET-22979string.IsNullOrEmpty() method in LINQ template throws an exceptionBug
WORDSNET-22859Image disappears when render document to PDF with SkiaSharp 2.80.3Bug
WORDSNET-22909ArgumentNullException is thrown in Linux when render MhtmlBug

Public API and Backward Incompatible Changes

This section lists public API changes that were introduced in Aspose.Words 21.12. It includes not only new and obsoleted public methods, but also a description of any changes in the behavior behind the scenes in Aspose.Words which may affect existing code. Any behavior introduced that could be seen as regression and modifies the existing behavior is especially important and is documented here.

Added new feature to save and load font search cache

Related issue: WORDSNET-22278

Loading previously saved font search cache will speed up the font cache initialization process. It is especially useful when access to font sources is complicated (e.g. when fonts are loaded via network).

To provide this feature following methods and properties has been added:

public class FontSettings
{
    /// <summary>
    /// Saves the font search cache to the stream.
    /// </summary>
    /// <param name="outputStream">Output stream.</param>
    /// <remarks>
    /// See <see cref="SetFontsSources(FontSourceBase[], Stream)"/> method description for more info.
    /// </remarks>
    public void SaveSearchCache(Stream outputStream);
 
    /// <summary>
    /// Sets the sources where Aspose.Words looks for TrueType fonts and additionally loads previously saved
    /// font search cache.
    /// </summary>
    /// <param name="sources">An array of sources that contain TrueType fonts.</param>
    /// <param name="cacheInputStream">Input stream with saved font search cache.</param>
    /// <remarks>
    /// <para>Loading previously saved font search cache will speed up the font cache initialization process. It is
    /// especially useful when access to font sources is complicated (e.g. when fonts are loaded via network).</para>
    ///
    /// <para>When saving and loading font search cache, fonts in the provided sources are identified via cache key.
    /// For the fonts in the <see cref="SystemFontSource"/> and <see cref="FolderFontSource"/> cache key is the path
    /// to the font file. For <see cref="MemoryFontSource"/> and <see cref="StreamFontSource"/> cache key is defined
    /// in the <see cref="MemoryFontSource.CacheKey"/> and <see cref="StreamFontSource.CacheKey"/> properties
    /// respectively. For the <see cref="FileFontSource"/> cache key is either <see cref="FileFontSource.CacheKey"/>
    /// property or a file path if the <see cref="FileFontSource.CacheKey"/> is <b>null</b>.</para>
    ///
    /// <para>It is highly recommended to provide the same font sources when loading cache as at the time the cache was saved.
    /// Any changes in the font sources (e.g. adding new fonts, moving font files or changing the cache key) may lead to the
    /// inaccurate font resolving by Aspose.Words.</para>
    /// </remarks>
    public void SetFontsSources(FontSourceBase[] sources, Stream cacheInputStream);
}
 
public class FileFontSource
{
    /// <summary>
    /// Ctor.
    /// </summary>
    /// <param name="filePath">Path to font file.</param>
    /// <param name="priority">Font source priority. See the <see cref="FontSourceBase.Priority"/> property description for more information.</param>
    /// <param name="cacheKey">The key of this source in the cache. See <see cref="CacheKey"/> property description for more information.</param>
    public FileFontSource(string filePath, int priority, string cacheKey);
 
    /// <summary>
    /// The key of this source in the cache.
    /// </summary>
    /// <remarks>
    /// <para>This key is used to identify cache item when saving/loading font search cache with
    /// <see cref="FontSettings.SaveSearchCache"/> and
    /// <see cref="FontSettings.SetFontsSources(FontSourceBase[], Stream)"/> methods.</para>
    ///
    /// <para>If key is not specified then <see cref="FilePath"/> will be used as a key instead.</para>
    /// </remarks>
    public string CacheKey { get; }
}
 
public class MemoryFontSource
{
    /// <summary>
    /// Ctor.
    /// </summary>
    /// <param name="fontData">Binary font data.</param>
    /// <param name="priority">Font source priority. See the <see cref="FontSourceBase.Priority"/> property description for more information.</param>
    /// <param name="cacheKey">The key of this source in the cache. See <see cref="CacheKey"/> property description for more information.</param>
    public MemoryFontSource(byte[] fontData, int priority, string cacheKey);
 
    /// <summary>
    /// The key of this source in the cache.
    /// </summary>
    /// <remarks>
    /// This key is used to identify cache item when saving/loading font search cache with
    /// <see cref="FontSettings.SaveSearchCache"/> and <see cref="FontSettings.SetFontsSources(FontSourceBase[], Stream)"/> methods.
    /// </remarks>
    public string CacheKey { get; }
}
 
public abstract class StreamFontSource
{
    /// <summary>
    /// Ctor.
    /// </summary>
    /// <param name="priority">Font source priority. See the <see cref="FontSourceBase.Priority"/> property description for more information.</param>
    /// <param name="cacheKey">The key of this source in the cache. See <see cref="CacheKey"/> property description for more information.</param>
    protected StreamFontSource(int priority, string cacheKey);
 
    /// <summary>
    /// The key of this source in the cache.
    /// </summary>
    /// <remarks>
    /// This key is used to identify cache item when saving/loading font search cache with
    /// <see cref="FontSettings.SaveSearchCache"/> and <see cref="FontSettings.SetFontsSources(FontSourceBase[], Stream)"/> methods.
    /// </remarks>
    public string CacheKey { get; }
}

Use Case:

// Prepare font sources and generate font search cache beforehand.
FileFontSource fileSource = new FileFontSource(filePath, fileSourcePriority, fileSourceKey);
MemoryFontSource memorySource = new MemoryFontSource(fontData, memorySourcePriority, memorySourceKey);
StreamFontSource streamSource = new SteamFontSourceMemoryImpl(streamSourcePriority, streamSourceKey);
FontSettings settings = new FontSettings();
settings.SetFontsSources(new FontSourceBase[] { fileSource, memorySource, streamSource });
settings.SaveSearchCache(cacheOutputStream);
 
// Set font sources and load search cache before processing documents. Note that sources should be the same as when saving font search cache.
FileFontSource fileSource = new FileFontSource(filePath, fileSourcePriority, fileSourceKey);
MemoryFontSource memorySource = new MemoryFontSource(fontData, memorySourcePriority, memorySourceKey);
StreamFontSource streamSource = new SteamFontSourceMemoryImpl(streamSourcePriority, streamSourceKey);
FontSettings settings = new FontSettings();
settings.SetFontsSources(new FontSourceBase[] { fileSource, memorySource, streamSource }, cacheInputStream);

Added new public methods Fill.SetImage

Related issue: WORDSNET-22811

Added the following methods to Fill class:

/// <summary>
/// Changes the fill type to single image.
/// </summary>
/// <param name="fileName">The path to the image file.</param>
public void SetImage(string fileName)
 
/// <summary>
/// Changes the fill type to single image.
/// </summary>
/// <param name="stream">The stream that contains the image bytes.</param>
public void SetImage(Stream stream)
 
/// <summary>
/// Changes the fill type to single image.
/// </summary>
/// <param name="imageBytes">The image bytes array.</param>
public void SetImage(byte[] imageBytes)

Use Case: Explains how to work with Fill.SetImage.

DocumentBuilder builder = new DocumentBuilder();
 
// Add new rectangle shape.
Shape shape = builder.InsertShape(ShapeType.Rectangle, 80, 80);
// Apply one single image to the shape.
shape.Fill.SetImage("ShapeBackground.jpg");
 
builder.Document.Save("SingleImageDocument.docx");

Added WordOpenXML property for content control nodes

Related issue: WORDSNET-22409

The following member has been added to the StructuredDocumentTag and StructuredDocumentTagRangeStart nodes:

/// <summary>
/// Gets a string that represents the XML contained within the node in the <see cref="SaveFormat.FlatOpc"/> format.
/// </summary>
public string WordOpenXML { get; }

Use Case:

Document doc = new Document("Test.docx");
StructuredDocumentTag sdt = (StructuredDocumentTag)doc.GetChild(NodeType.StructuredDocumentTag, 0, true);
string fopcContent = sdt.WordOpenXML;

Added the ReportBuildOptions.UseLegacyHeaderFooterVisiting enum member

Related issue: WORDSNET-22967

The following member has been added to the ReportBuildOptions enum:

/// <summary>
/// Specifies that the engine should visit section child nodes (headers, footers, bodies) in an order
/// compatible with Aspose.Words versions prior 21.9.
/// </summary>
/// <remarks>
/// <para>
/// By default, the engine treats headers and footers as if they were linked to section breaks. That is,
/// when visiting section child nodes, a body is visited first and only then, headers and footers are visited.
/// This agrees with Microsoft Word behavior when copy-pasting or removing multi-section contents and produces
/// more correct results in most scenarios.
/// </para>
/// <para>
/// Prior to Aspose.Words 21.9, the engine used another visiting order: Section child nodes were visited in
/// an order they appear in a document. Apply this value to <see cref="ReportingEngine.Options"/> if
/// compatibility with older versions of Aspose.Words is required.
/// </para>
/// </remarks>
UseLegacyHeaderFooterVisiting

The option can be applied while building a report in the following way:

ReportingEngine engine = new ReportingEngine();
engine.Options |= ReportBuildOptions.UseLegacyHeaderFooterVisiting;
engine.BuildReport(...);