Search code examples
xsl-foright-to-leftapache-fophebrew

Can Apache FOP display RTL languages such as Hebrew with bullet-points and other content right aligned?


I've been struggling to understand how Apache FOP handles Hebrew, and potentially other rtl scripts.

When generating a document it appears to still leave the content as being left aligned including bullet points:

Image showing FOP output with bullet points and text left-aligned

I previously worked with Ibex in .Net which handled this FO file as expected:

Image showing Ibex output with bullet points and text right-aligned as expected

I had a look at some previous questions such as FOP apache - support Hebrew letters which helped find some of the Java/FOP specific changes needed and some routes I tried. The reference docs here https://xmlgraphics.apache.org/fop/2.2/complexscripts.html also had info on some tags to add which didn't fix the issue, so I am hoping I just missed something obvious rather than this just not being possible in FOP.

Here's a stripped back FOP I used in both processors with some Lorem Ipsum text:

<?xml version="1.0" encoding="UTF-16"?>
<fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format">
  <fo:layout-master-set>
    <fo:simple-page-master master-name="core" page-height="297mm" page-width="210mm" margin-left="5mm"
                           margin-right="5mm" margin-top="9mm" margin-bottom="10mm">
      <fo:region-body region-name="Content" margin-left="5mm" margin-right="10mm" margin-top="10mm" margin-bottom="5mm"
                      column-gap="10mm" writing-mode="rl-tb" direction="rtl"/>
    </fo:simple-page-master>
  </fo:layout-master-set>
  <fo:page-sequence master-reference="core">
    <fo:flow flow-name="Content" font-family="Arial Unicode MS">
      <fo:block>
        <fo:block>קסאם מדינות מה. מיזם חשמל מיזמי רבה בה, לעריכת ופיתוחה פוליטיקה מתן מה:</fo:block>
        <fo:block>
          <fo:list-block>
            <fo:list-item>
              <fo:list-item-label end-indent="label-end()">
                <fo:block>●</fo:block>
              </fo:list-item-label>
              <fo:list-item-body start-indent="body-start()">
                <fo:block>קסאם מדינות מה. מיזם חשמל מיזמי רבה בה, לעריכת ופיתוחה פוליטיקה מתן מה.</fo:block>
              </fo:list-item-body>
            </fo:list-item>
          </fo:list-block>
        </fo:block>
      </fo:block>
    </fo:flow>
  </fo:page-sequence>
</fo:root>

I've tried adding the <fo:bidi-override unicode-bidi="embed" direction="rtl"> node around the text but it seemed to make no difference in FOP, and wasn't needed in ibex.

Adding language="hebr" script="he" to the page-sequence and flow nodes also made no difference.

The intention was to have FO files we could pass environmental variables into such as "rtl" and "rl-tb" (how this was handled with Ibex). If this can be achieved but we need two separate files for rtl and ltr that is always an option. Eventually this would be used for a variety of languages including Russian, Turkish, Korean etc so having one generic file would definitely be preferred!


Solution

  • A team mate managed to figure it out while I was away - the writing-mode attribute needs to be on the page-sequence node so like:

    <?xml version="1.0" encoding="UTF-16" ?>
    <fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format">
      <fo:layout-master-set>
        <fo:simple-page-master master-name="core" page-height="297mm" page-width="210mm" margin-left="5mm"
                               margin-right="5mm" margin-top="9mm" margin-bottom="10mm">
          <fo:region-body region-name="Content" margin-left="5mm" margin-right="10mm" margin-top="10mm" margin-bottom="5mm"
                          column-gap="10mm"/>
        </fo:simple-page-master>
      </fo:layout-master-set>
      <fo:page-sequence master-reference="core" writing-mode="rl-tb">
        <fo:flow flow-name="Content" font-family="Arial Unicode MS">
          <fo:block>
            <fo:block>קסאם מדינות מה. מיזם חשמל מיזמי רבה בה, לעריכת ופיתוחה פוליטיקה מתן מה:</fo:block>
            <fo:block>
              <fo:list-block>
                <fo:list-item>
                  <fo:list-item-label end-indent="label-end()">
                    <fo:block>●</fo:block>
                  </fo:list-item-label>
                  <fo:list-item-body start-indent="body-start()">
                    <fo:block>קסאם מדינות מה. מיזם חשמל מיזמי רבה בה, לעריכת ופיתוחה פוליטיקה מתן מה.</fo:block>
                  </fo:list-item-body>
                </fo:list-item>
              </fo:list-block>
            </fo:block>
          </fo:block>
        </fo:flow>
      </fo:page-sequence>
    </fo:root>
    

    I had tried the writing-mode and text-direction attributes on the fo:region-body node which appears to be incorrect in this case