我使用stb_truetype
在OpenGL上下文中渲染TrueType字体。
有没有简单的方法在呈现字符串之前预先确定字符串的高度和宽度?
答案 0 :(得分:1)
虽然@Tophandour的答案给出了宽度的良好近似值,但stb提供了更准确地执行此操作的功能。这是我现在在Java中使用的解决方案:
public float getWidth(String text) {
float length = 0f;
for (int i = 0; i < text.length(); i++) {
IntBuffer advancewidth = BufferUtils.createIntBuffer(1);
IntBuffer leftsidebearing = BufferUtils.createIntBuffer(1);
stbtt_GetCodepointHMetrics(info, (int)text.charAt(i), advancewidth, leftsidebearing);
length += advancewidth.get(0);
}
return length * cscale;
}
其中info是通过stbtt_InitFont创建的字体信息对象,cscale来自stbtt_ScaleForPixelHeight。
答案 1 :(得分:1)
LWJGL STB True Type演示包含现在(自2017年8月开始)的实现,其中包括字距调整:
private float getStringWidth(STBTTFontinfo info, String text, int from, int to, int fontHeight) {
int width = 0;
try (MemoryStack stack = stackPush()) {
IntBuffer pCodePoint = stack.mallocInt(1);
IntBuffer pAdvancedWidth = stack.mallocInt(1);
IntBuffer pLeftSideBearing = stack.mallocInt(1);
int i = from;
while (i < to) {
i += getCP(text, to, i, pCodePoint);
int cp = pCodePoint.get(0);
stbtt_GetCodepointHMetrics(info, cp, pAdvancedWidth, pLeftSideBearing);
width += pAdvancedWidth.get(0);
if (isKerningEnabled() && i < to) {
getCP(text, to, i, pCodePoint);
width += stbtt_GetCodepointKernAdvance(info, cp, pCodePoint.get(0));
}
}
}
return width * stbtt_ScaleForPixelHeight(info, fontHeight);
}
private static int getCP(String text, int to, int i, IntBuffer cpOut) {
char c1 = text.charAt(i);
if (Character.isHighSurrogate(c1) && i + 1 < to) {
char c2 = text.charAt(i + 1);
if (Character.isLowSurrogate(c2)) {
cpOut.put(0, Character.toCodePoint(c1, c2));
return 2;
}
}
cpOut.put(0, c1);
return 1;
}