首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何正确使用PDPageContentStream::setTextRise?

如何正确使用PDPageContentStream::setTextRise?
EN

Stack Overflow用户
提问于 2022-05-24 04:18:01
回答 1查看 56关注 0票数 -2

使用PDFBox,给定如下标注的数据:[G]Glory be to [D]God [Em]the [C]Father,\n[G]And to [A]Christ the [D]Son,,我正在创建如下吉他和弦表:

我的方法是遍历歌曲中的每个字符,并根据地图检查当前索引。每当地图有一个条目到那个字符索引,我们“跳”到上面的行,写和弦,然后跳下来。

setTextRise方法看起来很有希望,但仍然不正确地处理水平间距:

下面是一个SSCCE (需要PDFBox库),它生成上面的PDF:

代码语言:javascript
运行
复制
public static void main(String[] args) {
    try {
        
        String extracted_text = "Capo 1\n\n1\n[G]Glory be to [D]God [Em]the [C]Father,\n[G]And to [A]Christ the [D]Son,\n[B7]Glory to the [Em]Holy [C]Spirit—\n[D-D7]Ever [ G]One.\n\n2\nAs we view the vast creation,\nPlanned with wondrous skill,\nSo our hearts would move to worship,\nAnd be still.\n\n3\nBut, our God, how great Thy yearning\nTo have sons who love\nIn the Son e’en now to praise Thee,\nLove to prove!\n\n4\n’Twas Thy thought in revelation,\nTo present to men\nSecrets of Thine own affections,\nTheirs to win.\n\n5\nSo in Christ, through His redemption\n(Vanquished evil powers!)\nThou hast brought, in new creation,\nWorshippers!\n\n6\nGlory be to God the Father,\nAnd to Christ the Son,\nGlory to the Holy Spirit—\nEver One.\n".replaceAll("\n", "\r");
        
        String[] lines = extracted_text.split("\\r");
        
        ArrayList<SongLine> songlines = new ArrayList<>();
        for(String s : lines) {
            LinkedHashMap<Integer, String> chords = new LinkedHashMap();
            StringBuilder line = new StringBuilder();
            StringBuilder currentchord = null;
            int index = 0;
            for(char c : s.toCharArray()) {
                if(currentchord != null) {
                    if(c == ']') {
                        chords.put(index, currentchord.toString());
                        currentchord = null;
                    } else {
                        currentchord.append(c);
                    }
                } else {
                    if(c == '[') {
                        currentchord = new StringBuilder();
                    } else {
                        line.append(c);
                        index++;
                    }
                }
            }
            
            SongLine sl = new SongLine();
            if(chords.size() > 0)
                sl.char_index_to_chords = chords;
            sl.line = line.toString();
            
            songlines.add(sl);
        }
        
        try (PDDocument doc = new PDDocument()) {
            PDPage page = new PDPage();
            PDPageContentStream pcs = new PDPageContentStream(doc, page);
            int firstLineX = 25;
            int firstLineY = 700;
            boolean first = true;

            float leading = 14.5f;
            pcs.beginText();
            pcs.newLineAtOffset(firstLineX, firstLineY);
            pcs.setFont(PDType1Font.TIMES_ROMAN, 12);
            pcs.setLeading(leading);
            for(SongLine line : songlines) {
                if(line.char_index_to_chords != null)
                    System.out.println(line.char_index_to_chords.toString());
                System.out.println(line.line);
                if(!first) {
                    pcs.newLine();
                }
                first = false;
                if(line.char_index_to_chords != null) {
                    pcs.newLine();
                }
                for(int i = 0; i < line.line.length(); i++) {
                    pcs.showText(String.valueOf(line.line.charAt(i)));
                    if(line.char_index_to_chords != null && line.char_index_to_chords.containsKey(i)) {
                        
                        pcs.setTextRise(12);
                        pcs.showText(line.char_index_to_chords.get(i));
                        pcs.setTextRise(0);
                    }
                }
            }
            pcs.endText();
            pcs.close();
            doc.addPage(page);
            String path = "0001.pdf";
            doc.save(path);
            
            Desktop.getDesktop().open(new File(path));
        }
    } catch (Exception e) {
        e.printStackTrace();
    }
}


static class SongLine {
    Map<Integer, String> char_index_to_chords;
    String line;
}

您将如何在PDFBox中创建与和弦对齐的文本(如第一个图像)?

EN

回答 1

Stack Overflow用户

发布于 2022-05-24 14:42:20

这样啊,原来是这么回事。答案不是setTextRise,而是newLineAtOffset,同时使用getStringWidth计算字体大小:

代码语言:javascript
运行
复制
for(SongLine line : songlines) {
    if(!first) {
        pcs.newLine();
    }
    first = false;
    if(line.char_index_to_chords != null) {
        float offset = 0;
        for(Entry<Integer, String> entry : line.char_index_to_chords.entrySet()) {
            float offsetX = font.getStringWidth(line.char_index_to_leading_lyrics.get(entry.getKey())) / (float)1000 * fontSize;
            pcs.newLineAtOffset(offsetX, 0);
            offset += offsetX;
            pcs.showText(entry.getValue());
        }
        pcs.newLineAtOffset(-offset, -leading);
    }
    pcs.showText(line.line);
}
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/72357162

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档