为啥字体大小为 101 的 Graphics2D.drawString 的字母“o”会损坏?
Posted
技术标签:
【中文标题】为啥字体大小为 101 的 Graphics2D.drawString 的字母“o”会损坏?【英文标题】:Why is letter "o" with Graphics2D.drawString at font size 101 broken?为什么字体大小为 101 的 Graphics2D.drawString 的字母“o”会损坏? 【发布时间】:2019-11-18 07:51:58 【问题描述】:我想在 png 中绘制字符串。我需要高度不超过 600 像素的字母。
因此我尝试使用 Graphics2D.drawString:
String text = "o";
graphics.setFont(font.deriveFont(Font.PLAIN, fontsize));
graphics.drawString(text, 0, 200);
字体大小最大为 100 的文本可以正常工作。 问题:字体大小为 101 时,一些圆形字符(如“o”)有点倾斜。
这可通过字体“Abril_Fatface”、“Amatic_SC”和“Cinzel_Decorative”重现(来自谷歌字体,例如https://fonts.google.com/specimen/Abril+Fatface 或https://fonts.google.com/specimen/Amatic+SC;可通过“选择此字体”然后“下载此部分”下载 ttf 文件在“选择 1 个家庭”对话框中)。使用其他字体,字符串绘制正常。
LibreOffice 将字符显示为圆形(如预期的那样)。
这里是完整的代码:
import java.awt.Color;
import java.awt.Font;
import java.awt.FontFormatException;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
public class CustomFontWriting
public static void main(String[] args) throws FontFormatException, IOException
Font font = Font.createFont(Font.TRUETYPE_FONT, new File("Amatic_SC.ttf"));
// Create empty image
BufferedImage image = new BufferedImage(300, 300, BufferedImage.TYPE_INT_ARGB);
Graphics2D graphics = image.createGraphics();
graphics.setColor(Color.BLACK);
// Draw letter "o" with fontsize 101 in an image
graphics.setFont(font.deriveFont(Font.PLAIN, 101));
graphics.drawString("o", 0, 200);
// Write image to disk
File output = new File("output.png");
ImageIO.write(image, "png", output);
预期结果:圆形字母“o”。
实际结果:斜角字母“o”。
【问题讨论】:
看起来任何负责解释路径坐标的人都做错了——你可能想问这个问题,在 java 错误跟踪器上使用适当的minimal reproducible example。这是 Oracle 的 JDK 还是 OpenJDK? (甚至是第三个,其他版本?) OpenJDK 1.8.0_212 会发生这种情况。 这个例子现在有点短,但仍然重现了问题。使用 Java SE RE 1.8.0_171-b11 就没有这样的问题。示例字母是完美的圆形。 那么(基于this)您可能想在 bugs.java.com 上提交此文件,明确提到这是针对 OpenJDK 1.8(而不是 Oracle JDK)。有可能他们使用的是旧版本的 harfbuzz/freetype/uniscribe/etc,需要进行版本升级,或者他们所依赖的整形引擎中甚至可能存在需要先修复的错误。 好的,我在 bugs.java.com 上提交了这个文件,并使用更新的 OpenJDK 版本 1.11.3 (2019-04-16) 进行了额外测试。使用 OpenJDK 11,我的测试用例成功生成了圆形字母。伟大的。这是我将遵循的解决方案。谢谢! :-) 【参考方案1】:解决方案是使用 OpenJDK 11 或更高版本。请参阅问题中的 cmets。
【讨论】:
以上是关于为啥字体大小为 101 的 Graphics2D.drawString 的字母“o”会损坏?的主要内容,如果未能解决你的问题,请参考以下文章
为啥我的大小为 11 的 truetype 字体呈现与 windows 不同?
为啥微软雅黑字体打印出来大小不一?电脑显示正常,字号为小四,求解~
为啥 Twitter Bootstrap 使用像素作为字体大小?