I'm using iTextSharp to draw markup graphics in PDF documents, using PdfAnnotation.CreateInk. I'm trying to draw rectangles, passing in an array of five co-ordinates. I know iTextSharp has a dedicated function for drawing rectangles, but I'm trying to use just one method to draw the various kinds of markup lines I need, and it seems that CeateInk should be able to do that.
The problem is that CreateInk is drawing the rectangle with curves rather than corners. I haven't been able to figure out how to change this. This answer suggests that the solution might be to create a PdfAppearance; I haven't yet figured out whether that will work. Here's my code (the first bit converts a list of list of points to an array of arrays, which InkList requires):
public void MarkupInk(List<List<float>> InkList){
float[][] Coords = new float[InkList.Count][];
for (int i = 0; i < InkList.Count; i++) {
float[] thisarr = InkList [i].ToArray ();
Coords[i] = new float[InkList[i].Count];
System.Array.Copy (thisarr, Coords [i], InkList [i].Count);
}
using(MemoryStream ms = new MemoryStream ()){
PdfReader reader = new PdfReader (textmaster.pdfDocArr);
PdfStamper stamper = new PdfStamper (reader, ms);
pagerect = reader.GetPageSize (textmaster.currentfirstpage + 1);
PdfAnnotation an2 = PdfAnnotation.CreateInk (stamper.Writer, pagerect, "", Coords);
an2.Color = strokeColor;
an2.BorderStyle = new PdfBorderDictionary (strokeWeight, PdfBorderDictionary.STYLE_SOLID);
stamper.AddAnnotation (an2, textmaster.currentfirstpage+1);
stamper.Close ();
textmaster.pdfDocArr = ms.ToArray ();
reader.Close ();
}
}
Any suggestions are much appreciated. Thanks!
EDIT: following @mkl's code I now have code that creates PDFAnnotations with appearances. And most of those annotations show up correctly in the viewing applications I use. But there is one odd behavior that I have not been able to fix.
What's happening is that the most recently created annotation does not appear in the viewing applications until I've created another annotation. So if I create annotation A, it's invisible until I create annotation B, at which point annotation A appears and B does not. Creating annotation C causes annotation B to appear, and so on.
This behavior persists even if I close the pdf file and the viewing application and re-load from disk. So the data describing the last-created annotation exists as part of the pdf file, but it doesn't render until I've created a new annotation.
I suspect there's something I'm still missing in the code I'm using to create the annotations and pdfAppearances. Here's code that creates a single line annotation:
public void WriteLineAnnotation(List<float> polyCoords){
using (MemoryStream ms = new MemoryStream ()) {
PdfReader reader = new PdfReader (textmaster.pdfDocArr);
PdfStamper stamper = new PdfStamper (reader, ms) { AnnotationFlattening = true };
pagerect = reader.GetPageSize (textmaster.currentfirstpage + 1);
//Create the pdfAnnotation polyline
PdfAnnotation polyann = PdfAnnotation.CreatePolygonPolyline (stamper.Writer, pagerect, "", false, new PdfArray (polyCoords.ToArray ()));
polyann.Color = strokeColor;
polyann.BorderStyle = new PdfBorderDictionary (strokeWeight, PdfBorderDictionary.STYLE_SOLID);
polyann.Flags = iTextSharp.text.pdf.PdfAnnotation.FLAGS_PRINT;
//create the PdfAppearance and set attributes
PdfAppearance app = PdfAppearance.CreateAppearance (stamper.Writer, pagerect.Width, pagerect.Height);
app.SetColorStroke (strokeColor);
app.MoveTo (polyCoords [0], polyCoords [1]);
app.LineTo (polyCoords [2], polyCoords [3]);
app.Stroke ();
//set the annotation's appearance, add annotation, clean up
polyann.SetAppearance (PdfName.N, app);
stamper.AddAnnotation (polyann, textmaster.currentfirstpage + 1);
stamper.Close ();
reader.Close ();
//create bytearray from memorystream and send to pdf renderer
textmaster.pdfDocArr = ms.ToArray ();
}
}
[/code]
Is there something obvious that I'm missing? Thanks in advance for any help.