Telugu (Unicode) font not rendering correctly in pyfpdf - python

I am trying to render Telugu text into pdf using pyfpdf.
The problem is with font rendition in fpdf.
What might be the problem?
The code I used is :
#!/usr/bin/python
# -*- coding: utf8 -*-
from fpdf import FPDF
pdf = FPDF()
pdf.add_page()
pdf.add_font('lakkireddy', '', 'LakkiReddy.ttf', uni=True)
pdf.set_font('lakkireddy','', 16)
pdf.cell(40,10,u'హలో ప్రపంచమా!')
pdf.output('testfpdf.pdf','F')`
The expected output is :
But the actual output is broken text :
What could be the issue, Is it the font, Is it encoding or Is it font rendering engine?
Can I define which font rendering engine to use?

I am not familiar with fpdf but it seems that fpdf does not support proper text shaping for complex scripts. Glyph shapes change based on glyph position in the string and based on its neighbor glyphs but fpdf does not seem to do this kind of processing by default.
You have to check if there are options in fpdf for specifying this kind of processing for complex scripts.

Related

FPDF with python : Some Japanese characters are showing as rectangle

I try to print a simple japanese word in a pdf. I modified a basic exemple to see if it would work but not what I expected to see.
from fpdf import FPDF
pdf = FPDF()
pdf.add_page()
# Add a AR PL New Sung Unicode font (uses UTF-8)
# The Open Source Chinese Font (also supports other east Asian languages)
pdf.add_font('fireflysung', '', 'fireflysung.ttf', uni=True)
pdf.set_font('fireflysung', '', 14)
pdf.write(8, u'Chinese: 你好世界\n')
pdf.write(8, u'Japanese: こんにちは世界\n')
pdf.write(8, u'bicycle: 自転車 (ジテンシャ)\n')
pdf.ln(10)
pdf.output("unicode.pdf")
Result
Expected:
Japanese: 自転車 (ジテンシャ)
How do I display this missing character ?
Edit:
So I found a font that seams to work for now. I converted it to .ttf using otf2tff. Hope it will help.

MoviePy not displaying non-English characters

I'm trying to display non English characters in movie py but it's not displaying the actual character I typed. The language I'm trying is Telugu. What is the problem in displaying the characters?
This is the code I'm using
# -*- coding: utf-8 -*-
from moviepy.editor import *
# create clip from image
clip = ImageClip('img/1.jpg').on_color((1920, 1080))
clip = clip.set_duration(2)
# add annotation to clip
txtclip = TextClip('n+<ý² yûTq¿£yû', fontsize=50, color='red', font="Deepika")
cvc = CompositeVideoClip([ clip, txtclip.set_pos(('center', 'bottom'))])
cvc = cvc.set_duration(2)
# write video to file
cvc.write_videofile("text.mp4", fps=24)
The characters(Language) displayed in the code is weird but when I copy the text from the original file which was different characters displayed as this. And this worked in displaying the text in PySide QLabel.
Its just displaying boxes instead of the characters.
Can anyone help me with this issue?For your reference I'm adding image of text displayed in the code for language
I had a similar problem. I printed Japanese characters, but they were not displayed in video.
The problem was that the font did not support these characters.
Thus this produced empty result:
my_text = mp.TextClip("すみません。お先に失礼します",
font= "Amiri-regular", color= "white", fontsize= 34)
Solution was to download a custom font and import it as in example:
my_text2 = mp.TextClip("すみません。お先に失礼します",
font="wqy-microhei.ttc", color="white", fontsize=34)
I downloaded this font from github and it can be simply placed into directory with the python source code to be imported.

ReportLab Django Not Rendering Chinese Characters

I'm having difficulty making ReportLab render Chinese Characters. From everything I've looked up people are saying that it is probably a font problem but I've used a lot of different fonts and it doesn't even seem to be using them at all. The Chinese characters always just come out as black squares. Below is some sample code of what I have.
# -*- coding: utf8 -*-
from reportlab.lib.pagesizes import letter
from reportlab.pdfbase.ttfonts import TTFont
from io import BytesIO
pdfmetrics.registerFont(TTFont('Arial', 'arial.ttf', 'UTF-8'))
buffer = BytesIO()
doc = SimpleDocTemplate(buffer,
rightMargin=inch*0.5, # 1/2 Inch
leftMargin=inch*0.5, # 1/2 Inch
bottomMargin=0,
topMargin=inch*0.375, # 3/8 Inch
pagesize=letter)
# Get Styles
styles = getSampleStyleSheet()
# Custom Style
styles.add(ParagraphStyle(name='Address', font='Arial', fontSize=8))
elements = []
elements.append(Paragraph(u'6905\u897f\u963f\u79d1\u8857\uff0c\u5927\u53a6\uff03\u5927', styles['Address']))
doc.build(elements)
# Get the value of the BytesIO buffer and write it to the response.
pdf = buffer.getvalue()
buffer.close()
return pdf
I'm using an arial.ttf font found on my Ubuntu 12.04 installation in the fonts folder. I have also tried other fonts installed on this machine and all have exactly the same look even on the numbers and none of the Chinese characters are anything other than black squares.
Am I registering fonts wrong if even the numbers at the beginning aren't printing correctly? What could be causing the black squares?
Solved it. Turns out in your ParagraphStyle it needs to be fontName="Arial" not font="Arial" but I did learn some other tricks of getting it to work in other ways below.
styles.add(ParagraphStyle(name='Address', fontName='Arial')
After doing some digging I've learned a few things that I hope helps someone else in this situation. When you add the tags inside of your Paragraph around the Unicode text and set it explicitly to a font it will work.
elements.append(Paragraph(u'<font name="Arial">6905\u897f\u963f\u79d1\u8857\uff0c\u5927\u53a6\uff03\u5927</font>', styles['Address']))
This fixes the problem at least for Paragraphs with various fonts.
Again this code will work.
Choose the fonts that supports Chinese characters.
In Ubuntu, I choose "AR PL UMing CN" for example.
My code snippets:
# -*- coding: utf-8 -*-
...
pdfmetrics.registerFont(TTFont('AR PL UMing CN', 'uming.ttc'))
styles = getSampleStyleSheet()
...
styles.add(ParagraphStyle(name='Chinese', fontName='AR PL UMing CN', fontSize=20))
elements=[]
elements.append(Paragraph("成”, styles['Chinese']))
doc.build(elements)
...
I can even change to Chinese editor and type in the character straight off. Hope this helps.

Render vector letter in python

I would like to render a truetype letter to be used with the shapely module in python. (Say that I wish to make some morphologic operation on letters.)
Up to now, I managed to write a letter to a SVG file using cairo (see below). The letter is saved as a curve in the file header. The curve is basically what I need, but I believe there must be a much more elegant way to get the curve than to save, process and load a SVG file.
A second task is to load the curve in the format that shapely works with, but I think this can be done.
#!/usr/bin/env python
#-*- coding: utf-8 -*-
import cairo
fo = file('test.svg', 'w')
WIDTH, HEIGHT = 256, 256
surface = cairo.SVGSurface (fo, WIDTH, HEIGHT) ## Prepare a destination surface -> out to an SVG file!
ctx = cairo.Context (surface)
ctx.scale (WIDTH/1.0, HEIGHT/1.0) # Normalizing the canvas
ctx.move_to (0.1, 0.9)
ctx.set_font_size(1.)
character = "a"
ctx.show_text(character)
surface.finish()
Thank you in advance for your tips!
EDIT: I figured out that instead of show_text() one may draw a real curve using text_path(), but still I cannot read the points...
print ctx.text_path("b")
ctx.set_source_rgb (0.3, 0.2, 0.5) # Solid color
ctx.set_line_width (0.02)
ctx.stroke ()
EDIT2:
With a help of my colleague we managed to get a similar result as above. Using fontforge it is also possible to render a glyph and save it to SVG (in Bezier curves). It may be useful to somebody.
#!/usr/bin/python
# -*- coding: utf-8 -*-
## Outputs a glyph as a SVG, using FontForge (requires package 'python-fontforge')
import fontforge
f = fontforge.open("/usr/share/fonts/truetype/ubuntu-font-family/Ubuntu-R.ttf")
g = f["Aring"]
print g
g.export("orig.svg")
Optionally, one can already perform a morphologic dilation on the glyph before saving the SVG. (However, this is the only step of many that would be needed.)
g.stroke("circular", 100, "round", "round", "removeinternal") ## morphologic dilation of the glyph
g.export("stroke.svg")
Also the precise bounding box can be established.
print "Stroked: g.boundingBox() =", g.boundingBox()
By the way, trying to write even trivial Inkscape plugins is quite frustrating, but I still believe it is the best way for the task.
You'll probably need to use FreeType directly. The glyph-vector.py example shows how to get at the glyph vector information.

Reportlab: Asian fonts with encryption enabled does not work

I have been using Asian fonts (Chinese simplified/tradional, Japanese, and Korean) in my reportlab generated pdfs without issuse for a while now. However recently we have decided to enable the encryption options like this:
from reportlab.pdfbase import pdfmetrics
from reportlab.pdfbase.cidfonts import UnicodeCIDFont
pdfmetrics.registerFont(UnicodeCIDFont("STSong-Light"))
enc = pdfencrypt.StandardEncryption(
"", canPrint=1, canModify=0, canCopy=0, canAnnotate=0
)
self._Report = SimpleDocTemplate(
save_file,
topmargin=0.75*inch, bottommargin=0.75*inch,
rightmargin=0.70*inch, leftmargin=0.70*inch,
showBoundary=0,
author="xxx",
title="xxx",
subject=xxx",
encrypt=enc
)
For non Asian languages the encryption works as expected. When we use Asian fonts with encryption the pdf cannot be read by adobe reader. For example with simplified Chinese we get a "Cannot find the font "STSong-Light" error from Adobe Reader.
Anyone have any ideas on what encryption is breaking to not make this work?
I had the same problem. This might not solve your problem.
But, If I specify it into Japanese,
you can solve it by installing TTFont(in this example it is IPA gothic),
and set the font.
So, by installing another languages fonts, you can solve the problem though
this is not cool.
from reportlab.pdfgen import canvas
from reportlab.lib.pagesizes import letter,A4
from reportlab.pdfbase import pdfmetrics
from reportlab.pdfbase.ttfonts import TTFont
fontname = 'IPA Gothic'
pdfmetrics.registerFont(TTFont(fontname,'{directory that you put the font}/ipag.ttf'))
p = canvas.Canvas(response,pagesize=A4)
p.setFont(fonatname,13)
p.drawString(100,100,u'日本語,中国語,韓国語')
p.showPage()
p.save()

Categories