iText arabic RTL characters not shaped - itext

I am creating a PDF with Arabic & latin mixed data. The arabic comes out unshaped. The code i have is like the Ligatures2 example:
PdfPTable table = new PdfPTable(1);
table.setWidthPercentage(100);
table.getDefaultCell().setBorder(0);
table.setRunDirection(PdfWriter.RUN_DIRECTION_RTL);
ColumnText column = new ColumnText(writer.getDirectContent());
column.setSimpleColumn(0, 0, 1500, 1500);
column.setRunDirection(PdfWriter.RUN_DIRECTION_RTL);
document.add(new Paragraph(line, font));
column.go();

I'm sorry to disagree with you, but your code is nothing like the Ligatures2 example:
You create a PdfPTable object, but you don't add any content to it. You don't add the table to the document.
You create a ColumnText object, but you don't add any content to it. When you perform go() nothing happens.
If we remove all the unused lines from your code snippet, this is what remains:
document.add(new Paragraph(line, font));
As documented in the book that comes with the Ligatures2 example you refer to, this code, this is insufficient to render Arabic.
One way to fix your code would be to do something like this:
ColumnText column = new ColumnText(writer.getDirectContent());
column.setSimpleColumn(36, 36, 559, 806);
column.setRunDirection(PdfWriter.RUN_DIRECTION_RTL);
document.addElement(new Paragraph(line, font));
column.go();
Note that I am making an assumption here: I assume that your page size is A4. In your code, you defined the rectangle of the column like this:
column.setSimpleColumn(0, 0, 1500, 1500);
That's a very strange size.
Side-note:
Please avoid to copy/paste code from examples and then break those examples without reading the documentation that comes with the examples.
I see that (1.) this question isn't the first example of this behavior, and (2.) you don't provide feedback when somebody answers your question. If a question is solved correctly, you should do the right thing and accept the answer!
https://stackoverflow.com/questions/27941538/illegalpdfsyntaxexception-unbalanced-begin-end-operators: no feedback whatsoever on the counter-question. The question can't be answered due to lack of information.
IText font not subsetting or embedding: question reveals a lack of respect for the documentation. It was answered correctly, but the answer was not accepted.
JZOS and iText on z/OS: strange question and no feedback on the answer that was given. Did it solve the problem? One can only guess.

Related

Get Font Properties From Word Document With OpenXML (.NET)

How can I get font properties from word document with OpenXML?
var para = wordDocument.MainDocumentPart.RootElement.Descendants<Paragraph>().ToList();
With the code above, I can only get the paragraphs themselves.
Only font insertion shown in forum.
Please help me..
Although i don't really know, what 'font-properties' means in this context, my answer is: it depends.
styles (templates defining paragraph or run format, etc) are set in MainDocumentPart.StyleDefinitionsPart
formatting properties are defined in RunProperties or ParagraphProperties (applied styles can also be found here)
So if you like to retrieve certain formatting properties, you will have to look inside the openxml-package.

itext placeholder on top of every new page

i try to print invoices on a pre defined template on a piece of paper.
Because of that template i need some placeholders before the invoice is printed to avoid overplap. Sometimes the invoices get a little bit longer so that i need a second invoice page. If the invoice just has one page everything works fine.
My issue:
If the invoice gets longer (second page) the placeholder has to be on the beginning of the second page as well. I was not able to figure out how to do this.
Here is how i do it on first page:
PdfPTable placeholderTable = new PdfPTable(1);
placeholderTable.setHorizontalAlignment(PdfPTable.ALIGN_RIGHT);
placeholderTable.setWidthPercentage(91f);
PdfPCell placeholderCell = new PdfPCell(new Phrase(" ", font4GroßFett));
placeholderCell.setBorder(0);
placeholderTable.addCell(placeholderCell);
document.add(placeholderTable);
I tried a lot of things but especially i think the following is important (maybe i just use it in a wrong way)
writer.setPageEvent(new PdfPageEventHelper() {
#Override
public void onStartPage(final PdfWriter writer, final Document document) {
//add the placeholder here?
}
});
This seemed to be the best solution but i cant add elements to the document in this method (see offical documentation of itext)
My question is now: How can i set some placeholders (space) to the top of EVERY new page?
Thank you very much for helping!

How can I generate a PDF/UA compatible PDF with iText?

We have a number of dynamically generated printable forms files on our site that use iText 4.2.0. However, we also have a large number of users that have print disabilities and use screen readers, like JAWS, to render our PDFs. We use the .setTagged() method to tag the PDFs, but some elements of the PDF appear out of order. Some even become more jumbled after calling setTagged!
I read about PDF/UA in a 2013 interview about iText with Bruno Lowagie, and this seems like something that might help with our problem. However, I have not been able to find a good example of how to generate a PDF/UA document. Can you provide an example? Also, what is the minimum version of iText we will need to generate a PDF/UA compliant PDF document?
Please take a look at the PdfUA example. It explains step by step what is needed to be compliant with PDF/UA. A similar example was presented at the iText Summit in 2014 and at JavaOne. Watch the iText Summit video tutorial.
public void createPdf(String dest) throws IOException, DocumentException {
Document document = new Document(PageSize.A4.rotate());
PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream(dest));
writer.setPdfVersion(PdfWriter.VERSION_1_7);
//TAGGED PDF
//Make document tagged
writer.setTagged();
//===============
//PDF/UA
//Set document metadata
writer.setViewerPreferences(PdfWriter.DisplayDocTitle);
document.addLanguage("en-US");
document.addTitle("English pangram");
writer.createXmpMetadata();
//=====================
document.open();
Paragraph p = new Paragraph();
//PDF/UA
//Embed font
Font font = FontFactory.getFont(FONT, BaseFont.WINANSI, BaseFont.EMBEDDED, 20);
p.setFont(font);
//==================
Chunk c = new Chunk("The quick brown ");
p.add(c);
Image i = Image.getInstance(FOX);
c = new Chunk(i, 0, -24);
//PDF/UA
//Set alt text
c.setAccessibleAttribute(PdfName.ALT, new PdfString("Fox"));
//==============
p.add(c);
p.add(new Chunk(" jumps over the lazy "));
i = Image.getInstance(DOG);
c = new Chunk(i, 0, -24);
//PDF/UA
//Set alt text
c.setAccessibleAttribute(PdfName.ALT, new PdfString("Dog"));
//==================
p.add(c);
document.add(p);
p = new Paragraph("\n\n\n\n\n\n\n\n\n\n\n\n", font);
document.add(p);
List list = new List(true);
list.add(new ListItem("quick", font));
list.add(new ListItem("brown", font));
list.add(new ListItem("fox", font));
list.add(new ListItem("jumps", font));
list.add(new ListItem("over", font));
list.add(new ListItem("the", font));
list.add(new ListItem("lazy", font));
list.add(new ListItem("dog", font));
document.add(list);
document.close();
}
You make the document tagged with the setTagged document, but that's not sufficient. You also need to set document data: the document title needs to be displayed and you need to indicate the language used in the document. XMP metadata is mandatory.
Furthermore you need to embed all fonts. When you have images, you need a alternate description. In the example, we replace the words "dog" and "fox" by an image. To make sure that these images are "read out loud" correctly, we need to use the setAccessibleAttribute() method.
At the end of the example, I added a numbered list. In your duplicate question https://stackoverflow.com/questions/28222490/numbered-list-across-a-page-break-causes-jaws-to-read-numbers-out-of-order-in-it, you claim that the list is not read out loud correctly by JAWS. If you check the PDF file created with the above example, more specifically pdfua.pdf, you'll discover that JAWS reads the document as expected, with the numbers and the text in the right order.
The reason why "it doesn't work" when you try this, is simple. You claim that you are using iText, but you are not. You are using a "gork" of iText. A "gork" is an unofficial "fork" of which God Only Really Knows what's inside. You need the latest iText version to achieve what you want because PDF/UA is a standard dating from 2012 and you are using a version of iText that dates from 2009.
I suggest that you delete that other question because:
it is a duplicate of this question (if you disagree, read my answer: isn't it exactly what you're asking in both questions?),
it is off-topic in the sense that it sounds like "I am using an ancient DVD player and it doesn't want to play my blue ray disks." (I know that you downvoted my correct answer because you don't believe this to be true. So be it. Other people will find this answer valuable and understand that your vote was unfair.)
Please read the final question in The Best iText Questions on StackOverflow to find out what I think about people using unofficial, rogue, obsolete versions of iText.
See also https://stackoverflow.com/questions/25696851/can-itext-2-1-7-or-earlier-can-be-used-commercially

Inserting a table into multiple PDF pages with columnText

I am trying to insert a table into a PDF template. It is successful when the table fits on the page. However, if it is too big then we lose data. I basically just want it to paste what is left of the ColumnText to a next page which looks like page # 5.
Here is my current code, it is creating a blank white page in front of page #4 and it is writing the remaining ColumnText data over where it already pasted the first time.
PdfImportedPage templatePage = stamper.GetImportedPage(pdfReader, 5);
int pageNum = 5;
while (true)
{
ct.SetSimpleColumn(-75, 50, PageSize.A4.Height + 25, PageSize.A4.Width - 200);
if (!ColumnText.HasMoreText(ct.Go()))
break;
pageNum++;
stamper.InsertPage(pageNum, new Rectangle(792f, 612f));
stamper.GetOverContent(pageNum).AddTemplate(templatePage, 0, 0);
}
I've created a small code sample named AddLongTable that you can use to complete your code. The reason why all the content is added to the same page is simple. You forgot this line:
ct.setCanvas(stamper.getOverContent(pageNum));
Note that my example is written in Java, but I'm sure you'll know how to adapt it to C#. If you post your fix in a comment, I'll update my answer, adding the C# version of the solution.

Second page for PDFContentByte

I'm pretty sure I'm missing something simple, but since I've been breaking my head on this for a while, I'm just going to ask.
I'm using JavaScript to access the iText (Java) library to take a filable PDF and serve it up via a browser. The process has worked for my first one, and now I'm doing one where the original fillable PDF has 2 pages. I've been trying to get the second page for a while now. I'm using the PdfContentByte to get it to the browser, and it works except I can't seem to get the PdfContentByte to have a second page. My relevant code is below. When I add the second template (page2) they way I do, it moves what I'm writing, but I'm still just getting one (US letter) page.
This may not be the most efficient code, but like I said, I've been trying a few things on this. If someone has a pointer, I would be very grateful.
var cb:com.itextpdf.text.pdf.PdfContentByte = writer.getDirectContent();
var cb2:com.itextpdf.text.pdf.PdfContentByte = writer.getDirectContent();
var reader2:com.itextpdf.text.pdf.PdfReader = new com.itextpdf.text.pdf.PdfReader(os.toByteArray());
var page:com.itextpdf.text.pdf.PdfImportedPage = writer.getImportedPage(reader2, 1);
cb.addTemplate(page, 0, 0); //this works as expected
var page2:com.itextpdf.text.pdf.PdfImportedPage = writer.getImportedPage(reader2, 2);
// this will add, and with the 100 do an offset, but the
// "physical size" of the paper is the same
cb2.addTemplate(page2, 0, 100);
Have a look at chapter 6 of iText in Action, 2nd edition, especially at subsection 6.4.1: Concatenating and splitting PDF documents.
Listing 6.22, ConcatenateStamp.java, shows you how you should create a PDF from copies of pages of multiple other PDFs; the sample actually additionally adds a new "Page X of Y" footer which you may keep or remove from the sample.