Handle Adobe glyph names for fonts which include ADOBE_CUSTOM encodings
This commit is contained in:
parent
83321a017a
commit
7769c3213d
|
@ -21,7 +21,7 @@
|
|||
# TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
# PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
SUBDIRS=fontconfig fc-lang src fc-cache fc-list doc test
|
||||
SUBDIRS=fontconfig fc-lang fc-glyphname src fc-cache fc-list doc test
|
||||
|
||||
EXTRA_DIST = \
|
||||
fontconfig.pc.in \
|
||||
|
|
|
@ -357,6 +357,7 @@ AC_OUTPUT([
|
|||
Makefile
|
||||
fontconfig/Makefile
|
||||
fc-lang/Makefile
|
||||
fc-glyphname/Makefile
|
||||
src/Makefile
|
||||
src/fontconfig.def
|
||||
fc-cache/Makefile
|
||||
|
|
160
src/fcfreetype.c
160
src/fcfreetype.c
|
@ -1548,6 +1548,107 @@ FcFreeTypeGetPrivateMap (FT_Encoding encoding)
|
|||
return 0;
|
||||
}
|
||||
|
||||
#include "../fc-glyphname/fcglyphname.h"
|
||||
|
||||
static FcChar32
|
||||
FcHashGlyphName (const FcChar8 *name)
|
||||
{
|
||||
FcChar32 h = 0;
|
||||
FcChar8 c;
|
||||
|
||||
while ((c = *name++))
|
||||
{
|
||||
h = ((h << 1) | (h >> 31)) ^ c;
|
||||
}
|
||||
return h;
|
||||
}
|
||||
|
||||
/*
|
||||
* Use Type1 glyph names for fonts which have reliable names
|
||||
* and which export an Adobe Custom mapping
|
||||
*/
|
||||
static FcBool
|
||||
FcFreeTypeUseNames (FT_Face face)
|
||||
{
|
||||
FT_Int map;
|
||||
|
||||
if (!FT_Has_PS_Glyph_Names (face))
|
||||
return FcFalse;
|
||||
for (map = 0; map < face->num_charmaps; map++)
|
||||
if (face->charmaps[map]->encoding == FT_ENCODING_ADOBE_CUSTOM)
|
||||
return FcTrue;
|
||||
return FcFalse;
|
||||
}
|
||||
|
||||
static FcChar8 *
|
||||
FcUcs4ToGlyphName (FcChar32 ucs4)
|
||||
{
|
||||
int i = (int) (ucs4 % FC_GLYPHNAME_HASH);
|
||||
int r = 0;
|
||||
FcGlyphName *gn;
|
||||
|
||||
while ((gn = ucs_to_name[i]))
|
||||
{
|
||||
if (gn->ucs == ucs4)
|
||||
return gn->name;
|
||||
if (!r)
|
||||
{
|
||||
r = (int) (ucs4 % FC_GLYPHNAME_REHASH);
|
||||
if (!r)
|
||||
r = 1;
|
||||
}
|
||||
i += r;
|
||||
if (i >= FC_GLYPHNAME_HASH)
|
||||
i -= FC_GLYPHNAME_HASH;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static FcChar32
|
||||
FcGlyphNameToUcs4 (FcChar8 *name)
|
||||
{
|
||||
FcChar32 h = FcHashGlyphName (name);
|
||||
int i = (int) (h % FC_GLYPHNAME_HASH);
|
||||
int r = 0;
|
||||
FcGlyphName *gn;
|
||||
|
||||
while ((gn = name_to_ucs[i]))
|
||||
{
|
||||
if (!strcmp ((char *) name, (char *) gn->name))
|
||||
return gn->ucs;
|
||||
if (!r)
|
||||
{
|
||||
r = (int) (h % FC_GLYPHNAME_REHASH);
|
||||
if (!r)
|
||||
r = 1;
|
||||
}
|
||||
i += r;
|
||||
if (i >= FC_GLYPHNAME_HASH)
|
||||
i -= FC_GLYPHNAME_HASH;
|
||||
}
|
||||
return 0xffff;
|
||||
}
|
||||
|
||||
/*
|
||||
* Search through a font for a glyph by name. This is
|
||||
* currently a linear search as there doesn't appear to be
|
||||
* any defined order within the font
|
||||
*/
|
||||
static FT_UInt
|
||||
FcFreeTypeGlyphNameIndex (FT_Face face, FcChar8 *name)
|
||||
{
|
||||
FT_UInt gindex;
|
||||
FcChar8 name_buf[FC_GLYPHNAME_MAXLEN + 2];
|
||||
|
||||
for (gindex = 0; gindex < face->num_glyphs; gindex++)
|
||||
{
|
||||
if (FT_Get_Glyph_Name (face, gindex, name_buf, FC_GLYPHNAME_MAXLEN+1) == 0)
|
||||
if (!strcmp ((char *) name, (char *) name_buf))
|
||||
return gindex;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Map a UCS4 glyph to a glyph index. Use all available encoding
|
||||
* tables to try and find one that works. This information is expected
|
||||
|
@ -1594,6 +1695,19 @@ FcFreeTypeCharIndex (FT_Face face, FcChar32 ucs4)
|
|||
if (glyphindex)
|
||||
return glyphindex;
|
||||
}
|
||||
/*
|
||||
* Check postscript name table if present
|
||||
*/
|
||||
if (FcFreeTypeUseNames (face))
|
||||
{
|
||||
FcChar8 *name = FcUcs4ToGlyphName (ucs4);
|
||||
if (name)
|
||||
{
|
||||
glyphindex = FcFreeTypeGlyphNameIndex (face, name);
|
||||
if (glyphindex)
|
||||
return glyphindex;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1673,6 +1787,9 @@ FcFreeTypeCharSetAndSpacing (FT_Face face, FcBlanks *blanks, int *spacing)
|
|||
if (!fcs)
|
||||
goto bail0;
|
||||
|
||||
#ifdef CHECK
|
||||
printf ("Family %s style %s\n", face->family_name, face->style_name);
|
||||
#endif
|
||||
for (o = 0; o < NUM_DECODE; o++)
|
||||
{
|
||||
if (FT_Select_Charmap (face, fcFontDecoders[o].encoding) != 0)
|
||||
|
@ -1780,15 +1897,54 @@ FcFreeTypeCharSetAndSpacing (FT_Face face, FcBlanks *blanks, int *spacing)
|
|||
#endif
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Add mapping from PS glyph names if available
|
||||
*/
|
||||
if (FcFreeTypeUseNames (face))
|
||||
{
|
||||
FcChar8 name_buf[FC_GLYPHNAME_MAXLEN + 2];
|
||||
|
||||
for (glyph = 0; glyph < face->num_glyphs; glyph++)
|
||||
{
|
||||
if (FT_Get_Glyph_Name (face, glyph, name_buf, FC_GLYPHNAME_MAXLEN+1) == 0)
|
||||
{
|
||||
ucs4 = FcGlyphNameToUcs4 (name_buf);
|
||||
if (ucs4 != 0xffff &&
|
||||
FcFreeTypeCheckGlyph (face, ucs4, glyph, blanks, &advance))
|
||||
{
|
||||
if (!has_advance)
|
||||
{
|
||||
has_advance = FcTrue;
|
||||
all_advance = advance;
|
||||
}
|
||||
else if (advance != all_advance)
|
||||
fixed_advance = FcFalse;
|
||||
leaf = FcCharSetFindLeafCreate (fcs, ucs4);
|
||||
if (!leaf)
|
||||
goto bail1;
|
||||
leaf->map[(ucs4 & 0xff) >> 5] |= (1 << (ucs4 & 0x1f));
|
||||
#ifdef CHECK
|
||||
if (ucs4 > font_max)
|
||||
font_max = ucs4;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#ifdef CHECK
|
||||
printf ("%d glyphs %d encoded\n", (int) face->num_glyphs, FcCharSetCount (fcs));
|
||||
for (ucs4 = 0; ucs4 <= font_max; ucs4++)
|
||||
{
|
||||
FcBool has_char = FcFreeTypeCharIndex (face, ucs4) != 0;
|
||||
FcBool has_char = (glyph = FcFreeTypeCharIndex (face, ucs4)) != 0;
|
||||
FcBool has_bit = FcCharSetHasChar (fcs, ucs4);
|
||||
|
||||
if (has_char && !has_bit)
|
||||
printf ("Bitmap missing char 0x%x\n", ucs4);
|
||||
{
|
||||
if (!FcFreeTypeCheckGlyph (face, ucs4, glyph, blanks, &advance))
|
||||
printf ("Bitmap missing broken char 0x%x\n", ucs4);
|
||||
else
|
||||
printf ("Bitmap missing char 0x%x\n", ucs4);
|
||||
}
|
||||
else if (!has_char && has_bit)
|
||||
printf ("Bitmap extra char 0x%x\n", ucs4);
|
||||
}
|
||||
|
|
10
src/fcint.h
10
src/fcint.h
|
@ -218,6 +218,16 @@ typedef struct _FcStrBuf {
|
|||
int size;
|
||||
} FcStrBuf;
|
||||
|
||||
/*
|
||||
* To map adobe glyph names to unicode values, a precomputed hash
|
||||
* table is used
|
||||
*/
|
||||
|
||||
typedef struct _FcGlyphName {
|
||||
FcChar32 ucs; /* unicode value */
|
||||
FcChar8 name[1]; /* name extends beyond struct */
|
||||
} FcGlyphName;
|
||||
|
||||
/*
|
||||
* The per-user ~/.fonts.cache-<version> file is loaded into
|
||||
* this data structure. Each directory gets a substructure
|
||||
|
|
Loading…
Reference in New Issue