mirror of
https://github.com/nzp-team/fteqw.git
synced 2024-11-24 21:02:26 +00:00
Eukara expressed an interest in loading fonts without any antialiasing.
This commit is contained in:
parent
73f9cddcdf
commit
0d2a0c615a
6 changed files with 127 additions and 38 deletions
|
@ -105,6 +105,7 @@ struct {
|
|||
char facename[MAX_OSPATH];
|
||||
float scale; //poop
|
||||
int outline; //argh
|
||||
unsigned int fontflags; //erk
|
||||
int sizes;
|
||||
int size[FONT_SIZES];
|
||||
struct font_s *font[FONT_SIZES];
|
||||
|
@ -233,7 +234,7 @@ void PR_ReloadFonts(qboolean reload)
|
|||
{ //otherwise load it.
|
||||
for (j = 0; j < fontslot[i].sizes; j++)
|
||||
{
|
||||
fontslot[i].font[j] = Font_LoadFont(fontslot[i].facename, fontslot[i].size[j], fontslot[i].scale, fontslot[i].outline);
|
||||
fontslot[i].font[j] = Font_LoadFont(fontslot[i].facename, fontslot[i].size[j], fontslot[i].scale, fontslot[i].outline, fontslot[i].fontflags);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -333,7 +334,7 @@ void QCBUILTIN PF_CL_loadfont (pubprogfuncs_t *prinst, struct globalvars_s *pr_g
|
|||
if (qrenderer > QR_NONE)
|
||||
{
|
||||
for (i = 0; i < fontslot[slotnum].sizes; i++)
|
||||
fontslot[slotnum].font[i] = Font_LoadFont(facename, fontslot[slotnum].size[i], fontslot[slotnum].scale, fontslot[slotnum].outline);
|
||||
fontslot[slotnum].font[i] = Font_LoadFont(facename, fontslot[slotnum].size[i], fontslot[slotnum].scale, fontslot[slotnum].outline, fontslot[slotnum].fontflags);
|
||||
}
|
||||
|
||||
G_FLOAT(OFS_RETURN) = slotnum;
|
||||
|
@ -342,7 +343,7 @@ void QCBUILTIN PF_CL_loadfont (pubprogfuncs_t *prinst, struct globalvars_s *pr_g
|
|||
#ifdef HAVE_LEGACY
|
||||
void CL_LoadFont_f(void)
|
||||
{
|
||||
extern cvar_t r_font_postprocess_outline;
|
||||
extern cvar_t r_font_postprocess_outline, r_font_postprocess_mono;
|
||||
//console command for compat with dp/debug.
|
||||
if (Cmd_Argc() == 1)
|
||||
{
|
||||
|
@ -418,6 +419,8 @@ void CL_LoadFont_f(void)
|
|||
fontslot[slotnum].scale = 1;
|
||||
fontslot[slotnum].sizes = 0;
|
||||
fontslot[slotnum].outline = r_font_postprocess_outline.ival; //locked in at definition, so different fonts can have different settings even with vid_reload going on.
|
||||
fontslot[slotnum].fontflags = 0 |
|
||||
(r_font_postprocess_mono.ival?FONT_MONO:0);
|
||||
}
|
||||
if (!*facename)
|
||||
return;
|
||||
|
@ -437,6 +440,14 @@ void CL_LoadFont_f(void)
|
|||
fontslot[slotnum].outline = atoi(Cmd_Argv(sizenum++));
|
||||
continue;
|
||||
}
|
||||
if (!strcmp(a, "mono"))
|
||||
{
|
||||
if (atoi(Cmd_Argv(sizenum++)))
|
||||
fontslot[slotnum].fontflags |= FONT_MONO;
|
||||
else
|
||||
fontslot[slotnum].fontflags &= ~FONT_MONO;
|
||||
continue;
|
||||
}
|
||||
if (!strcmp(a, "blur"))
|
||||
{
|
||||
//fontslot[slotnum].blur = atoi(Cmd_Argv(sizenum++));
|
||||
|
@ -471,7 +482,7 @@ void CL_LoadFont_f(void)
|
|||
if (qrenderer > QR_NONE)
|
||||
{
|
||||
for (i = 0; i < fontslot[slotnum].sizes; i++)
|
||||
fontslot[slotnum].font[i] = Font_LoadFont(facename, fontslot[slotnum].size[i], fontslot[slotnum].scale, fontslot[slotnum].outline);
|
||||
fontslot[slotnum].font[i] = Font_LoadFont(facename, fontslot[slotnum].size[i], fontslot[slotnum].scale, fontslot[slotnum].outline, fontslot[slotnum].fontflags);
|
||||
}
|
||||
|
||||
//FIXME: slotnum0==default is problematic.
|
||||
|
|
|
@ -56,7 +56,7 @@ struct
|
|||
extern cvar_t scr_conalpha;
|
||||
extern cvar_t gl_conback;
|
||||
extern cvar_t gl_font, con_textfont;
|
||||
extern cvar_t r_font_postprocess_outline;
|
||||
extern cvar_t r_font_postprocess_outline, r_font_postprocess_mono;
|
||||
extern cvar_t gl_screenangle;
|
||||
extern cvar_t vid_minsize;
|
||||
extern cvar_t vid_conautoscale;
|
||||
|
@ -167,6 +167,7 @@ void R2D_Shutdown(void)
|
|||
Cvar_Unhook(&con_textfont);
|
||||
Cvar_Unhook(&gl_font);
|
||||
Cvar_Unhook(&r_font_postprocess_outline);
|
||||
Cvar_Unhook(&r_font_postprocess_mono);
|
||||
Cvar_Unhook(&vid_conautoscale);
|
||||
Cvar_Unhook(&gl_screenangle);
|
||||
Cvar_Unhook(&vid_conheight);
|
||||
|
@ -444,6 +445,7 @@ void R2D_Init(void)
|
|||
Cvar_Hook(&con_textfont, R2D_Font_Callback);
|
||||
Cvar_Hook(&gl_font, R2D_Font_Callback);
|
||||
Cvar_Hook(&r_font_postprocess_outline, R2D_Font_Callback);
|
||||
Cvar_Hook(&r_font_postprocess_mono, R2D_Font_Callback);
|
||||
Cvar_Hook(&vid_conautoscale, R2D_Conautoscale_Callback);
|
||||
Cvar_Hook(&gl_screenangle, R2D_ScreenAngle_Callback);
|
||||
Cvar_Hook(&vid_conheight, R2D_Conheight_Callback);
|
||||
|
@ -1137,6 +1139,7 @@ void R2D_Font_Changed(void)
|
|||
{
|
||||
float tsize;
|
||||
const char *con_font_name = con_textfont.string;
|
||||
unsigned int flags;
|
||||
if (!con_textsize.modified)
|
||||
return;
|
||||
if (!*con_font_name)
|
||||
|
@ -1170,6 +1173,10 @@ void R2D_Font_Changed(void)
|
|||
if (qrenderer == QR_NONE)
|
||||
return;
|
||||
|
||||
flags = 0;
|
||||
if (r_font_postprocess_mono.ival)
|
||||
flags |= FONT_MONO;
|
||||
|
||||
if (!strcmp(gl_font.string, "?"))
|
||||
{
|
||||
#ifndef AVAIL_FREETYPE
|
||||
|
@ -1184,9 +1191,9 @@ void R2D_Font_Changed(void)
|
|||
LOGFONTW lf = {0};
|
||||
CHOOSEFONTW cf = {sizeof(cf)};
|
||||
extern HWND mainwindow;
|
||||
font_default = Font_LoadFont("", 8, 1, r_font_postprocess_outline.ival);
|
||||
font_default = Font_LoadFont("", 8, 1, r_font_postprocess_outline.ival, flags);
|
||||
if (tsize != 8)
|
||||
font_console = Font_LoadFont("", tsize, 1, r_font_postprocess_outline.ival);
|
||||
font_console = Font_LoadFont("", tsize, 1, r_font_postprocess_outline.ival, flags);
|
||||
if (!font_console)
|
||||
font_console = font_default;
|
||||
|
||||
|
@ -1230,19 +1237,19 @@ void R2D_Font_Changed(void)
|
|||
}
|
||||
|
||||
if (COM_FCheckExists("fonts/qfont.kfont"))
|
||||
font_menu = Font_LoadFont("qfont", 20, 1, r_font_postprocess_outline.ival);
|
||||
font_menu = Font_LoadFont("qfont", 20, 1, r_font_postprocess_outline.ival, flags);
|
||||
else
|
||||
font_menu = NULL;
|
||||
|
||||
font_default = Font_LoadFont(gl_font.string, 8, 1, r_font_postprocess_outline.ival);
|
||||
font_default = Font_LoadFont(gl_font.string, 8, 1, r_font_postprocess_outline.ival, flags);
|
||||
if (!font_default && *gl_font.string)
|
||||
font_default = Font_LoadFont("", 8, 1, r_font_postprocess_outline.ival);
|
||||
font_default = Font_LoadFont("", 8, 1, r_font_postprocess_outline.ival, flags);
|
||||
|
||||
if (tsize != 8 || strcmp(gl_font.string, con_font_name))
|
||||
{
|
||||
font_console = Font_LoadFont(con_font_name, tsize, 1, r_font_postprocess_outline.ival);
|
||||
font_console = Font_LoadFont(con_font_name, tsize, 1, r_font_postprocess_outline.ival, flags);
|
||||
if (!font_console)
|
||||
font_console = Font_LoadFont("", tsize, 1, r_font_postprocess_outline.ival);
|
||||
font_console = Font_LoadFont("", tsize, 1, r_font_postprocess_outline.ival, flags);
|
||||
}
|
||||
if (!font_console)
|
||||
font_console = font_default;
|
||||
|
|
|
@ -458,6 +458,7 @@ cvar_t gl_texturemode2d = CVARFCD("gl_texturemode2d", "GL_LINEAR",
|
|||
"Specifies how 2d images are sampled. format is a 3-tupple ");
|
||||
cvar_t r_font_linear = CVARF("r_font_linear", "1", CVAR_ARCHIVE);
|
||||
cvar_t r_font_postprocess_outline = CVARFD("r_font_postprocess_outline", "0", 0, "Controls the number of pixels of dark borders to use around fonts.");
|
||||
cvar_t r_font_postprocess_mono = CVARFD("r_font_postprocess_mono", "0", 0, "Disables anti-aliasing on fonts.");
|
||||
|
||||
#if defined(HAVE_LEGACY) && defined(AVAIL_FREETYPE)
|
||||
cvar_t dpcompat_smallerfonts = CVARFD("dpcompat_smallerfonts", "0", 0, "Mimics DP's behaviour of using a smaller font size than was actually requested.");
|
||||
|
@ -984,6 +985,7 @@ void Renderer_Init(void)
|
|||
Cvar_Register (&gl_texturemode2d, GLRENDEREROPTIONS);
|
||||
Cvar_Register (&r_font_linear, GLRENDEREROPTIONS);
|
||||
Cvar_Register (&r_font_postprocess_outline, GLRENDEREROPTIONS);
|
||||
Cvar_Register (&r_font_postprocess_mono, GLRENDEREROPTIONS);
|
||||
#if defined(HAVE_LEGACY) && defined(AVAIL_FREETYPE)
|
||||
Cvar_Register (&dpcompat_smallerfonts, GLRENDEREROPTIONS);
|
||||
#endif
|
||||
|
|
|
@ -1279,7 +1279,7 @@ void Draw_TinyString (float x, float y, const qbyte *str)
|
|||
|
||||
if (!font_tiny)
|
||||
{
|
||||
font_tiny = Font_LoadFont("gfx/tinyfont", 8, 1, 0);
|
||||
font_tiny = Font_LoadFont("gfx/tinyfont", 8, 1, 0, 0);
|
||||
if (!font_tiny)
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -321,7 +321,8 @@ void Font_Init(void);
|
|||
void Font_Shutdown(void);
|
||||
int Font_RegisterTrackerImage(const char *image); //returns a unicode char value that can be used to embed the char within a line of text.
|
||||
qboolean Font_TrackerValid(unsigned int imid);
|
||||
struct font_s *Font_LoadFont(const char *fontfilename, float height, float scale, int outline);
|
||||
struct font_s *Font_LoadFont(const char *fontfilename, float height, float scale, int outline, unsigned int flags);
|
||||
#define FONT_MONO 1
|
||||
void Font_Free(struct font_s *f);
|
||||
void Font_BeginString(struct font_s *font, float vx, float vy, int *px, int *py);
|
||||
void Font_BeginScaledString(struct font_s *font, float vx, float vy, float szx, float szy, float *px, float *py); /*avoid using*/
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
|
||||
void Font_Init(void);
|
||||
void Font_Shutdown(void);
|
||||
struct font_s *Font_LoadFont(const char *fontfilename, float height, float scale, int outline);
|
||||
struct font_s *Font_LoadFont(const char *fontfilename, float height, float scale, int outline, unsigned int flags);
|
||||
void Font_Free(struct font_s *f);
|
||||
void Font_BeginString(struct font_s *font, float vx, float vy, int *px, int *py);
|
||||
void Font_BeginScaledString(struct font_s *font, float vx, float vy, float szx, float szy, float *px, float *py); /*avoid using*/
|
||||
|
@ -80,6 +80,9 @@ const char *(VARGS *pFT_Error_String) (FT_Error error_code);
|
|||
typedef unsigned int FT_Pixel_Mode; //for consistency even without freetype support.
|
||||
#endif
|
||||
|
||||
#ifndef FT_PIXEL_MODE_MONO
|
||||
#define FT_PIXEL_MODE_MONO 1
|
||||
#endif
|
||||
#ifndef FT_PIXEL_MODE_GRAY
|
||||
#define FT_PIXEL_MODE_GRAY 2
|
||||
#endif
|
||||
|
@ -322,6 +325,7 @@ typedef struct font_s
|
|||
unsigned short truecharheight; //what you actually got, for compat with dp's lets-use-the-wrong-size-for-double-padding-between-lines thing.
|
||||
float scale; //some sort of poop
|
||||
short outline;
|
||||
unsigned int flags;
|
||||
|
||||
unsigned short faces;
|
||||
fontface_t *face[MAX_FACES];
|
||||
|
@ -721,6 +725,32 @@ static struct charcache_s *Font_LoadGlyphData(font_t *f, CHARIDXTYPE charidx, FT
|
|||
out += PLANEWIDTH;
|
||||
}
|
||||
}
|
||||
else if (pixelmode == FT_PIXEL_MODE_MONO)
|
||||
{ //1bit font (
|
||||
for (y = -pad; y < 0; y++)
|
||||
{
|
||||
for (x = -pad; x < (int)bmw+pad; x++)
|
||||
out[x].c = BORDERCOLOUR;
|
||||
out += PLANEWIDTH;
|
||||
}
|
||||
for (; y < bmh; y++)
|
||||
{
|
||||
for (x = -pad; x < 0; x++)
|
||||
out[x].c = BORDERCOLOUR;
|
||||
for (; x < bmw; x++)
|
||||
out[x].c = (((unsigned char*)data)[x>>3]&(1<<(7-(x&7))))?0xffffffff:0;
|
||||
for (; x < bmw+pad; x++)
|
||||
out[x].c = BORDERCOLOUR;
|
||||
data = (char*)data + pitch;
|
||||
out += PLANEWIDTH;
|
||||
}
|
||||
for (; y < bmh+pad; y++)
|
||||
{
|
||||
for (x = -pad; x < (int)bmw+pad; x++)
|
||||
out[x].c = BORDERCOLOUR;
|
||||
out += PLANEWIDTH;
|
||||
}
|
||||
}
|
||||
else if ((unsigned int)pixelmode == FT_PIXEL_MODE_RGBA_SA)
|
||||
{ //rgba source using standard alpha.
|
||||
//(we'll multiply out the alpha for the gpu)
|
||||
|
@ -822,9 +852,6 @@ static struct charcache_s *Font_LoadGlyphData(font_t *f, CHARIDXTYPE charidx, FT
|
|||
|
||||
if (outline)
|
||||
{
|
||||
int bytes = (pixelmode == FT_PIXEL_MODE_GRAY)?1:4;
|
||||
qbyte *alpha = (char*)data + bytes-1 - pitch*bmh;
|
||||
|
||||
static int filter_outline;
|
||||
static unsigned char filter_highest[MAXOUTLINE*2+1][MAXOUTLINE*2+1];
|
||||
if (outline != filter_outline)
|
||||
|
@ -837,23 +864,57 @@ static struct charcache_s *Font_LoadGlyphData(font_t *f, CHARIDXTYPE charidx, FT
|
|||
|
||||
//expand it to out full(ish) size
|
||||
|
||||
alpha -= pitch*outline + bytes*outline;
|
||||
out = &fontplanes.plane[c->bmx+((int)c->bmy-outline)*PLANEHEIGHT];
|
||||
for (y = -outline; y < (int)bmh+outline; y++, out += PLANEWIDTH)
|
||||
for (x = -outline; x < (int)bmw+outline; x++)
|
||||
{
|
||||
int xn, x1 = max(outline-x, 0), x2 = min(2*outline, (int)bmw-1-x+outline);
|
||||
int yn, y1 = max(outline-y, 0), y2 = min(2*outline, (int)bmh-1-y+outline);
|
||||
int v, m = out[x].rgba[3]*255;
|
||||
for (yn = y1; yn <= y2; yn++)
|
||||
for (xn = x1; xn <= x2; xn++)
|
||||
{
|
||||
v = filter_highest[yn][xn] * alpha[(xn+x)*bytes+(yn+y)*pitch];
|
||||
m = max(m, v);
|
||||
}
|
||||
//out[x].c = 0;
|
||||
out[x].rgba[3] = m/255;
|
||||
}
|
||||
if (pixelmode == FT_PIXEL_MODE_MONO)
|
||||
{
|
||||
qbyte *alpha = (char*)data - pitch*bmh;
|
||||
qbyte a;
|
||||
int bit;
|
||||
|
||||
alpha -= pitch*outline;
|
||||
out = &fontplanes.plane[c->bmx+((int)c->bmy-outline)*PLANEHEIGHT];
|
||||
for (y = -outline; y < (int)bmh+outline; y++, out += PLANEWIDTH)
|
||||
for (x = -outline; x < (int)bmw+outline; x++)
|
||||
{
|
||||
int xn, x1 = max(outline-x, 0), x2 = min(2*outline, (int)bmw-1-x+outline);
|
||||
int yn, y1 = max(outline-y, 0), y2 = min(2*outline, (int)bmh-1-y+outline);
|
||||
int v, m = out[x].rgba[3]*255;
|
||||
for (yn = y1; yn <= y2; yn++)
|
||||
for (xn = x1; xn <= x2; xn++)
|
||||
{
|
||||
bit = (xn+x)-outline;
|
||||
a = alpha[(bit>>3)+(yn+y)*pitch];
|
||||
a = (a&(1<<(7-(bit&7))))?0xff:0;
|
||||
|
||||
v = filter_highest[yn][xn] * a;
|
||||
m = max(m, v);
|
||||
}
|
||||
//out[x].c = 0;
|
||||
out[x].rgba[3] = m/255;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
int bytes = (pixelmode == FT_PIXEL_MODE_GRAY)?1:4;
|
||||
qbyte *alpha = (char*)data + bytes-1 - pitch*bmh;
|
||||
|
||||
alpha -= pitch*outline + bytes*outline;
|
||||
out = &fontplanes.plane[c->bmx+((int)c->bmy-outline)*PLANEHEIGHT];
|
||||
for (y = -outline; y < (int)bmh+outline; y++, out += PLANEWIDTH)
|
||||
for (x = -outline; x < (int)bmw+outline; x++)
|
||||
{
|
||||
int xn, x1 = max(outline-x, 0), x2 = min(2*outline, (int)bmw-1-x+outline);
|
||||
int yn, y1 = max(outline-y, 0), y2 = min(2*outline, (int)bmh-1-y+outline);
|
||||
int v, m = out[x].rgba[3]*255;
|
||||
for (yn = y1; yn <= y2; yn++)
|
||||
for (xn = x1; xn <= x2; xn++)
|
||||
{
|
||||
v = filter_highest[yn][xn] * alpha[(xn+x)*bytes+(yn+y)*pitch];
|
||||
m = max(m, v);
|
||||
}
|
||||
//out[x].c = 0;
|
||||
out[x].rgba[3] = m/255;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
c->bmx -= outline;
|
||||
|
@ -1317,7 +1378,7 @@ static struct charcache_s *Font_TryLoadGlyph(font_t *f, CHARIDXTYPE charidx)
|
|||
return NULL; //some sort of error.
|
||||
}
|
||||
if (charidx == 0xfffe || pFT_Get_Char_Index(face, charidx)) //ignore glyph 0 (undefined)
|
||||
if (pFT_Load_Char(face, charidx, FT_LOAD_RENDER|FT_LOAD_COLOR) == 0)
|
||||
if (pFT_Load_Char(face, charidx, FT_LOAD_RENDER|(((f->flags&FONT_MONO)&&qface->ft.activeheight==qface->ft.actualsize/*FIXME*/)?FT_LOAD_TARGET_MONO:FT_LOAD_TARGET_NORMAL)|FT_LOAD_COLOR) == 0)
|
||||
{
|
||||
FT_GlyphSlot slot;
|
||||
FT_Bitmap *bm;
|
||||
|
@ -1349,6 +1410,12 @@ static struct charcache_s *Font_TryLoadGlyph(font_t *f, CHARIDXTYPE charidx)
|
|||
Image_ResampleTexture(PTI_L8, (void*)bm->buffer, bm->width, bm->rows, out, nw, nh);
|
||||
c = Font_LoadGlyphData(f, charidx, bm->pixel_mode, out, nw, nh, nw*sizeof(*out));
|
||||
}
|
||||
/*else if (bm->pixel_mode == FT_PIXEL_MODE_MONO)
|
||||
{
|
||||
unsigned char *out = alloca(nw*nh*sizeof(*out));
|
||||
Image_ResampleTexture(PTI_L1, (void*)bm->buffer, bm->width, bm->rows, out, nw, nh);
|
||||
c = Font_LoadGlyphData(f, charidx, bm->pixel_mode, out, nw, nh, nw*sizeof(*out));
|
||||
}*/
|
||||
else
|
||||
c = NULL;
|
||||
if (c)
|
||||
|
@ -2209,7 +2276,7 @@ static qboolean Font_LoadFontLump(font_t *f, const char *facename)
|
|||
|
||||
//creates a new font object from the given file, with each text row with the given height.
|
||||
//width is implicit and scales with height and choice of font.
|
||||
struct font_s *Font_LoadFont(const char *fontfilename, float vheight, float scale, int outline)
|
||||
struct font_s *Font_LoadFont(const char *fontfilename, float vheight, float scale, int outline, unsigned int flags)
|
||||
{
|
||||
struct font_s *f;
|
||||
int i = 0;
|
||||
|
@ -2237,6 +2304,7 @@ struct font_s *Font_LoadFont(const char *fontfilename, float vheight, float scal
|
|||
f->scale = scale;
|
||||
f->charheight = height;
|
||||
f->truecharheight = height;
|
||||
f->flags = flags;
|
||||
Q_strncpyz(f->name, fontfilename, sizeof(f->name));
|
||||
|
||||
switch(M_GameType())
|
||||
|
@ -2454,7 +2522,7 @@ struct font_s *Font_LoadFont(const char *fontfilename, float vheight, float scal
|
|||
}
|
||||
else
|
||||
{
|
||||
f->alt = Font_LoadFont(aname, vheight, scale, outline);
|
||||
f->alt = Font_LoadFont(aname, vheight, scale, outline, flags);
|
||||
if (f->alt)
|
||||
{
|
||||
VectorCopy(f->alt->tint, f->alttint);
|
||||
|
|
Loading…
Reference in a new issue