Modify line-breaking method for rendering fonts in PageText (#101)

Co-authored-by: ghostflyby <ghostflyby+git@outlook.com>
This commit is contained in:
ABKQPOandghostflyby authored and GitHub committed 2025-09-26 20:09:24 +08:00
1 parent 5dc4882038
commit 8350bd9dc7
2 files changed
+90 -60

No files matched your search

@@ -284,7 +284,7 @@ public class GuiLexicon extends GuiScreen {
boolean unicode = fontRendererObj.getUnicodeFlag();
fontRendererObj.setUnicodeFlag(true);
PageText.renderText(x + 5, y - 3, 92, 120, 0, noteDisplay);
PageText.renderText(x + 5, y - 3, 92, 0, noteDisplay);
fontRendererObj.setUnicodeFlag(unicode);
}
@@ -2,16 +2,18 @@
* This class was created by <Vazkii>. It's distributed as
* part of the Botania Mod. Get the Source Code in github:
* https://github.com/Vazkii/Botania
*
*
* Botania is Open Source and distributed under the
* Botania License: http://botaniamod.net/license.php
*
*
* File Created @ [Jan 14, 2014, 6:45:33 PM (GMT)]
*/
package vazkii.botania.common.lexicon.page;
import java.text.BreakIterator;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.FontRenderer;
@@ -47,74 +49,102 @@ public class PageText extends LexiconPage {
@SideOnly(Side.CLIENT)
public static void renderText(int x, int y, int width, int height, int paragraphSize, String unlocalizedText) {
x += 2;
y += 10;
width -= 4;
y += 10;
width -= 4;
FontRenderer font = Minecraft.getMinecraft().fontRenderer;
boolean unicode = font.getUnicodeFlag();
font.setUnicodeFlag(true);
String text = StatCollector.translateToLocal(unlocalizedText).replaceAll("&", "\u00a7");
String[] textEntries = text.split("<br>");
FontRenderer font = Minecraft.getMinecraft().fontRenderer;
boolean unicode = font.getUnicodeFlag();
font.setUnicodeFlag(true);
String text = StatCollector.translateToLocal(unlocalizedText).replaceAll("&", "\u00a7");
String[] textEntries = text.split("<br>");
List<List<String>> lines = new ArrayList<>();
List<List<String>> lines = new ArrayList<>(textEntries.length * 2);
String controlCodes = "";
for(String s : textEntries) {
List<String> words = new ArrayList<>();
String lineStr = "";
String[] tokens = s.split(" ");
for(String token : tokens) {
String prev = lineStr;
String spaced = token + " ";
lineStr += spaced;
String controlCodes;
var lang = Minecraft.getMinecraft().getLanguageManager().getCurrentLanguage();
var locale = Locale.forLanguageTag(lang.toString().replace(" (", "-").replace(")", ""));
if (locale == null) {
locale = Locale.forLanguageTag(lang.getLanguageCode());
}
if (locale == null) {
locale = Locale.ENGLISH;
}
for (String s : textEntries) {
List<String> words = new ArrayList<>();
String lineStr = "";
var breaker = BreakIterator.getLineInstance(locale);
breaker.setText(s);
int start = breaker.first();
for (int end = breaker.next(); end != BreakIterator.DONE; start = end, end = breaker.next()) {
String token = s.substring(start, end);
String prev = lineStr;
lineStr += token;
controlCodes = toControlCodes(getControlCodes(prev));
if(font.getStringWidth(lineStr) > width) {
lines.add(words);
lineStr = controlCodes + spaced;
words = new ArrayList<>();
}
controlCodes = toControlCodes(getControlCodes(prev));
if (font.getStringWidth(lineStr) > width) {
lines.add(words);
lineStr = controlCodes + token;
words = new ArrayList<>();
}
words.add(controlCodes + token);
}
words.add(controlCodes + token);
}
if(!lineStr.isEmpty())
lines.add(words);
lines.add(new ArrayList<>());
}
if (!lineStr.isEmpty())
lines.add(words);
lines.add(new ArrayList<>());
}
int i = 0;
for(List<String> words : lines) {
words.size();
int xi = x;
int spacing = 4;
int wcount = words.size();
int compensationSpaces = 0;
boolean justify = ConfigHandler.lexiconJustifiedText && wcount > 0 && lines.size() > i && !lines.get(i + 1).isEmpty();
int i = 0;
for (List<String> words : lines) {
int xi = x;
if(justify) {
String s = Joiner.on("").join(words);
int swidth = font.getStringWidth(s);
int space = width - swidth;
List<Integer> gapIds= new ArrayList<>(words.size());
for (int k = 0; k < words.size() - 1; k++) {
if (font.getStringWidth(words.get(k)) > 0 &&
font.getStringWidth(words.get(k + 1)) > 0) {
gapIds.add(k);
}
}
spacing = wcount == 1 ? 0 : space / (wcount - 1);
compensationSpaces = wcount == 1 ? 0 : space % (wcount - 1);
}
boolean nextLineExists = (i + 1) < lines.size();
boolean justify = ConfigHandler.lexiconJustifiedText
&& !words.isEmpty()
&& nextLineExists
&& !lines.get(i + 1).isEmpty()
&& !gapIds.isEmpty();
for(String s : words) {
int extra = 0;
if(compensationSpaces > 0) {
compensationSpaces--;
extra++;
}
font.drawString(s, xi, y, 0);
xi += font.getStringWidth(s) + spacing + extra;
}
int spacing = 0;
int compensation = 0;
y += words.isEmpty() ? paragraphSize : 10;
i++;
}
if (justify) {
String joined = Joiner.on("").join(words);
int swidth = font.getStringWidth(joined);
int extraSpace = width - swidth;
int gaps = gapIds.size();
spacing = extraSpace / gaps;
compensation = extraSpace % gaps;
}
int gi = 0;
for (int idx = 0; idx < words.size(); idx++) {
String tok = words.get(idx);
int tw = font.getStringWidth(tok);
font.drawString(tok, xi, y, 0);
xi += tw;
if (justify && gi < gapIds.size() && idx == gapIds.get(gi)) {
xi += spacing + (compensation > 0 ? 1 : 0);
if (compensation > 0) compensation--;
gi++;
}
}
y += words.isEmpty() ? paragraphSize : 10;
i++;
}
font.setUnicodeFlag(unicode);
}