Q:
I use PDFNet to remove certain annotations prior to printing. Sometimes if a user try to print a pdf within the pdf viewer an exception occurs:
Exception
pdftron.Common.PDFNetException
ExceptionMessage
Unknown exception.
CallStack
at pdftron.PDF.PDFDraw.DrawInRect(Page page, Graphics gr, Rect rect)
That doesn’t happen all the time but often enough.
I post the code of the PrintPage handler, maybe you see why the exception occurs.
The code runs in a separate thread parallel to the main thread.
try
{
while (this.printDocList[0].SomePages && this.printDocList[0].PageIterator.HasNext() && this.printDocList[0].PageIterator.GetPageNumber() < e.PageSettings.PrinterSettings.FromPage)
this.printDocList[0].PageIterator.Next();
e.Graphics.PageUnit = GraphicsUnit.Inch;
var rectPage = e.PageBounds;
var hardMarginX = e.PageSettings.HardMarginX;
var hardMarginY = e.PageSettings.HardMarginY;
var left = (rectPage.Left - hardMarginX) / 100.0;
var right = (rectPage.Right - hardMarginX) / 100.0;
var top = (rectPage.Top - hardMarginY) / 100.0;
var bottom = (rectPage.Bottom - hardMarginY) / 100.0;
using(var pageRectangle = new Rect(left * 72, bottom * 72, right * 72, top * 72))
{
using (var pdfDraw = new PDFDraw())
{
pdfDraw.SetDPI(450);
var page = this.printDocList[0].PageIterator.Current();
if (!this.printDocList[0].PrintAnnotations)
{
var annotCount = page.GetNumAnnots();
var annotType = Annot.Type.e_Unknown;
for (var annotIndex = 0; annotIndex < annotCount; )
{
using (Annot annot = page.GetAnnot(annotIndex))
{
if (!annot.IsValid())
{
annotIndex++;
continue;
}
annotType = annot.GetType();
if (annotType != Annot.Type.e_Caret || annotType == Annot.Type.e_Text)
page.AnnotRemove(annotIndex);
else
annotIndex++;
}
}
}
if (page.GetPageWidth() > page.GetPageHeight())
page.SetRotation(Page.Rotate.e_90);
pdfDraw.DrawInRect(page, e.Graphics, pageRectangle);
}
this.printDocList[0].PageIterator.Next();
if (this.printDocList[0].SomePages && this.printDocList[0].PageIterator.GetPageNumber() > e.PageSettings.PrinterSettings.ToPage)
e.HasMorePages = false;
else
e.HasMorePages = this.printDocList[0].PageIterator.HasNext();
}
}
catch (WillisException wEx)
{
this.Invoke((MethodInvoker)delegate { WillisException.ShowException(wEx); });
}
catch (Exception ex)
{
this.Invoke((MethodInvoker)delegate { WillisException.ShowException(new WillisException(Resources.CancelPrintExceptionMessage, ex)); });
}
A:
The first bug is in your code that removes text annotation.
Because PDF annotations are stored in an array you need to remove the annotation is the reverse order.
for (int i = page.GetNumAnnots.Size()-1; i>=0; --i) {
Annot annot = page.GetAnnot(i);
if (annot.GetType() == Annot.Type.e_Text) page.AnnotRemove(i);
}
The second issue is that because you are accessing the document from a separate thread you need to call doc.Lock() / doc.Unlock(). Otherwise you may run into a race condition with the main thread. If you would like to have 2 fully independent threads you should open a separate PDFDoc instance pointing to the same file on disk (in this case you don’t need to lock the document).
For printing, you may want to use ‘pdftron.PDF.Print.StartPrintJob()’ instead of PDFDraw. If the physical dimensions of PDF page are very large you could potentially run out of memory with PDFDraw. StartPrintJob() generates a vector spool format so memory is not an issue.