+extern int con_linewidth; // to force rewrapping
+static void LoadFont(qboolean override, const char *name, dp_font_t *fnt)
+{
+ int i;
+ float maxwidth, scale;
+ char widthfile[MAX_QPATH];
+ char *widthbuf;
+ fs_offset_t widthbufsize;
+
+ if(override || !fnt->texpath[0])
+ strlcpy(fnt->texpath, name, sizeof(fnt->texpath));
+
+ if(drawtexturepool == NULL)
+ return; // before gl_draw_start, so will be loaded later
+
+ fnt->tex = Draw_CachePic_Flags(fnt->texpath, CACHEPICFLAG_QUIET | CACHEPICFLAG_NOCOMPRESSION)->tex;
+ if(fnt->tex == r_texture_notexture)
+ {
+ fnt->tex = Draw_CachePic_Flags("gfx/conchars", CACHEPICFLAG_NOCOMPRESSION)->tex;
+ strlcpy(widthfile, "gfx/conchars.width", sizeof(widthfile));
+ }
+ else
+ dpsnprintf(widthfile, sizeof(widthfile), "%s.width", fnt->texpath);
+
+ // unspecified width == 1 (base width)
+ for(i = 1; i < 256; ++i)
+ fnt->width_of[i] = 1;
+ scale = 1;
+
+ // FIXME load "name.width", if it fails, fill all with 1
+ if((widthbuf = (char *) FS_LoadFile(widthfile, tempmempool, true, &widthbufsize)))
+ {
+ float extraspacing = 0;
+ const char *p = widthbuf;
+ int ch = 0;
+
+ while(ch < 256)
+ {
+ if(!COM_ParseToken_Simple(&p, false, false))
+ return;
+
+ switch(*com_token)
+ {
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ case '8':
+ case '9':
+ case '+':
+ case '-':
+ case '.':
+ fnt->width_of[ch++] = atof(com_token) + extraspacing;
+ break;
+ default:
+ if(!strcmp(com_token, "extraspacing"))
+ {
+ if(!COM_ParseToken_Simple(&p, false, false))
+ return;
+ extraspacing = atof(com_token);
+ }
+ else if(!strcmp(com_token, "scale"))
+ {
+ if(!COM_ParseToken_Simple(&p, false, false))
+ return;
+ scale = atof(com_token);
+ }
+ else
+ {
+ Con_Printf("Warning: skipped unknown font property %s\n", com_token);
+ if(!COM_ParseToken_Simple(&p, false, false))
+ return;
+ }
+ break;
+ }
+ }
+
+ Mem_Free(widthbuf);
+ }
+
+ maxwidth = fnt->width_of[1];
+ for(i = 2; i < 256; ++i)
+ maxwidth = max(maxwidth, fnt->width_of[i]);
+ fnt->maxwidth = maxwidth;
+
+ // fix up maxwidth for overlap
+ fnt->maxwidth *= scale;
+ fnt->scale = scale;
+
+ if(fnt == FONT_CONSOLE)
+ con_linewidth = -1; // rewrap console in next frame
+}
+
+static dp_font_t *FindFont(const char *title)
+{
+ int i;
+ for(i = 0; i < MAX_FONTS; ++i)
+ if(!strcmp(dp_fonts[i].title, title))
+ return &dp_fonts[i];
+ return NULL;
+}
+
+static void LoadFont_f(void)
+{
+ dp_font_t *f;
+ int i;
+ if(Cmd_Argc() < 2)
+ {
+ Con_Printf("Available font commands:\n");
+ for(i = 0; i < MAX_FONTS; ++i)
+ Con_Printf(" loadfont %s gfx/tgafile\n", dp_fonts[i].title);
+ return;
+ }
+ f = FindFont(Cmd_Argv(1));
+ if(f == NULL)
+ {
+ Con_Printf("font function not found\n");
+ return;
+ }
+ LoadFont(true, (Cmd_Argc() < 3) ? "gfx/conchars" : Cmd_Argv(2), f);
+}
+