Michel Melhem
Michel Melhem

Reputation: 681

Rotate text using pdfbox

I'm trying to rotate text using pdfbox by I couldn't achieve it. I tried to set the texMatrix but my text is not rotating as intended.

Does someone have an idea of how I could turn at 90 degrees my text?

This is my code :

contentStream.beginText();

 float tx = titleWidth / 2;
 float ty = titleHeight / 2;

contentStream.setTextMatrix(Matrix.getTranslateInstance(tx, ty)); 
contentStream.setTextMatrix(Matrix.getRotateInstance(Math.toRadians(90),tx,ty));
contentStream.setTextMatrix(Matrix.getTranslateInstance(-tx, -ty));

 contentStream.newLineAtOffset(xPos, yPos);

contentStream.setFont(font, fontSize);
contentStream.showText("Tets");
contentStream.endText();

Thank You

Upvotes: 6

Views: 5463

Answers (2)

JBWanscher
JBWanscher

Reputation: 370

This example rotates around the left baseline of the text and uses the matrix translation to position the text at the specific point. The showText() is always positioned at 0,0, which is the position before the rotation. The matrix translation then positions the text after the rotation.

If you want another rotation point of your text relocation the text rotation position in the contentStream.newLineAtOffset(0, 0)-line

float angle = 35;
double radians = Math.toRadians(angle);
for (int x : new int[] {50,85,125, 200}) 
  for (int y : new int[] {40, 95, 160, 300}) {
    contentStream.beginText();
    
    // Notice the post rotation position
    Matrix matrix = Matrix.getRotateInstance(radians,x,y);
    contentStream.setTextMatrix(matrix);

    // Notice the pre rotation position
    contentStream.newLineAtOffset(0, 0);

    contentStream.showText(".(" + x + "," + y + ")");
    contentStream.endText();
  }

To get the height and the width of the text you want to rotate use font.getBoundingBox().getHeight()/1000*fontSize and font.getStringWidth(text)/1000*fontSize.

Upvotes: 1

Tilman Hausherr
Tilman Hausherr

Reputation: 18851

Here's a solution that draws three pages, one with text unrotated, one with text rotated but keeping the coordinates as if planning landscape printing, and one that is what you wanted (rotated around the center of the text). My solution is close to that, it rotates around the bottom of the center of the text.

public static void main(String[] args) throws IOException
{
    PDDocument doc = new PDDocument();
    PDPage page1 = new PDPage();
    doc.addPage(page1);
    PDPage page2 = new PDPage();
    doc.addPage(page2);
    PDPage page3 = new PDPage();
    doc.addPage(page3);

    PDFont font = PDType1Font.HELVETICA;
    float fontSize = 20;
    int xPos = 100;
    int yPos = 400;
    float titleWidth = font.getStringWidth("Tets") / 1000;
    float titleHeight = fontSize;
    float tx = titleWidth / 2;
    float ty = titleHeight / 2;

    try (PDPageContentStream contentStream = new PDPageContentStream(doc, page1))
    {
        contentStream.beginText();

        contentStream.newLineAtOffset(xPos, yPos);

        contentStream.setFont(font, fontSize);
        contentStream.showText("Tets");
        contentStream.endText();
    }

    // classic case of rotated page
    try (PDPageContentStream contentStream = new PDPageContentStream(doc, page2))
    {
        contentStream.beginText();

        Matrix matrix = Matrix.getRotateInstance(Math.toRadians(90), 0, 0);
        matrix.translate(0, -page2.getMediaBox().getWidth());

        contentStream.setTextMatrix(matrix);

        contentStream.newLineAtOffset(xPos, yPos);

        contentStream.setFont(font, fontSize);
        contentStream.showText("Tets");
        contentStream.endText();
    }

    // rotation around text
    try (PDPageContentStream contentStream = new PDPageContentStream(doc, page3))
    {
        contentStream.beginText();

        Matrix matrix = Matrix.getRotateInstance(Math.toRadians(90), 0, 0);
        matrix.translate(0, -page3.getMediaBox().getWidth());

        contentStream.setTextMatrix(matrix);

        contentStream.newLineAtOffset(yPos - titleWidth / 2 - fontSize, page3.getMediaBox().getWidth() - xPos - titleWidth / 2 - fontSize);

        contentStream.setFont(font, fontSize);
        contentStream.showText("Tets");
        contentStream.endText();
    }
    doc.save("saved.pdf");
    doc.close();
}

Upvotes: 7

Related Questions