]> git.xonotic.org Git - xonotic/darkplaces.git/blobdiff - ft2.c
added developer_font, set > 100 to also dump the generated images
[xonotic/darkplaces.git] / ft2.c
diff --git a/ft2.c b/ft2.c
index 0e99c1e41a7cd979505bee9d56ed9398131a19b4..df81aba03bdee25875b420ea15665392fa8b6a66 100644 (file)
--- a/ft2.c
+++ b/ft2.c
@@ -35,6 +35,9 @@ 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", "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 developer_font = {CVAR_SAVE, "developer_font", "0", "prints debug messages about fonts"};
 
 /*
 ================================================================================
@@ -253,6 +256,9 @@ 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);
+       Cvar_RegisterVariable(&r_font_antialias);
+       Cvar_RegisterVariable(&developer_font);
 }
 
 /*
@@ -503,7 +509,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)
@@ -755,6 +761,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
@@ -777,6 +784,45 @@ static qboolean Font_LoadMap(ft2_font_t *font, ft2_font_map_t *mapstart, Uchar _
        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)
@@ -869,7 +915,7 @@ static qboolean Font_LoadMap(ft2_font_t *font, ft2_font_map_t *mapstart, Uchar _
 
                mapch = ch - map->start;
 
-               if (developer_extra.integer)
+               if (developer_font.integer)
                        Con_DPrint("glyphinfo: ------------- GLYPH INFO -----------------\n");
 
                ++gC;
@@ -903,7 +949,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;
@@ -921,7 +967,7 @@ 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);
@@ -947,23 +993,23 @@ 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_extra.integer)
+                       if (developer_font.integer)
                                Con_DPrint("glyphinfo:   Pixel Mode: MONO\n");
                        break;
                case FT_PIXEL_MODE_GRAY2:
-                       if (developer_extra.integer)
+                       if (developer_font.integer)
                                Con_DPrint("glyphinfo:   Pixel Mode: GRAY2\n");
                        break;
                case FT_PIXEL_MODE_GRAY4:
-                       if (developer_extra.integer)
+                       if (developer_font.integer)
                                Con_DPrint("glyphinfo:   Pixel Mode: GRAY4\n");
                        break;
                case FT_PIXEL_MODE_GRAY:
-                       if (developer_extra.integer)
+                       if (developer_font.integer)
                                Con_DPrint("glyphinfo:   Pixel Mode: GRAY\n");
                        break;
                default:
-                       if (developer_extra.integer)
+                       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);
@@ -981,14 +1027,14 @@ static qboolean Font_LoadMap(ft2_font_t *font, ft2_font_map_t *mapstart, Uchar _
                                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:
@@ -1007,8 +1053,8 @@ static qboolean Font_LoadMap(ft2_font_t *font, ft2_font_map_t *mapstart, Uchar _
                                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:
@@ -1032,24 +1078,29 @@ static qboolean Font_LoadMap(ft2_font_t *font, ft2_font_map_t *mapstart, Uchar _
                        // 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 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 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_y = 0;
 
-                       if (developer_extra.integer)
+                       if (developer_font.integer)
                        {
                                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);
@@ -1069,7 +1120,7 @@ static qboolean Font_LoadMap(ft2_font_t *font, ft2_font_map_t *mapstart, Uchar _
 
        // create a texture from the data now
 
-       if (developer_extra.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)