From 4b8a096ead68d8121ae98b64588d161ee1d42eca Mon Sep 17 00:00:00 2001 From: Maksym Tkachuk Date: Mon, 3 Nov 2025 09:24:40 +0200 Subject: [PATCH 1/2] fixed Dispose() issue of page.doc() --- Demo/Program.cs | 133 +++++++++++++++++++++++++-------- MuPDF.NET.Test/DocumentTest.cs | 39 ++++++++++ MuPDF.NET/Annot.cs | 20 ++++- MuPDF.NET/Document.cs | 2 +- MuPDF.NET/MuPDF.NET.nuspec | 2 +- MuPDF.NET/Page.cs | 58 ++++++++++---- MuPDF.NET/TextWriter.cs | 7 +- MuPDF.NET/Utils.cs | 9 ++- 8 files changed, 217 insertions(+), 53 deletions(-) diff --git a/Demo/Program.cs b/Demo/Program.cs index 38660f2c..347942de 100644 --- a/Demo/Program.cs +++ b/Demo/Program.cs @@ -1,4 +1,5 @@ -using MuPDF.NET; +using mupdf; +using MuPDF.NET; using SkiaSharp; using System; using System.Collections.Generic; @@ -7,6 +8,7 @@ using System.Linq; using System.Text; using System.Threading; +using static ICSharpCode.SharpZipLib.Zip.ExtendedUnixData; using static System.Net.Mime.MediaTypeNames; using static System.Net.WebRequestMethods; using File = System.IO.File; @@ -46,8 +48,8 @@ static void Main(string[] args) //TestExtractTextWithLayout(args); //TestWidget(args); //TestColor(args); - TestCMYKRecolor(args); - TestSVGRecolor(args); + //TestCMYKRecolor(args); + //TestSVGRecolor(args); //TestReplaceImage(args); //TestInsertImage(args); //TestGetImageInfo(args); @@ -56,30 +58,116 @@ static void Main(string[] args) //TestJoinPdfPages(args); //TestFreeTextAnnot(args); //TestTextFont(args); - TestMemoryLeak(); + //TestMemoryLeak(); //TestDrawLine(); //TestWriteBarcode1(); - //TestCMYKRecolor1(args); //TestUnicodeDocument(); //TestMorph(); - TestWidget(); + //TestMetadata(); + //TestTable(); + TestMoveFile(); return; } - static void TestWidget() + + static void TestMoveFile() { - Console.WriteLine("\n=== TestWidget ====================="); + string origfilename = @"E:\test.pdf"; + + Document d = new Document(origfilename); + + Page page = d[0]; + + Point tl = new Point(100, 120); + Point br = new Point(300, 150); + + Rect rect = new Rect(tl, br); + + TextWriter pw = new TextWriter(page.TrimBox); + /* + Font font = new Font(fontName: "tiro"); + + List<(string, float)> ret = pw.FillTextbox(rect, "This is a test to overwrite the original file and move it", font, fontSize: 24); + */ + pw.WriteText(page); + + page.Dispose(); + + MemoryStream tmp = new MemoryStream(); + + d.Save(tmp, garbage: 3, deflateFonts: 1, deflate: 1); + + d.Close(); + + File.WriteAllBytes(origfilename, tmp.ToArray()); + + tmp.Dispose(); + + File.Move(origfilename, @"e:\new.pdf", true); + } + + public static float MmToPs(float mm) + { + return mm * 2.8346456693f; + } + + static void TestTable() + { + Console.WriteLine("\n=== TestTable ====================="); + + string testFilePath = @"E:\MuPDF.NET\Tmp\Peter\Table\test.pdf"; + + Rect rect = new Rect(X0:MmToPs(110), X1:MmToPs(198), Y0: MmToPs(42), Y1: MmToPs(76)); + + Document doc = new Document(testFilePath); + + FzStextOptions options = new FzStextOptions(0); + options.Dispose(); + + string text = ""; + + text = doc[0].GetText(clip: rect, flags: (int)TextFlags.TEXT_MEDIABOX_CLIP, sort: true); + Console.WriteLine(text); + + /* + text = ""; + List textBlocks = doc[0].GetTextBlocks(rect); + foreach (TextBlock block in textBlocks) + { + text += block.Text; + } + + Console.WriteLine(text); + + text = doc[0].GetTextWithLayout(rect); - Document doc = new Document("../../../TestDocuments/test_widget_parse.pdf"); + Console.WriteLine(text); + */ + doc.Close(); + + Console.WriteLine("TestTable completed."); + } - var currentPage = 0; - while (currentPage < doc.PageCount) + static void TestMetadata() + { + Console.WriteLine("\n=== TestMetadata ====================="); + + string testFilePath = @"e:\Annot.pdf"; + + Document doc = new Document(testFilePath); + + Dictionary metaDict = doc.MetaData; + + foreach (string key in metaDict.Keys) { - var page = doc[currentPage]; - var widgets = page.GetWidgets().ToList(); - currentPage++; + Console.WriteLine(key + ": " + metaDict[key]); } + + doc.Close(); + + Console.WriteLine("TestDocument completed."); } + static void TestMorph() { Console.WriteLine("\n=== TestMorph ====================="); @@ -123,23 +211,6 @@ static void TestUnicodeDocument() Console.WriteLine("TestDocument completed."); } - static void TestCMYKRecolor1(string[] args) - { - Console.WriteLine("\n=== TestCMYKRecolor ====================="); - - string testFilePath = "../../../TestDocuments/CMYK_Recolor1.pdf"; - Document doc = new Document(testFilePath); - //List images = doc.GetPageImages(0); - //Console.WriteLine($"CaName: {images[0].CsName}"); - doc.Recolor(0, "CMYK"); - //images = doc.GetPageImages(0); - //Console.WriteLine($"CaName: {images[0].AltCsName}"); - doc.Save(@"CMYKRecolor.pdf"); - doc.Close(); - - Console.WriteLine("CMYK Recolor test completed."); - } - static void TestWriteBarcode1() { string testFilePath = Path.GetFullPath("../../../TestDocuments/Blank.pdf"); diff --git a/MuPDF.NET.Test/DocumentTest.cs b/MuPDF.NET.Test/DocumentTest.cs index bf8fbd29..7141ce01 100644 --- a/MuPDF.NET.Test/DocumentTest.cs +++ b/MuPDF.NET.Test/DocumentTest.cs @@ -202,5 +202,44 @@ public void TestJoinPdfPages() doc2.Close(); doc1.Close(); } + + [Test] + public void TestMoveFile() + { + string testFilePath1 = Path.GetFullPath(@"../../../resources/DocumentTest/Widget.pdf"); + string testFilePath2 = Path.GetFullPath(@"TestMoveOrig.pdf"); + string testFilePath3 = Path.GetFullPath(@"TestMoveNew.pdf"); + + File.Copy(testFilePath1, testFilePath2, true); + + Document doc = new Document(testFilePath2); + Page page = doc[0]; + + Point tl = new Point(100, 120); + Point br = new Point(300, 150); + + Rect rect = new Rect(tl, br); + TextWriter pw = new TextWriter(page.TrimBox); + Font font = new Font(fontName: "tiro"); + List<(string, float)> ret = pw.FillTextbox(rect, "This is a test to overwrite the original file and move it", font, fontSize: 24); + + pw.WriteText(page); + page.Dispose(); + + MemoryStream tmp = new MemoryStream(); + + doc.Save(tmp, garbage: 3, deflateFonts: 1, deflate: 1); + doc.Close(); + + File.WriteAllBytes(testFilePath2, tmp.ToArray()); + + tmp.Dispose(); + + File.Move(testFilePath2, testFilePath3, true); + + Document newDoc = new Document(testFilePath3); + Assert.IsTrue(newDoc.PageCount == 6); + newDoc.Close(); + } } } diff --git a/MuPDF.NET/Annot.cs b/MuPDF.NET/Annot.cs index 76da0b42..03bfa535 100644 --- a/MuPDF.NET/Annot.cs +++ b/MuPDF.NET/Annot.cs @@ -775,12 +775,14 @@ public void SetAP(byte[] buffer, int rect = 0) { throw new Exception("bad type: 'buffer'"); } - Utils.UpdateStream(page.doc(), apObj, buf, 1); + PdfDocument pageDoc = page.doc(); + Utils.UpdateStream(pageDoc, apObj, buf, 1); if (rect != 0) { FzRect bbox = annotObj.pdf_dict_get_rect(new PdfObj("Rect")); apObj.pdf_dict_put_rect(new PdfObj("Rect"), bbox); } + pageDoc.Dispose(); } catch (Exception) { } } @@ -897,11 +899,13 @@ private bool UpdateAppearance( } catch (Exception e) { + doc.Dispose(); throw new Exception("cannot update annot:" + e.Message); } if ((opacity < 0 || opacity >= 1) && blendMode == null) // no opacity, no blend_mode { + doc.Dispose(); return true; } @@ -914,6 +918,7 @@ private bool UpdateAppearance( if (ap.m_internal == null) { // should never happen + doc.Dispose(); throw new Exception("bad or missing annot AP/N"); } @@ -946,6 +951,8 @@ private bool UpdateAppearance( Console.WriteLine("cannot set opacity or blend mode"); } + doc.Dispose(); + return true; } @@ -1584,10 +1591,11 @@ public void SetIrtXref(int xref) PdfObj annotObj = annot.pdf_annot_obj(); PdfPage page = annot.pdf_annot_page(); - if (xref < 1 || xref >= page.doc().pdf_xref_len()) + PdfDocument pageDoc = page.doc(); + if (xref < 1 || xref >= pageDoc.pdf_xref_len()) throw new Exception(Utils.ErrorMessages["MSG_BAD_XREF"]); - PdfObj irt = page.doc().pdf_new_indirect(xref, 0); + PdfObj irt = pageDoc.pdf_new_indirect(xref, 0); PdfObj subt = irt.pdf_dict_get(new PdfObj("Subtype")); PdfAnnotType irtSubt = (PdfAnnotType) mupdf.mupdf.pdf_annot_type_from_string(subt.pdf_to_name()); @@ -1595,6 +1603,8 @@ public void SetIrtXref(int xref) throw new Exception(Utils.ErrorMessages["MSG_IS_NO_ANNOT"]); annotObj.pdf_dict_put(new PdfObj("IRT"), irt); + + pageDoc.Dispose(); } public void SetLanguage(string language) @@ -1722,7 +1732,9 @@ public Page GetParent() else { PdfPage page = _nativeAnnotion.pdf_annot_page(); - Document doc = (page.m_internal == null) ? null : new Document(page.doc()); + PdfDocument pageDoc = page.doc(); + Document doc = (page.m_internal == null) ? null : new Document(pageDoc); + pageDoc.Dispose(); ret = new Page(page, doc); Parent = ret; diff --git a/MuPDF.NET/Document.cs b/MuPDF.NET/Document.cs index 98b8b275..af335f23 100644 --- a/MuPDF.NET/Document.cs +++ b/MuPDF.NET/Document.cs @@ -747,7 +747,7 @@ public void InitDocument() { "format", "format" }, }; - if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + //if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) { values.Add("title", "info:Title"); values.Add("author", "info:Author"); diff --git a/MuPDF.NET/MuPDF.NET.nuspec b/MuPDF.NET/MuPDF.NET.nuspec index b94e2751..c81e5c9e 100644 --- a/MuPDF.NET/MuPDF.NET.nuspec +++ b/MuPDF.NET/MuPDF.NET.nuspec @@ -2,7 +2,7 @@ MuPDF.NET - 3.2.10 + 3.2.12-rc.2 Artifex Software Inc. true LICENSE.md diff --git a/MuPDF.NET/Page.cs b/MuPDF.NET/Page.cs index ec426cfb..ba2a98aa 100644 --- a/MuPDF.NET/Page.cs +++ b/MuPDF.NET/Page.cs @@ -510,13 +510,15 @@ public Annot AddFileAnnot( annot.pdf_set_annot_icon_name(icon); } - PdfObj val = Utils.EmbedFile(page.doc(), fileBuf, filename, uf, d, 1); + PdfDocument pageDoc = page.doc(); + PdfObj val = Utils.EmbedFile(pageDoc, fileBuf, filename, uf, d, 1); annot.pdf_annot_obj().pdf_dict_put(new PdfObj("FS"), val); annot.pdf_annot_obj().pdf_dict_put_text_string(new PdfObj("Contents"), filename); annot.pdf_update_annot(); annot.pdf_set_annot_rect(r); annot.pdf_set_annot_flags(flags); Utils.AddAnnotId(annot, "A"); + pageDoc.Dispose(); return new Annot(annot, this); } @@ -802,13 +804,14 @@ public Annot AddInkAnnot(List> list) PdfAnnot annot = page.pdf_create_annot(pdf_annot_type.PDF_ANNOT_INK); PdfObj annotObj = annot.pdf_annot_obj(); int n0 = list.Count; - PdfObj inkList = page.doc().pdf_new_array(n0); + PdfDocument pageDoc = page.doc(); + PdfObj inkList = pageDoc.pdf_new_array(n0); for (int j = 0; j < n0; j++) { dynamic subList = list[j]; int n1 = subList.Count; - PdfObj stroke = page.doc().pdf_new_array(n1 * 2); + PdfObj stroke = pageDoc.pdf_new_array(n1 * 2); for (int i = 0; i < n1; i++) { @@ -823,6 +826,8 @@ public Annot AddInkAnnot(List> list) annot.pdf_update_annot(); Utils.AddAnnotId(annot, "A"); + pageDoc.Dispose(); + return new Annot(annot, this); } @@ -916,7 +921,9 @@ public Annot AddRedactAnnot( { fCol = Annot.ColorFromSequence(fill); nFCol = fCol.Length; - PdfObj arr = page.doc().pdf_new_array(nFCol); + PdfDocument pageDoc = page.doc(); + PdfObj arr = pageDoc.pdf_new_array(nFCol); + pageDoc.Dispose(); for (int i = 0; i < nFCol; i++) { arr.pdf_array_push_real(fCol[i]); @@ -1021,12 +1028,14 @@ public Annot AddRedactAnnot( { float[] fCol = Annot.ColorFromSequence(fill); int nFCol = fCol.Length; - PdfObj arr = page.doc().pdf_new_array(nFCol); + PdfDocument pageDoc = page.doc(); + PdfObj arr = pageDoc.pdf_new_array(nFCol); for (int i = 0; i < nFCol; i++) { arr.pdf_array_push_real(fCol[i]); } annot.pdf_annot_obj().pdf_dict_put(new PdfObj("IC"), arr); + pageDoc.Dispose(); } if (!string.IsNullOrEmpty(text)) { @@ -1682,9 +1691,11 @@ public void AddAnnotFromString(List links) try { - PdfObj annot = page.doc().pdf_add_object(Utils.PdfObjFromStr(page.doc(), text)); - PdfObj indObj = page.doc().pdf_new_indirect(annot.pdf_to_num(), 0); + PdfDocument pageDoc = page.doc(); + PdfObj annot = pageDoc.pdf_add_object(Utils.PdfObjFromStr(pageDoc, text)); + PdfObj indObj = pageDoc.pdf_new_indirect(annot.pdf_to_num(), 0); annots.pdf_array_push(indObj); + pageDoc.Dispose(); } catch (Exception) { @@ -1754,6 +1765,7 @@ public Annot AddWidget(PdfWidgetType fieldType, string fieldName) PdfPage page = _pdfPage; PdfDocument pdf = page.doc(); PdfAnnot annot = Utils.CreateWidget(pdf, page, fieldType, fieldName); + pdf.Dispose(); if (annot == null) throw new Exception("cannot create widget"); @@ -1777,7 +1789,9 @@ private int _ApplyRedactions(int text = 0, int images = 2, int graphics = 1) opts.image_method = images; opts.line_art = graphics; opts.text = text; - int success = page.doc().pdf_redact_page(page, opts); + PdfDocument pageDoc = page.doc(); + int success = pageDoc.pdf_redact_page(page, opts); + pageDoc.Dispose(); return success; } @@ -2116,7 +2130,7 @@ public int InsertImage( if (temp != -1) { imgXRef = temp; - ref_ = page.doc().pdf_new_indirect(imgXRef, 0); + ref_ = pdf.pdf_new_indirect(imgXRef, 0); do_process_stream = 0; do_have_imask = 0; do_have_image = 0; @@ -2165,7 +2179,7 @@ public int InsertImage( if (tmp != -1) { imgXRef = tmp; - ref_ = page.doc().pdf_new_indirect(imgXRef, 0); + ref_ = pdf.pdf_new_indirect(imgXRef, 0); w = ref_.pdf_dict_geta(new PdfObj("Width"), new PdfObj("W")).pdf_to_int(); h = ref_.pdf_dict_geta(new PdfObj("Height"), new PdfObj("H")).pdf_to_int(); do_have_imask = 0; @@ -2240,6 +2254,8 @@ public int InsertImage( doc.InsertedImages = digests; } + pdf.Dispose(); + return imgXRef; } @@ -2663,6 +2679,8 @@ private int ShowPdfPage( nres.fz_append_string(" Do Q "); Utils.InsertContents(pdfOut, tpageObj, nres, overlay ? 1 : 0); + + pdfOut.Dispose(); return rcXref; } @@ -2862,6 +2880,9 @@ int ordering PdfObj fontObj = pdf.pdf_new_indirect(value.Xref, 0); fonts.pdf_dict_puts(fontName, fontObj); + + pdf.Dispose(); + return value; } @@ -2944,10 +2965,12 @@ public string SetOpacity( return gstate; } - PdfObj opa = _pdfPage.doc().pdf_new_dict(3); + PdfDocument pageDoc = _pdfPage.doc(); + PdfObj opa = pageDoc.pdf_new_dict(3); opa.pdf_dict_put_real(new PdfObj("CA"), CA); opa.pdf_dict_put_real(new PdfObj("ca"), ca); extg.pdf_dict_puts(gstate, opa); + pageDoc.Dispose(); return gstate; } @@ -3209,8 +3232,10 @@ void Finished() return; } annots.pdf_array_delete(i); - page.doc().pdf_delete_object(xref); + PdfDocument pageDoc = page.doc(); + pageDoc.pdf_delete_object(xref); page.obj().pdf_dict_put(new PdfObj("Annots"), annots); + pageDoc.Dispose(); Utils.RefreshLinks(page); Finished(); @@ -4555,7 +4580,9 @@ public void CleanContetns(int sanitize = 1) return; PdfFilterOptions filter = Utils.MakePdfFilterOptions(recurse: 1, sanitize: sanitize); - page.doc().pdf_filter_page_contents(page, filter); + PdfDocument pageDoc = page.doc(); + pageDoc.pdf_filter_page_contents(page, filter); + pageDoc.Dispose(); } /// @@ -4692,7 +4719,10 @@ public Annot AddWidget(Widget widget) widget.FieldName ); if (annot.m_internal == null) + { + pdf.Dispose(); throw new Exception("cannot create widget"); + } Utils.AddAnnotId(annot, "W"); Annot annot_ = new Annot(annot, this); @@ -4704,6 +4734,8 @@ public Annot AddWidget(Widget widget) widget._annot = new PdfAnnot(annot); widget.Update(); + pdf.Dispose(); + return annot_; } diff --git a/MuPDF.NET/TextWriter.cs b/MuPDF.NET/TextWriter.cs index 48c53734..3d805cea 100644 --- a/MuPDF.NET/TextWriter.cs +++ b/MuPDF.NET/TextWriter.cs @@ -251,9 +251,10 @@ public void WriteText(Page page, float[] color = null, float opacity = -1, int o else colorSpace = mupdf.mupdf.fz_device_gray(); - PdfObj resources = pdfPage.doc().pdf_new_dict(5); + PdfDocument pdfDoc = pdfPage.doc(); + PdfObj resources = pdfDoc.pdf_new_dict(5); FzBuffer contents = mupdf.mupdf.fz_new_buffer(1024); - FzDevice dev = mupdf.mupdf.pdf_new_pdf_device(pdfPage.doc(), new FzMatrix(), resources, contents); + FzDevice dev = mupdf.mupdf.pdf_new_pdf_device(pdfDoc, new FzMatrix(), resources, contents); IntPtr pDevColor = Marshal.AllocHGlobal(devColor.Length * sizeof(float)); Marshal.Copy(devColor, 0, pDevColor, devColor.Length); @@ -344,6 +345,8 @@ public void WriteText(Page page, float[] color = null, float opacity = -1, int o Utils.InsertContents(page, content, overlay); foreach (Font font in UsedFonts) Utils.RepairMonoFont(page, font); + + pdfDoc.Dispose(); } /// diff --git a/MuPDF.NET/Utils.cs b/MuPDF.NET/Utils.cs index 88dddc9f..2d4e7559 100644 --- a/MuPDF.NET/Utils.cs +++ b/MuPDF.NET/Utils.cs @@ -1261,6 +1261,8 @@ public static void GetWidgetProperties(Annot annot, Widget widget) widget.ScriptFocus = Utils.GetScript( Utils.pdf_dict_getl(annotObj, new string[] { "AA", "Fo" }) ); + + pdf.Dispose(); } internal static List GetChoiceOptions(PdfAnnot annot) @@ -1311,7 +1313,9 @@ internal static void AddAnnotId(PdfAnnot annot, string stem) } PdfObj name = mupdf.mupdf.pdf_new_string(stemId, (uint)stemId.Length); annotObj.pdf_dict_puts("NM", name); - page.doc().m_internal.resynth_required = 0; + PdfDocument pageDoc = page.doc(); + pageDoc.m_internal.resynth_required = 0; + pageDoc.Dispose(); } internal static List GetAnnotIDList(PdfPage page) @@ -3935,6 +3939,7 @@ internal static void RefreshLinks(PdfPage page) page.pdf_page_transform(pageMediabox, pageCtm); FzLink link = pdf.pdf_load_link_annots(page, obj, number, pageCtm); page.m_internal.links = mupdf.mupdf.ll_fz_keep_link(link.m_internal); + pdf.Dispose(); } } @@ -6568,6 +6573,8 @@ internal static void SaveWidget(PdfAnnot annot, Widget widget) annot.pdf_set_annot_hot(1); annot.pdf_set_annot_active(1); annot.pdf_update_annot(); + + pdf.Dispose(); } internal static void PutScript(PdfObj annotObj, PdfObj key1, PdfObj key2, string value) From 5fbfcd62acfdabea58e689d3d805651468d9df02 Mon Sep 17 00:00:00 2001 From: Maksym Tkachuk Date: Mon, 3 Nov 2025 16:30:36 +0200 Subject: [PATCH 2/2] renamed PdfDocument as pageDoc --- Demo/Program.cs | 98 ++++++++++++++++++++++++++++++++-------------- MuPDF.NET/Annot.cs | 16 ++++---- MuPDF.NET/Page.cs | 40 +++++++++---------- MuPDF.NET/Utils.cs | 32 +++++++-------- 4 files changed, 112 insertions(+), 74 deletions(-) diff --git a/Demo/Program.cs b/Demo/Program.cs index 347942de..4bf3afbc 100644 --- a/Demo/Program.cs +++ b/Demo/Program.cs @@ -35,41 +35,79 @@ class Program { static void Main(string[] args) { - //TestInsertHtmlbox(); - //TestLineAnnot(); - //AnnotationsFreeText1.Run(args); - //AnnotationsFreeText2.Run(args); - //NewAnnots.Run(args); - //TestHelloWorldToNewDocument(args); - //TestHelloWorldToExistingDocument(args); - //TestReadBarcode(args); - //TestReadDataMatrix(); - //TestWriteBarcode(args); - //TestExtractTextWithLayout(args); - //TestWidget(args); - //TestColor(args); - //TestCMYKRecolor(args); - //TestSVGRecolor(args); - //TestReplaceImage(args); - //TestInsertImage(args); - //TestGetImageInfo(args); - //TestGetTextPageOcr(args); - //TestCreateImagePage(args); - //TestJoinPdfPages(args); - //TestFreeTextAnnot(args); - //TestTextFont(args); - //TestMemoryLeak(); - //TestDrawLine(); - //TestWriteBarcode1(); - //TestUnicodeDocument(); - //TestMorph(); - //TestMetadata(); - //TestTable(); + TestInsertHtmlbox(); + TestLineAnnot(); + AnnotationsFreeText1.Run(args); + AnnotationsFreeText2.Run(args); + NewAnnots.Run(args); + TestHelloWorldToNewDocument(args); + TestHelloWorldToExistingDocument(args); + TestReadBarcode(args); + TestReadDataMatrix(); + TestWriteBarcode(args); + TestExtractTextWithLayout(args); + TestWidget(args); + TestColor(args); + TestCMYKRecolor(args); + TestSVGRecolor(args); + TestReplaceImage(args); + TestInsertImage(args); + TestGetImageInfo(args); + TestGetTextPageOcr(args); + TestCreateImagePage(args); + TestJoinPdfPages(args); + TestFreeTextAnnot(args); + TestTextFont(args); + TestMemoryLeak(); + TestDrawLine(); + TestWriteBarcode1(); + TestUnicodeDocument(); + TestMorph(); + TestMetadata(); + TestTable(); TestMoveFile(); + TestOpenErrorAtAcrobat(); return; } + static void TestOpenErrorAtAcrobat() + { + Console.WriteLine("\n=== TestOpenErrorAtAcrobat ====================="); + + string testFilePath = @"E:\MuPDF.NET\Tmp\Peter\1101\test.pdf"; + string outputFilePath = @"E:\MuPDF.NET\Tmp\Peter\1101\output.pdf"; + + Document doc = new Document(testFilePath); + + Page page = doc[0]; + + page.DrawLine(new Point(45, 50), new Point(80, 50), width: 0.5f, dashes: "[5] 0"); + page.DrawLine(new Point(90, 50), new Point(150, 50), width: 0.5f, dashes: "[5] 0"); + page.DrawLine(new Point(45, 80), new Point(180, 80), width: 0.5f, dashes: "[5] 0"); + page.DrawLine(new Point(45, 100), new Point(180, 100), width: 0.5f, dashes: "[5] 0"); + + Color lineColor = new Color(); // Default to black + lineColor.Stroke = new float[] { 0, 0, 0 }; // RGB black + + Shape img = page.NewShape(); + Point startPoint = new Point(100, 100); + Point endPoint = new Point(200, 200); + + String dashString = "[2] 0"; // Example dash pattern + + img.DrawLine(startPoint, endPoint); + img.Finish(width: 2, color: lineColor.Stroke, dashes: dashString); + img.Commit(); + + page.Dispose(); + + doc.Save(outputFilePath); + doc.Close(); + + Console.WriteLine("TestOpenErrorAtAcrobat completed."); + } + static void TestMoveFile() { string origfilename = @"E:\test.pdf"; diff --git a/MuPDF.NET/Annot.cs b/MuPDF.NET/Annot.cs index 03bfa535..1a4e1dfd 100644 --- a/MuPDF.NET/Annot.cs +++ b/MuPDF.NET/Annot.cs @@ -813,7 +813,7 @@ private bool UpdateAppearance( { PdfObj annotObj = _nativeAnnotion.pdf_annot_obj(); PdfPage page = _nativeAnnotion.pdf_annot_page(); - PdfDocument doc = page.doc(); + PdfDocument pageDoc = page.doc(); pdf_annot_type type = _nativeAnnotion.pdf_annot_type(); float[] cols = ColorFromSequence(fillColor); int nCols = cols.Length; @@ -886,7 +886,7 @@ private bool UpdateAppearance( } else if (nCols > 0) { - PdfObj col = doc.pdf_new_array(nCols); + PdfObj col = pageDoc.pdf_new_array(nCols); for (int i = 0; i < nCols; i++) { mupdf.mupdf.pdf_array_push_real(col, cols[i]); @@ -895,17 +895,17 @@ private bool UpdateAppearance( } _nativeAnnotion.pdf_dirty_annot(); _nativeAnnotion.pdf_update_annot(); - doc.m_internal.resynth_required = 0; + pageDoc.m_internal.resynth_required = 0; } catch (Exception e) { - doc.Dispose(); + pageDoc.Dispose(); throw new Exception("cannot update annot:" + e.Message); } if ((opacity < 0 || opacity >= 1) && blendMode == null) // no opacity, no blend_mode { - doc.Dispose(); + pageDoc.Dispose(); return true; } @@ -918,7 +918,7 @@ private bool UpdateAppearance( if (ap.m_internal == null) { // should never happen - doc.Dispose(); + pageDoc.Dispose(); throw new Exception("bad or missing annot AP/N"); } @@ -926,7 +926,7 @@ private bool UpdateAppearance( if (resources.m_internal == null) resources = ap.pdf_dict_put_dict(new PdfObj("Resources"), 2); - PdfObj alp0 = doc.pdf_new_dict(3); + PdfObj alp0 = pageDoc.pdf_new_dict(3); if (opacity >= 0 && opacity < 1) { alp0.pdf_dict_put_real(new PdfObj("CA"), opacity); @@ -951,7 +951,7 @@ private bool UpdateAppearance( Console.WriteLine("cannot set opacity or blend mode"); } - doc.Dispose(); + pageDoc.Dispose(); return true; } diff --git a/MuPDF.NET/Page.cs b/MuPDF.NET/Page.cs index ba2a98aa..d8237831 100644 --- a/MuPDF.NET/Page.cs +++ b/MuPDF.NET/Page.cs @@ -1763,9 +1763,9 @@ public void WriteText( public Annot AddWidget(PdfWidgetType fieldType, string fieldName) { PdfPage page = _pdfPage; - PdfDocument pdf = page.doc(); - PdfAnnot annot = Utils.CreateWidget(pdf, page, fieldType, fieldName); - pdf.Dispose(); + PdfDocument pageDoc = page.doc(); + PdfAnnot annot = Utils.CreateWidget(pageDoc, page, fieldType, fieldName); + pageDoc.Dispose(); if (annot == null) throw new Exception("cannot create widget"); @@ -2063,7 +2063,7 @@ public int InsertImage( FzBuffer maskBuf = new FzBuffer(); PdfPage page = _pdfPage; - PdfDocument pdf = page.doc(); + PdfDocument pageDoc = page.doc(); int w = width; int h = height; int imgXRef = xref; @@ -2083,7 +2083,7 @@ public int InsertImage( if (xref > 0) { - ref_ = pdf.pdf_new_indirect(xref, 0); + ref_ = pageDoc.pdf_new_indirect(xref, 0); w = ref_.pdf_dict_geta(new PdfObj("Width"), new PdfObj("W")).pdf_to_int(); h = ref_.pdf_dict_geta(new PdfObj("Height"), new PdfObj("H")).pdf_to_int(); @@ -2130,7 +2130,7 @@ public int InsertImage( if (temp != -1) { imgXRef = temp; - ref_ = pdf.pdf_new_indirect(imgXRef, 0); + ref_ = pageDoc.pdf_new_indirect(imgXRef, 0); do_process_stream = 0; do_have_imask = 0; do_have_image = 0; @@ -2179,7 +2179,7 @@ public int InsertImage( if (tmp != -1) { imgXRef = tmp; - ref_ = pdf.pdf_new_indirect(imgXRef, 0); + ref_ = pageDoc.pdf_new_indirect(imgXRef, 0); w = ref_.pdf_dict_geta(new PdfObj("Width"), new PdfObj("W")).pdf_to_int(); h = ref_.pdf_dict_geta(new PdfObj("Height"), new PdfObj("H")).pdf_to_int(); do_have_imask = 0; @@ -2223,9 +2223,9 @@ public int InsertImage( if (do_have_image != 0) { - ref_ = pdf.pdf_add_image(image); + ref_ = pageDoc.pdf_add_image(image); if (oc != 0) - Utils.AddOcObject(pdf, ref_, oc); + Utils.AddOcObject(pageDoc, ref_, oc); imgXRef = ref_.pdf_to_num(); digests.Add(Encoding.UTF8.GetString(md5), imgXRef); rcDigest = 1; @@ -2246,7 +2246,7 @@ public int InsertImage( nres.fz_append_string( string.Format(template, mat.a, mat.b, mat.c, mat.d, mat.e, mat.f, imgName) ); - Utils.InsertContents(pdf, page.obj(), nres, overlay); + Utils.InsertContents(pageDoc, page.obj(), nres, overlay); } if (rcDigest != 0) @@ -2254,7 +2254,7 @@ public int InsertImage( doc.InsertedImages = digests; } - pdf.Dispose(); + pageDoc.Dispose(); return imgXRef; } @@ -2850,10 +2850,10 @@ int ordering ) { PdfPage page = GetPdfPage(); - PdfDocument pdf = page.doc(); + PdfDocument pageDoc = page.doc(); FontInfo value = Utils.InsertFont( - pdf, + pageDoc, bfName, fontFile, fontBuffer, @@ -2870,18 +2870,18 @@ int ordering if (fonts.m_internal == null) { - fonts = pdf.pdf_new_dict(5); + fonts = pageDoc.pdf_new_dict(5); Utils.pdf_dict_putl(page.obj(), fonts, new string[2] { "Resources", "Font" }); } if (value.Xref == 0) throw new Exception("cannot insert font"); - PdfObj fontObj = pdf.pdf_new_indirect(value.Xref, 0); + PdfObj fontObj = pageDoc.pdf_new_indirect(value.Xref, 0); fonts.pdf_dict_puts(fontName, fontObj); - pdf.Dispose(); + pageDoc.Dispose(); return value; } @@ -4711,16 +4711,16 @@ public Annot AddWidget(Widget widget) widget.Validate(); PdfPage page = GetPdfPage(); - PdfDocument pdf = page.doc(); + PdfDocument pageDoc = page.doc(); PdfAnnot annot = Utils.CreateWidget( - pdf, + pageDoc, page, (PdfWidgetType)widget.FieldType, widget.FieldName ); if (annot.m_internal == null) { - pdf.Dispose(); + pageDoc.Dispose(); throw new Exception("cannot create widget"); } Utils.AddAnnotId(annot, "W"); @@ -4734,7 +4734,7 @@ public Annot AddWidget(Widget widget) widget._annot = new PdfAnnot(annot); widget.Update(); - pdf.Dispose(); + pageDoc.Dispose(); return annot_; } diff --git a/MuPDF.NET/Utils.cs b/MuPDF.NET/Utils.cs index 2d4e7559..6f1a46a8 100644 --- a/MuPDF.NET/Utils.cs +++ b/MuPDF.NET/Utils.cs @@ -1145,14 +1145,14 @@ public static void GetWidgetProperties(Annot annot, Widget widget) { PdfObj annotObj = mupdf.mupdf.pdf_annot_obj(annot.ToPdfAnnot()); PdfPage page = mupdf.mupdf.pdf_annot_page(annot.ToPdfAnnot()); - PdfDocument pdf = page.doc(); + PdfDocument pageDoc = page.doc(); PdfAnnot tw = annot.ToPdfAnnot(); pdf_widget_type fieldType = tw.pdf_widget_type(); widget.FieldType = (int)fieldType; if (fieldType == (pdf_widget_type)PdfWidgetType.PDF_WIDGET_TYPE_SIGNATURE) { - if (pdf.pdf_signature_is_signed(annotObj) != 0) + if (pageDoc.pdf_signature_is_signed(annotObj) != 0) widget.IsSigned = true; else widget.IsSigned = false; @@ -1262,7 +1262,7 @@ public static void GetWidgetProperties(Annot annot, Widget widget) Utils.pdf_dict_getl(annotObj, new string[] { "AA", "Fo" }) ); - pdf.Dispose(); + pageDoc.Dispose(); } internal static List GetChoiceOptions(PdfAnnot annot) @@ -3932,14 +3932,14 @@ internal static void RefreshLinks(PdfPage page) PdfObj obj = page.obj().pdf_dict_get(new PdfObj("Annots")); if (obj.m_internal != null) { - PdfDocument pdf = page.doc(); - int number = pdf.pdf_lookup_page_number(page.obj()); + PdfDocument pageDoc = page.doc(); + int number = pageDoc.pdf_lookup_page_number(page.obj()); FzRect pageMediabox = new FzRect(); FzMatrix pageCtm = new FzMatrix(); page.pdf_page_transform(pageMediabox, pageCtm); - FzLink link = pdf.pdf_load_link_annots(page, obj, number, pageCtm); + FzLink link = pageDoc.pdf_load_link_annots(page, obj, number, pageCtm); page.m_internal.links = mupdf.mupdf.ll_fz_keep_link(link.m_internal); - pdf.Dispose(); + pageDoc.Dispose(); } } @@ -6385,7 +6385,7 @@ internal static void SaveWidget(PdfAnnot annot, Widget widget) { PdfPage page = annot.pdf_annot_page(); PdfObj annotObj = annot.pdf_annot_obj(); - PdfDocument pdf = page.doc(); + PdfDocument pageDoc = page.doc(); int value = widget.FieldType; int fieldType = value; @@ -6399,7 +6399,7 @@ internal static void SaveWidget(PdfAnnot annot, Widget widget) if (color != null) { int n = color.Length; - PdfObj fillCol = pdf.pdf_new_array(n); + PdfObj fillCol = pageDoc.pdf_new_array(n); float col = 0; for (int i = 0; i < n; i++) { @@ -6413,7 +6413,7 @@ internal static void SaveWidget(PdfAnnot annot, Widget widget) if (borderDashes != null) { int n = borderDashes.Length; - PdfObj dashes = pdf.pdf_new_array(n); + PdfObj dashes = pageDoc.pdf_new_array(n); for (int i = 0; i < n; i++) { dashes.pdf_array_push_int(borderDashes[i]); @@ -6425,7 +6425,7 @@ internal static void SaveWidget(PdfAnnot annot, Widget widget) if (borderColor != null) { int n = borderColor.Length; - PdfObj borderCol = pdf.pdf_new_array(n); + PdfObj borderCol = pageDoc.pdf_new_array(n); float col = 0; for (int i = 0; i < n; i++) { @@ -6526,7 +6526,7 @@ internal static void SaveWidget(PdfAnnot annot, Widget widget) { if (string.IsNullOrEmpty(fieldVal)) { - pdf.pdf_set_field_value(annotObj, "Off", 1); + pageDoc.pdf_set_field_value(annotObj, "Off", 1); annotObj.pdf_dict_put_name(new PdfObj("AS"), "Off"); } else @@ -6535,7 +6535,7 @@ internal static void SaveWidget(PdfAnnot annot, Widget widget) if (onstate.m_internal != null) { string on = onstate.pdf_to_name(); - pdf.pdf_set_field_value(annotObj, on, 1); + pageDoc.pdf_set_field_value(annotObj, on, 1); annotObj.pdf_dict_put_name(new PdfObj("AS"), on); } else if (!string.IsNullOrEmpty(fieldVal)) @@ -6550,7 +6550,7 @@ internal static void SaveWidget(PdfAnnot annot, Widget widget) { PdfObj onstate = annotObj.pdf_button_field_on_state(); string on = onstate.pdf_to_name(); - pdf.pdf_set_field_value(annotObj, on, 1); + pageDoc.pdf_set_field_value(annotObj, on, 1); annotObj.pdf_dict_put_name(new PdfObj("AS"), "Yes"); annotObj.pdf_dict_put_name(new PdfObj("V"), "Yes"); } @@ -6562,7 +6562,7 @@ internal static void SaveWidget(PdfAnnot annot, Widget widget) } else if (!string.IsNullOrEmpty(fieldVal)) { - pdf.pdf_set_field_value(annotObj, fieldVal, 1); + pageDoc.pdf_set_field_value(annotObj, fieldVal, 1); if ( fieldType == (int)PdfWidgetType.PDF_WIDGET_TYPE_COMBOBOX || fieldType == (int)PdfWidgetType.PDF_WIDGET_TYPE_LISTBOX @@ -6574,7 +6574,7 @@ internal static void SaveWidget(PdfAnnot annot, Widget widget) annot.pdf_set_annot_active(1); annot.pdf_update_annot(); - pdf.Dispose(); + pageDoc.Dispose(); } internal static void PutScript(PdfObj annotObj, PdfObj key1, PdfObj key2, string value)