itext multiline text in bounding box - java

Does anyone know, how to, in iText, add multiline text in bounding box (with coordinates specified).
I tried
cb.showTextAligned(
PdfContentByte.ALIGN_LEFT,
text,
bounds.getLeft(),
TOTAL_HEIGHT-bounds.getTop(),
0 );
But it does not support newlines.
I also tried
PdfContentByte cb = writer.getDirectContent();
cb.moveText(300,400);
document.add(new Paragraph("TEST paragraph\nNewline"));
This supports newlines but does not react to moveText, so I don't know how to put it at given position or better: bounding box.
I suspect chunks or PdfTemplate or maybe table might help, but i don't (yet) know how to put it together. TIA for help.

Try this:
ColumnText ct = new ColumnText(cb);
Phrase myText = new Phrase("TEST paragraph\nAfter Newline");
ct.setSimpleColumn(myText, 34, 750, 580, 317, 15, Element.ALIGN_LEFT);
ct.go();
parameters of SetSimpleColumn are:
the phrase
the lower left x corner (left)
the lower left y corner (bottom)
the upper right x corner (right)
the upper right y corner (top)
line height (leading)
alignment.

ColumnText ct = new ColumnText(content);
ct.setSimpleColumn(
new Phrase("Very Long Text"),
left=20, bottom=100, right=500, top=500,
fontSize=18, Element.ALIGN_JUSTIFIED);
ct.go(); // for drawing

Related

How to draw a rectangle around multiline text

I am trying to draw a rectangle around multiline text in iText.
The user will be able to enter some lines of text. The font size of the text might be different and it can be formatted (bold, underlined...).
I use this code to draw the text:
ColumnText ct = new ColumnText(cb);
Phrase phrase = new Phrase("Some String\nOther string etc...\n test");
ct.setSimpleColumn(myText......);
ct.addElement(phrase);
ct.go();
I know how to draw a rectangle, but I am not able to draw a rectangle outlining this text.
It sounds as if you are missing only a single piece of the puzzle to meet your requirement. That piece is called getYLine().
Please take a look at the DrawRectangleAroundText example. This example draws the same paragraph twice. The first time, it adds a rectangle that probably looks like the solution you already have. The second time, it adds a rectangle the way you want it to look:
The first time, we add the text like this:
ColumnText ct = new ColumnText(cb);
ct.setSimpleColumn(120f, 500f, 250f, 780f);
Paragraph p = new Paragraph("This is a long paragraph that doesn't"
+ "fit the width we defined for the simple column of the"
+ "ColumnText object, so it will be distributed over several"
+ "lines (and we don't know in advance how many).");
ct.addElement(p);
ct.go();
You define your column using the coordinates:
llx = 120;
lly = 500;
urx = 250;
ury = 780;
This is a rectangle with lower left corner (120, 500), a width of 130 and a height of 380. Hence you draw a rectangle like this:
cb.rectangle(120, 500, 130, 280);
cb.stroke();
Unfortunately, that rectangle is too big.
Now let's add the text once more at slightly different coordinates:
ct = new ColumnText(cb);
ct.setSimpleColumn(300f, 500f, 430f, 780f);
ct.addElement(p);
ct.go();
Instead of using (300, 500) as lower left corner for the rectangle, we ask the ct object for its current Y position using the getYLine() method:
float endPos = ct.getYLine() - 5;
As you can see, I subtract 5 user units, otherwise the bottom line of my rectangle will coincide with the baseline of the final line of text and that doesn't look very nice. Now I can use the endPos value to draw my rectangle like this:
cb.rectangle(300, endPos, 130, 780 - endPos);
cb.stroke();

Java iText Rotate a Link Rectangle

I need to rotate a link rectangle using Java iText.
The original link rectangle appears in red. The rotated link rectangle appears in green.
My code:
PdfReader reader = new PdfReader( "input/blank.pdf" );
PdfStamper stamper = new PdfStamper( reader, new FileOutputStream( "output/blank_stamped.pdf" ) );
Rectangle linkLocation = new Rectangle( 100, 700, 100 + 200, 700 + 25 );
PdfName highlight = PdfAnnotation.HIGHLIGHT_INVERT;
PdfAnnotation linkRed = PdfAnnotation.createLink( stamper.getWriter(), linkLocation, highlight, "red" );
PdfAnnotation linkGreen = PdfAnnotation.createLink( stamper.getWriter(), linkLocation, highlight, "green" );
BaseColor baseColorRed = new BaseColor(255,0,0);
BaseColor baseColorGreen = new BaseColor(0,255,0);
linkRed.setColor(baseColorRed);
linkGreen.setColor(baseColorGreen);
double angleDegrees = 10;
double angleRadians = Math.PI*angleDegrees/180;
stamper.addAnnotation(linkRed, 1);
linkGreen.applyCTM(AffineTransform.getRotateInstance(angleRadians));
stamper.addAnnotation(linkGreen, 1);
stamper.close();
But this code does not rotate the recangle.
Please take a look at the following screen shot:
I have added 5 annotations to a simple Hello World file.
The first two are link annotations. Their position is defined by the rectangles linkLocation1 and linkLocation2:
Rectangle linkLocation1 = new Rectangle(30, 770, 120, 800);
PdfAnnotation link1 = PdfAnnotation.createLink(stamper.getWriter(),
linkLocation1, PdfAnnotation.HIGHLIGHT_INVERT, action);
link1.setColor(BaseColor.RED);
stamper.addAnnotation(link1, 1);
Rectangle linkLocation2 = new Rectangle(30, 670, 60, 760);
PdfAnnotation link2 = PdfAnnotation.createLink(stamper.getWriter(),
linkLocation2, PdfAnnotation.HIGHLIGHT_INVERT, action);
link2.setColor(BaseColor.GREEN);
stamper.addAnnotation(link2, 1);
The green rectangle looks like a rotated version of the red rectangle, but that's not really true: we just defined the "clickable" area that way. I don't understand why you'd want to get this effect by introducing a rotation. Why? Because a rotation always needs a rotating point. Suppose that you would introduce a rotation, what would be your rotation point? The (0, 0) coordinate? That would lead to strange results, wouldn't it?
Introducing a rotation for does make sense for some types of annotations though. In my example, I introduced three stamp annotations:
Rectangle linkLocation3 = new Rectangle(150, 770, 240, 800);
PdfAnnotation stamp1 = PdfAnnotation.createStamp(stamper.getWriter(), linkLocation3, "Landscape", "Confidential");
stamper.addAnnotation(stamp1, 1);
Rectangle linkLocation4 = new Rectangle(150, 670, 240, 760);
PdfAnnotation stamp2 = PdfAnnotation.createStamp(stamper.getWriter(), linkLocation4, "Portrait", "Confidential");
stamp2.setRotate(90);
stamper.addAnnotation(stamp2, 1);
Rectangle linkLocation5 = new Rectangle(250, 670, 340, 760);
PdfAnnotation stamp3 = PdfAnnotation.createStamp(stamper.getWriter(), linkLocation5, "Portrait", "Confidential");
stamp3.setRotate(45);
stamper.addAnnotation(stamp3, 1);
In this case, I introduce a rotation angle using the setRotate() method. This rotates the CONFIDENTIAL stamp inside the rectangle we defined. As you can see, this makes sense because the annotation does have actual content: the rotation has an impact on the way you read the word CONFIDENTIAL. In the case of the clickable area of the link annotation, there is no such content to be rotated.
If this doesn't answer your question, please rephrase your question because I don't think anyone can answer it in its current state.
Update
Please take a look at ISO-32000-1 aka the PDF specification. You'll discover that a rectangle is defined using 4 values: the x and y coordinate of the lower-left corner of the rectangle and the x and y coordinate of the upper-right corner of the rectangle. These are the two starting points of the horizontal and vertical sides. You want a rectangle that has sides that aren't horizontal/vertical. Obviously that isn't possible as you'd need the coordinates of 4 corner points to achieve that (8 values, not 4). You can achieve this using a polygon defined by QuadPoints.
See ITextShape Clickable Polygon or path

Java - Building GRect from the bottom left corner

I'm trying to create a Thermometer where I have an empty(white) stem and when getting a certain degrees Celsius, the stem fills up with mercury(red) by having two separate GRects(one white, the red one overlays the white). The trouble I'm having is that I can't make it seem like the mercury is filling up from the bottom. It either fills "down" starting at the top left corner going down like a normal GRect, or the red doesn't show up at all. I can't figure out how to invert the y coordinates so that it builds up instead of down..... Please help!! Thanks.
This is what I have for the positioning of the stems:
//Empty stem
GRect stemwhite = new GRect(200, 50, 50, 300);
stemwhite.setFilled(true);
stemwhite.setFillColor(Color.WHITE);
add(stemwhite);
//Fill stem
GRect stemred = new GRect(200, 50, 50, 300 * (tempC / 100);
stemred.setFilled(true);
stemred.setFillColor(Color.RED);
add(stemred);
tempC is the degrees Celsius that the user inputs. The only problem with this is the red is at the top of the white stem. I've tried a couple different things, like " -(300 * (tempC / 100); ", but nothing has worked yet.

Correct text position center in rectangle iText

I try to draw text inside rectangle which fit rectangle size, like my previous question, I want text align center in rectangle.
The problem is display text has wrong Y coordinate, look like this one:
And here is my code:
PdfContentByte cb = writer.getDirectContent();
Rectangle rect = new Rectangle(100, 150, 100 + 120, 150 + 50);
cb.saveState();
ColumnText ct = new ColumnText(writer.getDirectContent());
Font font = new Font(BaseFont.createFont());
float maxFontSize;
// try to get max font size that fit in rectangle
font.setSize(maxFontSize);
ct.setText(new Phrase("test", font));
ct.setSimpleColumn(rect.getLeft(), rect.getBottom(), rect.getRight(), rect.getTop());
ct.go();
// draw the rect
cb.setColorStroke(BaseColor.BLUE);
cb.rectangle(rect.getLeft(), rect.getBottom(), rect.getWidth(), rect.getHeight());
cb.stroke();
cb.restoreState();
I even draw text like this:
cb.saveState();
cb.beginText();
cb.moveText(rect.getLeft(), rect.getBottom());
cb.setFontAndSize(BaseFont.createFont(), maxSize);
cb.showText("test");
cb.endText();
cb.setColorStroke(BaseColor.BLUE);
cb.rectangle(rect.getLeft(), rect.getBottom(), rect.getWidth(), rect.getHeight());
cb.stroke();
And got the result:
So I wonder how can itext render text base on the coordinates? Because I use the same rectangle frame for text and rectangle bound.
I'm not sure if I understand your question correctly. I'm assuming you want to fit some text into a rectangle vertically, but I don't understand how you calculate the font size, and I don't see you setting the leading anywhere (which you can avoid by using ColumnText.showAligned()).
I've created an example named FitTextInRectangle which results in the PDF chunk_in_rectangle.pdf. Due to rounding factors (we're working with float values), the word test slightly exceeds the rectangle, but the code shows how to calculate a font size that makes the text fit more or less inside the rectangle.
In your code samples, the baseline is defined by the leading when using ColumnText (and the leading is wrong) or the bottom coordinate of the rectangle when using showText() (and you forgot to take into account value of the descender).

iText: PdfTable cell vertical alignment

I'm trying to vertical align my headet cell text to be in the middle of the cell height.
This is my code:
PdfPCell c1 = new PdfPCell(cerate_phrase("" ,regular_bold ));
c1.setHorizontalAlignment(Element.ALIGN_CENTER);
c1.setVerticalAlignment(Element.ALIGN_MIDDLE);
c1.setBackgroundColor(BaseColor.LIGHT_GRAY);
table_.addCell(c1);
but this does not work. setHorizontalAlignment is centered but not setVerticalAlignment.
Am I doing something wrong? how can i vertically align it in the middle?
Any help will be appreciated.
According to Lowagie:
PdfPCell cell = new PdfPCell(new Phrase("blah Blah blah");
cell.setVerticalAlignment(Element.ALIGN_MIDDLE);
This is always correct in a technical sense, but sometimes looks bad.
To center, draw a box around the object, find its middle, and align it with the center of its surrounding object.
iText thus finds the center of the phrase, and aligns it. But human eyes sometimes focus on the bulk of text, say the parts of the font between the baseline and the cap height. So to have it look good, you need to center relative to that.
Phrase content = new Phrase("Blah blah blah", Font);
Float fontSize = content.getFont().getSize();
Float capHeight = content.getFont().getBaseFont().getFontDescriptor(BaseFont.CAPHEIGHT, fontSize);
Float padding = 5f;
PdfPCell cell = new PdfPCell(content);
cell.setPadding(padding);
cell.setPaddingTop(capHeight - fontSize + padding);
Note that the PdfPCell method setVerticalAlignment(..) isn't used.
It seems like this wouldn't necessarily work for a multi-line phrase, but it does.
The problem would be obvious if iText could show bounding boxes around things (mind, you can tell iText to draw bounding boxes, it's just more work than a magical on/off switch).
This solution is adapted from an email from Paulo Soares.
Add cell.setUseAscender(true) before c1.setVerticalAlignment(Element.ALIGN_MIDDLE);
I have the same problem with you, when add code above I find it can work, hope this can solve your problem, thanks.
You can use the option ExtraParagraphSpace:
c1.HorizontalAlignment = Element.ALIGN_CENTER;
c1.VerticalAlignment = Element.ALIGN_MIDDLE;
c1.ExtraParagraphSpace = 2;
You cant do like this :
cell.setBackgroundColor(BaseColor.GRAY);
cell.setHorizontalAlignment(Element.ALIGN_LEFT);
cell.setVerticalAlignment(Element.ALIGN_MIDDLE);
cell.setUseAscender(true);

Categories

Resources