Skip to content

Commit

Permalink
Support for multipart (HD) fonts
Browse files Browse the repository at this point in the history
  • Loading branch information
mepeisen committed Mar 25, 2018
1 parent f8ea865 commit e7bf91f
Show file tree
Hide file tree
Showing 4 changed files with 194 additions and 78 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,8 @@ public class FixedWidthFontRenderer

public static ResourceLocation background = new ResourceLocation( "computercraft", "textures/gui/term_background.png" );

public static final int FONT_HEIGHT = FontManager.LEGACY.fontHeight(); // original values
public static final int FONT_WIDTH = FontManager.LEGACY.fontWidth(); // original values
public static final int FONT_HEIGHT = FontManager.LEGACY.getPart(' ').fontHeight(); // original values
public static final int FONT_WIDTH = FontManager.LEGACY.getPart(' ').fontWidth(); // original values

private TextureManager m_textureManager;

Expand All @@ -38,10 +38,10 @@ private static void greyscaleify( double[] rgb )
Arrays.fill( rgb, ( rgb[0] + rgb[1] + rgb[2] ) / 3.0f );
}

private void drawChar( FontDefinition fd, BufferBuilder renderer, double x, double y, int index, int color, Palette p, boolean greyscale )
private void drawChar( FontPart fd, BufferBuilder renderer, double x, double y, int index, int color, Palette p, boolean greyscale )
{
int column = index % fd.charsPerLine();
int row = index / fd.charsPerLine();
int column = (index - fd.begin()) % fd.charsPerLine();
int row = (index - fd.begin()) / fd.charsPerLine();

double[] colour = p.getColour( 15 - color );
if(greyscale)
Expand Down Expand Up @@ -125,7 +125,7 @@ public void drawStringBackgroundPart( int x, int y, TextBuffer backgroundColour,
GlStateManager.enableTexture2D();
}

private void drawStringTextPart( int x, int y, TextBuffer s, TextBuffer textColour, boolean greyScale, Palette p )
public void drawStringTextPart( int x, int y, TextBuffer s, TextBuffer textColour, boolean greyScale, Palette p )
{
drawStringTextPart(FontManager.LEGACY, x, y, s, textColour, greyScale, p);
}
Expand All @@ -135,28 +135,58 @@ public void drawStringTextPart( FontDefinition fd, int x, int y, TextBuffer s, T
// Draw the quads
Tessellator tessellator = Tessellator.getInstance();
BufferBuilder renderer = tessellator.getBuffer();
renderer.begin( GL11.GL_TRIANGLES, DefaultVertexFormats.POSITION_TEX_COLOR );
for( int i = 0; i < s.length(); i++ )
FontPart curPart = null;

for( int i = 0; i < s.length(); i++ )
{
// Draw char
int index = s.codepointAt( i );
if( index < 0 || index > fd.maxChars() )
{
index = (int)'?';
}
FontPart newPart = fd.getPart(index);
if (newPart == null)
{
// fall back to '?'
index = (int)'?';
newPart = fd.getPart(index);
}

// if newPart is null this font is corrupt... It does not know how to display simple quotion mark ('?')
if (newPart != null)
{
if (curPart != newPart)
{
if (curPart != null)
{
tessellator.draw();
}
curPart = newPart;
// begin drawing using this font part
bindFont(fd, curPart);
renderer.begin( GL11.GL_TRIANGLES, DefaultVertexFormats.POSITION_TEX_COLOR );
}
}

// Switch colour
int colour = "0123456789abcdef".indexOf( textColour.charAt( i ) );
if( colour < 0 || ( greyScale && !isGreyScale( colour ) ) )
{
colour = 0;
}

// Draw char
int index = s.codepointAt( i );
if( index < 0 || index > fd.maxChars() )
{
index = (int)'?';
}
drawChar( fd, renderer, x + i * FONT_WIDTH, y, index, colour, p, greyScale );
drawChar( curPart, renderer, x + i * FONT_WIDTH, y, index, colour, p, greyScale );
}
tessellator.draw();

if (curPart != null)
{
// we did draw something. Finish it.
tessellator.draw();
}
}

private void drawString( TextBuffer s, int x, int y, TextBuffer textColour, TextBuffer backgroundColour, double leftMarginSize, double rightMarginSize, boolean greyScale, Palette p )
public void drawString( TextBuffer s, int x, int y, TextBuffer textColour, TextBuffer backgroundColour, double leftMarginSize, double rightMarginSize, boolean greyScale, Palette p )
{
drawString(FontManager.LEGACY, s, x, y, textColour, backgroundColour, leftMarginSize, rightMarginSize, greyScale, p);
}
Expand All @@ -176,9 +206,6 @@ public void drawString( FontDefinition fd, TextBuffer s, int x, int y, TextBuffe
// Draw text
if( s != null && textColour != null )
{
// Bind the font texture
bindFont(fd);

// Draw the quads
drawStringTextPart( fd, x, y, s, textColour, greyScale, p );
}
Expand All @@ -193,14 +220,19 @@ public int getStringWidth(String s)
return s.length() * FONT_WIDTH;
}

private void bindFont()
public void bindFont()
{
bindFont(FontManager.LEGACY);
}

public void bindFont(FontDefinition fd)
{
m_textureManager.bindTexture( fd.font() );
bindFont(fd, fd.getPart(' '));
}

public void bindFont(FontDefinition fd, FontPart part)
{
m_textureManager.bindTexture( part.font() );
GlStateManager.glTexParameteri( GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_WRAP_S, GL11.GL_CLAMP );
if (fd.isBlending())
{
Expand Down
62 changes: 21 additions & 41 deletions src/main/java/dan200/computercraft/client/gui/FontDefinition.java
Original file line number Diff line number Diff line change
@@ -1,73 +1,53 @@
package dan200.computercraft.client.gui;

import net.minecraft.util.ResourceLocation;
import java.util.List;

import scala.actors.threadpool.Arrays;

public class FontDefinition {

private final ResourceLocation font;
private final int fontHeight;
private final int fontWidth;
private final double texHeight;
private final double texWidth;
private final int maxChars;
private final int charsPerLine;
private final String name;
private final boolean blending;
private final FontPart[] parts;

protected FontDefinition(String name, ResourceLocation font, int fontHeight, int fontWidth, int maxChars, int charsPerLine, double texWidth, double texHeight, boolean blending) {
protected FontDefinition(String name, int maxChars, boolean blending, FontPart... parts) {
this.name = name;
this.font = font;
this.fontHeight = fontHeight;
this.fontWidth = fontWidth;
this.maxChars = maxChars;
this.charsPerLine = charsPerLine;
this.texWidth = texWidth;
this.texHeight = texHeight;
this.blending = blending;
this.parts = parts;
}

public String name()
{
return this.name;
}

public ResourceLocation font()
{
return this.font;
}

public int fontHeight()
@SuppressWarnings("unchecked")
public List<FontPart> getParts()
{
return this.fontHeight;
}

public int fontWidth()
{
return this.fontWidth;
return Arrays.asList(this.parts);
}

public int maxChars()
{
return this.maxChars;
}

public int charsPerLine()
{
return this.charsPerLine;
}

public double texWidth()
{
return texWidth;
}

public double texHeight()
{
return texHeight;
}

public boolean isBlending() {
return blending;
}

public FontPart getPart(int codepoint)
{
for (final FontPart part : this.parts)
{
if (codepoint >= part.begin() && codepoint <= part.end())
{
return part;
}
}
return null;
}

}
69 changes: 54 additions & 15 deletions src/main/java/dan200/computercraft/client/gui/FontManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,13 @@ public class FontManager {
private TextureManager m_textureManager;

public static final FontDefinition LEGACY = new FontDefinition(
"LEGACY", new ResourceLocation( "computercraft", "textures/gui/term_font.png" ),
9, 6, 256, 16, 256.0, 256.0, false);
"LEGACY", 256, false,
new FontPart(
new ResourceLocation( "computercraft", "textures/gui/term_font.png" ),
9, 6,
0, 256,
16,
256.0, 256.0));

public FontManager(TextureManager textureManager)
{
Expand Down Expand Up @@ -61,23 +66,57 @@ private void loadFonts(IMount mount, String name)
try (final InputStream is = mount.openForRead(f))
{
props.load(is);
if (!"1".equals(props.getProperty("version")))
FontDefinition fd = null;
if ("1".equals(props.getProperty("version")))
{
ComputerCraft.log.error("font version " + fname + ":" + props.getProperty("version") + " not supported");
fd = new FontDefinition(
fname,
Integer.parseInt(props.getProperty("maxChars")),
"true".equalsIgnoreCase(props.getProperty("blending")),
new FontPart(
new ResourceLocation( "computercraft", "textures/gui/fonts/" + png ),
Integer.parseInt(props.getProperty("fontHeight")),
Integer.parseInt(props.getProperty("fontWidth")),
0,
Integer.parseInt(props.getProperty("maxChars")),
Integer.parseInt(props.getProperty("charsPerLine")),
Integer.parseInt(props.getProperty("texWidth")),
Integer.parseInt(props.getProperty("texHeight"))

));
}
else if ("2".equals(props.getProperty("version")))
{
final List<FontPart> parts = new ArrayList<>();
int partcount = Integer.parseInt(props.getProperty("parts"));
for (int partno = 0; partno < partcount; partno++) {
parts.add(
new FontPart(
new ResourceLocation( "computercraft", "textures/gui/fonts/" + props.getProperty("texture_"+partno) ),
Integer.parseInt(props.getProperty("fontHeight_"+partno)),
Integer.parseInt(props.getProperty("fontWidth_"+partno)),
Integer.parseInt(props.getProperty("start_"+partno)),
Integer.parseInt(props.getProperty("end_"+partno)),
Integer.parseInt(props.getProperty("charsPerLine_"+partno)),
Integer.parseInt(props.getProperty("texWidth_"+partno)),
Integer.parseInt(props.getProperty("texHeight_"+partno))
));
}

fd = new FontDefinition(
fname,
Integer.parseInt(props.getProperty("maxChars")),
"true".equalsIgnoreCase(props.getProperty("blending")),
parts.toArray(new FontPart[parts.size()]));
}
else
{
FontDefinition fd = new FontDefinition(
fname, new ResourceLocation( "computercraft", "textures/gui/fonts/" + png ),
Integer.parseInt(props.getProperty("fontHeight")),
Integer.parseInt(props.getProperty("fontWidth")),
Integer.parseInt(props.getProperty("maxChars")),
Integer.parseInt(props.getProperty("charsPerLine")),
Integer.parseInt(props.getProperty("texWidth")),
Integer.parseInt(props.getProperty("texHeight")),
"true".equalsIgnoreCase(props.getProperty("blending"))
);
m_textureManager.bindTexture( fd.font() );
ComputerCraft.log.error("font version " + fname + ":" + props.getProperty("version") + " not supported");
}

if (fd != null)
{
fd.getParts().forEach(fp -> m_textureManager.bindTexture( fp.font() ));
fonts.put(fname, fd);
}
}
Expand Down
65 changes: 65 additions & 0 deletions src/main/java/dan200/computercraft/client/gui/FontPart.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
package dan200.computercraft.client.gui;

import net.minecraft.util.ResourceLocation;

public class FontPart {

private final ResourceLocation font;
private final int fontHeight;
private final int fontWidth;
private final double texHeight;
private final double texWidth;
private final int begin;
private final int end;
private final int charsPerLine;

protected FontPart(ResourceLocation font, int fontHeight, int fontWidth, int begin, int end, int charsPerLine, double texWidth, double texHeight) {
this.font = font;
this.fontHeight = fontHeight;
this.fontWidth = fontWidth;
this.charsPerLine = charsPerLine;
this.texWidth = texWidth;
this.texHeight = texHeight;
this.begin = begin;
this.end = end;
}

public ResourceLocation font()
{
return this.font;
}

public int fontHeight()
{
return this.fontHeight;
}

public int fontWidth()
{
return this.fontWidth;
}

public int charsPerLine()
{
return this.charsPerLine;
}

public double texWidth()
{
return texWidth;
}

public double texHeight()
{
return texHeight;
}

public int begin() {
return begin;
}

public int end() {
return end;
}

}

0 comments on commit e7bf91f

Please sign in to comment.