use of org.lwjgl.stb.STBTTFontinfo in project PanguEngine by UnknownDomainGames.
the class STBFontManager method bakeTextMesh.
@Override
public TextMesh bakeTextMesh(CharSequence text, Font font) {
TextMesh.CharQuad[] quads = new TextMesh.CharQuad[text.length()];
NativeTTFont nativeTTFont = getNativeFont(font);
STBTTFontinfo fontInfo = nativeTTFont.getInfo().getFontInfo();
float scale = nativeTTFont.getScaleForPixelHeight();
try (MemoryStack stack = MemoryStack.stackPush()) {
IntBuffer charPointBuffer = stack.mallocInt(1);
FloatBuffer posX = stack.floats(0);
var fontPlaneTexture = nativeTTFont.getPlaneTextures().get(0);
for (int i = 0; i < text.length(); ) {
i += getCodePoint(text, i, charPointBuffer);
int charPoint = charPointBuffer.get(0);
if (!isSupportedCharacter(nativeTTFont, charPoint)) {
continue;
}
if (!nativeTTFont.isBlockLoaded((char) charPoint)) {
fontPlaneTexture.putBlock(Character.UnicodeBlock.of(charPoint));
}
if (fontPlaneTexture.isWaitingForReloading()) {
fontPlaneTexture.bakeTexture(nativeTTFont.getFont(), nativeTTFont.getInfo());
}
}
for (int i = 0, j = 0; i < text.length(); j++) {
i += getCodePoint(text, i, charPointBuffer);
int charPoint = charPointBuffer.get(0);
if (!isSupportedCharacter(nativeTTFont, charPoint)) {
charPoint = '\u001A';
charPointBuffer.put(0, charPoint);
}
float centerX = posX.get(0);
var quad = fontPlaneTexture.getQuad((char) charPoint);
if (quad == null)
continue;
posX.put(0, posX.get(0) + quad.getXOffset());
if (i < text.length()) {
getCodePoint(text, i, charPointBuffer);
posX.put(0, posX.get(0) + stbtt_GetCodepointKernAdvance(fontInfo, charPoint, charPointBuffer.get(0)) * scale);
}
float x0 = (float) Math.floor(centerX + quad.getPos().x() + 0.5), x1 = (float) Math.floor(centerX + quad.getPos().z() + 0.5), y0 = (float) Math.floor(quad.getPos().y() + 0.5), y1 = (float) Math.floor(quad.getPos().w() + 0.5);
quads[j] = new TextMesh.CharQuad((char) charPoint, x0, y0, x1, y1, quad.getTexCoord());
}
return new TextMesh(text, font, fontPlaneTexture.getTexture(), quads);
}
}
use of org.lwjgl.stb.STBTTFontinfo in project PanguEngine by UnknownDomainGames.
the class STBFontManager method loadFontInfo.
private NativeTTFontInfo[] loadFontInfo(Path fontFile, ByteBuffer fontData, boolean delayLoading, boolean enable) {
var fontCount = stbtt_GetNumberOfFonts(fontData);
if (fontCount == -1) {
throw new IllegalArgumentException("Cannot determine the number of fonts in the font buffer.");
}
NativeTTFontInfo[] results = new NativeTTFontInfo[fontCount];
for (int i = 0; i < fontCount; i++) {
STBTTFontinfo fontInfo = STBTTFontinfo.create();
if (!stbtt_InitFont(fontInfo, fontData)) {
throw new IllegalStateException("Failed in initializing ttf font info");
}
FontDataFormat format = findDataFormat(fontInfo);
if (format == null) {
throw new FontLoadException("Cannot load font because of not found encoding id.");
}
String family = stbtt_GetFontNameString(fontInfo, STBTT_PLATFORM_ID_MICROSOFT, format.encodingId, format.languageId, 1).order(ByteOrder.BIG_ENDIAN).asCharBuffer().toString();
String style = stbtt_GetFontNameString(fontInfo, STBTT_PLATFORM_ID_MICROSOFT, format.encodingId, format.languageId, 2).order(ByteOrder.BIG_ENDIAN).asCharBuffer().toString();
try (MemoryStack stack = stackPush()) {
IntBuffer pAscent = stack.mallocInt(1);
IntBuffer pDescent = stack.mallocInt(1);
IntBuffer pLineGap = stack.mallocInt(1);
stbtt_GetFontVMetrics(fontInfo, pAscent, pDescent, pLineGap);
IntBuffer x0 = stack.mallocInt(1);
IntBuffer y0 = stack.mallocInt(1);
IntBuffer x1 = stack.mallocInt(1);
IntBuffer y1 = stack.mallocInt(1);
stbtt_GetFontBoundingBox(fontInfo, x0, y0, x1, y1);
var builder = NativeTTFontInfo.builder().platformId(STBTT_PLATFORM_ID_MICROSOFT).encodingId(format.encodingId).languageId(format.languageId).family(family).style(style).offsetIndex(i).ascent(pAscent.get(0)).descent(pDescent.get(0)).lineGap(pLineGap.get(0)).boundingBox(new int[] { x0.get(), y0.get(), x1.get(), y1.get() });
if (delayLoading) {
builder.fontFile(fontFile);
} else {
builder.fontData(fontData).fontInfo(fontInfo);
}
var result = builder.build();
if (enable) {
loadedFontInfos.put(family, style, result);
availableFonts.add(result.getFont());
}
results[i] = result;
}
}
return results;
}
use of org.lwjgl.stb.STBTTFontinfo in project PanguEngine by UnknownDomainGames.
the class STBFontManager method computeTextWidth.
/**
* compute the text width
*
* @param text the text
* @param font the font of the text
* @param ceilingWidth the maximum width of the text. -1 if no limitation on it
*/
@Override
public float computeTextWidth(String text, Font font, float ceilingWidth) {
if (text == null || text.length() == 0) {
return 0;
}
List<String> trial;
if (ceilingWidth != -1) {
trial = text.lines().flatMap(str -> wrapText(str, ceilingWidth, font).stream()).collect(Collectors.toList());
} else {
trial = text.lines().collect(Collectors.toList());
}
if (trial.size() > 1) {
var max = -1.0f;
for (String s : trial) {
max = Math.max(max, computeTextWidth(s, font));
}
return max;
}
NativeTTFont nativeFont = getNativeFont(font);
STBTTFontinfo info = nativeFont.getInfo().getFontInfo();
int width = 0;
try (MemoryStack stack = stackPush()) {
IntBuffer pCodePoint = stack.mallocInt(1);
IntBuffer pAdvancedWidth = stack.mallocInt(1);
IntBuffer pLeftSideBearing = stack.mallocInt(1);
int i = 0;
while (i < text.length()) {
i += getCodePoint(text, i, pCodePoint);
int cp = pCodePoint.get(0);
stbtt_GetCodepointHMetrics(info, cp, pAdvancedWidth, pLeftSideBearing);
if (i < text.length()) {
getCodePoint(text, i, pCodePoint);
pAdvancedWidth.put(0, pAdvancedWidth.get(0) + stbtt_GetCodepointKernAdvance(info, cp, pCodePoint.get(0)));
}
width += pAdvancedWidth.get(0);
}
}
return width * nativeFont.getScaleForPixelHeight();
}
use of org.lwjgl.stb.STBTTFontinfo in project SpeedRunIGT by RedLime.
the class FontUtils method addFont.
public static void addFont(HashMap<Identifier, List<Font>> map, File file, File configFile) {
FileInputStream fileInputStream = null;
STBTTFontinfo sTBTTFontinfo = null;
ByteBuffer byteBuffer = null;
Throwable throwable = null;
try {
fileInputStream = new FileInputStream(file);
sTBTTFontinfo = STBTTFontinfo.malloc();
byteBuffer = TextureUtil.readAllToByteBuffer(fileInputStream);
byteBuffer.flip();
if (!STBTruetype.stbtt_InitFont(sTBTTFontinfo, byteBuffer)) {
return;
}
Identifier fontIdentifier = new Identifier(SpeedRunIGT.MOD_ID, file.getName().toLowerCase(Locale.ROOT).replace(".ttf", "").replaceAll(" ", "_").replaceAll("[^a-z0-9/._-]", ""));
ArrayList<Font> fontArrayList = new ArrayList<>();
FontConfigure fontConfigure;
if (configFile != null && configFile.exists()) {
fontConfigure = FontConfigure.fromJson(FileUtils.readFileToString(configFile, StandardCharsets.UTF_8));
} else {
fontConfigure = FontConfigure.create();
}
fontArrayList.add(new TrueTypeFont(byteBuffer, sTBTTFontinfo, fontConfigure.size, fontConfigure.oversample, fontConfigure.shift[0], fontConfigure.shift[1], fontConfigure.skip));
SpeedRunIGT.FONT_MAPS.put(fontIdentifier, new FontIdentifier(file, fontIdentifier, fontConfigure));
fontArrayList.add(new BlankFont());
map.put(fontIdentifier, fontArrayList);
} catch (FileNotFoundException e) {
if (sTBTTFontinfo != null)
sTBTTFontinfo.free();
MemoryUtil.memFree(byteBuffer);
} catch (IOException throwable1) {
throwable = throwable1;
} finally {
try {
if (fileInputStream != null)
fileInputStream.close();
} catch (IOException e) {
if (throwable != null)
throwable.addSuppressed(e);
}
}
}
Aggregations