mirror of
https://github.com/MightyPirates/OpenComputers.git
synced 2025-09-13 17:28:52 -04:00
Updated char width map for new font and made the width file resource-packable. Closes #1760.
This commit is contained in:
parent
d24d70554b
commit
e45acd967b
@ -72,10 +72,10 @@ opencomputers {
|
|||||||
# Defaults to white, feel free to make it some other color, tho!
|
# Defaults to white, feel free to make it some other color, tho!
|
||||||
monochromeColor: 0xFFFFFF
|
monochromeColor: 0xFFFFFF
|
||||||
|
|
||||||
# Which font renderer to use. Defaults to `unifont` if invalid.
|
# Which font renderer to use. Defaults to `hexfont` if invalid.
|
||||||
# Possible values:
|
# Possible values:
|
||||||
# - unifont: the (since 1.3.2) default font renderer. Based on the
|
# - hexfont: the (since 1.3.2) default font renderer. Font in .hex format
|
||||||
# Unifont and capable of rendering many unicode glyphs.
|
# capable of rendering many unicode glyphs.
|
||||||
# The used font data can be swapped out using resource packs,
|
# The used font data can be swapped out using resource packs,
|
||||||
# but is harder to work with, since it involves binary data.
|
# but is harder to work with, since it involves binary data.
|
||||||
# - texture: the old, font-texture based font renderer that was used
|
# - texture: the old, font-texture based font renderer that was used
|
||||||
@ -84,7 +84,7 @@ opencomputers {
|
|||||||
# is slightly less efficient than the new one, and more
|
# is slightly less efficient than the new one, and more
|
||||||
# importantly, can only render code page 437 (as opposed to...
|
# importantly, can only render code page 437 (as opposed to...
|
||||||
# a *lot* of unicode).
|
# a *lot* of unicode).
|
||||||
fontRenderer: "unifont"
|
fontRenderer=hexfont
|
||||||
|
|
||||||
# The sample rate used for generating beeps of computers' internal
|
# The sample rate used for generating beeps of computers' internal
|
||||||
# speakers. Use custom values at your own responsibility here; if it
|
# speakers. Use custom values at your own responsibility here; if it
|
||||||
@ -1480,7 +1480,7 @@ opencomputers {
|
|||||||
|
|
||||||
# Logs information about malformed glyphs (i.e. glyphs that deviate in
|
# Logs information about malformed glyphs (i.e. glyphs that deviate in
|
||||||
# width from what wcwidth says).
|
# width from what wcwidth says).
|
||||||
logUnifontErrors: false
|
logHexFontErrors: false
|
||||||
|
|
||||||
# Extract the native library with Lua into the system's temporary
|
# Extract the native library with Lua into the system's temporary
|
||||||
# directory instead of the game directory (e.g. /tmp on Linux). The
|
# directory instead of the game directory (e.g. /tmp on Linux). The
|
||||||
|
Binary file not shown.
@ -405,7 +405,7 @@ class Settings(val config: Config) {
|
|||||||
val logFullLibLoadErrors = config.getBoolean("debug.logFullNativeLibLoadErrors")
|
val logFullLibLoadErrors = config.getBoolean("debug.logFullNativeLibLoadErrors")
|
||||||
val forceNativeLib = config.getString("debug.forceNativeLibWithName")
|
val forceNativeLib = config.getString("debug.forceNativeLibWithName")
|
||||||
val logOpenGLErrors = config.getBoolean("debug.logOpenGLErrors")
|
val logOpenGLErrors = config.getBoolean("debug.logOpenGLErrors")
|
||||||
val logUnifontErrors = config.getBoolean("debug.logUnifontErrors")
|
val logHexFontErrors = config.getBoolean("debug.logHexFontErrors")
|
||||||
val alwaysTryNative = config.getBoolean("debug.alwaysTryNative")
|
val alwaysTryNative = config.getBoolean("debug.alwaysTryNative")
|
||||||
val debugPersistence = config.getBoolean("debug.verbosePersistenceErrors")
|
val debugPersistence = config.getBoolean("debug.verbosePersistenceErrors")
|
||||||
val nativeInTmpDir = config.getBoolean("debug.nativeInTmpDir")
|
val nativeInTmpDir = config.getBoolean("debug.nativeInTmpDir")
|
||||||
|
@ -19,7 +19,7 @@ import scala.collection.mutable
|
|||||||
*/
|
*/
|
||||||
class DynamicFontRenderer extends TextureFontRenderer with IResourceManagerReloadListener {
|
class DynamicFontRenderer extends TextureFontRenderer with IResourceManagerReloadListener {
|
||||||
private val glyphProvider: IGlyphProvider = Settings.get.fontRenderer match {
|
private val glyphProvider: IGlyphProvider = Settings.get.fontRenderer match {
|
||||||
case _ => new FontParserUnifont()
|
case _ => new FontParserHex()
|
||||||
}
|
}
|
||||||
|
|
||||||
private val textures = mutable.ArrayBuffer.empty[CharTexture]
|
private val textures = mutable.ArrayBuffer.empty[CharTexture]
|
||||||
|
@ -13,7 +13,7 @@ import java.io.InputStream;
|
|||||||
import java.io.InputStreamReader;
|
import java.io.InputStreamReader;
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
|
|
||||||
public class FontParserUnifont implements IGlyphProvider {
|
public class FontParserHex implements IGlyphProvider {
|
||||||
private static final byte[] OPAQUE = {(byte) 255, (byte) 255, (byte) 255, (byte) 255};
|
private static final byte[] OPAQUE = {(byte) 255, (byte) 255, (byte) 255, (byte) 255};
|
||||||
private static final byte[] TRANSPARENT = {0, 0, 0, 0};
|
private static final byte[] TRANSPARENT = {0, 0, 0, 0};
|
||||||
|
|
||||||
@ -26,17 +26,19 @@ public class FontParserUnifont implements IGlyphProvider {
|
|||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
final InputStream font = Minecraft.getMinecraft().getResourceManager().getResource(new ResourceLocation(Settings.resourceDomain(), "font.hex")).getInputStream();
|
final InputStream font = Minecraft.getMinecraft().getResourceManager().getResource(new ResourceLocation(Settings.resourceDomain(), "font.hex")).getInputStream();
|
||||||
OpenComputers.log().info("Initialized Unifont glyph provider.");
|
OpenComputers.log().info("Initialized unicode glyph provider.");
|
||||||
try {
|
try {
|
||||||
OpenComputers.log().info("Initializing Unifont glyph provider.");
|
OpenComputers.log().info("Initializing unicode glyph provider.");
|
||||||
final BufferedReader input = new BufferedReader(new InputStreamReader(font));
|
final BufferedReader input = new BufferedReader(new InputStreamReader(font));
|
||||||
String line;
|
String line;
|
||||||
int glyphCount = 0;
|
int glyphCount = 0;
|
||||||
while ((line = input.readLine()) != null) {
|
while ((line = input.readLine()) != null) {
|
||||||
final String[] info = line.split(":");
|
final String[] info = line.split(":");
|
||||||
final int charCode = Integer.parseInt(info[0], 16);
|
final int charCode = Integer.parseInt(info[0], 16);
|
||||||
|
if (charCode < 0 || charCode >= glyphs.length) continue; // Out of bounds.
|
||||||
final int expectedWidth = FontUtils.wcwidth(charCode);
|
final int expectedWidth = FontUtils.wcwidth(charCode);
|
||||||
if (expectedWidth < 1) continue; // Skip control characters.
|
if (expectedWidth < 1) continue; // Skip control characters.
|
||||||
|
// Two chars representing one byte represent one row of eight pixels.
|
||||||
final byte[] glyph = new byte[info[1].length() >> 1];
|
final byte[] glyph = new byte[info[1].length() >> 1];
|
||||||
final int glyphWidth = glyph.length / getGlyphHeight();
|
final int glyphWidth = glyph.length / getGlyphHeight();
|
||||||
if (expectedWidth == glyphWidth) {
|
if (expectedWidth == glyphWidth) {
|
||||||
@ -47,15 +49,16 @@ public class FontParserUnifont implements IGlyphProvider {
|
|||||||
glyphCount++;
|
glyphCount++;
|
||||||
}
|
}
|
||||||
glyphs[charCode] = glyph;
|
glyphs[charCode] = glyph;
|
||||||
} else if (Settings.get().logUnifontErrors()) {
|
} else if (Settings.get().logHexFontErrors()) {
|
||||||
OpenComputers.log().warn(String.format("Size of glyph for code point U+%04X (%s) in Unifont (%d) does not match expected width (%d), ignoring.", charCode, String.valueOf((char) charCode), glyphWidth, expectedWidth));
|
OpenComputers.log().warn(String.format("Size of glyph for code point U+%04X (%s) in font (%d) does not match expected width (%d), ignoring.", charCode, String.valueOf((char) charCode), glyphWidth, expectedWidth));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
OpenComputers.log().info("Loaded " + glyphCount + " glyphs.");
|
OpenComputers.log().info("Loaded " + glyphCount + " glyphs.");
|
||||||
} finally {
|
} finally {
|
||||||
try {
|
try {
|
||||||
font.close();
|
font.close();
|
||||||
} catch (IOException ignored) {
|
} catch (IOException ex) {
|
||||||
|
OpenComputers.log().warn("Error parsing font.", ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (IOException ex) {
|
} catch (IOException ex) {
|
||||||
@ -71,8 +74,10 @@ public class FontParserUnifont implements IGlyphProvider {
|
|||||||
final ByteBuffer buffer = BufferUtils.createByteBuffer(glyph.length * getGlyphWidth() * 4);
|
final ByteBuffer buffer = BufferUtils.createByteBuffer(glyph.length * getGlyphWidth() * 4);
|
||||||
for (byte aGlyph : glyph) {
|
for (byte aGlyph : glyph) {
|
||||||
int c = ((int) aGlyph) & 0xFF;
|
int c = ((int) aGlyph) & 0xFF;
|
||||||
|
// Grab all bits by grabbing the leftmost one then shifting.
|
||||||
for (int j = 0; j < 8; j++) {
|
for (int j = 0; j < 8; j++) {
|
||||||
if ((c & 128) > 0) buffer.put(OPAQUE);
|
final boolean isBitSet = (c & 0x80) > 0;
|
||||||
|
if (isBitSet) buffer.put(OPAQUE);
|
||||||
else buffer.put(TRANSPARENT);
|
else buffer.put(TRANSPARENT);
|
||||||
c <<= 1;
|
c <<= 1;
|
||||||
}
|
}
|
@ -12,7 +12,7 @@ public interface IGlyphProvider {
|
|||||||
* <p/>
|
* <p/>
|
||||||
* This should usually also be called from the implementation's constructor.
|
* This should usually also be called from the implementation's constructor.
|
||||||
*/
|
*/
|
||||||
public void initialize();
|
void initialize();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get a byte array of RGBA data describing the specified char.
|
* Get a byte array of RGBA data describing the specified char.
|
||||||
@ -30,9 +30,9 @@ public interface IGlyphProvider {
|
|||||||
*
|
*
|
||||||
* @param charCode the char to get the render glyph data for.
|
* @param charCode the char to get the render glyph data for.
|
||||||
* @return the RGBA byte array representing the char.
|
* @return the RGBA byte array representing the char.
|
||||||
* @see li.cil.oc.client.renderer.font.FontParserUnifont#getGlyph(int) See the Unifont parser for a reference implementation.
|
* @see FontParserHex#getGlyph(int) See the hexfont parser for a reference implementation.
|
||||||
*/
|
*/
|
||||||
public ByteBuffer getGlyph(int charCode);
|
ByteBuffer getGlyph(int charCode);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the single-width glyph width for this provider, in pixels.
|
* Get the single-width glyph width for this provider, in pixels.
|
||||||
@ -41,12 +41,12 @@ public interface IGlyphProvider {
|
|||||||
* a glyphs actual width (in pixels) is expected to be this value times
|
* a glyphs actual width (in pixels) is expected to be this value times
|
||||||
* {@link li.cil.oc.util.FontUtils#wcwidth(int)} (for a specific char).
|
* {@link li.cil.oc.util.FontUtils#wcwidth(int)} (for a specific char).
|
||||||
*/
|
*/
|
||||||
public int getGlyphWidth();
|
int getGlyphWidth();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the glyph height for this provider, in pixels.
|
* Get the glyph height for this provider, in pixels.
|
||||||
* <p/>
|
* <p/>
|
||||||
* Each glyph provided is expected to have the same height.
|
* Each glyph provided is expected to have the same height.
|
||||||
*/
|
*/
|
||||||
public int getGlyphHeight();
|
int getGlyphHeight();
|
||||||
}
|
}
|
||||||
|
@ -1,8 +1,12 @@
|
|||||||
package li.cil.oc.util
|
package li.cil.oc.util
|
||||||
|
|
||||||
import java.io.IOException
|
import java.io.IOException
|
||||||
|
import java.io.InputStream
|
||||||
|
|
||||||
import li.cil.oc.OpenComputers
|
import li.cil.oc.OpenComputers
|
||||||
|
import li.cil.oc.Settings
|
||||||
|
import net.minecraft.client.Minecraft
|
||||||
|
import net.minecraft.util.ResourceLocation
|
||||||
|
|
||||||
object FontUtils {
|
object FontUtils {
|
||||||
// Note: we load the widths from a file (one byte per width) because the Scala
|
// Note: we load the widths from a file (one byte per width) because the Scala
|
||||||
@ -11,14 +15,14 @@ object FontUtils {
|
|||||||
// who would have known!
|
// who would have known!
|
||||||
private val widths = {
|
private val widths = {
|
||||||
val ba = Array.fill[Byte](0x10000)(-1)
|
val ba = Array.fill[Byte](0x10000)(-1)
|
||||||
val is = FontUtils.getClass.getResourceAsStream("/assets/opencomputers/wcwidth.bin")
|
Minecraft.getMinecraft.getResourceManager.getResource(new ResourceLocation(Settings.resourceDomain, "wcwidth.bin")).getInputStream match {
|
||||||
if (is != null) {
|
case is: InputStream => try {
|
||||||
try {
|
|
||||||
is.read(ba)
|
is.read(ba)
|
||||||
is.close()
|
is.close()
|
||||||
} catch {
|
} catch {
|
||||||
case e: IOException => OpenComputers.log.warn("Failed loading character widths. Font rendering will probably be derpy as all hell.", e)
|
case e: IOException => OpenComputers.log.warn("Failed loading character widths. Font rendering will probably be derpy as all hell.", e)
|
||||||
}
|
}
|
||||||
|
case _ => // Null.
|
||||||
}
|
}
|
||||||
ba
|
ba
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user