Browse our Products
Aspose.Words for .NET 21.12 Release Notes
Major Features
There are 79 improvements and fixes in this regular monthly release. The most notable are:
- Introduced an 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.
- Provided the 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 .NET Users)
Key | Summary | Category |
---|---|---|
WORDSNET-22409 | Requesting feature to get OOXML of content control | New Feature |
WORDSNET-22278 | Add a possibility to cache FontSearchInfos in a file and then load it | New Feature |
WORDSNET-22892 | Add loading progress notification upon Markdown loading | New Feature |
WORDSNET-22811 | Implement Fill.SetImage() method | New Feature |
WORDSNET-16511 | Path gradient fill of rotated shape is rendered incorrectly | Bug |
WORDSNET-22564 | Comments for Content controls are messed up after clone | Bug |
WORDSNET-20192 | Curved lines of SmartArt render are rendered incorrectly in output PDF | Bug |
WORDSNET-22907 | DrawingML textbox position and text orientation is changed after updating page layout | Bug |
WORDSNET-23049 | Too big font size when notes are written on the page borders | Bug |
WORDSNET-22916 | Image is lost after DOCX to PDF conversion | Bug |
WORDSNET-22917 | Opening MHT file encoded quoted-printable hangs indefinitely | Bug |
WORDSNET-23048 | Text was skipped because of incorrect ClippingBounds calculation | Bug |
WORDSNET-20056 | Document comparison result issue if comments are there in document | Bug |
WORDSNET-22192 | DOCX to HTML and Back to DOCX conversion loses the footer page number alignment | Bug |
WORDSNET-23021 | NullReferenceException at CSJ2K’s FileBitstreamReaderAgent..ctor | Bug |
WORDSNET-23020 | NullReferenceException at CSJ2K’s readBox() | Bug |
WORDSNET-22928 | ArgumentNullException: Value cannot be null. (Parameter ‘buffer’) with SkiaSharp 20.8.3 in Docker | Bug |
WORDSNET-22780 | Shape is shifted when rendering | Bug |
WORDSNET-22782 | System.ArgumentOutOfRangeException is raised while exporting into Markdown format | Bug |
WORDSNET-22946 | Incorrect position calculation for East Asian characters in MathTextElement | Bug |
WORDSNET-22949 | draft2digital.com shows exception for EPUB generated by Aspose.Words | Bug |
WORDSNET-22958 | System.ArgumentNullException with SkiaSharp 20.8.3 in Docker | Bug |
WORDSNET-22406 | System.InvalidOperationException is thrown when DOCX is saved to HTML | Bug |
WORDSNET-22850 | Convert docx to PDF radar chart missing category labels and incorrect scale | Bug |
WORDSNET-22968 | System.IO.FileLoadException while loading PDF | Bug |
WORDSNET-22969 | PDF to DOCX - content is missing | Bug |
WORDSNET-22967 | Variables declared in document header when using LINQ are not working in document body | Bug |
WORDSNET-22970 | PDF to DOCX - extra content added | Bug |
WORDSNET-22974 | XmlException while saving to FOPC | Bug |
WORDSNET-22934 | Missing font fallback settings for the Geometric Shapes Extended Unicode block | Bug |
WORDSNET-22960 | Comment ranges are lost after comparing documents | Bug |
WORDSNET-22980 | FileCorruptedException is thrown upon loading RTF document | Bug |
WORDSNET-22906 | Rich text content control is not visible when the SetMapping function is used | Bug |
WORDSNET-22978 | Unexpected behavior of UpdateFields() | Bug |
WORDSNET-23060 | Duplicated letters in words after the conversion | Bug |
WORDSNET-22988 | DOCX to PDF/a: Empty ‘P’ tag added to output | Bug |
WORDSNET-22877 | Unable to set bit depth of output TIFF image | Bug |
WORDSNET-23047 | NotImplementedException: Security handler is not implemented for V=5, R=6 | Bug |
WORDSNET-23050 | NullReferenceException when a PDF file has empty cross-reference stream | Bug |
WORDSNET-23061 | NullReferenceException at TableOfContentsTabStorage.NumberIsIncreasing | Bug |
WORDSNET-23062 | InvalidOperationException: Subtype must be present in a Font resource | Bug |
WORDSNET-22839 | Infinite loop in FloaterOverlapResolver due to shape with zero height | Bug |
WORDSNET-22743 | Build logical structure for layout graphics | Bug |
WORDSNET-23065 | InvalidOperationException: Pdf corrupted | Bug |
WORDSNET-22955 | TOC in document prevents replacements with Range.Replace below the TOC if IgnoreFields = True | Bug |
WORDSNET-23139 | System.InvalidOperationException: Collection was modified | Bug |
WORDSNET-23140 | InvalidOperationException: Footnotes are only allowed inside the main text of the document | Bug |
WORDSNET-23150 | Rotated PathGradient shapes inside group are rendered incorrectly | Bug |
WORDSNET-22875 | DOCX to PDF conversion issue with hyperlink | Bug |
WORDSNET-22876 | Conversion issue with hyperlink upon converting to PDF | Bug |
WORDSNET-22874 | WML to PDF conversion issue with hyperlink | Bug |
WORDSNET-22931 | Sigma is rendered as S in EQ Field | Bug |
WORDSNET-22723 | Word to PDF Conversion loses space and lines | Bug |
WORDSNET-23158 | FileCorruptedException is thrown while loading DOC | Bug |
WORDSNET-22886 | Extra characters are added in output after DOCX to PDF conversion | Bug |
WORDSNET-22791 | Setting mapping creates corrupted output | Bug |
WORDSNET-22881 | RTF to HTML - System.ArgumentNullException | Bug |
WORDSNET-23051 | DivideByZeroException in TextCorrectionService if language is incorrect | Bug |
WORDSNET-23165 | Text of Field’s code part is exported into Markdown format | Bug |
WORDSNET-22903 | Some SVG symbols look distorted | Bug |
WORDSNET-23028 | NullReferenceException at CSJ2K’s FileFormatReader.readFileFormat | Bug |
WORDSNET-22198 | Text position is changed after DOCX to PDF conversion | Bug |
WORDSNET-22795 | Incorrect rendering of Chinese font | Bug |
WORDSNET-22979 | string.IsNullOrEmpty() method in LINQ template throws an exception | Bug |
WORDSNET-22859 | Image disappears when render document to PDF with SkiaSharp 2.80.3 | Bug |
WORDSNET-22909 | ArgumentNullException is thrown in Linux when render Mhtml | Bug |
Full List of Issues Covering all Changes in this Release (Reported by Java Users)
Key | Summary | Category |
---|---|---|
WORDSNET-22923 | DOCX to PDF: Differences in generated output files | Bug |
WORDSNET-22922 | Exporting highlighted paragraphs to PDF | Bug |
WORDSNET-22961 | DOCX to HTML conversion throws System.NullReferenceException | Bug |
WORDSNET-22971 | DOC to PDF conversion issue - new line in wrong place | Bug |
WORDSNET-22977 | IndexOutOfBoundsException when setting alternate text on the shape | Bug |
WORDSNET-22972 | getBoundsWithEffects returns 0 width and 0 height | Bug |
WORDSNET-22670 | Wrong text commented after comparing DOCX files | Bug |
WORDSNET-22480 | DOCX to PDF conversion issue with hidden bookmark | Bug |
WORDSNET-22862 | Chart conversion issue upon converting to PDF | Bug |
WORDSNET-19833 | IndexOutOfRangeException is thorwn while saving DOCX to PDF | Bug |
WORDSNET-22895 | Insert SVG with special characters in Text fails to render in output DOCX and PDF | Bug |
WORDSNET-18902 | Size of SVG images are not displayed correctly | Bug |
WORDSNET-22976 | DOCX to PDF: Inserted image has different dimensions | Bug |
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 StreamFontSourceMemoryImpl(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 StreamFontSourceMemoryImpl(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(...);