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
|
# TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||||
# PERFORMANCE OF THIS SOFTWARE.
|
# 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 = \
|
EXTRA_DIST = \
|
||||||
fontconfig.pc.in \
|
fontconfig.pc.in \
|
||||||
|
|
|
@ -357,6 +357,7 @@ AC_OUTPUT([
|
||||||
Makefile
|
Makefile
|
||||||
fontconfig/Makefile
|
fontconfig/Makefile
|
||||||
fc-lang/Makefile
|
fc-lang/Makefile
|
||||||
|
fc-glyphname/Makefile
|
||||||
src/Makefile
|
src/Makefile
|
||||||
src/fontconfig.def
|
src/fontconfig.def
|
||||||
fc-cache/Makefile
|
fc-cache/Makefile
|
||||||
|
|
160
src/fcfreetype.c
160
src/fcfreetype.c
|
@ -1548,6 +1548,107 @@ FcFreeTypeGetPrivateMap (FT_Encoding encoding)
|
||||||
return 0;
|
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
|
* Map a UCS4 glyph to a glyph index. Use all available encoding
|
||||||
* tables to try and find one that works. This information is expected
|
* tables to try and find one that works. This information is expected
|
||||||
|
@ -1594,6 +1695,19 @@ FcFreeTypeCharIndex (FT_Face face, FcChar32 ucs4)
|
||||||
if (glyphindex)
|
if (glyphindex)
|
||||||
return 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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1673,6 +1787,9 @@ FcFreeTypeCharSetAndSpacing (FT_Face face, FcBlanks *blanks, int *spacing)
|
||||||
if (!fcs)
|
if (!fcs)
|
||||||
goto bail0;
|
goto bail0;
|
||||||
|
|
||||||
|
#ifdef CHECK
|
||||||
|
printf ("Family %s style %s\n", face->family_name, face->style_name);
|
||||||
|
#endif
|
||||||
for (o = 0; o < NUM_DECODE; o++)
|
for (o = 0; o < NUM_DECODE; o++)
|
||||||
{
|
{
|
||||||
if (FT_Select_Charmap (face, fcFontDecoders[o].encoding) != 0)
|
if (FT_Select_Charmap (face, fcFontDecoders[o].encoding) != 0)
|
||||||
|
@ -1780,15 +1897,54 @@ FcFreeTypeCharSetAndSpacing (FT_Face face, FcBlanks *blanks, int *spacing)
|
||||||
#endif
|
#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
|
#ifdef CHECK
|
||||||
printf ("%d glyphs %d encoded\n", (int) face->num_glyphs, FcCharSetCount (fcs));
|
printf ("%d glyphs %d encoded\n", (int) face->num_glyphs, FcCharSetCount (fcs));
|
||||||
for (ucs4 = 0; ucs4 <= font_max; ucs4++)
|
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);
|
FcBool has_bit = FcCharSetHasChar (fcs, ucs4);
|
||||||
|
|
||||||
if (has_char && !has_bit)
|
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)
|
else if (!has_char && has_bit)
|
||||||
printf ("Bitmap extra char 0x%x\n", ucs4);
|
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;
|
int size;
|
||||||
} FcStrBuf;
|
} 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
|
* The per-user ~/.fonts.cache-<version> file is loaded into
|
||||||
* this data structure. Each directory gets a substructure
|
* this data structure. Each directory gets a substructure
|
||||||
|
|
Loading…
Reference in New Issue