Browse our Products
Aspose.Words for C++ 21.1 Release Notes
Major Features
We have added the following features from Aspose.Words for .NET on this regular monthly release:
- StartColumnBookmark and EndColumnBookmark methods were introduced in DocumentBuilder class.
- MarkdownSaveOptions.ImageSavingCallback has been added to control how images are saved upon converting to Markdown format.
- Added an ability to ignore <noscript> HTML elements upon loading HTML.
- TableStyle.VerticalAlignment was exposed publicly.
Limitations and API Differences
Aspose.Words for C++ has some differences as compared to its equivalent .NET version of the API. This section contains information about all such functionality that is not available in the current release. The missing features will be added in future releases.
- The current release does not support Metered license.
- The current release does not support LINQ and Reporting features.
- The current release does not support OpenGL 3D Shapes rendering.
- The current release does not support advanced typography based on HarfBuzz shaper.
- The current release does not support loading PDF documents.
- The current release has limited support for database features - C++ doesn’t have common API for DB like .NET System.Data.
- The current release supports Microsoft Visual C++ version 2017 or higher.
- The current release supports GCC 6.3 or higher and Clang 3.9.1 or higher on Linux and only for the x86_x64 platform.
Full List of Issues Covering all Changes in this Release
Key | Summary | Category |
---|---|---|
WORDSCPP-925 | Memory leak in Aspose.Words for C++ | Bug |
WORDSCPP-1038 | Unable to Retrieve the Number of Pages from Word DOC document | Bug |
WORDSNET-4987 | Support “cold” rendering of OOXML SmartArt (Diagrams) | New Feature |
WORDSNET-20666 | Add feature to create Move revision | New Feature |
WORDSNET-21389 | Add IImageSavingCallback into MarkdownSaveOptions | New Feature |
WORDSNET-17026 | LINQ Reporting Engine - Support section breaks inside data bands and conditional blocks | New Feature |
WORDSNET-20367 | Add a field to the Node class so a User can store some custom meta-data in Aspose.Words Document model | New Feature |
WORDSNET-18882 | Add feature to bookmark the table’s column | New Feature |
WORDSNET-21114 | Add feature to get or set Cell Vertical Alignment using TableStyle | New Feature |
WORDSNET-21426 | MS Word should automatically pick default Icon of Inserted OLE Object | Enhancement |
WORDSNET-21576 | Add LastChild property and AppendChild() method to StructuredDocumentRangeStart class | Enhancement |
WORDSNET-21433 | Improve URI processing to handle relative hyperlink | Enhancement |
WORDSNET-21493 | Convert Word to JSON in Parent Child Hierarchy | Enhancement |
WORDSNET-20881 | Partial rendering of Arabic Words in PDF | Bug |
WORDSNET-21005 | Document.PageCount hangs for MHTML file generated by Aspose.Email | Bug |
WORDSNET-18933 | DOCX to PDF conversion issue with math equation | Bug |
WORDSNET-15142 | Incorrect page count detection | Bug |
WORDSNET-21516 | First column content spilling into second column in PDF | Bug |
WORDSNET-17876 | Characters (subset) in charts are not rendered in output PDF | Bug |
WORDSNET-13179 | DOCX to PDF conversion issue with text rendering of Cambodian Fonts “Khmer” | Bug |
WORDSNET-18333 | Superscript and Subscript characters in picture are not retained in PDF | Bug |
WORDSNET-21191 | InvalidOperationException occurs during saving to HTML | Bug |
WORDSNET-16704 | BitonalConvertor gives not the same result as on .NET | Bug |
WORDSNET-17362 | Brackets and equation rendering issue in output PDF | Bug |
WORDSNET-21509 | DOCX to PDF conversion exception: System.ArgumentOutOfRangeException | Bug |
WORDSNET-21415 | Document.Compare generates the incorrect output | Bug |
WORDSNET-17888 | Arabic characters are improperly rendered to another font | Bug |
WORDSNET-17986 | Position of BookmarkStart and BookmarkEnd nodes is changed in output DOCX | Bug |
WORDSNET-21534 | Incorrect value of STYLEREF field in header - Word to PDF Conversion | Bug |
WORDSNET-21535 | Aspose.Words.FileCorruptedException is thrown for DOC | Bug |
WORDSNET-21462 | DOCX to HTML conversion fails with Stack empty error message | Bug |
WORDSNET-21506 | Hidden runs located in a Structured Document tag cannot be iterated | Bug |
WORDSNET-20715 | The conversion to PDF never ends | Bug |
WORDSNET-21510 | System.ArgumentOutOfRangeException occurs upon saving to PDF | Bug |
WORDSNET-21519 | DOCX to PDF conversion exception | Bug |
WORDSNET-21494 | Document.UpdateFields throws NullReferenceException | Bug |
WORDSNET-20010 | Infinity loop in FloaterOverlapResolver due to zero height floating table | Bug |
WORDSNET-21545 | Add obfuscation check to ApiTests.License.Net task | Bug |
WORDSNET-21552 | Incorrect identification of list level and list item | Bug |
WORDSNET-17735 | Certain Arabic characters are wrong when converting DOCX to PDF | Bug |
WORDSNET-20166 | Infinity loop in FloaterOverlapResolver | Bug |
WORDSNET-18940 | Conversion issue DOC/DOCX to PDF | Bug |
WORDSNET-17428 | Superscript and Subscript characters in Picture render as question mark in PDF | Bug |
WORDSNET-21579 | Insert SVG image failed on .NetFramework | Bug |
WORDSNET-21434 | DOCX to PDF conversion: The numbering issue in the output | Bug |
WORDSNET-21253 | Unexpected chart type | Bug |
WORDSNET-20876 | SmartArt to PNG conversion issue with wrong background color and wrong font | Bug |
WORDSNET-21443 | LINQ Reporting Engine - An issue with a JSON object having only complex properties | Bug |
WORDSNET-20892 | ODT to Html: Frame borders and position are lost when converting .odt to html | Bug |
WORDSNET-21116 | PDF/A-1a fails accessibility check | Bug |
WORDSNET-3814 | Line numbering shows up in OpenOffice after changing PageSetup settings | Bug |
WORDSNET-21419 | Inline ole shape overlaps container cell border after DOCX to PDF conversion | Bug |
WORDSNET-21325 | Comments date do not reflect to changed time zone | Bug |
WORDSNET-21453 | “Arithmetic operation resulted in an overflow.” exception when converting DOCX file to PNG/HTML/PDF | Bug |
WORDSNET-20954 | Table lost formatting on page extraction | Bug |
WORDSNET-21268 | DOC to PDF conversion hangs | Bug |
WORDSNET-21460 | Bibliography text disappears during conversion | Bug |
WORDSNET-21153 | UpdatePageLayout is throwing Array Dimensions exceeded supported range | Bug |
WORDSNET-20681 | OutOfMemoryException when SaveAs document as PNG | Bug |
WORDSNET-21173 | No content is loaded from a CHM file | Bug |
WORDSNET-21282 | Preserve Text Alignment in Table Cell during Word DOT to HTML Conversion | Bug |
WORDSNET-21286 | DataLabel customization does not work when chart is inserted into template | Bug |
WORDSNET-21171 | FileCorruptedException is thrown when trying to load a CHM document | Bug |
WORDSNET-21299 | Sunburst Chart DOCX to PDF - System.ArgumentException Unexpected chart type | Bug |
WORDSNET-21476 | Aspose.Words corrupts document containing statistical chart | Bug |
WORDSNET-21481 | Comment.DateTime get time in UTC without conversion to local | Bug |
WORDSNET-21326 | Execution of the Aspose.Words hangs on Linux when Tahoma font is absent | Bug |
WORDSNET-21203 | HTML to PDF output incomplete | Bug |
WORDSNET-21341 | 3rd level of Thai text is not shown and replaced by strange symbol - DOCX to PDF | Bug |
WORDSNET-19932 | Number list issues while converting DOCX -> HTML -> DOCX | Bug |
WORDSNET-21216 | Diffrent behavior of “=SUM(ABOVE)” compared to Microsoft Word | Bug |
WORDSNET-21366 | DOC->PDF conversion: Heading loses capitalization and bold effect in the output | Bug |
WORDSNET-16770 | Image’s text is rendered as “?” mark in output PDF | Bug |
WORDSNET-14872 | Lack of CSS background images while converting from HTML to Word | Bug |
WORDSNET-16336 | Khmer Mondulkiri font renders incorrectly | Bug |
WORDSNET-17887 | Arial Font is used instead of Calibri Fonts during DOCM to PDF conversion | Bug |
WORDSNET-16703 | TestRadialGradient is rendered improperly. | Bug |
WORDSNET-11650 | System.NullReferenceException is thrown while saving DOCX to PDF | Bug |
WORDSNET-19294 | TestLoadPerformanceLarge() performance test fails | Bug |
WORDSNET-16717 | Background in MHT looks differently | Bug |
Public API and Backward Incompatible Changes
This section lists public API changes that were introduced in Aspose.Words 21.1. 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 a new public property HtmlLoadOptions::IgnoreNoscriptElements
Related issue: WORDSNET-21203
Added a new public property HtmlLoadOptions::IgnoreNoscriptElements:
/// <summary>
/// Gets a value indicating whether to ignore <noscript> HTML elements.
/// Default value is <c>false</c>.
/// </summary>
/// <remarks>
/// Like MS Word, Aspose.Words does not support scripts and by default loads content of <noscript> elements
/// into the resulting document. In most browsers, however, scripts are supported and content from <noscript>
/// is not visible. Setting this property to <c>true</c> forces Aspose.Words to ignore all <noscript> elements
/// and helps to produce documents that look closer to what is seen in browsers.
/// </remarks>
bool get_IgnoreNoscriptElements() const;
/// Setter for HtmlLoadOptions::IgnoreNoscriptElements
void set_IgnoreNoscriptElements(bool value);
Customers may now instruct Aspose.Words to ignore <noscript> HTML elements like most modern browsers do.
Use Case:
auto loadOptions = MakeObject<HtmlLoadOptions>();
loadOptions->set_IgnoreNoscriptElements(true);
Added a new public property Node::CustomNodeId
Related issue: WORDSNET-21203
Added a new public property Node::CustomNodeId:
/// <summary>
/// Specifies custom node identifier.
/// </summary>
/// <remarks>
/// <p>Default is zero.</p>
/// <p>This identifier can be set and used arbitrarily. For example, as a key to get external data.</p>
/// </remarks>
void int32_t get_CustomNodeId() const;
void void set_CustomNodeId(int32_t value);
Customers now may track node position in the model tree and bind external data based on assigned identifier:
Use Case:
auto doc = MakeObject<Document>();
auto builder = MakeObject<DocumentBuilder>(doc);
auto shape = builder->InsertShape(ShapeType::Rectangle, 100, 100);
shape->set_CustomNodeId(100);
Added a new public property TableStyle::VerticalAlignment
Related issue: WORDSNET-21114
Added a new public options that allows to set table style cell vertical alignment.
/// <summary>
/// Specifies the vertical alignment for the cells.
/// </summary>
/// <remarks>
/// The default value is <see cref="CellVerticalAlignment::Top"/>.
/// </remarks>
CellVerticalAlignment get_VerticalAlignment() const;
void set_VerticalAlignment(CellVerticalAlignment value);
Use Case:
auto doc = MakeObject<Document>(filename);
auto style = StaticCast<TableStyle>(doc->get_Styles()->idx_get(u"Custom Table 1"));
style->set_VerticalAlignment(CellVerticalAlignment::Center);
Added new public methods StartColumnBookmark and EndColumnBookmark to DocumentBuilder class
Related issue: WORDSNET-18882
The following public methods have been added to the DocumentBuilder class:
/// <summary>
/// Marks the current position in the document as a column bookmark start. The position must be in a table cell.
/// </summary>
/// <remarks>
/// <p>A column bookmark covers one or more columns in a range of rows. To create a valid bookmark you
/// need to call both <see cref="StartColumnBookmark"/> and <see cref="EndColumnBookmark"/> with the same
/// <b>bookmarkName</b> parameter.</p>
/// <p>Badly formed bookmarks or bookmarks with duplicate names will be ignored when the document is saved.</p>
/// <p>The actual position of the inserted <see cref="BookmarkStart"/> node may differ from the current document
/// builder position.</p>
/// </remarks>
/// <param name="bookmarkName">Name of the bookmark.</param>
/// <returns>The bookmark start node that was just created.</returns>
SharedPtr<BookmarkStart> StartColumnBookmark(System::String bookmarkName);
/// <summary>
/// Marks the current position in the document as a column bookmark end. The position must be in a table cell.
/// </summary>
/// <remarks>
/// <p>A column bookmark covers one or more columns in a range of rows. To create a valid bookmark you
/// need to call both <see cref="StartColumnBookmark"/> and <see cref="EndColumnBookmark"/> with the same
/// <b>bookmarkName</b> parameter.</p>
/// <p>Badly formed bookmarks or bookmarks with duplicate names will be ignored when the document is saved.</p>
/// <p>The actual position of the inserted <see cref="BookmarkEnd"/> node may differ from the current document
/// builder position.</p>
/// </remarks>
/// <param name="bookmarkName">Name of the bookmark.</param>
/// <returns>The bookmark end node that was just created.</returns>
SharedPtr<BookmarkEnd> EndColumnBookmark(System::String bookmarkName);
Use Case:
auto doc = MakeObject<Document>();
auto builder = MakeObject<DocumentBuilder>(doc);
builder->StartTable();
builder->InsertCell();
builder->StartColumnBookmark(u"Bookmark1");
builder->Write(u"Cell 1");
builder->InsertCell();
builder->Write(u"Cell 2");
builder->InsertCell();
builder->Write(u"Cell 3");
builder->EndRow();
builder->InsertCell();
builder->Write(u"Cell 4");
builder->InsertCell();
builder->Write(u"Cell 5");
builder->EndColumnBookmark(u"Bookmark1");
builder->InsertCell();
builder->Write(u"Cell 6");
builder->EndRow();
builder->EndTable();
doc->Save(u"out.docx");
MarkdownSaveOptions::ImageSavingCallback has been added to control how images are saved upon converting to Markdown format
Related issue: WORDSNET-21389
A new public property ImageSavingCallback has been added to the MarkdownSaveOptions class:
/// <summary>
/// Allows to control how images are saved when a document is saved to <see cref="SaveFormat::Markdown"/> format.
/// </summary>
SharedPtr<IImageSavingCallback> get_ImageSavingCallback() const;
void set_ImageSavingCallback(SharedPtr<IImageSavingCallback> value);
Use Case:
class SavedImageRename;
void HandleDocument()
{
String outFileName = u"SavingCallback.DocumentParts.Rendering.md";
// Open a document to be converted to Markdown.
auto doc = MakeObject<Document>("Rendering.docx");
// We can use an appropriate SaveOptions subclass to customize the conversion process.
auto options = MakeObject<MarkdownSaveOptions>();
// If we convert a document that contains images into Markdown, we will end up with one Markdown file which links to several images.
// Each image will be in the form of a file in the local file system.
// There is also a callback that can customize the name and file system location of each image.
options->set_ImageSavingCallback(MakeObject<SavedImageRename>(outFileName));
// The ImageSaving() method of our callback will be run at this time.
doc->Save(outFileName, options);
}
/// <summary>
/// Renames saved images that are produced when an Markdown document is saved.
/// </summary>
class SavedImageRename : public IImageSavingCallback
{
public:
SavedImageRename(String outFileName) : mOutFileName(outFileName) {}
void ImageSaving(SharedPtr<ImageSavingArgs> args) override
{
mCount++;
String imageFileName = String::Format(u"{0} shape {1}, of type {2}{3}",
mOutFileName, mCount, ObjectExt::ToString(args->get_CurrentShape()->get_ShapeType()),
Path::GetExtension(args->get_ImageFileName());
args->set_ImageFileName(imageFileName);
args->set_ImageStream(MakeObject<FileStream>(imageFileName, FileMode::Create));
}
private:
int32_t mCount = 0;
String mOutFileName;
};
PdfSaveOptions::EscapeUri is marked as obsolete
We made several improvements in export of hyperlinks to PDF per WORDSNET-21443. Now the cases when setting PdfSaveOptions:;EscapeUri to false was required (improper unescaping of explicitly escaped URI delimiter chars) are handled well by default. Thus we do not see a reason to keep this option longer and marked it as obsolete.
/// <summary>
/// A flag specifying whether URI should be escaped before writing.
/// </summary>
/// <remarks>
/// Note that if this option is set to <c>false</c> hyperlinks are written "as is",
/// so valid (escaped) URI should be provided in document's model.
/// <para>The default value is <c>true</c>.</para>
/// </remarks>
[[deprecated("Writing of URI to PDF was improved and cases when disabled escaping was required are handled well now.")]]
bool get_EscapeUri() const;
[[deprecated("Writing of URI to PDF was improved and cases when disabled escaping was required are handled well now.")]]
void set_EscapeUri(bool value);
Removed obsolete properties FixedPageSaveOptions::PageIndex, FixedPageSaveOptions::PageCount, ImageSaveOptions::PageIndex, ImageSaveOptions::PageCount
Related issue: WORDSNET-21154
Deprecated properties related to page specification when printing were removed from the FixedPageSaveOptions and ImageSaveOptions classes.
[[deprecated("This property is obsolete. Please use PageSet property instead.")]]
int32_t get_PageCount() const;
[[deprecated("This property is obsolete. Please use PageSet property instead.")]]
void set_PageCount(int32_t value);
[[deprecated("This property is obsolete. Please use PageSet property instead.")]]
int32_t get_PageIndex() const;
[[deprecated("This property is obsolete. Please use PageSet property instead.")]]
void set_PageIndex(int32_t value);
The behavior of DocumentBuilder::InsertOleObject() and DocumentBuilder:;InsertOleObjectAsIcon() methods was changed
Related issue: WORDSNET-21426
In cases where the DocumentBuilder::InsertOleObject() and DocumentBuilder::InsertOleObjectAsIcon() methods need to create an icon with a caption, they can use the file extension to define the icon, and can use the filename for the icon caption.
More details:
SharedPtr<Shape> InsertOleObject(SharedPtr<Stream> stream, String progId, bool asIcon, SharedPtr<Stream> presentation)
SharedPtr<Shape> InsertOleObject(String fileName, bool isLinked, bool asIcon, SharedPtr<Stream> presentation)
SharedPtr<Shape> InsertOleObject(String fileName, String progId, bool isLinked, bool asIcon, SharedPtr<Stream> presentation)
SharedPtr<Shape> InsertOleObjectAsIcon(SharedPtr<Stream> stream, String progId, String iconFile, String iconCaption)
SharedPtr<Shape> InsertOleObjectAsIcon(String fileName, String progId, bool isLinked, String iconFile, String iconCaption)
SharedPtr<Shape> InsertOleObjectAsIcon(String fileName, bool isLinked, String iconFile, String iconCaption)
Changed XML comments for ‘iconCaption’ arguments of DocumentBuilder::InsertOleObjectAsIcon() methods:
/// <summary>
/// Inserts an embedded or linked OLE object as icon into the document.
/// Allows to specify icon file and caption. Detects OLE object type using file extension.
/// </summary>
/// <param name="fileName">Full path to the file.</param>
/// <param name="isLinked">
/// If true then linked OLE object is inserted otherwise embedded OLE object is inserted.
/// </param>
/// <param name="iconFile">
/// Full path to the ICO file. If the value is null, Aspose.Words will use a predefined image.
/// </param>
/// <param name="iconCaption">
/// Icon caption. If the value is null, Aspose.Words will use the file name.
/// </param>
/// <returns>Shape node containing Ole object and inserted at the current Builder position.</returns>
SharedPtr<Shape> InsertOleObjectAsIcon(String fileName, bool isLinked, String iconFile, String iconCaption)
/// <summary>
/// Inserts an embedded or linked OLE object as icon into the document.
/// Allows to specify icon file and caption. Detects OLE object type using given progID parameter.
/// </summary>
/// <param name="fileName">Full path to the file.</param>
/// <param name="progId">ProgId of OLE object.</param>
/// <param name="isLinked">
/// If true then linked OLE object is inserted otherwise embedded OLE object is inserted.
/// </param>
/// <param name="iconFile">
/// Full path to the ICO file. If the value is null, Aspose.Words will use a predefined image.
/// </param>
/// <param name="iconCaption">
/// Icon caption. If the value is null, Aspose.Words will use the file name.
/// </param>
/// <returns>Shape node containing Ole object and inserted at the current Builder position.</returns>
SharedPtr<Shape> InsertOleObjectAsIcon(String fileName, String progId, bool isLinked, String iconFile, String iconCaption)
/// <summary>
/// Inserts an embedded OLE object as icon from a stream into the document.
/// Allows to specify icon file and caption. Detects OLE object type using given progID parameter.
/// </summary>
/// <param name="stream">Stream containing application data.</param>
/// <param name="progId">ProgId of OLE object.</param>
/// <param name="iconFile">
/// Full path to the ICO file. If the value is null, Aspose.Words will use a predefined image.
/// </param>
/// <param name="iconCaption">
/// Icon caption. If the value is null, Aspose.Words will use the a predefined icon caption.
/// </param>
/// <returns>Shape node containing Ole object and inserted at the current Builder position.</returns>
SharedPtr<Shape> InsertOleObjectAsIcon(SharedPtr<Stream> stream, String progId, String iconFile, String iconCaption)
The behavior of revision tracking feature triggered by Document::StartTrackRevisions was changed
Related issue: WORDSNET-20666
When revisions are tracked using Document::StartTrackRevisions, if a node is moved from one location to another in the same document, move revisions are now generated, including move-from and move-to ranges.
Use Case:
auto doc = MakeObject<Document>();
auto builder = MakeObject<DocumentBuilder>(doc);
// Generate document contents.
builder->Writeln("Paragraph 1");
builder->Writeln("Paragraph 2");
builder->Writeln("Paragraph 3");
builder->Writeln("Paragraph 4");
builder->Writeln("Paragraph 5");
builder->Writeln("Paragraph 6");
auto body = doc->get_FirstSection()->get_Body();
// Returns 7.
std::cout << "Paragraph count: " << body->get_Paragraphs()->get_Count() << '\n';
doc->StartTrackRevisions(u"Author", DateTime(2020, 12, 23, 14, 0, 0));
auto node = body->get_Paragraphs()->idx_get(3);
auto endNode = body->get_Paragraphs()->idx_get(5)->get_NextSibling();
auto referenceNode = body->get_Paragraphs()->idx_get(0);
while (node != endNode)
{
auto nextNode = node->get_NextSibling();
body->InsertBefore(node, referenceNode);
node = nextNode;
}
doc->StopTrackRevisions();
// Returns 10: there are 3 additional paragraphs in the move-from range.
std::cout << "Paragraph count: " << body->get_Paragraphs()->get_Count() << '\n';
doc->Save("out.docx");