iText placement of Phrase within ColumnText - java

So I'm dealing with a situation where I have a Phrase added to a ColumnText object.
The title in black is where iText is placing the text of the Phrase within the ColumnText. The title in pink is the desired placement.
private void addText(PdfContentByte contentByte, PdfReader threePagesReader, Project project, CoverTemplate coverTemplate)
throws DocumentException {
ColumnText columnText = new ColumnText(contentByte);
// This only affects the space between Phrases, not the space between the top of the
//ColumnText and the first Phrase
int extraParagraphSpace = 12;
columnText.setExtraParagraphSpace(extraParagraphSpace);
Phrase mainTitle = new Phrase(project.getTitle(),buildCoverFont(coverTemplate.getFontSizeLine1()));
columnText.addText(mainTitle);
... <other code that is not pertinent to this question>
//these values are calculated from values that will place this columnText onto the PDF
//template
columnText.setSimpleColumn(llx, lly, urx, ury);
columnText.go();
private Font buildCoverFont(float fontSize) {
Font font = FontFactory.getFont(FONT_ARIAL, BaseFont.WINANSI, BaseFont.EMBEDDED, fontSize, Font.NORMAL, CMYK_BLACK);
BaseFont baseFont = font.getBaseFont();
if (baseFont != null) {
baseFont.setSubset(false); // fully embedded as per requirements
}
return font;
}
Is there anything I can do to tell iText not to put any space between the top of the highest glyphs (D and Z in this case) and the top of the ColumnText box?
I tried looking at the BaseFont.getAscension() to see if there was any value available, but it ended up 0 anyway.

Please take a look at the ColumnTextAscender example:
In both cases, I have drawn a red rectangle:
rect.setBorder(Rectangle.BOX);
rect.setBorderWidth(0.5f);
rect.setBorderColor(BaseColor.RED);
PdfContentByte cb = writer.getDirectContent();
cb.rectangle(rect);
To the left, you see the text added the way you do. In this case, iText will add extra space commonly known as the leading. To the right, you see the text added the way you want to add it. In this case, we have told the ColumnText that it needs to use the Ascender value of the font:
Phrase p = new Phrase("This text is added at the top of the column.");
ColumnText ct = new ColumnText(cb);
ct.setSimpleColumn(rect);
ct.setUseAscender(true);
ct.addText(p);
ct.go();
Now the top of the text touches the border of the rectangle.

Related

Java JTextPane changes line height when UTF8 character is added

I am using Java JDK 1.6 and have a problem using JTextPane to show text with a monospaced font. As soon as I add a UTF8-character like 😂, the line height in the textpane is reduced (for all the text already in the pane and also all text added later). How can I avoid this? I would like to have the normal line height.
Here is some sample code:
class AttributedTextPane extends JTextPane
{
private DefaultStyledDocument defaultStyledDocument;
protected AttributedTextPane()
{
this.defaultStyledDocument = new DefaultStyledDocument();
this.setDocument(defaultStyledDocument);
this.setContentType("text/plain");
...
}
}
...
This pane is integrated into an JInternalFrame. Creating the panel and setting the desired monospaced font:
Font font = new Font("DejaVu Sans Mono", Font.PLAIN, 11);
AttributedTextPane pane = new AttributedTextPane();
pane.setFont(font);
To display the desired text, I call pane.setText(...); As soon as I add the UTF8 character, the line height changes, see screenshot at http://i.imgur.com/Fq7XBJB.png. Is there a way to avoid that the line height is changed?
Thanks, Deejay
You could try setting/forcing a line height like so:
MutableAttributeSet jTextPaneSet = new SimpleAttributeSet(pane.getParagraphAttributes());
StyleConstants.setLineSpacing(jTextPaneSet, 1.5f); //replace float 1.5f with your desired line spacing/height
Source:
http://docs.oracle.com/javase/8/docs/api/javax/swing/JTextPane.html#setParagraphAttributes(javax.swing.text.AttributeSet,%20boolean)
https://docs.oracle.com/javase/7/docs/api/javax/swing/text/StyleConstants.html#setLineSpacing(javax.swing.text.MutableAttributeSet,%20float)
Old question but I have been struggling with it for some time, though with a JTextArea. The solution is to have either a VM param -Di18n=true or put the i18n property in the document.
My test code:
import javax.swing.JTextArea;
public class Test {
public static void main(String[] argv) {
JTextArea ta = new JTextArea();
//ta.getDocument().putProperty("i18n", Boolean.TRUE);
ta.setText("A");
System.out.println(ta.getPreferredSize()); // - height 16 without i18n and using default font, 15 with i18n
ta.setText("\ud8ff\udc05"); // surrogate pair
System.out.println(ta.getPreferredSize()); // - height 15
ta.setText("A");
System.out.println(ta.getPreferredSize()); // - height 15
}
}
When i18n is not enabled and the document is appended, the elements that are created are PlainView/WrappedPlainView that return the height based on the FontMetrics height.
When i18n is enabled the elements are PlainParagraph that contain GlyphView that calculates the height differently.
When i18n is not enabled and the document is appended with a surrogate pair then due to SwingUtilities2.isComplexLayout returning true, the i18n property is automatically set to true for the document and then all elements are created as PlainParagraph containing GlyphView that return the different (always smaller?) height.

Add paragraph from a document to another document

After I solved my problem on docx4j previously, I'm be able to use it now.
I just try to run the sample code from this link
http://www.smartjava.org/content/create-complex-word-docx-documents-programatically-docx4j
with some modification.
let's say I have two documents.
One is main template that have about 2-3 pages.
Second one have only 1 paragraph of text with various of style (Bold, Italic, Underline, Font Size, etc).
I want to replace a parameter in my template with a paragraph in the second document.
The result is it can replace my parameter with a paragraph but there is a problem with style. What I can observe with many experiment is:
Indent still there
New Line still there
Underline move along too
Font Color/ Font Size is working
Bold/Italic not come along
Font Family not come along
Here is my code
private static void replaceParagraph2(String placeholder, WordprocessingMLPackage template, ContentAccessor addTo) throws Exception {
//get the paragraph
WordprocessingMLPackage paragraph_template = getTemplate("./resources/input/paragraph.docx");
List<Object> paragraphs_LineList = getAllElementFromObject(paragraph_template.getMainDocumentPart(), P.class);
// get the template
List<Object> template_lineList = getAllElementFromObject(template.getMainDocumentPart(), P.class);
int position = 0;
P toReplace = null;
//find placeholder position
for (Object p : template_lineList) {
List<Object> texts = getAllElementFromObject(p, Text.class);
for (Object t : texts) {
Text content = (Text) t;
if (content.getValue().equals(placeholder)) {
toReplace = (P) p;
position = template_lineList.indexOf(toReplace);
break;
}
}
}
//add paragraph into template
for (int i = 0; i < paragraphs_LineList.size(); i++) {
P para = (P) XmlUtils.deepCopy(paragraphs_LineList.get(i));
addTo.getContent().add(position + 1 + i, para);
}
// remove the placeholder on the template
((ContentAccessor)toReplace.getParent()).getContent().remove(toReplace);
}
Do I missing something?
PS. I debug to check the object of template. It seems that bold value in the P object is config to null. (It's booleanTrueifNull type I think.)
The formatting comes from direct formatting (in rPr and pPr elements in the paragraph), and also from the styles part. If no style is specified, the default styles will be used.
You'll need to look at the XML in your paragraph, and in the styles part.
Microsoft Word (2010 at least) has a useful "Reveal Formatting" sidebar which can help you to understand where the formatting is coming from. Click the "distinguish style source" at the bottom.
There is code in docx4j (used by its PDF output) to determine the effective formatting. I guess you could use that to specifically apply the effective formatting from your source to each run in your target.

How to add a FormField to section without a position using iText?

In want to add interactive formfields like checkboxes to a newly created multiple page PDF, in the example from iText the code looks like this:
PdfContentByte canvas = writer.getDirectContent();
Rectangle rect = new Rectangle(180, 806 * 40, 200, 788 * 40);
RadioCheckField checkbox = new RadioCheckField(writer, rect, "box1", "Yes");
PdfFormField field = checkbox.getCheckField();
writer.addAnnotation(field);
ColumnText.showTextAligned(canvas, Element.ALIGN_LEFT, new Phrase("checkbox1", normal), 210, 790 * 40, 0);
But this uses absolute positions and I don't know the position because the content before the field has optional images and text parts, where I don't know how many lines they take.
I am also using Chapters and Sections, so I would like to use something like this:
Section section = chap.addSection(new Paragraph("sectionTitel",header2));
section.add(new Paragraph("line before field"));
//add FormField
section.add(field);
section.add(new Paragraph("line after field"));
Have you an idea how to do something like this or how to get the position from the line before ?
Check this example for displaying checkboxes or radiobuttons without specifying positions. You need to use PdfPTable. http://itextpdf.com/sandbox/acroforms/CreateRadioInTable . There is one issue for displaying radiobuttons on multiple pages which I have posted here Issue with iText RadioCheckField when displayed on multiple pages and still waiting for answers

I want to change fontsize in textflow or label

I'm implementing multiline Label Figure.
I have a question.
How can i change font size of textflow ?
I tried with the method [textflow.setFont] before I had changed height value of fontdata.
use this code,Font tFont = m_Textflow.getFont();
FontData[] tFontDataList = tFont.getFontData();
tFontDataList[0].setHeight(aSize);
m_Textflow.setFont(new Font(null, tFontDataList[0]));
But that didn’t work correctly and made any space on head.
Help me please T^T
See the Font API. You'll find the constructor
Font(String name, int style, int size) -
Creates a new Font from the specified name, style and point size.
So you could do something like
String family = textFlow.getFont().getFamily();
int style = textFlow.getFont().getStyle();
int theNewFontSize = 30;
textFlow.setFont(new Font(family, style, theNewFontSize));

Drawing diagonal line in a cell of a table in iTExt?

I'm creating a table in iText, but I've a problem with a cell that could be divided by a diagonal line. Someone know how can I do that?
The easiest way would be via an onGenericTag handler in a PdfPageEvent.
You give the contents of that cell a generic tag via Chunk.setGenericTag(String tag), and set up a PdfPageEvent hanlder that will draw your line when that chunk is drawn.
Something like:
public class MyPdfPageEvent extends PdfPageEventHelper {
public void onGenericTag(PdfWriter writer, Document doc, Rectangle rect, String tag) {
PdfContentByte canvas = writer.getDirectContent();
canvas.saveState();
canvas.setColorStroke(Color.BLACK); // or whatever
// You can also mess with the line's thickness, endcaps, dash style, etc.
// Lots of options to play with.
canvas.moveTo(rect.getLeft(), rect.getBottom());
canvas.lineTo(rect.getRight(), rect.getTop());
canvas.stroke();
canvas.restoreState();
}
}
Well. The answer of #Mark Storer was helpful, in this case there was a cell of a table I used "PdfPCellEvent" to inherid this methods.
Thanks Mark!

Categories

Resources