user12636046
user12636046

Reputation:

Hindi string is not resolved properly on PDF

I am trying to add hindi text using mangal font on PDF.

ISSUE: Some characters are not being resolved properly for hindi strings. Mostly of which consists of 'choti e matra', 'r matra' and characters with 'halanth'. Kindly provide a solution.

public static void main(String[] args) throws FileNotFoundException, DocumentException {
        Document document = new Document();
        PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream(DEST));
        document.open();
        FontFactory.register("C:\\Users\\Downloads\\Mangal Regular\\Mangal Regular.ttf");
        Font f1 =FontFactory.getFont("Mangal", BaseFont.IDENTITY_H, true);
        String str="रिन्यूअल सूचना";     //sample text

        Phrase p = new Phrase(str,f1);

        document.add(p);
        document.close();
    }

NOTE: The text being generated on PDF when copied and pasted to word, is resolved correctly.

Attached the screenshot of the PDF generated after executing the above code.

screenshot of PDF

screenshot of same content copied on Word from same PDF

Upvotes: 2

Views: 4014

Answers (3)

stacky
stacky

Reputation: 820

For Itext5 and Hindi, I used the workaround of this site (http://hrishikeshbanik.blogspot.com/2013/11/indic-script-like-bengali-hindi-support.html) : Convert text to image whith the font Google Font NotoSans

 com.itextpdf.text.Image png = com.itextpdf.text.Image.getInstance(textToImage(TEXT_HINDI,font));
       png.scalePercent(50f);
Paragraph p = new Paragraph();
p.add(png)
...

Method "textToImage"

public static byte[] textToImage(String text,  java.awt.Font fnt) throws IOException, FontFormatException {        
BufferedImage img = new BufferedImage(1, 1, BufferedImage.TYPE_INT_ARGB);
        try{
            Graphics2D g2d = img.createGraphics();
            g2d.setFont(fnt);
            FontMetrics fm = g2d.getFontMetrics();
            int width = fm.stringWidth(text) ;
            int height = fm.getHeight();
            g2d.dispose();

            img = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
            g2d = img.createGraphics();
            g2d.setRenderingHint(RenderingHints.KEY_ALPHA_INTERPOLATION, RenderingHints.VALUE_ALPHA_INTERPOLATION_QUALITY);
            g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
            g2d.setRenderingHint(RenderingHints.KEY_COLOR_RENDERING, RenderingHints.VALUE_COLOR_RENDER_QUALITY);
            g2d.setRenderingHint(RenderingHints.KEY_DITHERING, RenderingHints.VALUE_DITHER_ENABLE);
            g2d.setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS, RenderingHints.VALUE_FRACTIONALMETRICS_ON);
            g2d.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
            g2d.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
            g2d.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_PURE);

            g2d.setFont(fnt);
            fm = g2d.getFontMetrics();
            g2d.setBackground(Color.WHITE);
            g2d.setColor(Color.BLACK);
            g2d.drawString(text, 0, fm.getAscent());
            g2d.dispose();
        }catch(Exception e){
            e.printStackTrace();
        }
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        ImageIO.write( img, "png", baos );
        baos.flush();
        byte[] imageInByte = baos.toByteArray();
        baos.close();

        return imageInByte;
    }

Upvotes: 0

rhens
rhens

Reputation: 4871

iText 5 does not fully support rendering of Hindi text. If you want to use iText, you'll have to use iText 7 with the pdfCalligraph add-on.

PdfDocument pdfDoc = new PdfDocument(new PdfWriter("hindi.pdf"));
Document doc = new Document(pdfDoc);
PdfFont f = PdfFontFactory.createFont("FreeSans.ttf", PdfEncodings.IDENTITY_H);

String str = "रिन्यूअल सूचना";
Paragraph p1 = new Paragraph(str);
p1.setFont(f);

doc.add(p1);
doc.close();

Output without pdfCalligraph:

Without pdfCalligraph, wrong Hindi

Output with pdfCalligraph:

With pdfCalligraph, correct Hindi

This blogpost gives some more background information and a way to select fonts automatically instead of setting them explicitly on the content elements:

final PdfWriter writer = new PdfWriter("languages.pdf");
final PdfDocument pdfDocument = new PdfDocument(writer);
final Document document = new Document(pdfDocument);
final FontSet set = new FontSet();
set.addFont("fonts/NotoNaskhArabic-Regular.ttf");
set.addFont("fonts/NotoSansTamil-Regular.ttf");
set.addFont("fonts/FreeSans.ttf");
document.setFontProvider(new FontProvider(set));

Upvotes: 2

Deepak Singh
Deepak Singh

Reputation: 94

try below code

import com.itextpdf.text.BaseColor;
import com.itextpdf.text.Document;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.Font;
import com.itextpdf.text.FontFactory;
import com.itextpdf.text.Paragraph;
import com.itextpdf.text.Phrase;
import com.itextpdf.text.pdf.BaseFont;
import com.itextpdf.text.pdf.PdfPCell;
import com.itextpdf.text.pdf.PdfPTable;
import com.itextpdf.text.pdf.PdfWriter;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import sandbox.WrapToTest;

public class HindiExample {

    public static final String DEST = "results/fonts/hindi.pdf";
    public static final String FONT = "resources/fonts/FreeSans.ttf";

    public static void main(String[] args) throws IOException, DocumentException {
        File file = new File(DEST);
        file.getParentFile().mkdirs();
        new HindiExample().createPdf(DEST);
    }

    public void createPdf(String dest) throws IOException, DocumentException {
        Document document = new Document();
        PdfWriter.getInstance(document, new FileOutputStream(dest));
        document.open();
        Font f = FontFactory.getFont(FONT, BaseFont.IDENTITY_H, BaseFont.EMBEDDED);
        Paragraph p1 = new Paragraph("\u0915\u093e\u0930 \u092a\u093e\u0930\u094d\u0915\u093f\u0902\u0917", f);
        document.add(p1);
        Paragraph p2 = new Paragraph("\\u0915 \u0915 \\u093e \u093e \\0930 \u0930\n"
                + "\\u092a \u092a \\u093e \u093e \\u0930 \u0930 \\u094d \u094d"
                + "\\u0915 \u0915 \\u093f \\u093f \u093f \\u0902 \u0902"
                + "\\u0917 \u0917", f);
        document.add(p2);

        BaseFont unicode = BaseFont.createFont(FONT, BaseFont.IDENTITY_H, BaseFont.EMBEDDED);
        Font font=new Font(unicode,12,Font.NORMAL,new BaseColor(50,205,50));
        PdfPTable table = new PdfPTable(new float[] { 10, 60, 30 });
        table.setWidthPercentage(100);
        PdfPCell customerLblCell = new PdfPCell(new Phrase("CUSTOMERS"));
        PdfPCell balanceLblCell = new PdfPCell(new Phrase("\u0915\u093e\u0930\u092a\u093e\u0930\u094d\u0915\u093f\u0902\u0917", font));
        table.addCell(customerLblCell);
        table.addCell(balanceLblCell);
        table.completeRow();
        table.setSpacingBefore(10);
        document.add(table);
        document.close();
    }
}

Upvotes: -1

Related Questions