Fix typo.
Add detection for font capabilities (bug #105) reviewed by: Keith Packard <keithp@keithp.com>
This commit is contained in:
parent
4f27c1c0a3
commit
dbf68dd5fe
13
ChangeLog
13
ChangeLog
|
@ -1,3 +1,16 @@
|
||||||
|
2004-12-04 Daniel Glassey <danglassey@ntlworld.com>
|
||||||
|
|
||||||
|
reviewed by: Keith Packard <keithp@keithp.com>
|
||||||
|
|
||||||
|
* doc/fontconfig-user.sgml:
|
||||||
|
Fix typo.
|
||||||
|
|
||||||
|
* fontconfig/fontconfig.h:
|
||||||
|
* src/fcfreetype.c: (FcFreeTypeQuery), (addtag), (compareulong),
|
||||||
|
(GetScriptTags), (FcFontCapabilities):
|
||||||
|
* src/fcname.c:
|
||||||
|
Add detection for font capabilities (bug #105)
|
||||||
|
|
||||||
2004-12-04 Keith Packard <keithp@keithp.com>
|
2004-12-04 Keith Packard <keithp@keithp.com>
|
||||||
|
|
||||||
* Makefile.am:
|
* Makefile.am:
|
||||||
|
|
|
@ -319,6 +319,7 @@ elements have a matching value, then the pattern matches the font. This can
|
||||||
be used to select fonts based on attributes of the font (scalable, bold,
|
be used to select fonts based on attributes of the font (scalable, bold,
|
||||||
etc), which is a more reliable mechanism than using file extensions.
|
etc), which is a more reliable mechanism than using file extensions.
|
||||||
Pattern elements include patelt elements.
|
Pattern elements include patelt elements.
|
||||||
|
</para></refsect2>
|
||||||
<refsect2><title><sgmltag>patelt name="property"</></title><para>
|
<refsect2><title><sgmltag>patelt name="property"</></title><para>
|
||||||
Patelt elements hold a single pattern element and list of values. They must
|
Patelt elements hold a single pattern element and list of values. They must
|
||||||
have a 'name' attribute which indicates the pattern element name. Patelt
|
have a 'name' attribute which indicates the pattern element name. Patelt
|
||||||
|
|
|
@ -93,6 +93,7 @@ typedef int FcBool;
|
||||||
#define FC_FAMILYLANG "familylang" /* String RFC 3066 langs */
|
#define FC_FAMILYLANG "familylang" /* String RFC 3066 langs */
|
||||||
#define FC_STYLELANG "stylelang" /* String RFC 3066 langs */
|
#define FC_STYLELANG "stylelang" /* String RFC 3066 langs */
|
||||||
#define FC_FULLNAMELANG "fullnamelang" /* String RFC 3066 langs */
|
#define FC_FULLNAMELANG "fullnamelang" /* String RFC 3066 langs */
|
||||||
|
#define FC_CAPABILITY "capability" /* String */
|
||||||
|
|
||||||
#define FC_DIR_CACHE_FILE "fonts.cache-"FC_CACHE_VERSION
|
#define FC_DIR_CACHE_FILE "fonts.cache-"FC_CACHE_VERSION
|
||||||
#define FC_USER_CACHE_FILE ".fonts.cache-"FC_CACHE_VERSION
|
#define FC_USER_CACHE_FILE ".fonts.cache-"FC_CACHE_VERSION
|
||||||
|
|
188
src/fcfreetype.c
188
src/fcfreetype.c
|
@ -55,6 +55,9 @@
|
||||||
#include FT_SFNT_NAMES_H
|
#include FT_SFNT_NAMES_H
|
||||||
#include FT_TRUETYPE_IDS_H
|
#include FT_TRUETYPE_IDS_H
|
||||||
#include FT_TYPE1_TABLES_H
|
#include FT_TYPE1_TABLES_H
|
||||||
|
#include FT_INTERNAL_STREAM_H
|
||||||
|
#include FT_INTERNAL_SFNT_H
|
||||||
|
#include FT_INTERNAL_TRUETYPE_TYPES_H
|
||||||
|
|
||||||
#if HAVE_FT_GET_BDF_PROPERTY
|
#if HAVE_FT_GET_BDF_PROPERTY
|
||||||
#include FT_BDF_H
|
#include FT_BDF_H
|
||||||
|
@ -551,6 +554,9 @@ static const FcMacRomanFake fcMacRomanFake[] = {
|
||||||
{ TT_MS_LANGID_ENGLISH_UNITED_STATES, "ASCII" },
|
{ TT_MS_LANGID_ENGLISH_UNITED_STATES, "ASCII" },
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static FcChar8 *
|
||||||
|
FcFontCapabilities(FT_Face face);
|
||||||
|
|
||||||
#define NUM_FC_MAC_ROMAN_FAKE (sizeof (fcMacRomanFake) / sizeof (fcMacRomanFake[0]))
|
#define NUM_FC_MAC_ROMAN_FAKE (sizeof (fcMacRomanFake) / sizeof (fcMacRomanFake[0]))
|
||||||
|
|
||||||
#if HAVE_ICONV && HAVE_ICONV_H
|
#if HAVE_ICONV && HAVE_ICONV_H
|
||||||
|
@ -985,6 +991,7 @@ FcFreeTypeQuery (const FcChar8 *file,
|
||||||
#if 0
|
#if 0
|
||||||
FcChar8 *family = 0;
|
FcChar8 *family = 0;
|
||||||
#endif
|
#endif
|
||||||
|
FcChar8 *complex;
|
||||||
const FcChar8 *foundry = 0;
|
const FcChar8 *foundry = 0;
|
||||||
int spacing;
|
int spacing;
|
||||||
TT_OS2 *os2;
|
TT_OS2 *os2;
|
||||||
|
@ -1366,6 +1373,15 @@ FcFreeTypeQuery (const FcChar8 *file,
|
||||||
case 9: width = FC_WIDTH_ULTRAEXPANDED; break;
|
case 9: width = FC_WIDTH_ULTRAEXPANDED; break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (os2 && (complex = FcFontCapabilities(face)))
|
||||||
|
{
|
||||||
|
if (!FcPatternAddString (pat, FC_CAPABILITY, complex))
|
||||||
|
{
|
||||||
|
free (complex);
|
||||||
|
goto bail1;
|
||||||
|
}
|
||||||
|
free (complex);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Type 1: Check for FontInfo dictionary information
|
* Type 1: Check for FontInfo dictionary information
|
||||||
|
@ -2604,3 +2620,175 @@ FcFreeTypeCharSet (FT_Face face, FcBlanks *blanks)
|
||||||
|
|
||||||
return FcFreeTypeCharSetAndSpacing (face, blanks, &spacing);
|
return FcFreeTypeCharSetAndSpacing (face, blanks, &spacing);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#define TTAG_GPOS FT_MAKE_TAG( 'G', 'P', 'O', 'S' )
|
||||||
|
#define TTAG_GSUB FT_MAKE_TAG( 'G', 'S', 'U', 'B' )
|
||||||
|
#define TTAG_SILF FT_MAKE_TAG( 'S', 'i', 'l', 'f')
|
||||||
|
#define TT_Err_Ok FT_Err_Ok
|
||||||
|
#define TT_Err_Invalid_Face_Handle FT_Err_Invalid_Face_Handle
|
||||||
|
#define TTO_Err_Empty_Script 0x1005
|
||||||
|
#define TTO_Err_Invalid_SubTable 0x1001
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
addtag(FcChar8 *complex, FT_ULong tag)
|
||||||
|
{
|
||||||
|
FcChar8 tagstring[15];
|
||||||
|
sprintf (tagstring, "otlayout:%c%c%c%c ",
|
||||||
|
(unsigned char)(tag >> 24),
|
||||||
|
(unsigned char)((tag & 0xff0000) >> 16),
|
||||||
|
(unsigned char)((tag & 0xff00) >> 8),
|
||||||
|
(unsigned char)(tag & 0xff));
|
||||||
|
strncat(complex, tagstring, 14);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
compareulong (const void *a, const void *b)
|
||||||
|
{
|
||||||
|
const FT_ULong *ua = (const FT_ULong *) a;
|
||||||
|
const FT_ULong *ub = (const FT_ULong *) b;
|
||||||
|
return *ua - *ub;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static FT_Error
|
||||||
|
GetScriptTags(FT_Face face, FT_ULong tabletag, FT_ULong **stags, FT_UShort *script_count)
|
||||||
|
{
|
||||||
|
FT_ULong cur_offset, new_offset, base_offset;
|
||||||
|
TT_Face tt_face = (TT_Face)face;
|
||||||
|
FT_Stream stream = face->stream;
|
||||||
|
FT_Error error;
|
||||||
|
FT_UShort n, p;
|
||||||
|
FT_Memory memory = stream->memory;
|
||||||
|
|
||||||
|
if ( !stream )
|
||||||
|
return TT_Err_Invalid_Face_Handle;
|
||||||
|
|
||||||
|
if (( error = tt_face->goto_table( tt_face, tabletag, stream, 0 ) ))
|
||||||
|
return error;
|
||||||
|
|
||||||
|
base_offset = FT_STREAM_POS();
|
||||||
|
|
||||||
|
/* skip version */
|
||||||
|
|
||||||
|
if ( FT_STREAM_SEEK( base_offset + 4L ) || FT_FRAME_ENTER( 2L ) )
|
||||||
|
return error;
|
||||||
|
|
||||||
|
new_offset = FT_GET_USHORT() + base_offset;
|
||||||
|
|
||||||
|
FT_FRAME_EXIT();
|
||||||
|
|
||||||
|
cur_offset = FT_STREAM_POS();
|
||||||
|
|
||||||
|
if ( FT_STREAM_SEEK( new_offset ) != TT_Err_Ok )
|
||||||
|
return error;
|
||||||
|
|
||||||
|
base_offset = FT_STREAM_POS();
|
||||||
|
|
||||||
|
if ( FT_FRAME_ENTER( 2L ) )
|
||||||
|
return error;
|
||||||
|
|
||||||
|
*script_count = FT_GET_USHORT();
|
||||||
|
|
||||||
|
FT_FRAME_EXIT();
|
||||||
|
|
||||||
|
if ( FT_SET_ERROR (FT_MEM_ALLOC_ARRAY( *stags, *script_count, FT_ULong )) )
|
||||||
|
return error;
|
||||||
|
|
||||||
|
p = 0;
|
||||||
|
for ( n = 0; n < *script_count; n++ )
|
||||||
|
{
|
||||||
|
if ( FT_FRAME_ENTER( 6L ) )
|
||||||
|
goto Fail;
|
||||||
|
|
||||||
|
(*stags)[p] = FT_GET_ULONG();
|
||||||
|
new_offset = FT_GET_USHORT() + base_offset;
|
||||||
|
|
||||||
|
FT_FRAME_EXIT();
|
||||||
|
|
||||||
|
cur_offset = FT_STREAM_POS();
|
||||||
|
|
||||||
|
if ( FT_STREAM_SEEK( new_offset ) )
|
||||||
|
goto Fail;
|
||||||
|
|
||||||
|
if ( error == TT_Err_Ok )
|
||||||
|
p++;
|
||||||
|
else if ( error != TTO_Err_Empty_Script )
|
||||||
|
goto Fail;
|
||||||
|
|
||||||
|
(void)FT_STREAM_SEEK( cur_offset );
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!p)
|
||||||
|
{
|
||||||
|
error = TTO_Err_Invalid_SubTable;
|
||||||
|
goto Fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
// sort the tag list before returning it
|
||||||
|
qsort(*stags, *script_count, sizeof(FT_ULong), compareulong);
|
||||||
|
|
||||||
|
return TT_Err_Ok;
|
||||||
|
|
||||||
|
Fail:
|
||||||
|
FT_FREE( *stags );
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
static FcChar8 *
|
||||||
|
FcFontCapabilities(FT_Face face)
|
||||||
|
{
|
||||||
|
FcBool issilgraphitefont = 0;
|
||||||
|
FT_Error err;
|
||||||
|
FT_ULong len = 0;
|
||||||
|
FT_ULong *gsubtags=NULL, *gpostags=NULL;
|
||||||
|
FT_UShort gsub_count=0, gpos_count=0, maxsize;
|
||||||
|
FT_Memory memory = face->stream->memory;
|
||||||
|
FcChar8 *complex = NULL;
|
||||||
|
int indx1 = 0, indx2 = 0;
|
||||||
|
|
||||||
|
err = FT_Load_Sfnt_Table(face, TTAG_SILF, 0, 0, &len);
|
||||||
|
issilgraphitefont = ( err == FT_Err_Ok);
|
||||||
|
|
||||||
|
err = GetScriptTags(face, TTAG_GPOS, &gpostags, &gpos_count);
|
||||||
|
err = GetScriptTags(face, TTAG_GSUB, &gsubtags, &gsub_count);
|
||||||
|
if (!issilgraphitefont && !gsub_count && !gpos_count)
|
||||||
|
{
|
||||||
|
goto bail;
|
||||||
|
}
|
||||||
|
|
||||||
|
maxsize = ((gpos_count + gsub_count) * 15) + (issilgraphitefont ? 13 : 0);
|
||||||
|
complex = malloc (sizeof (FcChar8) * maxsize);
|
||||||
|
if (issilgraphitefont)
|
||||||
|
{
|
||||||
|
strcpy(complex, "ttable:Silf ");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
strcpy(complex, "");
|
||||||
|
}
|
||||||
|
|
||||||
|
while ((indx1 < gsub_count) || (indx2 < gpos_count)) {
|
||||||
|
if (indx1 == gsub_count) {
|
||||||
|
addtag(complex, gpostags[indx2]);
|
||||||
|
indx2++;
|
||||||
|
} else if ((indx2 == gpos_count) || (gsubtags[indx1] < gpostags[indx2])) {
|
||||||
|
addtag(complex, gsubtags[indx1]);
|
||||||
|
indx1++;
|
||||||
|
} else if (gsubtags[indx1] == gpostags[indx2]) {
|
||||||
|
addtag(complex, gsubtags[indx1]);
|
||||||
|
indx1++;
|
||||||
|
indx2++;
|
||||||
|
} else {
|
||||||
|
addtag(complex, gpostags[indx2]);
|
||||||
|
indx2++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (FcDebug () & FC_DBG_SCANV)
|
||||||
|
printf("complex features in this font: %s\n", complex);
|
||||||
|
bail:
|
||||||
|
FT_FREE(gsubtags);
|
||||||
|
FT_FREE(gpostags);
|
||||||
|
return complex;
|
||||||
|
}
|
||||||
|
|
|
@ -67,6 +67,7 @@ static const FcObjectType _FcBaseObjectTypes[] = {
|
||||||
{ FC_CHARSET, FcTypeCharSet },
|
{ FC_CHARSET, FcTypeCharSet },
|
||||||
{ FC_LANG, FcTypeLangSet },
|
{ FC_LANG, FcTypeLangSet },
|
||||||
{ FC_FONTVERSION, FcTypeInteger },
|
{ FC_FONTVERSION, FcTypeInteger },
|
||||||
|
{ FC_CAPABILITY, FcTypeString },
|
||||||
};
|
};
|
||||||
|
|
||||||
#define NUM_OBJECT_TYPES (sizeof _FcBaseObjectTypes / sizeof _FcBaseObjectTypes[0])
|
#define NUM_OBJECT_TYPES (sizeof _FcBaseObjectTypes / sizeof _FcBaseObjectTypes[0])
|
||||||
|
|
Loading…
Reference in New Issue