cvar_t r_font_disable_freetype = {CVAR_SAVE, "r_font_disable_freetype", "1", "disable freetype support for fonts entirely"};
cvar_t r_font_use_alpha_textures = {CVAR_SAVE, "r_font_use_alpha_textures", "0", "use alpha-textures for font rendering, this should safe memory"};
cvar_t r_font_size_snapping = {CVAR_SAVE, "r_font_size_snapping", "1", "stick to good looking font sizes whenever possible - bad when the mod doesn't support it!"};
+cvar_t r_font_hinting = {CVAR_SAVE, "r_font_hinting", "3", "0 = no hinting, 1 = light autohinting, 2 = full autohinting, 3 = full hinting"};
+cvar_t r_font_antialias = {CVAR_SAVE, "r_font_antialias", "1", "0 = monochrome, 1 = grey" /* , 2 = rgb, 3 = bgr" */};
+cvar_t r_font_kerning = {CVAR_SAVE, "r_font_kerning", "1", "Use kerning if available"};
+cvar_t developer_font = {CVAR_SAVE, "developer_font", "0", "prints debug messages about fonts"};
/*
================================================================================
{
const char* dllnames [] =
{
-#if defined(WIN64)
- #error path for freetype 2 dll
-#elif defined(WIN32)
- #error path for freetype 2 dll
+#if defined(WIN32)
+ "freetype6.dll",
+ "libfreetype-6.dll",
#elif defined(MACOSX)
+ "libfreetype.6.dylib",
"libfreetype.dylib",
#else
"libfreetype.so.6",
Cvar_RegisterVariable(&r_font_disable_freetype);
Cvar_RegisterVariable(&r_font_use_alpha_textures);
Cvar_RegisterVariable(&r_font_size_snapping);
+ Cvar_RegisterVariable(&r_font_hinting);
+ Cvar_RegisterVariable(&r_font_antialias);
+ Cvar_RegisterVariable(&r_font_kerning);
+ Cvar_RegisterVariable(&developer_font);
+ // let's open it at startup already
+ Font_OpenLibrary();
}
/*
return true;
}
+float Font_VirtualToRealSize(float sz)
+{
+ int vh, vw, si;
+ float sn;
+ if(sz < 0)
+ return sz;
+ vw = ((vid.width > 0) ? vid.width : vid_width.value);
+ vh = ((vid.height > 0) ? vid.height : vid_height.value);
+ // now try to scale to our actual size:
+ sn = sz * vh / vid_conheight.value;
+ si = (int)sn;
+ if ( sn - (float)si >= 0.5 )
+ ++si;
+ return si;
+}
+
+float Font_SnapTo(float val, float snapwidth)
+{
+ return floor(val / snapwidth + 0.5f) * snapwidth;
+}
+
static qboolean Font_LoadFile(const char *name, int _face, ft2_font_t *font);
-static qboolean Font_LoadSize(ft2_font_t *font, float size, qboolean no_texture, qboolean no_kerning);
+static qboolean Font_LoadSize(ft2_font_t *font, float size, qboolean check_only);
qboolean Font_LoadFont(const char *name, dp_font_t *dpfnt)
{
int s, count, i;
break;
}
count = 0;
- for (s = 0; s < MAX_FONT_SIZES; ++s)
+ for (s = 0; s < MAX_FONT_SIZES && dpfnt->req_sizes[s] >= 0; ++s)
{
- if (Font_LoadSize(fb, dpfnt->req_sizes[s], true, false))
+ if (Font_LoadSize(fb, Font_VirtualToRealSize(dpfnt->req_sizes[s]), true))
++count;
}
if (!count)
}
count = 0;
- for (s = 0; s < MAX_FONT_SIZES; ++s)
+ for (s = 0; s < MAX_FONT_SIZES && dpfnt->req_sizes[s] >= 0; ++s)
{
- if (Font_LoadSize(ft2, dpfnt->req_sizes[s], false, false))
+ if (Font_LoadSize(ft2, Font_VirtualToRealSize(dpfnt->req_sizes[s]), false))
++count;
}
if (!count)
static qboolean Font_LoadFile(const char *name, int _face, ft2_font_t *font)
{
size_t namelen;
- char filename[PATH_MAX];
+ char filename[MAX_QPATH];
int status;
size_t i;
unsigned char *data;
return true;
}
+static float Font_SearchSize(ft2_font_t *font, FT_Face fontface, float size);
static qboolean Font_LoadMap(ft2_font_t *font, ft2_font_map_t *mapstart, Uchar _ch, ft2_font_map_t **outmap);
-static qboolean Font_LoadSize(ft2_font_t *font, float size, qboolean no_texture, qboolean no_kerning)
+static qboolean Font_LoadSize(ft2_font_t *font, float size, qboolean check_only)
{
int map_index;
ft2_font_map_t *fmap, temp;
- if (IS_NAN(size))
+ if (!(size > 0.001f && size < 1000.0f))
size = 0;
if (!size)
if (size < 2) // bogus sizes are not allowed - and they screw up our allocations
return false;
- if (!no_texture)
+ for (map_index = 0; map_index < MAX_FONT_SIZES; ++map_index)
{
- for (map_index = 0; map_index < MAX_FONT_SIZES; ++map_index)
- {
- if (!font->font_maps[map_index])
- break;
- // if a similar size has already been loaded, ignore this one
- //abs(font->font_maps[map_index]->size - size) < 4
- if (font->font_maps[map_index]->size == size)
- return true;
- }
+ if (!font->font_maps[map_index])
+ break;
+ // if a similar size has already been loaded, ignore this one
+ //abs(font->font_maps[map_index]->size - size) < 4
+ if (font->font_maps[map_index]->size == size)
+ return true;
+ }
- if (map_index >= MAX_FONT_SIZES)
- return false;
+ if (map_index >= MAX_FONT_SIZES)
+ return false;
- memset(&temp, 0, sizeof(temp));
- temp.size = size;
- temp.glyphSize = CeilPowerOf2(size*2);
- temp.sfx = (1.0/64.0)/(double)size;
- temp.sfy = (1.0/64.0)/(double)size;
- temp.intSize = -1; // negative value: LoadMap must search now :)
- if (!Font_LoadMap(font, &temp, 0, &fmap))
- {
- Con_Printf("ERROR: can't load the first character map for %s\n"
- "This is fatal\n",
- font->name);
- Font_UnloadFont(font);
- return false;
- }
- font->font_maps[map_index] = temp.next;
+ if (check_only) {
+ FT_Face fontface;
+ if (font->image_font)
+ fontface = (FT_Face)font->next->face;
+ else
+ fontface = (FT_Face)font->face;
+ return (Font_SearchSize(font, fontface, size) > 0);
+ }
- fmap->sfx = temp.sfx;
- fmap->sfy = temp.sfy;
+ memset(&temp, 0, sizeof(temp));
+ temp.size = size;
+ temp.glyphSize = CeilPowerOf2(size*2);
+ temp.sfx = (1.0/64.0)/(double)size;
+ temp.sfy = (1.0/64.0)/(double)size;
+ temp.intSize = -1; // negative value: LoadMap must search now :)
+ if (!Font_LoadMap(font, &temp, 0, &fmap))
+ {
+ Con_Printf("ERROR: can't load the first character map for %s\n"
+ "This is fatal\n",
+ font->name);
+ Font_UnloadFont(font);
+ return false;
}
- if (!no_kerning)
+ font->font_maps[map_index] = temp.next;
+
+ fmap->sfx = temp.sfx;
+ fmap->sfy = temp.sfy;
+
+ // load the default kerning vector:
+ if (font->has_kerning)
{
- // load the default kerning vector:
- if (font->has_kerning)
+ Uchar l, r;
+ FT_Vector kernvec;
+ for (l = 0; l < 256; ++l)
{
- Uchar l, r;
- FT_Vector kernvec;
- for (l = 0; l < 256; ++l)
+ for (r = 0; r < 256; ++r)
{
- for (r = 0; r < 256; ++r)
+ FT_ULong ul, ur;
+ ul = qFT_Get_Char_Index(font->face, l);
+ ur = qFT_Get_Char_Index(font->face, r);
+ if (qFT_Get_Kerning(font->face, ul, ur, FT_KERNING_DEFAULT, &kernvec))
{
- FT_ULong ul, ur;
- ul = qFT_Get_Char_Index(font->face, l);
- ur = qFT_Get_Char_Index(font->face, r);
- if (qFT_Get_Kerning(font->face, ul, ur, FT_KERNING_DEFAULT, &kernvec))
- {
- fmap->kerning.kerning[l][r][0] = 0;
- fmap->kerning.kerning[l][r][1] = 0;
- }
- else
- {
- fmap->kerning.kerning[l][r][0] = (kernvec.x >> 6) / fmap->size;
- fmap->kerning.kerning[l][r][1] = (kernvec.y >> 6) / fmap->size;
- }
+ fmap->kerning.kerning[l][r][0] = 0;
+ fmap->kerning.kerning[l][r][1] = 0;
+ }
+ else
+ {
+ fmap->kerning.kerning[l][r][0] = Font_SnapTo((kernvec.x / 64.0) / fmap->size, 1 / fmap->size);
+ fmap->kerning.kerning[l][r][1] = Font_SnapTo((kernvec.y / 64.0) / fmap->size, 1 / fmap->size);
}
}
}
}
-
return true;
}
int nval;
int matchsize = -10000;
int m;
- int size;
- float fsize;
+ float fsize_x, fsize_y;
ft2_font_map_t **maps = font->font_maps;
- fsize = _fsize * vid.height / vid_conheight.value;
+ fsize_x = fsize_y = _fsize * vid.height / vid_conheight.value;
+ if(outw && *outw)
+ fsize_x = *outw * vid.width / vid_conwidth.value;
+ if(outh && *outh)
+ fsize_y = *outh * vid.height / vid_conheight.value;
- if (fsize < 0)
- size = 16;
+ if (fsize_x < 0)
+ {
+ if(fsize_y < 0)
+ fsize_x = fsize_y = 16;
+ else
+ fsize_x = fsize_y;
+ }
else
{
- // round up
- size = (int)fsize;
- if (fsize - (float)size >= 0.49)
- ++size;
+ if(fsize_y < 0)
+ fsize_y = fsize_x;
}
for (m = 0; m < MAX_FONT_SIZES; ++m)
if (!maps[m])
continue;
// "round up" to the bigger size if two equally-valued matches exist
- nval = abs(maps[m]->size - size);
+ nval = 0.5 * (abs(maps[m]->size - fsize_x) + abs(maps[m]->size - fsize_y));
if (match == -1 || nval < value || (nval == value && matchsize < maps[m]->size))
{
value = nval;
break;
}
}
- if (value <= r_font_size_snapping.integer)
+ if (value <= r_font_size_snapping.value)
{
- if (outw && outh)
- {
- if (!*outh) *outh = *outw;
- if (!*outw) *outw = *outh;
- }
- // keep the aspect
+ // do NOT keep the aspect for perfect rendering
if (outh) *outh = maps[match]->size * vid_conheight.value / vid.height;
- if (outw) *outw = maps[match]->size * vid_conwidth.value / vid.width * *outw / _fsize;
+ if (outw) *outw = maps[match]->size * vid_conwidth.value / vid.width;
}
return match;
}
qboolean Font_GetKerningForMap(ft2_font_t *font, int map_index, float w, float h, Uchar left, Uchar right, float *outx, float *outy)
{
ft2_font_map_t *fmap;
- if (!font->has_kerning)
+ if (!font->has_kerning || !r_font_kerning.integer)
return false;
if (map_index < 0 || map_index >= MAX_FONT_SIZES)
return false;
return false;
if (left < 256 && right < 256)
{
+ //Con_Printf("%g : %f, %f, %f :: %f\n", (w / (float)fmap->size), w, fmap->size, fmap->intSize, Font_VirtualToRealSize(w));
// quick-kerning, be aware of the size: scale it
- if (outx) *outx = fmap->kerning.kerning[left][right][0] * w / (float)fmap->size;
- if (outy) *outy = fmap->kerning.kerning[left][right][1] * h / (float)fmap->size;
+ if (outx) *outx = fmap->kerning.kerning[left][right][0];// * (w / (float)fmap->size);
+ if (outy) *outy = fmap->kerning.kerning[left][right][1];// * (h / (float)fmap->size);
return true;
}
else
FT_ULong ul, ur;
//if (qFT_Set_Pixel_Sizes((FT_Face)font->face, 0, fmap->size))
+#if 0
if (!Font_SetSize(font, w, h))
{
// this deserves an error message
ur = qFT_Get_Char_Index(font->face, right);
if (qFT_Get_Kerning(font->face, ul, ur, FT_KERNING_DEFAULT, &kernvec))
{
- if (outx) *outx = kernvec.x * fmap->sfx;
- if (outy) *outy = kernvec.y * fmap->sfy;
+ if (outx) *outx = Font_SnapTo(kernvec.x * fmap->sfx, 1 / fmap->size);
+ if (outy) *outy = Font_SnapTo(kernvec.y * fmap->sfy, 1 / fmap->size);
+ return true;
+ }
+#endif
+ if (!Font_SetSize(font, fmap->intSize, fmap->intSize))
+ {
+ // this deserves an error message
+ Con_Printf("Failed to get kerning for %s\n", font->name);
+ return false;
+ }
+ ul = qFT_Get_Char_Index(font->face, left);
+ ur = qFT_Get_Char_Index(font->face, right);
+ if (qFT_Get_Kerning(font->face, ul, ur, FT_KERNING_DEFAULT, &kernvec))
+ {
+ if (outx) *outx = Font_SnapTo(kernvec.x * fmap->sfx, 1 / fmap->size);// * (w / (float)fmap->size);
+ if (outy) *outy = Font_SnapTo(kernvec.y * fmap->sfy, 1 / fmap->size);// * (h / (float)fmap->size);
return true;
}
return false;
}
}
+static float Font_SearchSize(ft2_font_t *font, FT_Face fontface, float size)
+{
+ float intSize = size;
+ while (1)
+ {
+ if (!Font_SetSize(font, intSize, intSize))
+ {
+ Con_Printf("ERROR: can't set size for font %s: %f ((%f))\n", font->name, size, intSize);
+ return -1;
+ }
+ if ((fontface->size->metrics.height>>6) <= size)
+ return intSize;
+ if (intSize < 2)
+ {
+ Con_Printf("ERROR: no appropriate size found for font %s: %f\n", font->name, size);
+ return -1;
+ }
+ --intSize;
+ }
+}
+
static qboolean Font_LoadMap(ft2_font_t *font, ft2_font_map_t *mapstart, Uchar _ch, ft2_font_map_t **outmap)
{
- char map_identifier[PATH_MAX];
+ char map_identifier[MAX_QPATH];
unsigned long mapidx = _ch / FONT_CHARS_PER_MAP;
unsigned char *data;
FT_ULong ch, mapch;
int status;
int tp;
+ FT_Int32 load_flags;
int pitch;
int gR, gC; // glyph position: row and column
else
fontface = (FT_Face)font->face;
+ switch(r_font_antialias.integer)
+ {
+ case 0:
+ switch(r_font_hinting.integer)
+ {
+ case 0:
+ load_flags = FT_LOAD_NO_HINTING | FT_LOAD_NO_AUTOHINT | FT_LOAD_TARGET_MONO | FT_LOAD_MONOCHROME;
+ break;
+ case 1:
+ case 2:
+ load_flags = FT_LOAD_FORCE_AUTOHINT | FT_LOAD_TARGET_MONO | FT_LOAD_MONOCHROME;
+ break;
+ default:
+ case 3:
+ load_flags = FT_LOAD_TARGET_MONO | FT_LOAD_MONOCHROME;
+ break;
+ }
+ break;
+ default:
+ case 1:
+ switch(r_font_hinting.integer)
+ {
+ case 0:
+ load_flags = FT_LOAD_NO_HINTING | FT_LOAD_NO_AUTOHINT | FT_LOAD_TARGET_NORMAL;
+ break;
+ case 1:
+ load_flags = FT_LOAD_FORCE_AUTOHINT | FT_LOAD_TARGET_LIGHT;
+ break;
+ case 2:
+ load_flags = FT_LOAD_FORCE_AUTOHINT | FT_LOAD_TARGET_NORMAL;
+ break;
+ default:
+ case 3:
+ load_flags = FT_LOAD_TARGET_NORMAL;
+ break;
+ }
+ break;
+ }
+
//status = qFT_Set_Pixel_Sizes((FT_Face)font->face, /*size*/0, mapstart->size);
//if (status)
if (font->image_font && mapstart->intSize < 0)
mapstart->intSize = mapstart->size;
if (mapstart->intSize < 0)
{
+ /*
mapstart->intSize = mapstart->size;
while (1)
{
}
--mapstart->intSize;
}
- if (developer.integer)
- Con_Printf("Using size: %f for requested size %f\n", mapstart->intSize, mapstart->size);
+ */
+ if ((mapstart->intSize = Font_SearchSize(font, fontface, mapstart->size)) <= 0)
+ return false;
+ Con_DPrintf("Using size: %f for requested size %f\n", mapstart->intSize, mapstart->size);
}
if (!font->image_font && !Font_SetSize(font, mapstart->intSize, mapstart->intSize))
Mem_Free(map);
return false;
}
+ memset(map->width_of, 0, sizeof(map->width_of));
// initialize as white texture with zero alpha
tp = 0;
mapch = ch - map->start;
- if (developer.integer)
- Con_Print("glyphinfo: ------------- GLYPH INFO -----------------\n");
+ if (developer_font.integer)
+ Con_DPrint("glyphinfo: ------------- GLYPH INFO -----------------\n");
++gC;
if (gC >= FONT_CHARS_PER_LINE)
glyphIndex = qFT_Get_Char_Index(face, ch);
if (glyphIndex == 0)
continue;
- status = qFT_Load_Glyph(face, glyphIndex, FT_LOAD_RENDER);
+ status = qFT_Load_Glyph(face, glyphIndex, FT_LOAD_RENDER | load_flags);
if (status)
continue;
break;
{
usefont = font;
face = font->face;
- status = qFT_Load_Glyph(face, glyphIndex, FT_LOAD_RENDER);
+ status = qFT_Load_Glyph(face, glyphIndex, FT_LOAD_RENDER | load_flags);
if (status)
{
//Con_Printf("failed to load glyph %lu for %s\n", glyphIndex, font->name);
- Con_Printf("failed to load glyph for char %lx from font %s\n", (unsigned long)ch, font->name);
+ Con_DPrintf("failed to load glyph for char %lx from font %s\n", (unsigned long)ch, font->name);
continue;
}
}
switch (bmp->pixel_mode)
{
case FT_PIXEL_MODE_MONO:
- if (developer.integer)
- Con_Print("glyphinfo: Pixel Mode: MONO\n");
+ if (developer_font.integer)
+ Con_DPrint("glyphinfo: Pixel Mode: MONO\n");
break;
case FT_PIXEL_MODE_GRAY2:
- if (developer.integer)
- Con_Print("glyphinfo: Pixel Mode: GRAY2\n");
+ if (developer_font.integer)
+ Con_DPrint("glyphinfo: Pixel Mode: GRAY2\n");
break;
case FT_PIXEL_MODE_GRAY4:
- if (developer.integer)
- Con_Print("glyphinfo: Pixel Mode: GRAY4\n");
+ if (developer_font.integer)
+ Con_DPrint("glyphinfo: Pixel Mode: GRAY4\n");
break;
case FT_PIXEL_MODE_GRAY:
- if (developer.integer)
- Con_Print("glyphinfo: Pixel Mode: GRAY\n");
+ if (developer_font.integer)
+ Con_DPrint("glyphinfo: Pixel Mode: GRAY\n");
break;
default:
- if (developer.integer)
- Con_Printf("glyphinfo: Pixel Mode: Unknown: %i\n", bmp->pixel_mode);
+ if (developer_font.integer)
+ Con_DPrintf("glyphinfo: Pixel Mode: Unknown: %i\n", bmp->pixel_mode);
Mem_Free(data);
Con_Printf("ERROR: Unrecognized pixel mode for font %s size %f: %i\n", font->name, mapstart->size, bmp->pixel_mode);
return false;
for (x = 0; x < bmp->width; x += 8)
{
unsigned char ch = *src++;
- *dst = 255 * ((ch & 0x80) >> 7); dst += bytesPerPixel;
- *dst = 255 * ((ch & 0x40) >> 6); dst += bytesPerPixel;
- *dst = 255 * ((ch & 0x20) >> 5); dst += bytesPerPixel;
- *dst = 255 * ((ch & 0x10) >> 4); dst += bytesPerPixel;
- *dst = 255 * ((ch & 0x08) >> 3); dst += bytesPerPixel;
- *dst = 255 * ((ch & 0x04) >> 2); dst += bytesPerPixel;
- *dst = 255 * ((ch & 0x02) >> 1); dst += bytesPerPixel;
- *dst = 255 * ((ch & 0x01) >> 0); dst += bytesPerPixel;
+ *dst = 255 * !!((ch & 0x80) >> 7); dst += bytesPerPixel;
+ *dst = 255 * !!((ch & 0x40) >> 6); dst += bytesPerPixel;
+ *dst = 255 * !!((ch & 0x20) >> 5); dst += bytesPerPixel;
+ *dst = 255 * !!((ch & 0x10) >> 4); dst += bytesPerPixel;
+ *dst = 255 * !!((ch & 0x08) >> 3); dst += bytesPerPixel;
+ *dst = 255 * !!((ch & 0x04) >> 2); dst += bytesPerPixel;
+ *dst = 255 * !!((ch & 0x02) >> 1); dst += bytesPerPixel;
+ *dst = 255 * !!((ch & 0x01) >> 0); dst += bytesPerPixel;
}
break;
case FT_PIXEL_MODE_GRAY2:
for (x = 0; x < bmp->width; x += 2)
{
unsigned char ch = *src++;
- *dst = ( ((ch & 0xF0) >> 4) * 0x24); dst += bytesPerPixel;
- *dst = ( ((ch & 0x0F) ) * 0x24); dst += bytesPerPixel;
+ *dst = ( ((ch & 0xF0) >> 4) * 0x11); dst += bytesPerPixel;
+ *dst = ( ((ch & 0x0F) ) * 0x11); dst += bytesPerPixel;
}
break;
case FT_PIXEL_MODE_GRAY:
// old way
// double advance = (double)glyph->metrics.horiAdvance * map->sfx;
- double bearingX = (glyph->metrics.horiBearingX >> 6) / map->size;
- double bearingY = (glyph->metrics.horiBearingY >> 6) / map->size;
- double advance = (glyph->advance.x >> 6) / map->size;
- double mWidth = (glyph->metrics.width >> 6) / map->size;
- double mHeight = (glyph->metrics.height >> 6) / map->size;
+ double bearingX = (glyph->metrics.horiBearingX / 64.0) / map->size;
+ //double bearingY = (glyph->metrics.horiBearingY >> 6) / map->size;
+ double advance = (glyph->advance.x / 64.0) / map->size;
+ //double mWidth = (glyph->metrics.width >> 6) / map->size;
+ //double mHeight = (glyph->metrics.height >> 6) / map->size;
- mapglyph->vxmin = bearingX;
- mapglyph->vxmax = bearingX + mWidth;
- mapglyph->vymin = -bearingY;
- mapglyph->vymax = mHeight - bearingY;
mapglyph->txmin = ( (double)(gC * map->glyphSize) ) / ( (double)(map->glyphSize * FONT_CHARS_PER_LINE) );
mapglyph->txmax = mapglyph->txmin + (double)bmp->width / ( (double)(map->glyphSize * FONT_CHARS_PER_LINE) );
mapglyph->tymin = ( (double)(gR * map->glyphSize) ) / ( (double)(map->glyphSize * FONT_CHAR_LINES) );
mapglyph->tymax = mapglyph->tymin + (double)bmp->rows / ( (double)(map->glyphSize * FONT_CHAR_LINES) );
+ //mapglyph->vxmin = bearingX;
+ //mapglyph->vxmax = bearingX + mWidth;
+ mapglyph->vxmin = glyph->bitmap_left / map->size;
+ mapglyph->vxmax = mapglyph->vxmin + bmp->width / map->size; // don't ask
+ //mapglyph->vymin = -bearingY;
+ //mapglyph->vymax = mHeight - bearingY;
+ mapglyph->vymin = -glyph->bitmap_top / map->size;
+ mapglyph->vymax = mapglyph->vymin + bmp->rows / map->size;
+ //Con_Printf("dpi = %f %f (%f %d) %d %d\n", bmp->width / (mapglyph->vxmax - mapglyph->vxmin), bmp->rows / (mapglyph->vymax - mapglyph->vymin), map->size, map->glyphSize, (int)fontface->size->metrics.x_ppem, (int)fontface->size->metrics.y_ppem);
//mapglyph->advance_x = advance * usefont->size;
- mapglyph->advance_x = advance;
+ //mapglyph->advance_x = advance;
+ mapglyph->advance_x = Font_SnapTo(advance, 1 / map->size);
mapglyph->advance_y = 0;
- if (developer.integer)
+ if (developer_font.integer)
{
- Con_Printf("glyphinfo: Glyph: %lu at (%i, %i)\n", (unsigned long)ch, gC, gR);
- Con_Printf("glyphinfo: %f, %f, %lu\n", bearingX, map->sfx, (unsigned long)glyph->metrics.horiBearingX);
+ Con_DPrintf("glyphinfo: Glyph: %lu at (%i, %i)\n", (unsigned long)ch, gC, gR);
+ Con_DPrintf("glyphinfo: %f, %f, %lu\n", bearingX, map->sfx, (unsigned long)glyph->metrics.horiBearingX);
if (ch >= 32 && ch <= 128)
- Con_Printf("glyphinfo: Character: %c\n", (int)ch);
- Con_Printf("glyphinfo: Vertex info:\n");
- Con_Printf("glyphinfo: X: ( %f -- %f )\n", mapglyph->vxmin, mapglyph->vxmax);
- Con_Printf("glyphinfo: Y: ( %f -- %f )\n", mapglyph->vymin, mapglyph->vymax);
- Con_Printf("glyphinfo: Texture info:\n");
- Con_Printf("glyphinfo: S: ( %f -- %f )\n", mapglyph->txmin, mapglyph->txmax);
- Con_Printf("glyphinfo: T: ( %f -- %f )\n", mapglyph->tymin, mapglyph->tymax);
- Con_Printf("glyphinfo: Advance: %f, %f\n", mapglyph->advance_x, mapglyph->advance_y);
+ Con_DPrintf("glyphinfo: Character: %c\n", (int)ch);
+ Con_DPrintf("glyphinfo: Vertex info:\n");
+ Con_DPrintf("glyphinfo: X: ( %f -- %f )\n", mapglyph->vxmin, mapglyph->vxmax);
+ Con_DPrintf("glyphinfo: Y: ( %f -- %f )\n", mapglyph->vymin, mapglyph->vymax);
+ Con_DPrintf("glyphinfo: Texture info:\n");
+ Con_DPrintf("glyphinfo: S: ( %f -- %f )\n", mapglyph->txmin, mapglyph->txmax);
+ Con_DPrintf("glyphinfo: T: ( %f -- %f )\n", mapglyph->tymin, mapglyph->tymax);
+ Con_DPrintf("glyphinfo: Advance: %f, %f\n", mapglyph->advance_x, mapglyph->advance_y);
}
}
map->glyphs[mapch].image = false;
// create a texture from the data now
- if (developer.integer)
+ if (developer_font.integer > 100)
{
+ // LordHavoc: why are we writing this? And why not write it as TGA using the appropriate function?
// view using `display -depth 8 -size 512x512 name_page.rgba` (be sure to use a correct -size parameter)
dpsnprintf(map_identifier, sizeof(map_identifier), "%s_%u.rgba", font->name, (unsigned)map->start/FONT_CHARS_PER_MAP);
FS_WriteFile(map_identifier, data, pitch * FONT_CHAR_LINES * map->glyphSize);
ft2_font_map_t *FontMap_FindForChar(ft2_font_map_t *start, Uchar ch)
{
- while (start && start->start + FONT_CHARS_PER_MAP < ch)
+ while (start && start->start + FONT_CHARS_PER_MAP <= ch)
start = start->next;
if (start && start->start > ch)
return NULL;