第四步,将自动换行后的文本在海报背景上打印。
这里需要用到 FontDesignMetrics 的 getHeight() 方法获取每行文本的高度。对照下面的示意图,理解 height 的具体高度。
// 自动换行后的文本 String zhWrap = FontUtil.makeLineFeed(graphics2dPoster.getZh(), metrics, graphics2dPoster.getSuitableWidth()); // 拆分行 String[] zhWraps = zhWrap.split("\n"); // 将每一行在海报背景上打印 for (int i = 0; i < zhWraps.length; i++) { graphics2dPoster.addCurrentY(metrics.getHeight()); graphics2d.drawString(zhWraps[i], MARGIN, graphics2dPoster.getCurrentY()); }
此时的海报效果如下图所示。
可以看得出,文字带有很强的锯齿感,怎么消除呢?
graphics2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
如果英语不好的话,看起来这段代码会很吃力。ANTIALIASING 单词的意思就是“消除混叠现象,消除走样,图形保真”。
07、利用 Graphics2D 在海报上打印英文
英文和中文最大的不同在于,换行的单位不再是单个字符,而是整个单词。
第一步,根据当前字体下每个英文单词的宽度,以及海报可容纳的最大文本宽度,对文本进行换行。
public static String makeEnLineFeed(String en, FontDesignMetrics metrics, int max_width) { // 每个单词后追加空格 char space = ' '; int spaceWidth = metrics.charWidth(space); // 按照空格对英文文本进行拆分 String[] words = en.split(String.valueOf(space)); // 利用 StringBuilder 对字符串进行修改 StringBuilder sb = new StringBuilder(); // 每行文本的宽度 int len = 0; for (int i = 0; i < words.length; i++) { String word = words[i]; int wordWidth = metrics.stringWidth(word); // 叠加当前单词的宽度 len += wordWidth; // 超出最大宽度,进行换行 if (len > max_width) { sb.append("\n"); sb.append(word); sb.append(space); // 下一行的起始宽度 len = wordWidth + spaceWidth; } else { sb.append(word); sb.append(space); // 多了一个空格 len += spaceWidth; } } return sb.toString(); }
假如文本是“Fear can hold you prisoner. Hope can set you free. It takes a strong man to save himself, and a great man to save another.”我们来通过 makeEnLineFeed() 方法试验一下。
Font font = new Font("微软雅黑", Font.PLAIN, 28);
FontDesignMetrics metrics = FontDesignMetrics.getMetrics(font);
String en = "Fear can hold you prisoner. Hope can set you free. It takes a strong man to save himself, and a great man to save another.";
String[] rows = makeEnLineFeed(en, metrics, 600).split("\n");
for (int i = 0; i < rows.length; i++) {
System.out.println(rows[i]);
}
其结果如下所示。
Fear can hold you prisoner. Hope can set
you free. It takes a strong man to save
himself, and a great man to save another.
第三步,将自动换行后的文本在海报背景上打印。
// 设置封面图和下方中文之间的距离 graphics2dPoster.addCurrentY(20); Graphics2D graphics2d = graphics2dPoster.getGraphics2d(); graphics2d.setColor(new Color(157, 157, 157)); FontDesignMetrics metrics = FontDesignMetrics.getMetrics(graphics2d.getFont()); String enWrap = FontUtil.makeEnLineFeed(graphics2dPoster.getEn(), metrics, graphics2dPoster.getSuitableWidth()); String[] enWraps = enWrap.split("\n"); for (int i = 0; i < enWraps.length; i++) { graphics2dPoster.addCurrentY(metrics.getHeight()); graphics2d.drawString(enWraps[i], MARGIN, graphics2dPoster.getCurrentY()); }
此时的海报效果如下图所示。