问题描述
如何在Processing或Java中找出PFont字符串的高度和宽度?
解决方法
遇到类似问题时,最好的办法就是通读Processing reference。
特别是您可能正在寻找textWidth()
,textAscent()
和textDescent()
函数。
size(400,400);
textSize(36);
String str = "Hello world";
float x = 100;
float y = 100;
float strWidth = textWidth(str);
float strAscent = textAscent();
float strDescent = textDescent();
float strHeight = strAscent + strDescent;
rect(x,y - strAscent,strWidth,strHeight);
fill(0);
text(str,x,y);
,
使用内置函数textWidth()
,textAscent()
和textDescent()
是获得字符串高度和宽度 good 近似结果的简便方法,但它们不是 exact 。
为什么?
-
textAscent()
根据字母'd' 返回行上方的文本高度
-
textDescent()
根据字母'p' 返回行以下的文本高度。
-
textWidth()
包含字形空格(又称填充;理想情况下,我们希望忽略第一个和最后一个字符)
textAscent() + textDescent()
测量给定字体和字体大小的字符串的最大高度,而不是特定字符串的高度。换句话说,如果您的文本不同时包含'd'和'p'字符,则使用这些方法确定文本高度会高估结果(如我们在Kevin的屏幕截图中所见)。
获取确切的高度
我们可以使用这种方法获取高度的精确结果:
- 获取每个字符的矢量表示形式
- 遍历向量的顶点,发现:
- Y位置最高的顶点
- Y位置最低的顶点
- 从最低Y位置减去最高Y位置以确定确切的弦高
代码示例
请注意,您需要为此显式创建一个PFont
。
String string = "Hello world";
PFont font = createFont("Arial",96,true); // arial,size 96
textFont(font);
float minY = Float.MAX_VALUE;
float maxY = Float.NEGATIVE_INFINITY;
for (Character c : string.toCharArray()) {
PShape character = font.getShape(c); // create character vector
for (int i = 0; i < character.getVertexCount(); i++) {
minY = min(character.getVertex(i).y,minY);
maxY = max(character.getVertex(i).y,maxY);
}
}
final float textHeight = maxY - minY;
结果
(请注意,此处我们仍在使用textWidth()
作为宽度)
text(string,mouseX,mouseY);
rect(mouseX,mouseY,textWidth("Hello world"),-textHeight);
获取确切宽度
代码示例
String string = "Hello world";
PFont font = createFont("Arial",size 96
textFont(font);
float textWidth = textWidth(string); // call Processing method
float whitespace = (font.width(string.charAt(string.length() - 1)) * font.getSize()
- font.getGlyph(string.charAt(string.length() - 1)).width) / 2;
textWidth -= whitespace; // subtract whitespace of last character
whitespace = (font.width(string.charAt(0)) * font.getSize() - font.getGlyph(string.charAt(0)).width) / 2;
textWidth -= whitespace; // subtract whitespace of first character
结果
(将两者放在一起...)
text(string,mouseY);
rect(mouseX + whitespace,textWidth,-textHeight);
Y轴对齐
在"Hello world"
周围绘制的矩形恰好对齐,因为没有一个字形下降到基线以下。
在使用@#'pdXW\
之类的字符串时,@
和p
都下降到基线以下,因此,尽管矩形是正确的高度,但矩形却未与y轴,如下所示:
一种确定y偏移的编程方法是找到最低的Y坐标(尽管请记住,Processing的y轴向下延伸,所以我们实际上是在寻找最大值)顶点。幸运的是,这是找到确切高度的一部分。
我们可以简单地使用在那里计算出的maxY
值来抵消文本边界框。
结果
text(string,mouseY + maxY,-textHeight);