Unplanned
Last Updated: 18 Apr 2024 15:38 by John

When calling a PDF export in a high-concurrency environment the internal state can get corrupted because it uses a non-thread safe collection internally.

Sample code:

void WriteToPdf(RadFlowDocument document, Stream outputStream) {

   PdfFormatProvider pdfWriter = new() {};

   pdfWriter.Export(document, outputStream);
}

When calling it like this:

Parallel.ForEachAsync(listOfDocuments, (document, _) => {
   WriteToPdf(document, Stream.Null);
});

An exception may occur:

System.InvalidOperationException: Operations that change non-concurrent collections must have exclusive access. A concurrent update was performed on this collection and corrupted its state. The collection's state is no longer correct.
   at System.Collections.Generic.Dictionary`2.FindValue(TKey key)
   at Telerik.Windows.Documents.Fixed.Model.Fonts.FontsRepository.TryCreateFont(FontFamily fontFamily, FontStyle fontStyle, FontWeight fontWeight, FontBase& font)
   at Telerik.Windows.Documents.Flow.FormatProviders.Pdf.Utils.Extensions.CopyPropertiesFrom(CharacterProperties fixedProperties, PdfExportContext context, CharacterProperties properties)
   at Telerik.Windows.Documents.Flow.FormatProviders.Pdf.Export.PdfExporter.CreateListLevel(ListLevel flowLevel)
   at Telerik.Windows.Documents.Flow.FormatProviders.Pdf.Export.PdfExporter.CreateList(List flowList)
   at Telerik.Windows.Documents.Flow.FormatProviders.Pdf.Export.PdfExporter.ExportDocument(RadFlowDocument document, RadFixedDocumentEditor editor)
   at Telerik.Windows.Documents.Flow.FormatProviders.Pdf.Export.PdfExporter.ExportInternal()
   at Telerik.Windows.Documents.Common.FormatProviders.FormatProviderBase`1.Export(T document, Stream output)
   at xxxxx.Application.Common.PdfGeneration.PdfWriter.WriteToPdf(RadFlowDocument document, Stream outputStream) 

The state is then corrupted forever, until the application is restarted.

Realistic scenario where this is also reproduced: Web application that generates PDFs and is called concurrently.

 

In Development
Last Updated: 18 Apr 2024 12:13 by ADMIN
When merging documents with exactly the same font but different character widths, some characters are rendered with the wrong width.

In Development
Last Updated: 18 Apr 2024 12:11 by ADMIN

This is the code used for merging:

        private  void MergeDifferentDocumentsPagesWithFixed()
        {
            string[] documentsToMerge =
            {
                "14301-STOCK_Proforma.pdf",
                "14302-STOCK_Proforma.pdf",
                "14303-STOCK_Proforma.pdf",
                "14304-STOCK_Proforma.pdf",
                "14305-STOCK_Proforma.pdf",
                "14330-STOCK_Proforma.pdf"
            };
            RadFixedDocument doc = new RadFixedDocument();
            PdfFormatProvider provider = new PdfFormatProvider();
            foreach (string current_item in documentsToMerge)
            {
                string path = @"..\..\Samples\" + current_item;
                RadFixedDocument docToMerge;
                if (!File.Exists(path))
                {
                    continue;
                }
                using (Stream stream = File.OpenRead(path))
                {
                    docToMerge = provider.Import(stream);
                }
                doc.Merge(docToMerge);
            }


            string outputFilePath = @"..\..\mergedFixed.pdf";
            File.Delete(outputFilePath);

            using (Stream output = File.OpenWrite(outputFilePath))
            {
                provider.Export(doc, output);
            }
            Process.Start(new ProcessStartInfo() { FileName = outputFilePath, UseShellExecute = true });


        }

Workaround:  

   private void MergeDifferentDocumentsPages(string resultFileName)
   {
       string[] documentsToMerge =
       {
           "14301-STOCK_Proforma.pdf",
           "14302-STOCK_Proforma.pdf",
           "14303-STOCK_Proforma.pdf",
           "14304-STOCK_Proforma.pdf",
           "14305-STOCK_Proforma.pdf",
           "14330-STOCK_Proforma.pdf"
       };

       File.Delete(resultFileName);
       using (PdfStreamWriter fileWriter = new PdfStreamWriter(File.OpenWrite(resultFileName)))
       {
           foreach (string documentName in documentsToMerge)
           {
               string path = @"..\..\Samples\" + documentName;
               using (PdfFileSource fileToMerge = new PdfFileSource(File.OpenRead(path)))
               {
                   foreach (PdfPageSource pageToMerge in fileToMerge.Pages)
                   {
                       fileWriter.WritePage(pageToMerge);
                   }
               }
           }
       }


      
       Process.Start(new ProcessStartInfo() { FileName = resultFileName, UseShellExecute = true });
   }

Unplanned
Last Updated: 18 Apr 2024 05:36 by Sujith

This is the code snippet for reproducing the error message: 

        static void Main(string[] args)
        {
            string filePath = "Lorem ipsum dolor sit amet.pdf";
            //load a random document
            PdfFormatProvider provider = new PdfFormatProvider();
            RadFixedDocument originalDocument;
            using (Stream stream = File.OpenRead(filePath))
            {
                originalDocument = provider.Import(stream);
            }
            //draw something on the first page
            FixedContentEditor editor = new FixedContentEditor(originalDocument.Pages[0]);
            editor.GraphicProperties.IsFilled = true;
            editor.GraphicProperties.FillColor = RgbColors.Black;
            Telerik.Documents.Primitives.Rect Rect = new Telerik.Documents.Primitives.Rect(10, 10, 200, 100);
            editor.DrawRectangle(Rect);

            //export the pages as images and build a brand new document from the images
            SkiaImageFormatProvider imageProvider = new SkiaImageFormatProvider();
            imageProvider.ExportSettings.ImageFormat = SkiaImageFormat.Jpeg;
            imageProvider.ExportSettings.ScaleFactor = 0.8;
            imageProvider.ExportSettings.Quality = 80;


            RadFixedDocument doc = new RadFixedDocument();
            foreach (RadFixedPage page in originalDocument.Pages)
            {
                byte[] resultImage = imageProvider.Export(page);
                RadFixedPage pdfpage = doc.Pages.AddPage();
                editor = new FixedContentEditor(pdfpage);
                Stream imageStream = new MemoryStream(resultImage);
                editor.DrawImage(imageStream);
            }

            //export the pdf built from the images
            PdfFormatProvider pdfFormatProvider = new PdfFormatProvider();
            string outputPdf = @"output.pdf";
            File.Delete(outputPdf);
            using (Stream output = File.OpenWrite(outputPdf))
            {
                pdfFormatProvider.Export(doc, output);
            }
            Process.Start(new ProcessStartInfo() { FileName = outputPdf, UseShellExecute = true });
        }

Workaround:

        static void Main(string[] args)
        {
            string filePath = "Lorem ipsum dolor sit amet.pdf";
            //load a random document
            PdfFormatProvider provider = new PdfFormatProvider();
            RadFixedDocument originalDocument;
            using (Stream stream = File.OpenRead(filePath))
            {
                originalDocument = provider.Import(stream);
            }
            //draw something on the first page
            FixedContentEditor editor = new FixedContentEditor(originalDocument.Pages[0]);
            editor.GraphicProperties.IsFilled = true;
            editor.GraphicProperties.FillColor = RgbColors.Black;
            Telerik.Documents.Primitives.Rect Rect = new Telerik.Documents.Primitives.Rect(10, 10, 200, 100);
            editor.DrawRectangle(Rect);

            using (Stream output = File.OpenWrite(filePath))
            {
                provider.Export(originalDocument, output);
            }

            using (Stream stream = File.OpenRead(filePath))
            {
                originalDocument = provider.Import(stream);
            }
            //export the pages as images and build a brand new document from the images
            SkiaImageFormatProvider imageProvider = new SkiaImageFormatProvider();
            imageProvider.ExportSettings.ImageFormat = SkiaImageFormat.Jpeg;
            imageProvider.ExportSettings.ScaleFactor = 0.8;
            imageProvider.ExportSettings.Quality = 80;


            RadFixedDocument doc = new RadFixedDocument();
            foreach (RadFixedPage page in originalDocument.Pages)
            {
                byte[] resultImage = imageProvider.Export(page);
                RadFixedPage pdfpage = doc.Pages.AddPage();
                editor = new FixedContentEditor(pdfpage);
                Stream imageStream = new MemoryStream(resultImage);
                editor.DrawImage(imageStream);
            }

            //export the pdf built from the images
            PdfFormatProvider pdfFormatProvider = new PdfFormatProvider();
            string outputPdf = @"output.pdf";
            File.Delete(outputPdf);
            using (Stream output = File.OpenWrite(outputPdf))
            {
                pdfFormatProvider.Export(doc, output);
            }
            Process.Start(new ProcessStartInfo() { FileName = outputPdf, UseShellExecute = true });
        }

Unplanned
Last Updated: 17 Apr 2024 12:39 by Nathan
Created by: Nathan
Comments: 0
Category: WordsProcessing
Type: Bug Report
1
PdfFormatProvider: TOC entries are blue.
Unplanned
Last Updated: 17 Apr 2024 12:31 by Nathan
TOC list numbering and page numbering are missing.
Unplanned
Last Updated: 17 Apr 2024 12:18 by Nathan
PdfFormatProvider: TOC page numbering is in Roman instead of Arabic numerals.
In Development
Last Updated: 16 Apr 2024 11:12 by ADMIN
ArgumentNullException when importing documents containing comments with no DateTime.
In Development
Last Updated: 16 Apr 2024 11:02 by ADMIN
Unplanned
Last Updated: 15 Apr 2024 13:10 by Belma
Created by: Belma
Comments: 0
Category: WordsProcessing
Type: Bug Report
0
Outline color of some shapes is not respected.
In Development
Last Updated: 15 Apr 2024 08:37 by ADMIN
When parsing a CFF Type1 font a NullReferenceException is thrown.
Unplanned
Last Updated: 12 Apr 2024 12:33 by Yeison
Sometimes when an XLSX file has a combo chart, you can get an error on import "The axes are incorrectly paired.". This happens when a combo chart has secondary axes and the file has likely been produced by an application other than Excel.
Unplanned
Last Updated: 10 Apr 2024 14:03 by Benjamin

Use the code for inserting the code:

        static void Main(string[] args)
        {
                      Telerik.Windows.Documents.Flow.Model.RadFlowDocument templateDocument = GetDocument("Template.rtf");
            Telerik.Windows.Documents.Flow.Model.RadFlowDocument contentDocument = GetDocument("Content.rtf");
            InsertDocumentOptions options = new InsertDocumentOptions();
            options.ConflictingStylesResolutionMode = ConflictingStylesResolutionMode.RenameSourceStyle;
            options.InsertLastParagraphMarker = true;

            RadFlowDocumentEditor editor = new RadFlowDocumentEditor(templateDocument);
            editor.InsertDocument(contentDocument, options);

            string mergedDocumentFilePath ="MergeDocumentsWithWordsProcessing.rtf";
            File.Delete(mergedDocumentFilePath);
            WriteDocToFile(templateDocument, mergedDocumentFilePath);

        }
        private static Telerik.Windows.Documents.Flow.Model.RadFlowDocument GetDocument(string rtfFilePath)
        {
            Telerik.Windows.Documents.Flow.Model.RadFlowDocument document = null;
            var rtfImporter = new Telerik.Windows.Documents.Flow.FormatProviders.Rtf.RtfFormatProvider();
            using (Stream stream = File.OpenRead(rtfFilePath))
            {
                document = rtfImporter.Import(stream);
            }
            return document;
        }


        private static void WriteDocToFile(Telerik.Windows.Documents.Flow.Model.RadFlowDocument doc, string filename)
        {
            var rtfExporter = new Telerik.Windows.Documents.Flow.FormatProviders.Rtf.RtfFormatProvider();
            string rtfText = rtfExporter.Export(doc);
            File.WriteAllText(filename, rtfText);

            Process.Start(filename);
        }

Observed result: The After spacing is reset

Expected result: keep the style settings from the original documents.

In Development
Last Updated: 09 Apr 2024 06:29 by ADMIN
NullReferenceException caused by a Hyperlink Field during nested Mail Merge.
Unplanned
Last Updated: 08 Apr 2024 12:03 by ADMIN

NumberedHierarchical list type has inconsistent indentation after bullets.

In Development
Last Updated: 04 Apr 2024 06:43 by ADMIN
InvalidOperationException is thrown when exporting font that is available but not used.

The stack trace is as follows:
   at System.Linq.Enumerable.Max(IEnumerable`1 source)
   at Telerik.Windows.Documents.Fixed.FormatProviders.Pdf.Model.Elements.Fonts.Cid.CidSet.CopyPropertiesFrom(IPdfExportContext context, FontBase font)
   at Telerik.Windows.Documents.Fixed.FormatProviders.Pdf.Model.Elements.Fonts.CidFontDescriptor.CalculateCidSet(IPdfExportContext context, CidFontBase font)
   at Telerik.Windows.Documents.Fixed.FormatProviders.Pdf.Model.Elements.Fonts.CidFontDescriptor.<>c__DisplayClass34.<CopyPropertiesFrom>b__30()
   at Telerik.Windows.Documents.Fixed.FormatProviders.Pdf.Utilities.PdfObjectsExtensions.ToPrimitive[P,T](PdfProperty`1 pdfProperty, Func`2 convertToPrimitive, Func`1 getDefaultValue)
   at Telerik.Windows.Documents.Fixed.FormatProviders.Pdf.Model.Elements.Fonts.CidFontDescriptor.CopyPropertiesFrom(IPdfExportContext context, FontBase font)
   at Telerik.Windows.Documents.Fixed.FormatProviders.Pdf.Model.Elements.Fonts.CidFontObject.CopyPropertiesFromOverride(IPdfExportContext context, FontBase font)
   at Telerik.Windows.Documents.Fixed.FormatProviders.Pdf.Model.Elements.Fonts.CidFontObject.CopyPropertiesFrom(IPdfExportContext context, FontBase font)
   at Telerik.Windows.Documents.Fixed.FormatProviders.Pdf.Model.Elements.Fonts.Type0FontObject.CopyPropertiesFromOverride(IPdfExportContext context, FontBase font)
   at Telerik.Windows.Documents.Fixed.FormatProviders.Pdf.Export.PdfExporter.WriteFontsFromContext(PdfWriter writer, IPdfExportContext context)
   at Telerik.Windows.Documents.Fixed.FormatProviders.Pdf.Export.PdfExporter.Export(IRadFixedDocumentExportContext context, Stream output)
   at Telerik.Windows.Documents.Fixed.FormatProviders.Pdf.PdfFormatProvider.ExportOverride(RadFixedDocument document, Stream output)
   at Telerik.Windows.Documents.Common.FormatProviders.FormatProviderBase`1.Export(T document, Stream output)
Declined
Last Updated: 03 Apr 2024 15:43 by ADMIN

Steps to reproduce:

1.Create a zip archive for a txt file with password protection

2. Try updating the protected file and insert a new text line for example.


As a result,  an error occurs: System.ObjectDisposedException: 'Cannot access a closed Stream.'

 
Imports System.IO
Imports System.Text
Imports Telerik.Windows.Zip

Module Module1

    Sub Main()
        Dim sZipFilePath As String = "..\..\test.zip"
        File.Delete(sZipFilePath)

        CreateArchive(sZipFilePath)

        Dim decryptionSettings As DecryptionSettings = EncryptionSettings.CreateDecryptionSettings()
        AddHandler decryptionSettings.PasswordRequired, AddressOf DecryptionSettings_PasswordRequired
        Dim compressionSettings As CompressionSettings = Nothing
        Dim encoding As Encoding = Nothing
        Using oFS As FileStream = File.Open(sZipFilePath, FileMode.OpenOrCreate)


            Using oArchive As ZipArchive = ZipArchive.Update(oFS, encoding, compressionSettings, decryptionSettings)
                For Each entry As ZipArchiveEntry In oArchive.Entries
                    Using entryStream As Stream = entry.Open()
                        Dim reader As New StreamReader(entryStream)
                        Dim content As String = reader.ReadToEnd()

                        entryStream.Seek(0, SeekOrigin.End)
                        Dim writer As New StreamWriter(entryStream)
                        writer.WriteLine("Updated line.")
                        writer.Flush()
                    End Using
                Next
            End Using
        End Using
    End Sub

    Private Sub CreateArchive(sZipFilePath As String)
        Using stream As Stream = File.Open(sZipFilePath, FileMode.Create)
            Dim encryptionSettings As PasswordEncryptionSettings = encryptionSettings.CreatePkzipPasswordEncryptionSettings()
            encryptionSettings.Password = "MyPassword"
            Dim compressionSettings As CompressionSettings = Nothing
            Dim encoding As Encoding = Nothing

            Using archive As ZipArchive = ZipArchive.Create(stream, encoding, compressionSettings, encryptionSettings)

                Using entry As ZipArchiveEntry = archive.CreateEntry("text.txt")
                    Dim writer As StreamWriter = New StreamWriter(entry.Open())
                    writer.WriteLine("Hello world!")
                    writer.Flush()
                End Using
            End Using
        End Using
    End Sub

    Private Sub DecryptionSettings_PasswordRequired(ByVal sender As Object, ByVal e As PasswordRequiredEventArgs)
        e.Password = "MyPassword"
    End Sub

End Module
In Development
Last Updated: 03 Apr 2024 11:29 by ADMIN

The attached gif file illustrates the inability to open the newly added file with the password: 

Sub Main()
	Dim sZipFilePath As String = "..\..\test.zip"
	File.Delete(sZipFilePath)

	CreateArchive(sZipFilePath)
	Dim decryptionSettings As DecryptionSettings = EncryptionSettings.CreateDecryptionSettings()
	AddHandler decryptionSettings.PasswordRequired, AddressOf DecryptionSettings_PasswordRequired
	Dim compressionSettings As CompressionSettings = Nothing
	Dim encoding As Encoding = Nothing
	Using oFS As FileStream = File.Open(sZipFilePath, FileMode.OpenOrCreate)


		Using oArchive As ZipArchive = ZipArchive.Update(oFS, encoding, compressionSettings, decryptionSettings)
			Using entry As ZipArchiveEntry = oArchive.CreateEntry("newText.txt")
				Dim writer As StreamWriter = New StreamWriter(entry.Open())
				writer.WriteLine("Hello world!")
				writer.Flush()
			End Using
		End Using
	End Using
End Sub

Private Sub CreateArchive(sZipFilePath As String)
	Using stream As Stream = File.Open(sZipFilePath, FileMode.Create)
		Dim _encryptionSettings As PasswordEncryptionSettings = EncryptionSettings.CreatePkzipPasswordEncryptionSettings()
		_encryptionSettings.Password = "telerik"
		Dim compressionSettings As CompressionSettings = Nothing
		Dim encoding As Encoding = Nothing

		Using archive As ZipArchive = ZipArchive.Create(stream, encoding, compressionSettings, _encryptionSettings)

			Using entry As ZipArchiveEntry = archive.CreateEntry("text.txt")
				Dim writer As StreamWriter = New StreamWriter(entry.Open())
				writer.WriteLine("Hello world!")
				writer.Flush()
			End Using
		End Using
	End Using
End Sub

Private Sub DecryptionSettings_PasswordRequired(ByVal sender As Object, ByVal e As PasswordRequiredEventArgs)
	e.Password = "telerik"
End Sub

 

Workaround: Until this bug is fixed the obsolete API could be used instead: 

ZipArchive archive = new ZipArchive(stream, ZipArchiveMode.Create, true, encoding, compressionSettings, encryptionSettings)
and
ZipArchive oArchive = new ZipArchive(stream, ZipArchiveMode.Update, true, encoding, compressionSettings, decryptionSettings)

Duplicated
Last Updated: 03 Apr 2024 11:24 by ADMIN

Converting some DocX files to PDF format with page numbering leads to incorrect formatting in the exported PDF:

Input DocX:

Output PDF:

 

Unplanned
Last Updated: 02 Apr 2024 13:27 by Graeme

Original DOCX document:

Exported DOCX document:

Workaround:

            Telerik.Windows.Documents.Flow.Model.RadFlowDocument document;

            Telerik.Windows.Documents.Flow.FormatProviders.Docx.DocxFormatProvider docXprovider = new Telerik.Windows.Documents.Flow.FormatProviders.Docx.DocxFormatProvider();

            using (Stream input = File.OpenRead("PT1987 VU22888 Moodle Specification List [2024032716].docx"))
            {
                document = docXprovider.Import(input);
            }

            string normalStyleId = BuiltInStyleNames.NormalStyleId;
            Style normalStyle = document.StyleRepository.AddBuiltInStyle(normalStyleId);
            normalStyle.ParagraphProperties.SpacingAfter.LocalValue = 0;
            normalStyle.ParagraphProperties.LineSpacing.LocalValue = 1;

1 2 3 4 5 6