How to reduce redundant code when adding content at absolute positions?

Tags: ColumnTextcoordinate systemiText 5

This is part of a app that uses the itextsharp library:

Dim cb As PdfContentByte = writer.DirectContent
cb.SetFontAndSize(Californian, 36)
    "CERTIFICATE OF COMPLETION", 396, 397.91, 0)
cb.SetFontAndSize(Bold_Times, 22)
cb.ShowTextAligned(PdfContentByte.ALIGN_CENTER, name, 396, 322.35, 0)
cb.SetFontAndSize(Bold_Times, 16)
    _hours + " Hours", 297.05, 285.44, 0)
cb.SetFontAndSize(Bold_Times, 16)
    _dates, 494.95, 285.44, 0)
cb.SetFontAndSize(Bold_Times, 16)
cb.ShowTextAligned(PdfContentByte.ALIGN_CENTER, _class1, 396, 250.34, 0)
If Not String.IsNullOrWhiteSpace(_class2) Then
    cb.SetFontAndSize(Bold_Times, 16)
    cb.ShowTextAligned(PdfContentByte.ALIGN_CENTER, _class2, 396, 235.34, 0)
End If
cb.SetFontAndSize(Copper, 16)
    _conf_num + _prefix + " Annual Conference " + _dates, 396, 193.89, 0)
cb.SetFontAndSize(Bold_Times, 13)
cb.ShowTextAligned(PdfContentByte.ALIGN_CENTER, "Some Name", 396, 175.69, 0)
cb.SetFontAndSize(Bold_Times, 10)
    "Some Company Manager", 396, 162.64, 0)
Plenty of lines in this snippet look awfully redundant and in my opinion, this can't be the cleanest way to do things. Unfortunately, I can't figure out how to create a separate function to which I can simply pass some parameters, such as string, x_Cord, y_Cord, tilt. Such a function would then perform the necessary operations on the PdfContentByte.

Posted on StackOverflow on Nov 23, 2012 by Skindeep2366

You're adding content "the hard way". If I were you, I'd write a separate class/factory/method that creates either a Phrase or a Paragraph with the content. For instance:

protected Font f1 = new Font(Californian, 36);
protected Font f2 = new Font(Bold_times, 16);
public Phrase getCustomPhrase(String name, int hours, ...) {
  Phrase p = new Phrase();
  p.add(new Chunk("...", f1));
  p.add(new Chunk(name, f2);
  return p;

Then I would use ColumnText to add the Phrase or Paragraph at the correct position. In the case of a Phrase, I'd use the ColumnText.showTextAligned() method. In the case of Paragraph, I'd use this construction:

ColumnText ct = new ColumnText(writer.DirectContent);
ct.addElement(getCustomParagraph(name, hours, ...));

The former (using a Phrase) is best if you only need to write one line that doesn't need to be wrapped, oriented in any direction you want.

The latter (using a Paragraph in composite mode) is best if you want to add text inside a specific rectangle (defined by the coordinates of the lower-left corner and the upper-right corner).

The approach you've taken works, but... it involves writing PDF syntax almost "manually". That's more difficult and therefore more error-prone. You already discovered that, otherwise you wouldn't ask the question ;-)