[reportlab-users] RTL Support
    Hosam Aly 
    haly at centrivision.com
       
    Tue Nov 17 13:23:24 EST 2009
    
    
  
Hello,
I have been working on supporting RTL functionality (as I described in 
my previous message), and I was able to get much of this working by 
adding just 1 line of code to the `PDFTextObject._formatText` function 
(not counting some imports). I have also created a test case in 
`test_paragraphs.py`, and it is working relatively fine. There are still 
some corner cases to be addressed (as mentioned above), but they are 
relatively rare. More work still needs to be done to support paragraph 
direction and different character shapes (according to whether the 
character appears at the beginning, the middle or the end of the word).
Please find attached a patch file for the latest revision on the public 
Subversion repository as of the time of writing this message (revision 
3585, 2009-11-17 4:42 PM). I am also writing it down below for the archive.
Best regards,
Hosam Aly
Software Engineer
Centrivision (http://www.centrivision.com/)
http://www.linkedin.com/in/hosamaly
--- BEGIN PATCH ---
Index: src/reportlab/pdfgen/textobject.py
===================================================================
--- src/reportlab/pdfgen/textobject.py    (revision 3585)
+++ src/reportlab/pdfgen/textobject.py    (working copy)
@@ -15,6 +15,17 @@
 from reportlab.lib.utils import fp_str
 from reportlab.pdfbase import pdfmetrics
 
+# try to import pyfribidi
+try:
+    import pyfribidi
+    log2vis = pyfribidi.log2vis
+    DIR_ON = pyfribidi.ON
+except:
+    import warnings
+    warnings.warn('pyfribidi is not installed - RTL not supported')
+    log2vis = None
+    DIR_ON = None
+
 class _PDFColorSetter:
     '''Abstracts the color setting operations; used in Canvas and 
Textobject
     asseumes we have a _code object'''
@@ -329,6 +340,15 @@
 
     def _formatText(self, text):
         "Generates PDF text output operator(s)"
+        ###################################################
+        # RTL text patch, Hosam Aly, November 2009
+        # <haly at centrivision.com>
+        # Based on the patch by Moshe Wagner, June 2009
+        # <moshe.wagner at gmail.com>
+        # Use pyfribidi to write the text in the correct visual order.
+        text = log2vis(text, base_direction = DIR_ON)
+        ###################################################
+
         canv = self._canvas
         font = pdfmetrics.getFont(self._fontname)
         R = []
Index: tests/test_paragraphs.py
===================================================================
--- tests/test_paragraphs.py    (revision 3583)
+++ tests/test_paragraphs.py    (working copy)
@@ -160,6 +160,55 @@
                                      showBoundary=1)
         template.build(story,
             onFirstPage=myFirstPage, onLaterPages=myLaterPages)
+   
+    def test1(self):
+        def registerFont(filename):
+            from reportlab.pdfbase import pdfmetrics
+            from reportlab.pdfbase import ttfonts
+            from reportlab.lib.fonts import addMapping
+       
+            face = ttfonts.TTFontFace(filename)
+            pdfmetrics.registerFont(ttfonts.TTFont(face.name, filename, 
asciiReadable=0))
+            addMapping(face.familyName, face.bold, face.italic, face.name)
+
+        import os
+        fontDir = 'ttf-dejavu'
+        fontName = 'DejaVuSans'
+        registerFont(os.path.join('/usr/share/fonts/truetype/', 
fontDir, fontName + '.ttf'))
+
+
+        story = []
+
+        #need a style
+        from reportlab.lib.enums import TA_RIGHT
+        styNormal = ParagraphStyle('normal', fontName = fontName, 
alignment = TA_RIGHT)
+        styGreen = ParagraphStyle('green',parent=styNormal,textColor=green)
+
+        # some to test
+        stySpaced = ParagraphStyle('spaced',
+                                   parent=styNormal,
+                                   spaceBefore=12,
+                                   spaceAfter=12)
+
+
+        story.append(
+            Paragraph('\xd9\x87\xd8\xb0\xd9\x87 
\xd9\x81\xd9\x82\xd8\xb1\xd8\xa9 
\xd8\xb9\xd8\xa7\xd8\xaf\xd9\x8a\xd8\xa9. ', styNormal))
+        story.append(
+            Paragraph('\xd9\x87\xd8\xb0\xd9\x87 
\xd8\xa7\xd9\x84\xd9\x81\xd9\x82\xd8\xb1\xd8\xa9 
\xd9\x84\xd8\xaf\xd9\x8a\xd9\x87\xd8\xa7 12 
\xd9\x86\xd9\x82\xd8\xb7\xd8\xa9 
\xd9\x82\xd8\xa8\xd9\x84\xd9\x87\xd8\xa7 
\xd9\x88\xd8\xa8\xd8\xb9\xd8\xaf\xd9\x87\xd8\xa7. ', stySpaced))
+        story.append(
+            Paragraph('\xd9\x87\xd8\xb0\xd9\x87 
\xd8\xa7\xd9\x84\xd9\x81\xd9\x82\xd8\xb1\xd8\xa9 
\xd8\xb9\xd8\xa7\xd8\xaf\xd9\x8a\xd8\xa9. ' +
+                      randomText(), styNormal))
+
+        story.append(
+            Paragraph('<para spacebefore="12" spaceafter="12">' +
+                        '\xd9\x87\xd8\xb0\xd9\x87 
\xd8\xa7\xd9\x84\xd9\x81\xd9\x82\xd8\xb1\xd8\xa9 
\xd9\x84\xd8\xaf\xd9\x8a\xd9\x87\xd8\xa7 12 
\xd9\x86\xd9\x82\xd8\xb7\xd8\xa9 
\xd9\x82\xd8\xa8\xd9\x84\xd9\x87\xd8\xa7 
\xd9\x88\xd8\xa8\xd8\xb9\xd8\xaf\xd9\x87\xd8\xa7\xd8\x8c 
\xd9\x85\xd8\xad\xd8\xaf\xd8\xaf\xd8\xa9 \xd8\xa8\xd9\x80 XML. 
\xd8\xa5\xd9\x86\xd9\x87\xd8\xa7 \xd8\xaa\xd8\xb9\xd9\x85\xd9\x84 
\xd8\xa3\xd9\x8a\xd8\xb6\xd8\xa7! \xd9\x80.'*5
+                         +'</para',
+                      styNormal))
+
+        template = SimpleDocTemplate(outputfile('test_paragraphs_ar.pdf'),
+                                     showBoundary=1)
+        template.build(story,
+            onFirstPage=myFirstPage, onLaterPages=myLaterPages)
 
 
 def makeSuite():
--- END PATCH ---
-------------- next part --------------
A non-text attachment was scrubbed...
Name: reportlab-rtl.patch
Type: text/x-patch
Size: 4389 bytes
Desc: not available
Url : <http://two.pairlist.net/pipermail/reportlab-users/attachments/20091117/ca5db102/attachment.bin>
    
    
More information about the reportlab-users
mailing list