Indic font support in Apache FOP

2019-07-26 04:40发布

问题:

While using Apache FOP 2.2 from my Java application to print Hindi strings in PDF by using mangal.ttf, some Hindi characters are not displayed correctly.
I am Using JDK 1.8 and spring MVC.

I tried lohit.ttf, devanagari.ttf, aparajita.ttf and kokila.ttf but all have the same issue.

case 1:

When fop-conf.xml is set as below:

<font kerning="yes"    embed-url="classpath:/mangal.ttf"   >
<font-triplet name="Mangal" style="normal" weight="normal"></font-triplet>
</font>   

Result: से is shown like this स े, as shown in this screenshot

case 2:

When fop-conf.xml is set as below:

<font kerning="yes"   metrics-url="classpath:/mangal.xml" embed-url="classpath:/mangal.ttf"   >
<font-triplet name="Mangal" style="normal" weight="normal"></font-triplet>
</font>

Result: problem listed in case 1 is resolved but I am facing another issue attached as shown in the following screenshot


You can see the expected output at the link https://www.fonts.com/font/microsoft-corporation/aparajita) using this sample text:

से and ग्रामीण should be printed in pdf

Other things I tried:

  • I tried PDFOne to generate the PDF. Yet the same issue. Windows however seems to show it correctly.
  • configuring complex-script: <fop version="1.0"> <complex-scripts disabled="true"/> ... </fop>
  • using the script attribute: <fo:block font-family="ARIALUNI" script="dev2" > देवी ग्रामीण</fo:block>

Is there any configuration setting in FOP that I am missing?

回答1:

Shorter, general answer:

If the font is configured but the output is not correct, the problem could be FOP incorrectly determining which script mode to use.

Solution: explicitly set the script property in the FO file, using either a standard or an extended script code.
Note that Indic scripts have both a standard code and an extended one (for example deva and dev2 for Devanagari) and the resulting output is different, so you may need to try them both and choose the appropriate one.

Longer answer:

I don't have the fonts you mention available, so I tested using the Amiko Google Open Font.
More importantly, I know nothing about devanagari script, so I really cannot say whether the output is right or wrong, I can only compare it with your images.

This is the complete input file I used, with the sentence copied from your question:

<?xml version="1.0" encoding="UTF-8"?>
<fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format">
  <fo:layout-master-set>
    <fo:simple-page-master master-name="simpleA4" page-height="29.7cm" page-width="21cm" margin-top="2cm" margin-bottom="2cm" margin-left="2cm" margin-right="2cm">
      <fo:region-body/>
    </fo:simple-page-master>
  </fo:layout-master-set>
  <fo:page-sequence master-reference="simpleA4">
    <fo:flow flow-name="xsl-region-body">
      <fo:block font-family="Amiko" script="deva">deva: से and ग्रामीण should be printed in pdf</fo:block>
      <fo:block font-family="Amiko" script="dev2">dev2: से and ग्रामीण should be printed in pdf</fo:block>
    </fo:flow>
  </fo:page-sequence>
</fo:root>

Here is a minimal configuration:

<?xml version="1.0"?>
<fop version="1.0">
  <renderers>
    <renderer mime="application/pdf">
      <fonts>
        <font kerning="yes" embed-url="Amiko/Amiko-Regular.ttf">
          <font-triplet name="Amiko" style="normal" weight="normal"/>
        </font>
      </fonts>
    </renderer>
  </renderers>
</fop>

which produces this output:

If I understand correctly, the output you are trying to achieve is the one with script="deva".


Note that the metrics-url attribute in your configuration is not needed.

Moreover, putting <complex-scripts disabled="true"/> in your configuration has the effect of disabling the "complex script" support, so I expect this to produce the wrong output.

This configuration

<?xml version="1.0"?>
<fop version="1.0">
  <complex-scripts disabled="true"/>
  <renderers>
    <renderer mime="application/pdf">
      <fonts>
        <font kerning="yes" embed-url="Amiko/Amiko-Regular.ttf">
          <font-triplet name="Amiko" style="normal" weight="normal"/>
        </font>
      </fonts>
    </renderer>
  </renderers>
</fop>

produces the following output: