通过FontMetrics和AffineTransform等比例缩放字体


背景

使用Graphics2D进行绘图的过程中,对于指定的区域可能会填充文字,如果文字个数是不固定的话,区域的宽度很难把控。本文将介绍一个方法,通过代码实现对字体的等比例缩放。

解决思路

  • Graphics2D设置要使用的字体及其大小;
  • 通过FontMetrics计算要填充的文字填充后需要占用的宽度;
  • 计算的宽度和当前画图区域的宽度进行比较(假设当前计算要占用的宽度为W1,预计要存放文字的区域为W2):
    • 如果W1比W2还小,证明预置的空间还未占满,可以不做任何处理,因为空间放得下;
    • 如果W1比W2还大,那么W1/W2的值即为缩放的比例,记录为S1(需要将文字大小等比例缩放才能在预置的空间显示出来);
    • 重新设置字体大小(原来的大小乘以S1,等比例缩放)。

代码实现

Graphics2D g2d = image.createGraphics();
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g2d.setFont(font);

FontMetrics fm = g2d.getFontMetrics();
// 名称宽度,+5为了修正
int textWidth = fm.stringWidth(name) + 5;
// 名称高度
int textHeight = fm.getHeight();

// 如果超过预置的文本宽度textWidth,进行缩放
if (textWidth > width || textHeight > height) {
  double xScale = width / (double) textWidth;
  double yScale = height / (double) textHeight;
  double scale = xScale;
  if (xScale > yScale) {
    scale = yScale;
  }
  // 字体缩放
  g2d.setFont(font.deriveFont(AffineTransform.getScaleInstance(scale, scale)));
  if (logger.isDebugEnabled()) {
    logger.debug("textWidth: {}, image width: {}, will scale now, scale: {}",
            new Object[]{textWidth, width, scale});
  }
  fm = g2d.getFontMetrics();
}

g2d.drawString(name, (width - textWidth) / 2, fm.getAscent() + (height - fm.getHeight()) / 2);

g2d.dispose();

文章作者: zzq0324
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 zzq0324 !
  目录