2017-05-23 12 views
0

アラビア語、ヘブライ語、イディッシュ語の一部をPDFで記述しようとしていますが、逆の順序で記述されています。私はPDFBox 2.0.5を使用して、PDF文書を作成して書き込みます。PDFBox 2.0.5では、ヘブライ語、アラビア語、イディッシュ語の逆順で書かれています。

私のサンプルコード

String relativeWebPath = "/font/arial.ttf"; 
String absoluteDiskPath = getServletContext().getRealPath(relativeWebPath); 
File file = new File(absoluteDiskPath); 

ByteArrayOutputStream output=new ByteArrayOutputStream(); 
PDDocument document=new PDDocument(); 
PDFont font = PDType0Font.load(document, new File(absoluteDiskPath)); 
PDPage test=new PDPage(); 
document.addPage(test); 
PDPageContentStream content=new PDPageContentStream(document, test); 
final String EXAMPLE = "النص العربي"; 
System.out.print(EXAMPLE); 

content.beginText(); 
content.newLineAtOffset(50, 680); 
content.setFont(font, 12); 
content.showText(EXAMPLE); 
System.out.print(EXAMPLE); 
content.endText(); 

content.close(); 

document.save(output); 
document.close(); 

解決のために研究している間、私はそれがプロジェクトにICU4Jライブラリを追加することによって処理されるが、それは私の作品ともICU4J依存性がPDFBox 2.0(PDFBox-2118)から削除されていないことがわかりました。

+0

RTL言語と複雑なスクリプトは、悲しいことにPDF作成ではサポートされていません。 –

答えて

2

これはPDFBox自体では処理されないため、最後に処理する必要があります。これを回避する方法があります。RTL言語の文字列を逆順に作成してPDFBoxに渡すと、PDFBoxは正しい方向に書き込みます。

次に、RTL言語のテキストを検出する方法とそれを元に戻す方法を解説します。これは、JavaのBiDiクラスオブジェクトを使用して解決できます。これは私の問題を解決し

String word = EXAMPLE; // string from question 
    Bidi bidi = new Bidi(word, -2); 
    if (!bidi.isMixed() && bidi.getBaseLevel() == 0) { 
     return word; 
    } 
    else { 
     int runCount = bidi.getRunCount(); 
     byte[] levels = new byte[runCount]; 
     Integer[] runs = new Integer[runCount]; 

     for (int result = 0; result < runCount; ++result) { 
      levels[result] = (byte) bidi.getRunLevel(result); 
      runs[result] = Integer.valueOf(result); 
     } 

     Bidi.reorderVisually(levels, 0, runs, 0, runCount); 
     StringBuilder bidiText = new StringBuilder(); 

     for (int i = 0; i < runCount; ++i) { 
      int index = runs[i].intValue(); 
      int start = bidi.getRunStart(index); 
      int end = bidi.getRunLimit(index); 
      byte level = levels[index]; 
      if ((level & 1) != 0) { 
       while (true) { 
        --end; 
        if (end < start) { 
         break; 
        } 

        char character = word.charAt(end); 
        if (Character.isMirrored(word.codePointAt(end))) { 
         bidiText.append(character); 
        } 
        else { 
         bidiText.append(character); 
        } 
       } 
      } 
      else { 
       bidiText.append(word, start, end); 
      } 
     } 

     return bidiText.toString(); 
    } 

完全なソリューションは、この解決策は、文字列の組み合わせを処理します。それが他人を助けることを願っています。