forked from minhngoc25a/freetype2
Generalize the concept of `tricky' fonts by introducing
FT_FACE_FLAG_TRICKY to indicate that the font format's hinting engine is necessary for correct rendering. At the same time, slightly modify the behaviour of tricky fonts: FT_LOAD_NO_HINTING is now ignored. To really force raw loading of tricky fonts (without hinting), both FT_LOAD_NO_HINTING and FT_LOAD_NO_AUTOHINT must be used. Finally, tricky TrueType fonts always use the bytecode interpreter even if the patented code is used. * include/freetype/freetype.h (FT_FACE_FLAG_TRICKY, FT_IS_TRICKY): New macros. * src/truetype/ttdriver.c (Load_Glyph): Handle new load flags semantics as described above. * src/truetype/ttobjs.c (tt_check_trickyness): New function, using code of ... (tt_face_init): This function, now simplified and updated to new semantics. * src/base/ftobjs.c (FT_Load_Glyph): Don't use autohinter for tricky fonts. * docs/CHANGES: Document it.
This commit is contained in:
parent
1474f439b5
commit
b972a2a294
30
ChangeLog
30
ChangeLog
|
@ -1,3 +1,33 @@
|
|||
2008-12-10 Werner Lemberg <wl@gnu.org>
|
||||
|
||||
Generalize the concept of `tricky' fonts by introducing
|
||||
FT_FACE_FLAG_TRICKY to indicate that the font format's hinting
|
||||
engine is necessary for correct rendering.
|
||||
|
||||
At the same time, slightly modify the behaviour of tricky fonts:
|
||||
FT_LOAD_NO_HINTING is now ignored. To really force raw loading
|
||||
of tricky fonts (without hinting), both FT_LOAD_NO_HINTING and
|
||||
FT_LOAD_NO_AUTOHINT must be used.
|
||||
|
||||
Finally, tricky TrueType fonts always use the bytecode interpreter
|
||||
even if the patented code is used.
|
||||
|
||||
* include/freetype/freetype.h (FT_FACE_FLAG_TRICKY, FT_IS_TRICKY):
|
||||
New macros.
|
||||
|
||||
* src/truetype/ttdriver.c (Load_Glyph): Handle new load flags
|
||||
semantics as described above.
|
||||
|
||||
* src/truetype/ttobjs.c (tt_check_trickyness): New function, using
|
||||
code of ...
|
||||
(tt_face_init): This function, now simplified and updated to new
|
||||
semantics.
|
||||
|
||||
* src/base/ftobjs.c (FT_Load_Glyph): Don't use autohinter for tricky
|
||||
fonts.
|
||||
|
||||
* docs/CHANGES: Document it.
|
||||
|
||||
2008-12-09 Werner Lemberg <wl@gnu.org>
|
||||
|
||||
Really fix Savannah bug #25010: An SFNT font with neither outlines
|
||||
|
|
22
docs/CHANGES
22
docs/CHANGES
|
@ -10,9 +10,9 @@ CHANGES BETWEEN 2.3.8 and 2.3.7
|
|||
was very noticeable for outlines processed with FT_Glyph_Stroke,
|
||||
using thick strokes.
|
||||
|
||||
- `FT_Get_TrueType_Engine_Type' returned a wrong value if both
|
||||
TT_CONFIG_OPTION_BYTECODE_INTERPRETER and
|
||||
TT_CONFIG_OPTION_UNPATENTED_HINTING are defined.
|
||||
- `FT_Get_TrueType_Engine_Type' returned a wrong value if both
|
||||
configuration macros TT_CONFIG_OPTION_BYTECODE_INTERPRETER and
|
||||
TT_CONFIG_OPTION_UNPATENTED_HINTING were defined.
|
||||
|
||||
|
||||
II. IMPORTANT CHANGES
|
||||
|
@ -35,6 +35,22 @@ CHANGES BETWEEN 2.3.8 and 2.3.7
|
|||
is provided for x86 and ARM. See FT_CONFIG_OPTION_INLINE_MULFIX
|
||||
and FT_CONFIG_OPTION_NO_ASSEMBLER (in ftoption.h) for more.
|
||||
|
||||
- The handling of `tricky' fonts (this is, fonts which don't work
|
||||
with the autohinter, needing the font format's hinting engine)
|
||||
has been generalized and changed slightly:
|
||||
|
||||
. A new face flag FT_FACE_FLAG_TRICKY indicates that the font
|
||||
format's hinting engine is necessary for correct rendering.
|
||||
The macro FT_IS_TRICKY can be used to check this flag.
|
||||
|
||||
. FT_LOAD_NO_HINTING is now ignored for tricky fonts. To really
|
||||
force raw loading of such fonts (without hinting), both
|
||||
FT_LOAD_NO_HINTING and FT_LOAD_NO_AUTOHINT must be used --
|
||||
this is something which you probably never want to do.
|
||||
|
||||
. Tricky TrueType fonts always use the bytecode interpreter,
|
||||
either the patented or unpatented version.
|
||||
|
||||
|
||||
======================================================================
|
||||
|
||||
|
|
|
@ -1042,6 +1042,22 @@ FT_BEGIN_HEADER
|
|||
/* way (using contiguous indices); the `CID-ness' isn't visible to */
|
||||
/* the application. */
|
||||
/* */
|
||||
/* FT_FACE_FLAG_TRICKY :: */
|
||||
/* Set if the font is `tricky', this is, it always needs the */
|
||||
/* font format's native hinting engine to get a reasonable result. */
|
||||
/* A typical example is the Chinese font `mingli.ttf' which uses */
|
||||
/* TrueType bytecode instructions to move and scale all of its */
|
||||
/* subglyphs. */
|
||||
/* */
|
||||
/* It is not possible to autohint such fonts using */
|
||||
/* @FT_LOAD_FORCE_AUTOHINT; it will also ignore */
|
||||
/* @FT_LOAD_NO_HINTING. You have to set both FT_LOAD_NO_HINTING */
|
||||
/* and @FT_LOAD_NO_AUTOHINT to really disable hinting; however, you */
|
||||
/* probably never want this except for demonstration purposes. */
|
||||
/* */
|
||||
/* Currently, there are six TrueType fonts in the list of tricky */
|
||||
/* fonts; they are hard-coded in file `ttobjs.c'. */
|
||||
/* */
|
||||
#define FT_FACE_FLAG_SCALABLE ( 1L << 0 )
|
||||
#define FT_FACE_FLAG_FIXED_SIZES ( 1L << 1 )
|
||||
#define FT_FACE_FLAG_FIXED_WIDTH ( 1L << 2 )
|
||||
|
@ -1055,6 +1071,7 @@ FT_BEGIN_HEADER
|
|||
#define FT_FACE_FLAG_EXTERNAL_STREAM ( 1L << 10 )
|
||||
#define FT_FACE_FLAG_HINTER ( 1L << 11 )
|
||||
#define FT_FACE_FLAG_CID_KEYED ( 1L << 12 )
|
||||
#define FT_FACE_FLAG_TRICKY ( 1L << 13 )
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
|
@ -1225,6 +1242,20 @@ FT_BEGIN_HEADER
|
|||
( face->face_flags & FT_FACE_FLAG_CID_KEYED )
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
*
|
||||
* @macro:
|
||||
* FT_IS_TRICKY( face )
|
||||
*
|
||||
* @description:
|
||||
* A macro that returns true whenever a face represents a `tricky' font.
|
||||
* See the discussion of @FT_FACE_FLAG_TRICKY for more details.
|
||||
*
|
||||
*/
|
||||
#define FT_IS_TRICKY( face ) \
|
||||
( face->face_flags & FT_FACE_FLAG_TRICKY )
|
||||
|
||||
|
||||
/*************************************************************************/
|
||||
/* */
|
||||
/* <Const> */
|
||||
|
@ -2411,6 +2442,9 @@ FT_BEGIN_HEADER
|
|||
* @FT_LOAD_NO_AUTOHINT in case you don't want the auto-hinter to be
|
||||
* used at all.
|
||||
*
|
||||
* See the description of @FT_FACE_FLAG_TRICKY for a special exception
|
||||
* (affecting only a handful of Asian fonts).
|
||||
*
|
||||
* Besides deciding which hinter to use, you can also decide which
|
||||
* hinting algorithm to use. See @FT_LOAD_TARGET_XXX for details.
|
||||
*/
|
||||
|
@ -3717,7 +3751,7 @@ FT_BEGIN_HEADER
|
|||
/* */
|
||||
/* <Return> */
|
||||
/* The old setting value. This will always be false if this is not */
|
||||
/* a SFNT font, or if the unpatented hinter is not compiled in this */
|
||||
/* an SFNT font, or if the unpatented hinter is not compiled in this */
|
||||
/* instance of the library. */
|
||||
/* */
|
||||
/* <Since> */
|
||||
|
|
|
@ -41,6 +41,7 @@
|
|||
|
||||
#define GRID_FIT_METRICS
|
||||
|
||||
|
||||
FT_BASE_DEF( FT_Pointer )
|
||||
ft_service_list_lookup( FT_ServiceDesc service_descriptors,
|
||||
const char* service_id )
|
||||
|
@ -552,7 +553,7 @@
|
|||
FT_Driver driver;
|
||||
FT_GlyphSlot slot;
|
||||
FT_Library library;
|
||||
FT_Bool autohint = 0;
|
||||
FT_Bool autohint = FALSE;
|
||||
FT_Module hinter;
|
||||
|
||||
|
||||
|
@ -596,22 +597,22 @@
|
|||
*
|
||||
* - Otherwise, auto-hint for LIGHT hinting mode.
|
||||
*
|
||||
* - Exception: The font requires the unpatented
|
||||
* bytecode interpreter to load properly.
|
||||
* - Exception: The font is `tricky' and requires
|
||||
* the native hinter to load properly.
|
||||
*/
|
||||
|
||||
autohint = 0;
|
||||
if ( hinter &&
|
||||
( load_flags & FT_LOAD_NO_HINTING ) == 0 &&
|
||||
( load_flags & FT_LOAD_NO_AUTOHINT ) == 0 &&
|
||||
FT_DRIVER_IS_SCALABLE( driver ) &&
|
||||
FT_DRIVER_USES_OUTLINES( driver ) &&
|
||||
face->internal->transform_matrix.yy > 0 &&
|
||||
face->internal->transform_matrix.yx == 0 )
|
||||
if ( hinter &&
|
||||
!( load_flags & FT_LOAD_NO_HINTING ) &&
|
||||
!( load_flags & FT_LOAD_NO_AUTOHINT ) &&
|
||||
FT_DRIVER_IS_SCALABLE( driver ) &&
|
||||
FT_DRIVER_USES_OUTLINES( driver ) &&
|
||||
!FT_IS_TRICKY( face ) &&
|
||||
face->internal->transform_matrix.yy > 0 &&
|
||||
face->internal->transform_matrix.yx == 0 )
|
||||
{
|
||||
if ( ( load_flags & FT_LOAD_FORCE_AUTOHINT ) != 0 ||
|
||||
!FT_DRIVER_HAS_HINTER( driver ) )
|
||||
autohint = 1;
|
||||
if ( ( load_flags & FT_LOAD_FORCE_AUTOHINT ) ||
|
||||
!FT_DRIVER_HAS_HINTER( driver ) )
|
||||
autohint = TRUE;
|
||||
else
|
||||
{
|
||||
FT_Render_Mode mode = FT_LOAD_TARGET_MODE( load_flags );
|
||||
|
@ -619,7 +620,7 @@
|
|||
|
||||
if ( mode == FT_RENDER_MODE_LIGHT ||
|
||||
face->internal->ignore_unpatented_hinter )
|
||||
autohint = 1;
|
||||
autohint = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
/* FreeType API for checking patented TrueType bytecode instructions */
|
||||
/* (body). */
|
||||
/* */
|
||||
/* Copyright 2007 by David Turner. */
|
||||
/* Copyright 2007, 2008 by David Turner. */
|
||||
/* */
|
||||
/* This file is part of the FreeType project, and may only be used, */
|
||||
/* modified, and distributed under the terms of the FreeType project */
|
||||
|
@ -260,7 +260,7 @@
|
|||
FT_Face_SetUnpatentedHinting( FT_Face face,
|
||||
FT_Bool value )
|
||||
{
|
||||
FT_Bool result = 0;
|
||||
FT_Bool result = FALSE;
|
||||
|
||||
|
||||
#if defined( TT_CONFIG_OPTION_UNPATENTED_HINTING ) && \
|
||||
|
|
|
@ -272,7 +272,7 @@
|
|||
/* glyph_index :: The index of the glyph in the font file. */
|
||||
/* */
|
||||
/* load_flags :: A flag indicating what to load for this glyph. The */
|
||||
/* FTLOAD_??? constants can be used to control the */
|
||||
/* FT_LOAD_XXX constants can be used to control the */
|
||||
/* glyph loading process (e.g., whether the outline */
|
||||
/* should be scaled, whether to load bitmaps or not, */
|
||||
/* whether to hint the outline, etc). */
|
||||
|
@ -301,11 +301,24 @@
|
|||
if ( !face || glyph_index >= (FT_UInt)face->num_glyphs )
|
||||
return TT_Err_Invalid_Argument;
|
||||
|
||||
if ( load_flags & FT_LOAD_NO_HINTING )
|
||||
{
|
||||
/* both FT_LOAD_NO_HINTING and FT_LOAD_NO_AUTOHINT */
|
||||
/* are necessary to disable hinting for tricky fonts */
|
||||
|
||||
if ( FT_IS_TRICKY( face ) )
|
||||
load_flags &= ~FT_LOAD_NO_HINTING;
|
||||
|
||||
if ( load_flags & FT_LOAD_NO_AUTOHINT )
|
||||
load_flags |= FT_LOAD_NO_HINTING;
|
||||
}
|
||||
|
||||
if ( load_flags & ( FT_LOAD_NO_RECURSE | FT_LOAD_NO_SCALE ) )
|
||||
{
|
||||
load_flags |= FT_LOAD_NO_HINTING |
|
||||
FT_LOAD_NO_BITMAP |
|
||||
FT_LOAD_NO_SCALE;
|
||||
load_flags |= FT_LOAD_NO_BITMAP | FT_LOAD_NO_SCALE;
|
||||
|
||||
if ( !FT_IS_TRICKY( face ) )
|
||||
load_flags |= FT_LOAD_NO_HINTING;
|
||||
}
|
||||
|
||||
/* now load the glyph outline if necessary */
|
||||
|
|
|
@ -144,6 +144,38 @@
|
|||
#endif /* TT_USE_BYTECODE_INTERPRETER */
|
||||
|
||||
|
||||
/* Compare the face with a list of well-known `tricky' fonts. */
|
||||
/* This list shall be expanded as we find more of them. */
|
||||
|
||||
static FT_Bool
|
||||
tt_check_trickyness( FT_String* name )
|
||||
{
|
||||
static const char* const trick_names[] =
|
||||
{
|
||||
"DFKaiSho-SB", /* dfkaisb.ttf */
|
||||
"DFKai-SB", /* kaiu.ttf */
|
||||
"HuaTianSongTi?", /* htst3.ttf */
|
||||
"MingLiU", /* mingliu.ttf & mingliu.ttc */
|
||||
"PMingLiU", /* mingliu.ttc */
|
||||
"MingLi43", /* mingli.ttf */
|
||||
NULL
|
||||
};
|
||||
int nn;
|
||||
|
||||
|
||||
if ( !name )
|
||||
return FALSE;
|
||||
|
||||
/* Note that we only check the face name at the moment; it might */
|
||||
/* be worth to do more checks for a few special cases. */
|
||||
for ( nn = 0; trick_names[nn] != NULL; nn++ )
|
||||
if ( ft_strstr( name, trick_names[nn] ) )
|
||||
return TRUE;
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
/*************************************************************************/
|
||||
/* */
|
||||
/* <Function> */
|
||||
|
@ -180,7 +212,7 @@
|
|||
TT_Face face = (TT_Face)ttface;
|
||||
|
||||
|
||||
library = face->root.driver->root.library;
|
||||
library = ttface->driver->root.library;
|
||||
sfnt = (SFNT_Service)FT_Get_Module_Interface( library, "sfnt" );
|
||||
if ( !sfnt )
|
||||
goto Bad_Format;
|
||||
|
@ -206,7 +238,7 @@
|
|||
}
|
||||
|
||||
#ifdef TT_USE_BYTECODE_INTERPRETER
|
||||
face->root.face_flags |= FT_FACE_FLAG_HINTER;
|
||||
ttface->face_flags |= FT_FACE_FLAG_HINTER;
|
||||
#endif
|
||||
|
||||
/* If we are performing a simple font format check, exit immediately. */
|
||||
|
@ -218,16 +250,19 @@
|
|||
if ( error )
|
||||
goto Exit;
|
||||
|
||||
if ( tt_check_trickyness( ttface->family_name ) )
|
||||
ttface->face_flags |= FT_FACE_FLAG_TRICKY;
|
||||
|
||||
error = tt_face_load_hdmx( face, stream );
|
||||
if ( error )
|
||||
goto Exit;
|
||||
|
||||
if ( face->root.face_flags & FT_FACE_FLAG_SCALABLE )
|
||||
if ( FT_IS_SCALABLE( ttface ) )
|
||||
{
|
||||
|
||||
#ifdef FT_CONFIG_OPTION_INCREMENTAL
|
||||
|
||||
if ( !face->root.internal->incremental_interface )
|
||||
if ( !ttface->internal->incremental_interface )
|
||||
error = tt_face_load_loca( face, stream );
|
||||
if ( !error )
|
||||
error = tt_face_load_cvt( face, stream );
|
||||
|
@ -267,38 +302,8 @@
|
|||
if ( params[i].tag == FT_PARAM_TAG_UNPATENTED_HINTING )
|
||||
unpatented_hinting = TRUE;
|
||||
|
||||
/* Compare the face with a list of well-known `tricky' fonts. */
|
||||
/* This list shall be expanded as we find more of them. */
|
||||
if ( !unpatented_hinting )
|
||||
{
|
||||
static const char* const trick_names[] =
|
||||
{
|
||||
"DFKaiSho-SB", /* dfkaisb.ttf */
|
||||
"DFKai-SB", /* kaiu.ttf */
|
||||
"HuaTianSongTi?", /* htst3.ttf */
|
||||
"MingLiU", /* mingliu.ttf & mingliu.ttc */
|
||||
"PMingLiU", /* mingliu.ttc */
|
||||
"MingLi43", /* mingli.ttf */
|
||||
NULL
|
||||
};
|
||||
int nn;
|
||||
|
||||
|
||||
/* Note that we only check the face name at the moment; it might */
|
||||
/* be worth to do more checks for a few special cases. */
|
||||
for ( nn = 0; trick_names[nn] != NULL; nn++ )
|
||||
{
|
||||
if ( ttface->family_name &&
|
||||
ft_strstr( ttface->family_name, trick_names[nn] ) )
|
||||
{
|
||||
unpatented_hinting = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ttface->internal->ignore_unpatented_hinter =
|
||||
FT_BOOL( !unpatented_hinting );
|
||||
ttface->internal->ignore_unpatented_hinter = TRUE;
|
||||
}
|
||||
|
||||
#endif /* TT_CONFIG_OPTION_UNPATENTED_HINTING &&
|
||||
|
@ -339,8 +344,8 @@
|
|||
if ( !face )
|
||||
return;
|
||||
|
||||
memory = face->root.memory;
|
||||
stream = face->root.stream;
|
||||
memory = ttface->memory;
|
||||
stream = ttface->stream;
|
||||
sfnt = (SFNT_Service)face->sfnt;
|
||||
|
||||
/* for `extended TrueType formats' (i.e. compressed versions) */
|
||||
|
@ -680,7 +685,7 @@
|
|||
if ( !size->cvt_ready )
|
||||
{
|
||||
FT_UInt i;
|
||||
TT_Face face = (TT_Face) size->root.face;
|
||||
TT_Face face = (TT_Face)size->root.face;
|
||||
|
||||
|
||||
/* Scale the cvt values to the new ppem. */
|
||||
|
|
Loading…
Reference in New Issue