Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 10 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -1053,7 +1053,7 @@ if (BUILD_CLIENT)

add_custom_command(
OUTPUT ${outpath}
COMMAND ${CMAKE_COMMAND} "-DINPUT_FILE=${res}" "-DOUTPUT_FILE=${outpath}"
COMMAND ${CMAKE_COMMAND} "-DINPUT_FILE=${res}" "-DOUTPUT_FILE=${outpath}" -DTEXT_MODE=1
"-DVARIABLE_NAME=${filename_no_ext}_glsl" -P ${CMAKE_CURRENT_SOURCE_DIR}/cmake/EmbedText.cmake
MAIN_DEPENDENCY ${res}
)
Expand All @@ -1071,6 +1071,15 @@ if (BUILD_CLIENT)
string(APPEND SHADERS_CPP_TEXT "};\n")

daemon_write_generated("shaders.cpp" "${SHADERS_CPP_TEXT}")

add_custom_command(
OUTPUT ${EMBED_INCLUDE_DIR}/daemon_unifont.h
COMMAND ${CMAKE_COMMAND} "-DINPUT_FILE=${CMAKE_CURRENT_SOURCE_DIR}/libs/unifont/unifont.otf" "-DOUTPUT_FILE=${EMBED_INCLUDE_DIR}/daemon_unifont.h"
-DTEXT_MODE=0 -DVARIABLE_NAME=daemon_unifont_bin -P ${CMAKE_CURRENT_SOURCE_DIR}/cmake/EmbedText.cmake
MAIN_DEPENDENCY ${CMAKE_CURRENT_SOURCE_DIR}/libs/unifont/unifont.otf
)
set_property(TARGET client-objects APPEND PROPERTY SOURCES ${EMBED_INCLUDE_DIR}/daemon_unifont.h)
include_directories(${EMBED_INCLUDE_DIR})
endif()

if (BUILD_SERVER)
Expand Down
8 changes: 6 additions & 2 deletions cmake/EmbedText.cmake
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
# Converts a text file into a C-language char array definition.
# For use in CMake script mode (cmake -P).
# Required definitions on command line: INPUT_FILE, OUTPUT_FILE, VARIABLE_NAME
# Required definitions on command line: INPUT_FILE, OUTPUT_FILE, VARIABLE_NAME, TEXT_MODE

# Inspired by https://stackoverflow.com/questions/11813271/embed-resources-eg-shader-code-images-into-executable-library-with-cmake/27206982#27206982
file(READ ${INPUT_FILE} contents HEX)
string(REGEX REPLACE "(0d)?(..)" "0x\\2," contents ${contents}) # Strip \r for consistency
if (TEXT_MODE)
string(REGEX REPLACE "(0d)?(..)" "0x\\2," contents ${contents}) # Strip \r for consistency
else()
string(REGEX REPLACE "(..)" "0x\\1," contents ${contents})
endif()
file(WRITE ${OUTPUT_FILE} "const unsigned char ${VARIABLE_NAME}[] = {${contents}};\n")
Binary file added libs/unifont/unifont.otf
Binary file not shown.
Binary file removed pkg/daemon_src.dpkdir/gfx/2d/bigchars.png
Binary file not shown.
12 changes: 0 additions & 12 deletions pkg/daemon_src.dpkdir/scripts/engine.shader
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,3 @@ white
rgbgen vertex
}
}

// console font fallback
gfx/2d/bigchars
{
nopicmip
nomipmaps
{
map gfx/2d/bigchars
blendFunc GL_SRC_ALPHA GL_ONE_MINUS_SRC_ALPHA
rgbgen vertex
}
}
53 changes: 25 additions & 28 deletions src/engine/client/cl_main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2095,50 +2095,47 @@ bool CL_InitRenderer()
return false;
}

fileHandle_t f;

// this sets up the renderer and calls R_Init
if ( !re.BeginRegistration( &cls.windowConfig ) )
{
return false;
}

cl_consoleFont = Cvar_Get( "cl_consoleFont", "fonts/unifont.ttf", CVAR_LATCH );
cl_consoleFont = Cvar_Get( "cl_consoleFont", "", CVAR_LATCH );
cl_consoleFontSize = Cvar_Get( "cl_consoleFontSize", "16", CVAR_LATCH );
cl_consoleFontScaling = Cvar_Get( "cl_consoleFontScaling", "1", CVAR_LATCH );

// load character sets
cls.charSetShader = re.RegisterShader( "gfx/2d/bigchars", RSF_2D );
cls.useLegacyConsoleFont = cls.useLegacyConsoleFace = true;
// Register console font specified by cl_consoleFont. Empty string means use the embbed Unifont

int fontSize = cl_consoleFontSize->integer;

// Register console font specified by cl_consoleFont, if any
// filehandle is unused but forces FS_FOpenFileRead() to heed purecheck because it does not when filehandle is nullptr
if ( cl_consoleFont->string[0] )
if ( cl_consoleFontScaling->integer )
{
if ( FS_FOpenFileRead( cl_consoleFont->string, &f ) >= 0 )
{
if ( cl_consoleFontScaling->value == 0 )
{
cls.consoleFont = re.RegisterFont( cl_consoleFont->string, cl_consoleFontSize->integer );
}
else
{
// This gets 12px on 1920×1080 screen, which is libRocket default for 1em
int fontScale = std::min(cls.windowConfig.vidWidth, cls.windowConfig.vidHeight) / 90;
// This gets 12px on 1920×1080 screen, which is libRocket default for 1em
int fontScale = std::min(cls.windowConfig.vidWidth, cls.windowConfig.vidHeight) / 90;

// fontScale / 12px gets 1px on 1920×1080 screen
cls.consoleFont = re.RegisterFont( cl_consoleFont->string, cl_consoleFontSize->integer * fontScale / 12 );
}
// fontScale / 12px gets 1px on 1920×1080 screen
fontSize = cl_consoleFontSize->integer * fontScale / 12;
}

if ( cls.consoleFont != nullptr )
cls.useLegacyConsoleFont = false;
}
else
if ( cl_consoleFont->string[ 0 ] )
{
cls.consoleFont = re.RegisterFont( cl_consoleFont->string, fontSize );
if ( cls.consoleFont == nullptr )
{
Log::Warn("Font file '%s' not found", cl_consoleFont->string);
Log::Warn( "Couldn't load font file '%s', falling back to default console font",
cl_consoleFont->string );
}
}

FS_FCloseFile( f );
if ( cls.consoleFont == nullptr )
{
cls.consoleFont = re.RegisterFont( "", fontSize );

if ( cls.consoleFont == nullptr )
{
Sys::Error( "Failed to load built-in console font" );
}
}

cls.whiteShader = re.RegisterShader( "white", RSF_NOMIP );
Expand Down
87 changes: 3 additions & 84 deletions src/engine/client/cl_scrn.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -107,12 +107,6 @@ static glyphInfo_t *Glyph( int ch )

void SCR_DrawConsoleFontUnichar( float x, float y, int ch )
{
if ( cls.useLegacyConsoleFont )
{
SCR_DrawSmallUnichar( ( int ) x, ( int ) y, ch );
return;
}

if ( ch != ' ' )
{
glyphInfo_t *glyph = Glyph( ch );
Expand All @@ -126,53 +120,6 @@ void SCR_DrawConsoleFontUnichar( float x, float y, int ch )
}
}

/*
** SCR_DrawSmallUnichar
** small chars are drawn at native screen resolution
*/
void SCR_DrawSmallUnichar( int x, int y, int ch )
{
int row, col;
float frow, fcol;
float size;

if ( ch < 0x100 || cls.useLegacyConsoleFont )
{
if ( ch == ' ' ) {
return;
}

if ( y < -SMALLCHAR_HEIGHT ) {
return;
}

if ( ch >= 0x100 ) { ch = 0; }

row = ch>>4;
col = ch&15;

frow = row*0.0625;
fcol = col*0.0625;
size = 0.0625;

// adjust for baseline
re.DrawStretchPic( x, y - (int)( SMALLCHAR_HEIGHT / ( CONSOLE_FONT_VPADDING + 1 ) ),
SMALLCHAR_WIDTH, SMALLCHAR_HEIGHT,
fcol, frow,
fcol + size, frow + size,
cls.charSetShader );
} else {
glyphInfo_t *glyph = Glyph( ch );

re.DrawStretchPic( x, y, SMALLCHAR_WIDTH, glyph->imageHeight,
glyph->s,
glyph->t,
glyph->s2,
glyph->t2,
glyph->glyph );
}
}

/*
==================
SCR_DrawSmallString[Color]
Expand Down Expand Up @@ -335,9 +282,7 @@ void SCR_UpdateScreen()

float SCR_ConsoleFontUnicharWidth( int ch )
{
return cls.useLegacyConsoleFont
? SMALLCHAR_WIDTH
: Glyph( ch )->xSkip + cl_consoleFontKerning->value;
return Glyph( ch )->xSkip + cl_consoleFontKerning->value;
}

float SCR_ConsoleFontCharWidth( const char *s )
Expand All @@ -347,44 +292,18 @@ float SCR_ConsoleFontCharWidth( const char *s )

float SCR_ConsoleFontCharHeight()
{
return cls.useLegacyConsoleFont
? SMALLCHAR_HEIGHT
: cls.consoleFont->glyphBlock[0][(unsigned)'I'].imageHeight + CONSOLE_FONT_VPADDING * cl_consoleFontSize->value;
return cls.consoleFont->glyphBlock[0][(unsigned)'I'].imageHeight + CONSOLE_FONT_VPADDING * cl_consoleFontSize->value;
}

float SCR_ConsoleFontCharVPadding()
{
return cls.useLegacyConsoleFont
? 0
: std::max( 0, -cls.consoleFont->glyphBlock[0][(unsigned)'g'].bottom >> 6);
return std::max( 0, -cls.consoleFont->glyphBlock[0][(unsigned)'g'].bottom >> 6);
}

float SCR_ConsoleFontStringWidth( const char* s, int len )
{
float width = 0;

if( cls.useLegacyConsoleFont )
{
if( cls.useLegacyConsoleFace )
{
return len * SMALLCHAR_WIDTH;
}
else
{
int l = 0;
const char *str = s;

while( *str && len > 0 )
{
l++;
str += Q_UTF8_Width( str );
len--;
}

return l * SMALLCHAR_WIDTH;
}
}

while( *s && len > 0 )
{
width += SCR_ConsoleFontCharWidth( s );
Expand Down
4 changes: 0 additions & 4 deletions src/engine/client/client.h
Original file line number Diff line number Diff line change
Expand Up @@ -315,10 +315,7 @@ struct clientStatic_t

// rendering info
WindowConfig windowConfig;
qhandle_t charSetShader;
qhandle_t whiteShader;
bool useLegacyConsoleFont;
bool useLegacyConsoleFace;
fontInfo_t *consoleFont;

// www downloading
Expand Down Expand Up @@ -655,7 +652,6 @@ void SCR_AdjustFrom640( float *x, float *y, float *w, float *h );
void SCR_FillRect( float x, float y, float width, float height, const Color::Color& color );

void SCR_DrawSmallStringExt( int x, int y, const char *string, const Color::Color& setColor, bool forceColor, bool noColorEscape );
void SCR_DrawSmallUnichar( int x, int y, int ch );
void SCR_DrawConsoleFontUnichar( float x, float y, int ch );
float SCR_ConsoleFontCharWidth( const char *s );
float SCR_ConsoleFontUnicharWidth( int ch );
Expand Down
7 changes: 5 additions & 2 deletions src/engine/null/null_renderer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,11 @@ qhandle_t RE_RegisterShader( const char *, int )
}
fontInfo_t* RE_RegisterFont( const char *, int )
{
return nullptr;
return new fontInfo_t{};
}
void RE_UnregisterFont( fontInfo_t* p )
{
delete p;
}
void RE_GlyphChar( fontInfo_t *, int, glyphInfo_t *glyph )
{
Expand All @@ -70,7 +74,6 @@ void RE_GlyphChar( fontInfo_t *, int, glyphInfo_t *glyph )
glyph->glyph = 1;
glyph->shaderName[0] = '\0';
}
void RE_UnregisterFont( fontInfo_t* ) { }
void RE_LoadWorldMap( const char * ) { }
void RE_SetWorldVisData( const byte * ) { }
void RE_EndRegistration() { }
Expand Down
36 changes: 28 additions & 8 deletions src/engine/renderer/tr_font.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@ Maryland 20850 USA.
#include "qcommon/qcommon.h"
#include "qcommon/q_unicode.h"

#include "daemon_unifont.h"

#include <ft2build.h>
#include FT_FREETYPE_H
#include FT_ERRORS_H
Expand Down Expand Up @@ -417,28 +419,46 @@ void RE_RenderChunk( fontInfo_t *font, const int chunk )

static int RE_LoadFontFile( const char *name, void **buffer )
{
void *tmp;
int length = ri.FS_ReadFile( name, &tmp );
if ( !*name )
{
*buffer = (void *)( &daemon_unifont_bin );
return sizeof( daemon_unifont_bin );
}

std::string tmp;

try
{
tmp = FS::HomePath::OpenRead( name ).ReadAll();
}
catch ( const std::system_error &exc )
{
Log::Warn( "Failed to read font file: %s", exc.what() );
return 0;
}

if ( length <= 0 )
if ( tmp.size() > 1000 * 1000 * 1000 )
{
return 0;
}

void *data = Z_AllocUninit( length );
void *data = Z_AllocUninit( tmp.size() );
*buffer = data;

memcpy( data, tmp, length );
ri.FS_FreeFile( tmp );
memcpy( data, tmp.data(), tmp.size() );

return length;
return tmp.size();
}

static void RE_FreeFontFile( void *data )
{
Z_Free( data );
if ( data != daemon_unifont_bin )
{
Z_Free( data );
}
}

// If name is the empty string, load the embedded Unifont
fontInfo_t* RE_RegisterFont( const char *fontName, int pointSize )
{
FT_Face face;
Expand Down