Commit 44786f59 authored by Akira TAGOH's avatar Akira TAGOH

Improve monospace font detection

Considered it is a monospaced font if there are few widths
but not counting if a width can be approximately divided by
the minimal width.

In this change, obsoleting FC_DUAL with FC_CHARCELL. both property
is actually provided for same purpose though, the meaning of "dual"
in the name isn't accurate anymore.

fontconfig/fontconfig#176
parent 65087ac7
Pipeline #70892 passed with stage
in 12 minutes and 13 seconds
......@@ -173,7 +173,7 @@ typedef int FcBool;
#define FC_WIDTH_ULTRAEXPANDED 200
#define FC_PROPORTIONAL 0
#define FC_DUAL 90
#define FC_DUAL FC_CHARCELL
#define FC_MONO 100
#define FC_CHARCELL 110
......
......@@ -2377,14 +2377,14 @@ FcFreeTypeCharIndex (FT_Face face, FcChar32 ucs4)
static inline int fc_min (int a, int b) { return a <= b ? a : b; }
static inline int fc_max (int a, int b) { return a >= b ? a : b; }
static inline FcBool fc_approximately_equal (int x, int y)
{ return abs (x - y) * 33 <= fc_max (abs (x), abs (y)); }
{ return abs (x - y) <= .03 * fc_max (abs (x), abs (y)); }
static int
FcFreeTypeSpacing (FT_Face face)
{
FT_Int load_flags = FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH | FT_LOAD_NO_SCALE | FT_LOAD_NO_HINTING;
FT_Pos advances[3] = {0};
unsigned int num_advances = 0;
FT_Pos advances[32] = {0};
unsigned int num_advances = 0, num_type_of_advances = 0;
int o;
/* When using scalable fonts, only report those glyphs
......@@ -2420,33 +2420,64 @@ FcFreeTypeSpacing (FT_Face face)
if (FT_Select_Charmap (face, fcFontEncodings[o]) != 0)
continue;
if (FcDebug () & FC_DBG_SCANV)
printf ("encoding: %d\n", fcFontEncodings[o]);
ucs4 = FT_Get_First_Char (face, &glyph);
while (glyph != 0 && num_advances < 3)
while (glyph != 0)
{
FT_Pos advance = 0;
if (!FT_Get_Advance (face, glyph, load_flags, &advance) && advance)
{
unsigned int j;
for (j = 0; j < num_advances; j++)
if (fc_approximately_equal (advance, advances[j]))
break;
{
if (fc_approximately_equal (advance, advances[j]))
break;
}
if (j == num_advances)
advances[num_advances++] = advance;
{
if (num_advances > 31)
return FC_PROPORTIONAL;
for (j = 0; j < num_advances; j++)
{
if (advance > advances[j] && advance % advances[j] == 0)
{
if (FcDebug () & FC_DBG_SCANV)
printf ("[%d] %ld > %ld\n", num_advances, advance, advances[j]);
advances[num_advances++] = advance;
break;
}
else if (advance < advances[j] && advances[j] % advance == 0)
{
if (FcDebug () & FC_DBG_SCANV)
printf ("[%d] %ld <\n", num_advances, advance);
advances[num_advances++] = advance;
break;
}
}
if (j == num_advances)
{
if (num_type_of_advances > 16)
return FC_PROPORTIONAL;
if (FcDebug () & FC_DBG_SCANV)
printf ("[%d] %ld\n", num_advances, advance);
advances[num_advances++] = advance;
num_type_of_advances++;
}
}
}
ucs4 = FT_Get_Next_Char (face, ucs4, &glyph);
}
break;
}
if (FcDebug () & FC_DBG_SCANV)
printf ("num_advances: %d\n", num_advances);
if (num_advances <= 1)
return FC_MONO;
else if (num_advances == 2 &&
fc_approximately_equal (fc_min (advances[0], advances[1]) * 2,
fc_max (advances[0], advances[1])))
return FC_DUAL;
else
return FC_PROPORTIONAL;
return FC_CHARCELL;
}
FcCharSet *
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment