Coming from itextsharp, where you can use ColumnText to place text at specific coordinates like so:
ColumnText ct = new ColumnText(cb);
ct.SetSimpleColumn(DrawingSpace.llx, DrawingSpace.lly, DrawingSpace.urx, DrawingSpace.ury);
And then calculate the height of where you are able to draw next:
ct.Go(SimulateOnlyForHeight);
var lowestText = ct.YLine + (float)Math.Floor(ListFont.GetCalculatedBaseFont(false).GetFontDescriptor(BaseFont.DESCENT, ListFont.Size));
return DrawingSpace.y - lowestText;
I thought transitioning to itext7 would be relatively painless. This has not been my experience. I cannot get the things to cooperate and the way that Rectangles are placed and moved around on the Canvas seems to be counter-intuitive -- the rectangles grow upwards from the starting Y value, margin values are added seemingly randomly in places such as ParagraphRenderer.cs from the itext7 source code, and generally the text just seems to bounce around.
Also, to be clear, setting a fixed position on a paragraph and adding that to our page seemed to encounter the same issues with Y values. If I use .SetFixedPosition(llx, lly, width) on the paragraph, it's too far down, if it's written using ury, its too far up.
here is my code, along with the horizontal line drawing function i've been using to test y values
static void Main(string[] args)
{
float llx = 71.001f;
float urx = 720.9f;
float lly = 495f;
float ury = 561;
float calcwidth = urx - llx; // this equals 649.9f in our case
float calcheight = ury - lly; //this equals 66f in our case
float PageMarginSize = 35; // Page margins
float PageTopMarginSize = 38; // Page top margin
string filePath = "PATH TO FILE EXAMPLE";
string fontpath = "PATH TO FONT EXAMPLE";
PdfFont font = PdfFontFactory.CreateFont(fontpath + "Trade Bold.ttf", "CP1252", PdfFontFactory.EmbeddingStrategy.PREFER_EMBEDDED);
PdfDocument pdfdocument = new PdfDocument(new PdfWriter(filePath));
Document document = new Document(pdfdocument, PageSize.LETTER.Rotate());
document.SetMargins(PageTopMarginSize, PageMarginSize, PageMarginSize, PageMarginSize);
PdfPage page = pdfdocument.AddNewPage();
PdfCanvas pdfCanvas = new PdfCanvas(page);
DrawHorizontalDottedLine(ref pdfdocument, new DeviceRgb(0, 0, 0), llx,
lly, 400f);
DrawHorizontalDottedLine(ref pdfdocument, new DeviceRgb(0, 0, 255), llx,
lly, 400f);
Rectangle rectangle = new Rectangle(llx, lly, calcwidth, 52f);
pdfCanvas.SetFillColor(new DeviceRgb(255, 250, 250));
pdfCanvas.Rectangle(rectangle);
pdfCanvas.FillStroke();
Canvas canvas = new Canvas(pdfCanvas, rectangle);
Paragraph paragraph = new Paragraph().Add("Example Text")
.SetFontSize(52f).SetFontColor(new DeviceRgb(204, 0, 0))
.SetFixedLeading(52f)
.SetFont(font);
paragraph.SetProperty(Property.MARGIN_TOP, UnitValue.CreatePointValue(0));
paragraph.SetProperty(Property.MARGIN_BOTTOM, UnitValue.CreatePointValue(0));
canvas.Add(paragraph);
canvas.Close();
pdfdocument.Close();
}
public static void DrawHorizontalDottedLine(
ref PdfDocument pdfDocument, DeviceRgb lineColor, float x, float y, float width,
float weight = 1f)
{
PdfCanvas canvas = new PdfCanvas(pdfDocument.GetLastPage());
canvas.SetTextRenderingMode(0);
// Set CMYK stroke color
canvas.SetStrokeColor(lineColor);
// Set line dash pattern
canvas.SetLineDash(0);
// Draw horizontal dotted line
canvas.MoveTo(x, y)
.LineTo(x + width, y);
canvas.SetLineWidth(weight);
canvas.Stroke();
}
I've been under the impression that under Itext7's workflow we would want to use llx and ury to draw a rectangle, create a canvas from it, create a paragraph, and that paragraph will be added to the canvas and flow through.
Generally I am very confused. The rectangle when added seems to start at the ury value and then be built upwards, depending on height or font size instead of being bounded by llx and ury and the text being written inside of that area, downwards. You will also note that I was playing around with .SetProperty, which was another conundrum. When I downloaded the source code, I noticed that within ParagraphRenderer.cs, we apply margins to the rectangle (parentBBox) seemingly arbitrarily?
I would very much appreciate if someone could explain the proper way to add a block of text at a given set of coordinates. Thank you!
