希伯来语,阿拉伯语,意第绪语文本在PDFBox 2.0.5中以相反顺序书写

时间:2017-05-23 14:00:38

标签: pdfbox

我正在尝试用PDF写一些阿拉伯语,希伯来语和意第绪语字符,但它们是以相反的顺序编写的。我正在使用PDFBox 2.0.5来创建和编写PDF文档。

我的示例代码

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库来处理的,但它对我不起作用,并且从PDFBox 2.0(PDFBox-2118)中删除了icu4j依赖项。

1 个答案:

答案 0 :(得分:3)

我们需要在最后处理它,因为这不是由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();
    }

这解决了我的问题。希望它能帮助别人。

相关问题