I am using Itext to create pdf files in android using below code:
Document document = new Document();
PdfWriter.getInstance(document, new FileOutputStream(root.getPath() + "/" + System.currentTimeMillis() + ".pdf"));
document.open();
Font chapterFont = FontFactory.getFont("", BaseFont.IDENTITY_H, 16, Font.BOLDITALIC);
Font paragraphFont = FontFactory.getFont("", BaseFont.IDENTITY_H, 12, Font.NORMAL);
Chunk chunk = new Chunk(b.getTitle(), chapterFont);
Chapter chapter = new Chapter(new Paragraph(chunk), 1);
chapter.setNumberDepth(0);
chapter.add(new Paragraph(b.getLead(), paragraphFont));
document.add(chapter);
document.close();
when i use english words it works fine, but when i use arabic or persian words it shows empty lines,
what is the problem? and how can i solve it?
thanks in advance,
step 1 - add font:
Font font= FontFactory.getFont("assets/arial.ttf", BaseFont.IDENTITY_H, 16, Font.NORMAL);
step 2 - add table (in my case) :
PdfPTable table = new PdfPTable(4);
table.setRunDirection(PdfWriter.RUN_DIRECTION_RTL);
table.addCell(new PdfPCell(new Paragraph("بستانکار",font)));
and for RTL use :
setRunDirection(PdfWriter.RUN_DIRECTION_RTL) .
you can use this method in PdfWriter too;
This problem fixed by changing this line:
Font chapterFont = FontFactory.getFont("", BaseFont.IDENTITY_H, 16, Font.BOLDITALIC);
to
Font chapterFont = FontFactory.getFont("assets/arial.ttf", BaseFont.IDENTITY_H, 16, Font.BOLDITALIC);
It's probably a encoding issue, Make sure the default enconding is set to UTF-8.
Related
i am creaing a pdf using with itext libary but i cant able to print rupee symbol in pdf
i have string value to print rupee symbol
<string name="Rs">\u20B9</string>
and my code to add data in to table is below
PdfPTable table1 = new PdfPTable(columnWidths);
table1.setWidthPercentage(100);
table1.getDefaultCell().setUseAscender(true);
PdfPCell cell;
cell = new PdfPCell(new Phrase((R.string.rs)+"2500",StaticValue.FONT_SUBTITLE));
cell.setFixedHeight(28);
cell.setHorizontalAlignment(Element.ALIGN_RIGHT);
table1.addCell(cell);
In your case, maybe the front (StaticValue.FONT_SUBTITLE) does not support the Rupees symbol. So required to use any fonts which support the Rupees Symbol. (For example, fonts such as Lato, Arial, etc.)
Refer the below code snipet,
//Rupees symbol
Font rupeesFont = FontFactory.getFont("assets/font"+FONT_NAME, BaseFont.IDENTITY_H, BaseFont.EMBEDDED, FONT_SIZE);
chunkRupee = new Chunk(getString(R.string.rupee_symbol), rupeesFont);
Where FONT_NAME is the font in asset->font folder which supports Rupees symbol, FONT_SIZE is the required text size and rupee_symbol is "\u20B9"
Paragraph p = new Paragraph();
Chunk chunkContent = new Chunk("Rupees 2500", font);
cell.add(chunkContent); // your content
cell.add(chunkRupee); // rupees symbol
table1.addCell(cell);
I am trying to add some special characters in my Android App Studio generated PDF, but other than °, none of the characters are visible in iText generated pdf. Please help!
Document doc = new Document(PageSize.A4, 15f, 15f, 35f, 25f);
String outPath = Environment.getExternalStorageDirectory()+"/Bar_Fixed_Compressive.pdf";
try {
PdfWriter pdfWriter = PdfWriter.getInstance(doc, new FileOutputStream(outPath));
doc.open();
doc.add(new Paragraph("On increase in the temperature of the bar by " +mEditText4b1113.getText().toString() +"\u00B0 C, the uniform thermal " +
"strain is given by, \n " +"\u03B5 =" +"\u03B1" +"x T " ));
doc.close();
}
i am generating a pdf file. Everything works fine. Now I want to increase the paragraph text size in my pdf document but don't know how.
Here is my code
Font f = new Font(Font.FontFamily.TIMES_ROMAN, 25.0f, Font.BOLD, BaseColor.BLACK);
Chunk c = new Chunk("Ergebnisse");
c.setBackground(BaseColor.RED);
Paragraph p1 = new Paragraph(c);
document.add(p1);
p1.setAlignment(Paragraph.ALIGN_CENTER);
I want the text "Ergebnisse" to get bigger and centered in the middle.
Your code was almost correct:
Font f = new Font(Font.FontFamily.TIMES_ROMAN, 25.0f, Font.BOLD, BaseColor.BLACK);
// you created a font, but you never used it:
Chunk c = new Chunk("Ergebnisse", f);
c.setBackground(BaseColor.RED);
Paragraph p1 = new Paragraph(c);
// you changed the alignment AFTER adding p1 to the document
p1.setAlignment(Paragraph.ALIGN_CENTER);
document.add(p1);
So:
use f when creating the Chunk.
switch the last two lines in your code snippet.
I am currently drawing text on Canvas while using external (non-standard) font, loaded from TTF file. I want to enable kerning for the text I am displaying.
What I want to know is if there is a possibility to read kerning pairs from typeface using Android API.
What I want to know is if there is a possibility to read kerning pairs from typeface using Android API.
There is no public API to read kerning pairs from a TTF file. However, I pulled the relevant code from Apache FOP and you can read the kerning pairs using this library.
Example usage:
TTFFile file = TTFFile.open(getAssets().open("fonts/font.ttf"));
Map<Integer, Map<Integer, Integer>> kerning = file.getKerning();
You can also retrieve other metadata. Example:
TTFFile ttfFile = TTFFile.open(new File("/system/fonts/Roboto-Regular.ttf"));
String name = ttfFile.getFullName(); // "Roboto Regular"
String family = ttfFile.getSubFamilyName(); // "Regular"
int fontWeight = ttfFile.getWeightClass(); // 400
String copyright = ttfFile.getCopyrightNotice(); // "Font data copyright Google 2014"
I want to enable kerning for the text I am displaying.
See:
How to adjust text kerning in Android TextView?
setLetterSpacing(float)
I was willing to use the parser described above using standard Java on Windows. If anyone wants to do it, one needs to use Rectangle instead of Rect. This is just a minor conversion. I also eliminated the directory jaredrummler because it was a bit too long (I kept the copyright comments in the beginning of the files, though). But there are two TTFFile classes in this parser. This code:
TTFFile file;
File ttf = new File("C:\\Windows\\Fonts\\calibri.ttf" );
try { file = TTFFile.open(ttf); }
catch (IOException e) {e.printStackTrace(); }
Map<Integer, Map<Integer, Integer>> kerning = file.getKerning();
Only works if you import the correct class file:
import com.fontreader.truetype.TTFFile;
Finally, the code works but the kerning pairs returned don't work with the paths you convert using:
void vectorize(Path2D.Float path, String s) {
PathIterator pIter;
FontRenderContext frc = new FontRenderContext(null,true,true);
GlyphVector gv;
Shape glyph;
gv = font.createGlyphVector(frc, s);
glyph = gv.getGlyphOutline(0);
pIter = glyph.getPathIterator(null);
while (!pIter.isDone()) {
switch(pIter.currentSegment(points)) {
case PathIterator.SEG_MOVETO:
path.moveTo(points[0], points[1]);
break;
case PathIterator.SEG_LINETO :
path.lineTo(points[0], points[1]);
break;
case PathIterator.SEG_QUADTO :
path.quadTo(points[0], points[1], points[2], points[3]);
break;
case PathIterator.SEG_CUBICTO :
path.curveTo(points[0], points[1], points[2], points[3], points[4], points[5]);
break;
case PathIterator.SEG_CLOSE :
path.closePath();
}
pIter.next();
}
}
And lengths recovered by lens in the following code:
double interchar = fontsize * 0.075;
int size = '}' - ' ' + 1;
Path2D.Float[] glyphs = new Path2D.Float[size];
double[] lens = new double[size];
String chars[] = new String[size];
int i; char c;
char[] s = { '0' };
for (i = 0, c = ' '; c <= '}'; c++, i++) { s[0] = c; chars[i] = new String(s); }
for (i = 0; i < size; i++) {
vectorize(glyphs[i] = new Path2D.Float(), chars[i], tx[i], 0f);
lens[i] = glyphs[i].getBounds2D().getWidth() + interchar;
}
Just to be clear, I display the glyphs using fill in Graphics2D and I translate using the lengths above added to the kerning displacements returned by the library Apache FOP as suggested above, but the result is horrible. The fontsize is standard 1000 as suggested in this discussion and interchar results in 75, after multiplying by the font size. All this seems correct but my manual kerning pairs look far much better than using the kerning pairs from the ttf file.
Is there anyone trained with this library to be able to tell how we are supposed to use these kerning pairs?
Sorry for diverting slightly from the original question but this might complete the information since once one reads the kerning pairs how one uses them correctly on either Windows or Android?
I am generating PDF file using itext lib.
I want to write Arabic words.
When i run the below code, The words characters are reverse displayed.
The used code :
PdfContentByte cb = docWriter.getDirectContent();
BaseFont bfBold = BaseFont.createFont("assets/arial.ttf", BaseFont.IDENTITY_H, BaseFont.EMBEDDED);
createHeadings(cb, document.leftMargin(), 70, "السعر الاجمالي: " + tprice + " L.E.");
.
.
.
private void createHeadings(PdfContentByte cb, float x, float y, String text){
cb.beginText();
cb.setFontAndSize(bfBold, 10);
cb.setTextMatrix(x,y);
cb.showText(text.trim());
cb.endText();
}
This image describes the output of the code above:
http://i.stack.imgur.com/OLoLo.jpg
Please take a look at the Ligatures2 example.
Aren't you forgetting this line:
cb.setRunDirection(PdfWriter.RUN_DIRECTION_RTL);
The setRunDirection() method is necessary when you want iText to write the text from right to left and create ligatures where necessary. This method also exists in the context of tables in which case you apply it to a PdfPCell object instead of to a ColumnText object.
Also, I don't understand why you use this String: "السعر الاجمالي: ". Please use the Unicode notation instead (e.g. something like "\u0644\u0648\u0631\u0627\u0646\u0633 \u0627\u0644\u0639\u0631\u0628"), because using a String like yours can create all kinds of confusion regarding encoding and ligatures. Some editors won't use the correct encoding (changing your text into gibberish); some editors will make ligatures (which isn't what iText expects).
For instance, in your case, I don't know Arabic, so I don't know if it's "\u0627\u0644\u0633\u0639\u0631 \u0627\u0644\u0627\u062c\u0645\u0627\u0644\u064a" or "\u064a\u0644\u0627\u0645\u062c\u0627\u0644\u0627 \u0631\u0639\u0633\u0644\u0627" because I don't know if I have to start to read at the glyph with value \u0627 or at the glyph with value \u064a. In any case: iText expects the first "character" in the String to be the first thing that is read by humans.
Please take a look at the ArabicExample example:
The first line is incorrect, because RTL nor Arabic ligatures are supported when using document.add(). The second line is correct (as far as I know: I can't read Arabic) because I used ColumnText.
This is the code I used:
public static final String FONT = "resources/fonts/NotoNaskhArabic-Regular.ttf";
public static final String ARABIC = "\u0627\u0644\u0633\u0639\u0631 \u0627\u0644\u0627\u062c\u0645\u0627\u0644\u064a";
public void createPdf(String dest) throws IOException, DocumentException {
Document document = new Document();
PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream(dest));
document.open();
Font f = FontFactory.getFont(FONT, BaseFont.IDENTITY_H, BaseFont.EMBEDDED);
Phrase p = new Phrase("This is incorrect: ");
p.add(new Chunk(ARABIC, f));
p.add(new Chunk(": 50.00 USD"));
document.add(p);
p = new Phrase("This is correct: ");
p.add(new Chunk(ARABIC, f));
p.add(new Phrase(": 50.00"));
ColumnText canvas = new ColumnText(writer.getDirectContent());
canvas.setSimpleColumn(36, 750, 559, 780);
canvas.setRunDirection(PdfWriter.RUN_DIRECTION_LTR);
canvas.addElement(p);
canvas.go();
document.close();
}
I used a Phrase, but you can expect the same result when using a Paragraph (Paragraph extends Phrase). Please clarify if this doesn't answer your question. Take into account that most people on StackOverflow don't understand Arabic, so you have to be very explicit when you ask a question and when you say "it doesn't work". As we don't know Arabic, we don't know how it is supposed to work.