Grub through style to find weight/slant/width values when other techniques

fail
This commit is contained in:
Keith Packard 2003-05-02 01:11:53 +00:00
parent 1f71c4d878
commit 11fec41c0e
3 changed files with 233 additions and 75 deletions

View File

@ -255,6 +255,87 @@ FcVendorFoundry(const char *vendor)
return 0; return 0;
} }
typedef struct _FcStringConst {
const char *name;
int value;
} FcStringConst;
static int
FcStringIsConst (const FcChar8 *string,
const FcStringConst *c,
int nc)
{
int i;
for (i = 0; i < nc; i++)
if (FcStrCmpIgnoreBlanksAndCase (string, c[i].name) == 0)
return c[i].value;
return -1;
}
static int
FcStringContainsConst (const FcChar8 *string,
const FcStringConst *c,
int nc)
{
int i;
for (i = 0; i < nc; i++)
if (FcStrContainsIgnoreBlanksAndCase (string, c[i].name))
return c[i].value;
return -1;
}
static const FcStringConst weightConsts[] = {
{ "thin", FC_WEIGHT_THIN },
{ "extralight", FC_WEIGHT_EXTRALIGHT },
{ "ultralight", FC_WEIGHT_ULTRALIGHT },
{ "light", FC_WEIGHT_LIGHT },
{ "book", FC_WEIGHT_BOOK },
{ "regular", FC_WEIGHT_REGULAR },
{ "normal", FC_WEIGHT_NORMAL },
{ "medium", FC_WEIGHT_MEDIUM },
{ "demibold", FC_WEIGHT_DEMIBOLD },
{ "demi", FC_WEIGHT_DEMIBOLD },
{ "semibold", FC_WEIGHT_SEMIBOLD },
{ "bold", FC_WEIGHT_BOLD },
{ "extrabold", FC_WEIGHT_EXTRABOLD },
{ "ultrabold", FC_WEIGHT_ULTRABOLD },
{ "black", FC_WEIGHT_BLACK },
{ "heavy", FC_WEIGHT_HEAVY },
};
#define NUM_WEIGHT_CONSTS (sizeof (weightConsts) / sizeof (weightConsts[0]))
#define FcIsWeight(s) FcStringIsConst(s,weightConsts,NUM_WEIGHT_CONSTS)
#define FcContainsWeight(s) FcStringContainsConst (s,weightConsts,NUM_WEIGHT_CONSTS)
static const FcStringConst widthConsts[] = {
{ "ultracondensed", FC_WIDTH_ULTRACONDENSED },
{ "extracondensed", FC_WIDTH_EXTRACONDENSED },
{ "semicondensed", FC_WIDTH_SEMICONDENSED },
{ "condensed", FC_WIDTH_CONDENSED }, /* must be after *condensed */
{ "normal", FC_WIDTH_NORMAL },
{ "semiexpanded", FC_WIDTH_SEMIEXPANDED },
{ "extraexpanded", FC_WIDTH_EXTRAEXPANDED },
{ "ultraexpanded", FC_WIDTH_ULTRAEXPANDED },
{ "expanded", FC_WIDTH_EXPANDED }, /* must be after *expanded */
};
#define NUM_WIDTH_CONSTS (sizeof (widthConsts) / sizeof (widthConsts[0]))
#define FcIsWidth(s) FcStringIsConst(s,widthConsts,NUM_WIDTH_CONSTS)
#define FcContainsWidth(s) FcStringContainsConst (s,widthConsts,NUM_WIDTH_CONSTS)
static const FcStringConst slantConsts[] = {
{ "italic", FC_SLANT_ITALIC },
{ "oblique", FC_SLANT_OBLIQUE },
};
#define NUM_SLANT_CONSTS (sizeof (slantConsts) / sizeof (slantConsts[0]))
#define FcIsSlant(s) FcStringIsConst(s,slantConsts,NUM_SLANT_CONSTS)
#define FcContainsSlant(s) FcStringContainsConst (s,slantConsts,NUM_SLANT_CONSTS)
FcPattern * FcPattern *
FcFreeTypeQuery (const FcChar8 *file, FcFreeTypeQuery (const FcChar8 *file,
@ -264,8 +345,8 @@ FcFreeTypeQuery (const FcChar8 *file,
{ {
FT_Face face; FT_Face face;
FcPattern *pat; FcPattern *pat;
int slant; int slant = -1;
int weight; int weight = -1;
int width = -1; int width = -1;
int i; int i;
FcCharSet *cs; FcCharSet *cs;
@ -307,15 +388,6 @@ FcFreeTypeQuery (const FcChar8 *file,
goto bail1; goto bail1;
slant = FC_SLANT_ROMAN;
if (face->style_flags & FT_STYLE_FLAG_ITALIC)
slant = FC_SLANT_ITALIC;
weight = FC_WEIGHT_MEDIUM;
if (face->style_flags & FT_STYLE_FLAG_BOLD)
weight = FC_WEIGHT_BOLD;
/* /*
* Get the OS/2 table * Get the OS/2 table
*/ */
@ -598,30 +670,15 @@ FcFreeTypeQuery (const FcChar8 *file,
} }
if (FcDebug() & FC_DBG_SCAN) if (FcDebug() & FC_DBG_SCAN)
printf ("\"%s\" \"%s\" ", family, style ? style : (FcChar8 *) "<none>"); printf ("\n\"%s\" \"%s\"\n", family, style ? style : (FcChar8 *) "<none>");
if (!FcPatternAddString (pat, FC_FAMILY, family)) if (!FcPatternAddString (pat, FC_FAMILY, family))
{
if (family_allocated)
free (family);
if (style_allocated)
free (style);
goto bail1; goto bail1;
}
if (family_allocated)
free (family);
if (style) if (style)
{ {
if (!FcPatternAddString (pat, FC_STYLE, style)) if (!FcPatternAddString (pat, FC_STYLE, style))
{
if (style_allocated)
free (style);
goto bail1; goto bail1;
}
if (style_allocated)
free (style);
} }
if (!FcPatternAddString (pat, FC_FILE, file)) if (!FcPatternAddString (pat, FC_FILE, file))
@ -695,7 +752,7 @@ FcFreeTypeQuery (const FcChar8 *file,
if (os2 && os2->version != 0xffff) if (os2 && os2->version != 0xffff)
{ {
if (os2->usWeightClass == 0) if (os2->usWeightClass == 0)
weight = -1; ;
else if (os2->usWeightClass < 150) else if (os2->usWeightClass < 150)
weight = FC_WEIGHT_THIN; weight = FC_WEIGHT_THIN;
else if (os2->usWeightClass < 250) else if (os2->usWeightClass < 250)
@ -714,8 +771,6 @@ FcFreeTypeQuery (const FcChar8 *file,
weight = FC_WEIGHT_EXTRABOLD; weight = FC_WEIGHT_EXTRABOLD;
else if (os2->usWeightClass < 950) else if (os2->usWeightClass < 950)
weight = FC_WEIGHT_BLACK; weight = FC_WEIGHT_BLACK;
else
weight = FC_WEIGHT_MEDIUM;
switch (os2->usWidthClass) { switch (os2->usWidthClass) {
case 1: width = FC_WIDTH_ULTRACONDENSED; break; case 1: width = FC_WIDTH_ULTRACONDENSED; break;
@ -737,44 +792,15 @@ FcFreeTypeQuery (const FcChar8 *file,
if (FT_Get_PS_Font_Info(face, &psfontinfo) == 0) if (FT_Get_PS_Font_Info(face, &psfontinfo) == 0)
{ {
if (psfontinfo.weight) #if 0
if (weight == -1 && psfontinfo.weight)
{ {
static struct { weight = FcIsWeight (psfontinfo.weight);
char *name; if (FcDebug() & FC_DBG_SCANV)
int value; printf ("\tType1 weight %s maps to %d\n",
} ps_weights[] = { psfontinfo.weight, weight);
{ "thin", FC_WEIGHT_THIN },
{ "extralight", FC_WEIGHT_EXTRALIGHT },
{ "ultralight", FC_WEIGHT_ULTRALIGHT },
{ "light", FC_WEIGHT_LIGHT },
{ "book", FC_WEIGHT_BOOK },
{ "regular", FC_WEIGHT_REGULAR },
{ "normal", FC_WEIGHT_NORMAL },
{ "medium", FC_WEIGHT_MEDIUM },
{ "demibold", FC_WEIGHT_DEMIBOLD },
{ "demi", FC_WEIGHT_DEMIBOLD },
{ "semibold", FC_WEIGHT_SEMIBOLD },
{ "bold", FC_WEIGHT_BOLD },
{ "extrabold", FC_WEIGHT_EXTRABOLD },
{ "ultrabold", FC_WEIGHT_ULTRABOLD },
{ "black", FC_WEIGHT_BLACK },
{ "heavy", FC_WEIGHT_HEAVY },
};
#define NUM_PS_WEIGHTS (sizeof (ps_weights) / sizeof (ps_weights[0]))
int w;
for (w = 0; w < NUM_PS_WEIGHTS; w++)
if (!FcStrCmpIgnoreBlanksAndCase ((FcChar8 *) ps_weights[w].name,
(FcChar8 *) psfontinfo.weight))
{
weight = ps_weights[w].value;
break;
}
if (FcDebug () & FC_DBG_SCANV)
{
if (w == NUM_PS_WEIGHTS)
printf ("\tunknown PS weight name %s\n", psfontinfo.weight);
}
} }
#endif
#if 0 #if 0
/* /*
@ -838,14 +864,11 @@ FcFreeTypeQuery (const FcChar8 *file,
FcChar8 *width_name; FcChar8 *width_name;
int width; int width;
} FcSetWidths[] = { } FcSetWidths[] = {
{ "Condensed", FC_WIDTH_CONDENSED },
{ "SemiCondensed", FC_WIDTH_SEMICONDENSED },
{ "Normal", FC_WIDTH_NORMAL },
}; };
int i; int i;
if (FcDebug () & FC_DBG_SCANV) if (FcDebug () & FC_DBG_SCANV)
printf ("\nsetwidth: %s\n", prop.u.atom); printf ("\tsetwidth: %s\n", prop.u.atom);
for (i = 0; i < sizeof (FcSetWidths) / sizeof (FcSetWidths[0]); i++) for (i = 0; i < sizeof (FcSetWidths) / sizeof (FcSetWidths[0]); i++)
if (!FcStrCmpIgnoreBlanksAndCase ((FcChar8 *) prop.u.atom, if (!FcStrCmpIgnoreBlanksAndCase ((FcChar8 *) prop.u.atom,
FcSetWidths[i].width_name)) FcSetWidths[i].width_name))
@ -858,6 +881,48 @@ FcFreeTypeQuery (const FcChar8 *file,
#endif #endif
/*
* Look for weight, width and slant names in the style value
*/
if (style)
{
if (weight == -1)
{
weight = FcContainsWeight (style);
if (FcDebug() & FC_DBG_SCANV)
printf ("\tStyle %s maps to weight %d\n", style, weight);
}
if (width == -1)
{
width = FcContainsWidth (style);
if (FcDebug() & FC_DBG_SCANV)
printf ("\tStyle %s maps to width %d\n", style, width);
}
if (slant == -1)
{
slant = FcContainsSlant (style);
if (FcDebug() & FC_DBG_SCANV)
printf ("\tStyle %s maps to slant %d\n", style, slant);
}
}
/*
* Pull default values from the FreeType flags if more
* specific values not found above
*/
if (slant == -1)
{
slant = FC_SLANT_ROMAN;
if (face->style_flags & FT_STYLE_FLAG_ITALIC)
slant = FC_SLANT_ITALIC;
}
if (weight == -1)
{
weight = FC_WEIGHT_MEDIUM;
if (face->style_flags & FT_STYLE_FLAG_BOLD)
weight = FC_WEIGHT_BOLD;
}
if (!FcPatternAddInteger (pat, FC_SLANT, slant)) if (!FcPatternAddInteger (pat, FC_SLANT, slant))
goto bail1; goto bail1;
@ -905,11 +970,6 @@ FcFreeTypeQuery (const FcChar8 *file,
if (!FcPatternAddInteger (pat, FC_SPACING, spacing)) if (!FcPatternAddInteger (pat, FC_SPACING, spacing))
goto bail2; goto bail2;
/*
* Drop our reference to the charset
*/
FcCharSetDestroy (cs);
if (!(face->face_flags & FT_FACE_FLAG_SCALABLE)) if (!(face->face_flags & FT_FACE_FLAG_SCALABLE))
{ {
for (i = 0; i < face->num_fixed_sizes; i++) for (i = 0; i < face->num_fixed_sizes; i++)
@ -920,6 +980,20 @@ FcFreeTypeQuery (const FcChar8 *file,
goto bail1; goto bail1;
} }
/*
* Drop our reference to the charset
*/
FcCharSetDestroy (cs);
/*
* Deallocate family/style values
*/
if (family_allocated)
free (family);
if (style_allocated)
free (style);
FT_Done_Face (face); FT_Done_Face (face);
FT_Done_FreeType (ftLibrary); FT_Done_FreeType (ftLibrary);
return pat; return pat;
@ -928,6 +1002,10 @@ bail2:
FcCharSetDestroy (cs); FcCharSetDestroy (cs);
bail1: bail1:
FcPatternDestroy (pat); FcPatternDestroy (pat);
if (family_allocated)
free (family);
if (style_allocated)
free (style);
bail0: bail0:
FT_Done_Face (face); FT_Done_Face (face);
bail: bail:

View File

@ -653,6 +653,12 @@ FcStrBufData (FcStrBuf *buf, const FcChar8 *s, int len);
int int
FcStrCmpIgnoreBlanksAndCase (const FcChar8 *s1, const FcChar8 *s2); FcStrCmpIgnoreBlanksAndCase (const FcChar8 *s1, const FcChar8 *s2);
const FcChar8 *
FcStrContainsIgnoreBlanksAndCase (const FcChar8 *s1, const FcChar8 *s2);
const FcChar8 *
FcStrContainsIgnoreCase (const FcChar8 *s1, const FcChar8 *s2);
FcBool FcBool
FcStrUsesHome (const FcChar8 *s); FcStrUsesHome (const FcChar8 *s);

View File

@ -114,6 +114,80 @@ FcStrCmp (const FcChar8 *s1, const FcChar8 *s2)
return (int) c1 - (int) c2; return (int) c1 - (int) c2;
} }
/*
* Is the head of s1 equal to s2?
*/
static FcBool
FcStrIsAtIgnoreBlanksAndCase (const FcChar8 *s1, const FcChar8 *s2)
{
FcChar8 c1, c2;
for (;;)
{
do
c1 = *s1++;
while (c1 == ' ');
do
c2 = *s2++;
while (c2 == ' ');
if (!c1 || (c1 != c2 && (c1 = FcToLower(c1)) != (c2 = FcToLower(c2))))
break;
}
return c1 == c2 || !c2;
}
/*
* Does s1 contain an instance of s2 (ignoring blanks and case)?
*/
const FcChar8 *
FcStrContainsIgnoreBlanksAndCase (const FcChar8 *s1, const FcChar8 *s2)
{
while (*s1)
{
if (FcStrIsAtIgnoreBlanksAndCase (s1, s2))
return s1;
s1++;
}
return 0;
}
/*
* Is the head of s1 equal to s2?
*/
static FcBool
FcStrIsAtIgnoreCase (const FcChar8 *s1, const FcChar8 *s2)
{
FcChar8 c1, c2;
for (;;)
{
c1 = *s1++;
c2 = *s2++;
if (!c1 || (c1 != c2 && (c1 = FcToLower(c1)) != (c2 = FcToLower(c2))))
break;
}
return c1 == c2 || !c2;
}
/*
* Does s1 contain an instance of s2 (ignoring blanks and case)?
*/
const FcChar8 *
FcStrContainsIgnoreCase (const FcChar8 *s1, const FcChar8 *s2)
{
while (*s1)
{
if (FcStrIsAtIgnoreCase (s1, s2))
return s1;
s1++;
}
return 0;
}
int int
FcUtf8ToUcs4 (const FcChar8 *src_orig, FcUtf8ToUcs4 (const FcChar8 *src_orig,
FcChar32 *dst, FcChar32 *dst,