]> de.git.xonotic.org Git - xonotic/darkplaces.git/blobdiff - ft2.c
r_font_hinting cvar makes more sense: 0 no hinting, 1 force autohinting, 2 fullhintin...
[xonotic/darkplaces.git] / ft2.c
diff --git a/ft2.c b/ft2.c
index 1fd78bd31349e47387c8129e310855e6eaea62d1..13a855eec4a22583a1bb046c098740c47991b4b3 100644 (file)
--- a/ft2.c
+++ b/ft2.c
@@ -35,6 +35,7 @@ CVars introduced with the freetype extension
 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", "2", "0 = no hinting, 1 = force autohinting, 2 = full hinting"};
 
 /*
 ================================================================================
@@ -169,10 +170,8 @@ qboolean Font_OpenLibrary (void)
 {
        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",
 #elif defined(MACOSX)
                "libfreetype.dylib",
 #else
@@ -255,6 +254,7 @@ void Font_Init(void)
        Cvar_RegisterVariable(&r_font_disable_freetype);
        Cvar_RegisterVariable(&r_font_use_alpha_textures);
        Cvar_RegisterVariable(&r_font_size_snapping);
+       Cvar_RegisterVariable(&r_font_hinting);
 }
 
 /*
@@ -290,6 +290,22 @@ qboolean Font_Attach(ft2_font_t *font, ft2_attachment_t *attachment)
        return true;
 }
 
+static 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;
+}
+
 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);
 qboolean Font_LoadFont(const char *name, dp_font_t *dpfnt)
@@ -349,7 +365,7 @@ qboolean Font_LoadFont(const char *name, dp_font_t *dpfnt)
                count = 0;
                for (s = 0; s < MAX_FONT_SIZES; ++s)
                {
-                       if (Font_LoadSize(fb, dpfnt->req_sizes[s], true, false))
+                       if (Font_LoadSize(fb, Font_VirtualToRealSize(dpfnt->req_sizes[s]), true, false))
                                ++count;
                }
                if (!count)
@@ -376,7 +392,7 @@ qboolean Font_LoadFont(const char *name, dp_font_t *dpfnt)
        count = 0;
        for (s = 0; s < MAX_FONT_SIZES; ++s)
        {
-               if (Font_LoadSize(ft2, dpfnt->req_sizes[s], false, false))
+               if (Font_LoadSize(ft2, Font_VirtualToRealSize(dpfnt->req_sizes[s]), false, false))
                        ++count;
        }
        if (!count)
@@ -489,7 +505,7 @@ static qboolean Font_LoadSize(ft2_font_t *font, float size, qboolean no_texture,
        int map_index;
        ft2_font_map_t *fmap, temp;
 
-       if (IS_NAN(size))
+       if (!(size > 0.001f && size < 1000.0f))
                size = 0;
 
        if (!size)
@@ -741,6 +757,7 @@ static qboolean Font_LoadMap(ft2_font_t *font, ft2_font_map_t *mapstart, Uchar _
        FT_ULong ch, mapch;
        int status;
        int tp;
+       FT_Int32 load_flags;
 
        int pitch;
        int gR, gC; // glyph position: row and column
@@ -763,6 +780,12 @@ static qboolean Font_LoadMap(ft2_font_t *font, ft2_font_map_t *mapstart, Uchar _
        else
                fontface = (FT_Face)font->face;
 
+       load_flags = FT_LOAD_NO_HINTING | FT_LOAD_NO_AUTOHINT;
+       if (r_font_hinting.integer == 1)
+               load_flags = FT_LOAD_FORCE_AUTOHINT;
+       else if (r_font_hinting.integer == 2)
+               load_flags = 0;
+
        //status = qFT_Set_Pixel_Sizes((FT_Face)font->face, /*size*/0, mapstart->size);
        //if (status)
        if (font->image_font && mapstart->intSize < 0)
@@ -786,8 +809,7 @@ static qboolean Font_LoadMap(ft2_font_t *font, ft2_font_map_t *mapstart, Uchar _
                        }
                        --mapstart->intSize;
                }
-               if (developer.integer)
-                       Con_Printf("Using size: %f for requested size %f\n", mapstart->intSize, mapstart->size);
+               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))
@@ -856,8 +878,8 @@ static qboolean Font_LoadMap(ft2_font_t *font, ft2_font_map_t *mapstart, Uchar _
 
                mapch = ch - map->start;
 
-               if (developer.integer)
-                       Con_Print("glyphinfo: ------------- GLYPH INFO -----------------\n");
+               if (developer_extra.integer)
+                       Con_DPrint("glyphinfo: ------------- GLYPH INFO -----------------\n");
 
                ++gC;
                if (gC >= FONT_CHARS_PER_LINE)
@@ -890,7 +912,7 @@ static qboolean Font_LoadMap(ft2_font_t *font, ft2_font_map_t *mapstart, Uchar _
                                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;
@@ -908,11 +930,11 @@ static qboolean Font_LoadMap(ft2_font_t *font, ft2_font_map_t *mapstart, Uchar _
                {
                        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;
                        }
                }
@@ -934,24 +956,24 @@ static qboolean Font_LoadMap(ft2_font_t *font, ft2_font_map_t *mapstart, Uchar _
                switch (bmp->pixel_mode)
                {
                case FT_PIXEL_MODE_MONO:
-                       if (developer.integer)
-                               Con_Print("glyphinfo:   Pixel Mode: MONO\n");
+                       if (developer_extra.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_extra.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_extra.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_extra.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_extra.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;
@@ -1036,19 +1058,19 @@ static qboolean Font_LoadMap(ft2_font_t *font, ft2_font_map_t *mapstart, Uchar _
                        mapglyph->advance_x = advance;
                        mapglyph->advance_y = 0;
 
-                       if (developer.integer)
+                       if (developer_extra.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;
@@ -1056,8 +1078,9 @@ static qboolean Font_LoadMap(ft2_font_t *font, ft2_font_map_t *mapstart, Uchar _
 
        // create a texture from the data now
 
-       if (developer.integer)
+       if (developer_extra.integer)
        {
+               // 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);