* src/smooth/ftsmooth.c, src/base/ftobjs.c,

include/freetype/config/ftmodule.h: updated to correctly support
        sub-pixel rendering

        * include/freetype/cache/ftcimage.h, include/freetype/cache/ftcsbits.h,
        src/cache/ftcimage.c, src/cache/ftcsbit.c: updated to support sub-pixel
        rendering correctly. Definition of FTC_ImageTypeRec that replaces the
        obsolete FTC_ImageDesc, and has slightly different fields. The
        image type is now determined directly by "load_flags" values.

        * src/autohint/ahtypes.h, src/autohint/ahhint.c,
        src/pshinter/pshalgo3.c, src/pshinter/pshalgo3.h: various enhancements
        to the automatic and Postscript hinters !! and sub-pixel hinting now
        works correctly (see demo programs)
This commit is contained in:
David Turner 2002-09-08 21:29:11 +00:00
parent d6f74d3b66
commit 2e22c90f78
13 changed files with 504 additions and 568 deletions

View File

@ -1,3 +1,20 @@
2002-09-08 David Turner <david@freetype.org>
* src/smooth/ftsmooth.c, src/base/ftobjs.c,
include/freetype/config/ftmodule.h: updated to correctly support
sub-pixel rendering
* include/freetype/cache/ftcimage.h, include/freetype/cache/ftcsbits.h,
src/cache/ftcimage.c, src/cache/ftcsbit.c: updated to support sub-pixel
rendering correctly. Definition of FTC_ImageTypeRec that replaces the
obsolete FTC_ImageDesc, and has slightly different fields. The
image type is now determined directly by "load_flags" values.
* src/autohint/ahtypes.h, src/autohint/ahhint.c,
src/pshinter/pshalgo3.c, src/pshinter/pshalgo3.h: various enhancements
to the automatic and Postscript hinters !! and sub-pixel hinting now
works correctly (see demo programs)
2002-09-05 Werner Lemberg <wl@gnu.org>
* src/cid/cidobjs.c (CID_Size_Init): Renamed to...

View File

@ -53,65 +53,43 @@ FT_BEGIN_HEADER
/*************************************************************************/
#define FTC_IMAGE_FORMAT( x ) ( (x) & 7 )
#define ftc_image_format_bitmap 0x0000
#define ftc_image_format_outline 0x0001
#define ftc_image_format_mask 0x000F
#define ftc_image_flag_monochrome 0x0010
#define ftc_image_flag_unhinted 0x0020
#define ftc_image_flag_autohinted 0x0040
#define ftc_image_flag_unscaled 0x0080
#define ftc_image_flag_no_sbits 0x0100
/* monochrome bitmap */
#define ftc_image_mono ftc_image_format_bitmap | \
ftc_image_flag_monochrome
/* anti-aliased bitmap */
#define ftc_image_grays ftc_image_format_bitmap
/* scaled outline */
#define ftc_image_outline ftc_image_format_outline
/*************************************************************************/
/* */
/* <Struct> */
/* FTC_ImageDesc */
/* */
/* <Description> */
/* A simple structure used to describe a given glyph image category. */
/* Note that this is different from @FTC_Image_Desc. */
/* */
/* <Fields> */
/* size :: An @FTC_SizeRec used to describe the glyph's face and */
/* size. */
/* */
/* type :: The glyph image's type. Note that it is a 32-bit uint. */
/* */
/* <Note> */
/* This type deprecates @FTC_Image_Desc. */
/* */
typedef struct FTC_ImageDesc_
/**************************************************************************
*
* @struct: FTC_ImageTypeRec
*
* @description:
* a simple structure used to describe the type of glyph image to be
* loaded into the cache
*
* @fields:
* font :: An @FTC_FontRec used to describe the glyph's face and size
* flags :: the load flags to be applied when loading the glyph, see
* the @FT_LOAD_XXX constants for details
*
* @note:
* this type completely replaces the @FTC_Image_Desc structure which is
* now obsolete..
*/
typedef struct FTC_ImageTypeRec_
{
FTC_FontRec font;
FT_UInt32 type;
FT_Int32 flags;
} FTC_ImageDesc;
} FTC_ImageTypeRec;
typedef struct FTC_ImageTypeRec_* FTC_ImageType;
/* */
#define FTC_IMAGE_DESC_COMPARE( d1, d2 ) \
#define FTC_IMAGE_TYPE_COMPARE( d1, d2 ) \
( FTC_FONT_COMPARE( &(d1)->font, &(d2)->font ) && \
(d1)->type == (d2)->type )
(d1)->flags == (d2)->flags )
#define FTC_IMAGE_DESC_HASH( d ) \
#define FTC_IMAGE_TYPE_HASH( d ) \
(FT_UFast)( FTC_FONT_HASH( &(d)->font ) ^ \
( (d)->type << 4 ) )
( (d)->flags << 4 ) )
/*************************************************************************/
@ -160,7 +138,7 @@ FT_BEGIN_HEADER
/* <Input> */
/* cache :: A handle to the source glyph image cache. */
/* */
/* desc :: A pointer to a glyph image descriptor. */
/* type :: A pointer to a glyph image type descriptor. */
/* */
/* gindex :: The glyph index to retrieve. */
/* */
@ -193,13 +171,36 @@ FT_BEGIN_HEADER
/* */
FT_EXPORT( FT_Error )
FTC_ImageCache_Lookup( FTC_ImageCache cache,
FTC_ImageDesc* desc,
FTC_ImageType type,
FT_UInt gindex,
FT_Glyph *aglyph,
FTC_Node *anode );
/* */
#define ftc_image_format( x ) ( (x) & 7 )
#define ftc_image_format_bitmap 0x0000
#define ftc_image_format_outline 0x0001
#define ftc_image_format_mask 0x000F
#define ftc_image_flag_monochrome 0x0010
#define ftc_image_flag_unhinted 0x0020
#define ftc_image_flag_autohinted 0x0040
#define ftc_image_flag_unscaled 0x0080
#define ftc_image_flag_no_sbits 0x0100
/* monochrome bitmap */
#define ftc_image_mono ftc_image_format_bitmap | \
ftc_image_flag_monochrome
/* anti-aliased bitmap */
#define ftc_image_grays ftc_image_format_bitmap
/* scaled outline */
#define ftc_image_outline ftc_image_format_outline
/*************************************************************************/
/* */

View File

@ -72,7 +72,7 @@ FT_BEGIN_HEADER
/* */
/* format :: The format of the glyph bitmap (monochrome or gray). */
/* */
/* num_grays :: The number of gray levels. */
/* max_grays :: maximum gray level value, from 1 to 255 */
/* */
/* pitch :: The number of bytes per bitmap line. May be positive */
/* or negative. */
@ -91,8 +91,8 @@ FT_BEGIN_HEADER
FT_Char top;
FT_Byte format;
FT_Short num_grays; /* XXX: Should be FT_Byte. See ftcsbits.c */
FT_Char pitch;
FT_Byte max_grays;
FT_Short pitch;
FT_Char xadvance;
FT_Char yadvance;
@ -113,7 +113,7 @@ FT_BEGIN_HEADER
/* implemented by @FTC_ImageCache. */
/* */
typedef struct FTC_SBitCacheRec_* FTC_SBitCache;
/*************************************************************************/
/* */
@ -160,7 +160,7 @@ FT_BEGIN_HEADER
/* <Input> */
/* cache :: A handle to the source sbit cache. */
/* */
/* desc :: A pointer to the glyph image descriptor. */
/* type :: A pointer to the glyph image type descriptor. */
/* */
/* gindex :: The glyph index. */
/* */
@ -195,7 +195,7 @@ FT_BEGIN_HEADER
/* */
FT_EXPORT( FT_Error )
FTC_SBitCache_Lookup( FTC_SBitCache cache,
FTC_ImageDesc* desc,
FTC_ImageType type,
FT_UInt gindex,
FTC_SBit *sbit,
FTC_Node *anode );

View File

@ -9,6 +9,8 @@ FT_USE_MODULE(pshinter_module_class)
FT_USE_MODULE(ft_raster1_renderer_class)
FT_USE_MODULE(sfnt_module_class)
FT_USE_MODULE(ft_smooth_renderer_class)
FT_USE_MODULE(ft_smooth_lcd_renderer_class)
FT_USE_MODULE(ft_smooth_lcdv_renderer_class)
FT_USE_MODULE(tt_driver_class)
FT_USE_MODULE(t1_driver_class)
FT_USE_MODULE(t42_driver_class)

View File

@ -2009,202 +2009,147 @@ FT_BEGIN_HEADER
FT_Int32 load_flags );
/*************************************************************************/
/* */
/* <Constant> */
/* FT_LOAD_NO_SCALE */
/* */
/* <Description> */
/* A bit field constant, used with @FT_Load_Glyph to indicate that */
/* the vector outline being loaded should not be scaled to 26.6 */
/* fractional pixels, but kept in notional units. */
/* */
#define FT_LOAD_NO_SCALE 0x1
/*************************************************************************/
/* */
/* <Constant> */
/* FT_LOAD_NO_HINTING */
/* */
/* <Description> */
/* A bit-field constant, used with @FT_Load_Glyph to indicate that */
/* the vector outline being loaded should not be fitted to the pixel */
/* grid but simply scaled to 26.6 fractional pixels. */
/* */
/* This flag is ignored if FT_LOAD_NO_SCALE is set. */
/* */
#define FT_LOAD_NO_HINTING 0x2
/*************************************************************************/
/* */
/* <Constant> */
/* FT_LOAD_RENDER */
/* */
/* <Description> */
/* A bit-field constant, used with @FT_Load_Glyph to indicate that */
/* the function should load the glyph and immediately convert it into */
/* a bitmap, if necessary, by calling @FT_Render_Glyph. */
/* */
/* Note that by default, @FT_Load_Glyph loads the glyph image in its */
/* native format. */
/* */
#define FT_LOAD_RENDER 0x4
/*************************************************************************/
/* */
/* <Constant> */
/* FT_LOAD_NO_BITMAP */
/* */
/* <Description> */
/* A bit-field constant, used with @FT_Load_Glyph to indicate that */
/* the function should not load the bitmap or pixmap of a given */
/* glyph. This is useful when you do not want to load the embedded */
/* bitmaps of scalable formats, as the native glyph image will be */
/* loaded, and can then be rendered through @FT_Render_Glyph. */
/* */
#define FT_LOAD_NO_BITMAP 0x8
/*************************************************************************/
/* */
/* <Constant> */
/* FT_LOAD_VERTICAL_LAYOUT */
/* */
/* <Description> */
/* A bit-field constant, used with @FT_Load_Glyph to indicate that */
/* the glyph image should be prepared for vertical layout. This */
/* basically means that `face.glyph.advance' will correspond to the */
/* vertical advance height (instead of the default horizontal */
/* advance width), and that the glyph image will translated to match */
/* the vertical bearings positions. */
/* */
#define FT_LOAD_VERTICAL_LAYOUT 0x10
/*************************************************************************/
/* */
/* <Constant> */
/* FT_LOAD_FORCE_AUTOHINT */
/* */
/* <Description> */
/* A bit-field constant, used with @FT_Load_Glyph to indicate that */
/* the function should try to auto-hint the glyphs, even if a driver */
/* specific hinter is available. */
/* */
/* Note that it is ignored if @FT_LOAD_NO_AUTOHINT is also set. */
/* */
#define FT_LOAD_FORCE_AUTOHINT 0x20
/*************************************************************************/
/* */
/* <Constant> */
/* FT_LOAD_CROP_BITMAP */
/* */
/* <Description> */
/* A bit-field constant, used with @FT_Load_Glyph to indicate that */
/* the font driver should try to crop the bitmap (i.e. remove all */
/* space around its black bits) when loading it. For now, this */
/* really only works with embedded bitmaps in TrueType fonts. */
/* */
#define FT_LOAD_CROP_BITMAP 0x40
/*************************************************************************/
/* */
/* <Constant> */
/* FT_LOAD_PEDANTIC */
/* */
/* <Description> */
/* A bit-field constant, used with @FT_Load_Glyph to indicate that */
/* the glyph loader should perform a pedantic bytecode */
/* interpretation. Many popular fonts come with broken glyph */
/* programs. When this flag is set, loading them will return an */
/* error. Otherwise, errors are ignored by the loader, sometimes */
/* resulting in ugly glyphs. */
/* */
#define FT_LOAD_PEDANTIC 0x80
/*************************************************************************/
/* */
/* <Constant> */
/* FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH */
/* */
/* <Description> */
/* A bit-field constant, used with @FT_Load_Glyph to indicate that */
/* the glyph loader should ignore the global advance width defined */
/* in the font. As far as we know, this is only used by the */
/* X-TrueType font server, in order to deal correctly with the */
/* incorrect metrics contained in DynaLab's TrueType CJK fonts. */
/* */
/****************************************************************************
*
* @enum: FT_LOAD_XXX
*
* @description:
* a list of bit-field constants, used with @FT_Load_Glyph to indicate
* what kind of operations to perform during glyph loading
*
* @values:
* FT_LOAD_DEFAULT ::
* corresponding to 0, this value is used a default glyph load. In this
* case, the following will happen:
*
* 1/ FreeType will look for a bitmap for the glyph corresponding to
* the face's current size. If one is found, the function returns.
* the bitmap data can be accessed from the glyph slot (see note
* below)
*
* 2/ If no embedded bitmap is searched or found, FreeType looks for
* a scalable outline. If one is found, it is loaded from the font
* file, scaled to device pixels, then "hinted" to the pixel grid
* in order to optimize it. the outline data can be accessed from
* the glyph slot (see note below)
*
* Note that by default, the glyph loader doesn't render outlines into
* bitmaps. the following flags are used to modify this default behaviour
* to more specific and useful cases.
*
* FT_LOAD_NO_SCALE ::
* indicates that the vector outline being loaded should not be scaled
* to 26.6 fractional pixels, but kept in font units. Note that this
* also disables hinting and the loading of embedded bitmaps. You should
* only use it when you want to retrieve the original glyph outlines
* in font units.
*
* FT_LOAD_NO_HINTING ::
* indicates that the glyph outlines should not be hinted after their
* scaling to device pixels. This generally generates "blurrier" glyphs
* in anti-aliased modes.
*
* this flag is ignored if @FT_LOAD_NO_SCALE is set
*
* FT_LOAD_RENDER ::
* indicates that the glyph outline should be rendered immediately into
* a bitmap before the glyph loader returns. By default, the glyph is
* rendered for the @FT_RENDER_MODE_NORMAL mode, which corresponds to
* 8-bit anti-aliased bitmaps using 256 opacity levels. You can use
* either @FT_LOAD_TARGET_MONO or @FT_LOAD_MONOCHROME to render
* 1-bit monochrome bitmaps
*
* This flag is ignored if @FT_LOAD_NO_SCALE is set
*
*
* FT_LOAD_NO_BITMAP ::
* indicates that you do not want to look for bitmaps when loading
* the glyph. Only scalable outlines will be loaded when available,
* and scaled/hinted/rendered depending on other bit flags
*
* this does not prevent you from rendering outlines to bitmaps
* with @FT_LOAD_RENDER however.
*
* FT_LOAD_VERTICAL_LAYOUT:
* indicates that the glyph image should be prepared for vertical
* text layout. This basically means that 'face.glyph.advance' will
* correspond to the vertical advance height (instead of the default
* horizontal advance width), and that the glyph image will be
* translated to match the vertical bearings positions
*
* FT_LOAD_FORCE_AUTOHINT ::
* indicates that you want to force the use of the FreeType auto-hinter
* when a glyph outline is loaded. You shouldn't need this in a typical
* application, since it's mostly used to experiment with its algorithm
*
* FT_LOAD_CROP_BITMAP ::
* indicates that the glyph loader should try to crop the bitmap (i.e.
* remove all space around its black bits) when loading it. This is
* only useful when loading embedded bitmaps in certain fonts, since
* bitmaps rendered with @FT_LOAD_RENDER are always cropped by default
*
* FT_LOAD_PEDANTIC ::
* indicates that the glyph loader should perform pedantic verifications
* during glyph loading. This is mostly used to detect broken glyphs in
* fonts. By default, FreeType will always try to deal with such cases.
*
* FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH ::
* indicates that the glyph loader should ignore the global advance
* width defined in the font. As far as we know, this is only used by the
* X-TrueType font server, in order to deal correctly with the incorrect
* metrics contained in DynaLab's TrueType CJK fonts.
*
* FT_LOAD_NO_RECURSE ::
* this flag is only used internally. It merely indicates that the glyph
* loader should not load composite glyphs recursively. Instead, it should
* set the 'num_subglyph' and 'subglyphs' values of the glyph slot
* accordingly, and set "glyph->format" to @FT_GLYPH_FORMAT_COMPOSITE
*
* the description of sub-glyphs is not available to client applications
* for now
*
* FT_LOAD_IGNORE_TRANSFORM ::
* indicates that the glyph loader should not try to transform the
* loaded glyph image. This doesn't prevent scaling/hinting/rendering
*
* FT_LOAD_MONOCHROME ::
* this flag is used with @FT_LOAD_RENDER to indicate that you want
* to render a 1-bit monochrome glyph bitmap from a vectorial outline.
*
* note that this has no effect on the hinting algorithm used by the
* glyph loader. You'd better use @FT_LOAD_TARGET_MONO if you want to
* render monochrome-optimized glyph images instead.
*
* FT_LOAD_LINEAR_DESIGN ::
* indicates that the function should return the linearly scaled metrics
* expressed in original font units, instead of the default 16.16 pixel
* values
*
* FT_LOAD_NO_AUTOHINT ::
* indicates that the auto-hinter should never be used to hint glyph
* outlines. This doesn't prevent native format-specific hinters from
* being used. This can be important for certain fonts where un-hinted
* output is better than auto-hinted one.
*
*
*
*
*
*/
#define FT_LOAD_NO_SCALE 0x1
#define FT_LOAD_NO_HINTING 0x2
#define FT_LOAD_RENDER 0x4
#define FT_LOAD_NO_BITMAP 0x8
#define FT_LOAD_VERTICAL_LAYOUT 0x10
#define FT_LOAD_FORCE_AUTOHINT 0x20
#define FT_LOAD_CROP_BITMAP 0x40
#define FT_LOAD_PEDANTIC 0x80
#define FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH 0x200
/*************************************************************************/
/* */
/* <Constant> */
/* FT_LOAD_NO_RECURSE */
/* */
/* <Description> */
/* A bit-field constant, used with @FT_Load_Glyph to indicate that */
/* the glyph loader should not load composite glyph recursively. */
/* Rather, when a composite glyph is encountered, it should set */
/* the values of `num_subglyphs' and `subglyphs', as well as set */
/* `face->glyph.format' to FT_GLYPH_FORMAT_COMPOSITE. */
/* */
/* This is for use by the auto-hinter and possibly other tools. */
/* For nearly all applications, this flags should be left unset */
/* when invoking @FT_Load_Glyph. */
/* */
/* Note that the flag forces the load of unscaled glyphs. */
/* */
#define FT_LOAD_NO_RECURSE 0x400
/*************************************************************************/
/* */
/* <Constant> */
/* FT_LOAD_IGNORE_TRANSFORM */
/* */
/* <Description> */
/* A bit-field constant, used with @FT_Load_Glyph to indicate that */
/* the glyph loader should not try to transform the loaded glyph */
/* image. */
/* */
#define FT_LOAD_IGNORE_TRANSFORM 0x800
/*************************************************************************/
/* */
/* <Constant> */
/* FT_LOAD_MONOCHROME */
/* */
/* <Description> */
/* Only used with FT_LOAD_RENDER set, it indicates that the returned */
/* glyph image should be 1-bit monochrome. This really tells the */
/* glyph loader to use `FT_RENDER_MODE_MONO' when calling */
/* @FT_Render_Glyph. */
/* */
#define FT_LOAD_NO_RECURSE 0x400
#define FT_LOAD_IGNORE_TRANSFORM 0x800
#define FT_LOAD_MONOCHROME 0x1000
/*************************************************************************/
/* */
/* <Constant> */
/* FT_LOAD_LINEAR_DESIGN */
/* */
/* <Description> */
/* A bit-field constant, used with @FT_Load_Glyph to indicate that */
/* the function should return the linearly scaled metrics expressed */
/* in original font units, instead of the default 16.16 pixel values. */
/* */
#define FT_LOAD_LINEAR_DESIGN 0x2000
/* temporary hack! */
#define FT_LOAD_SBITS_ONLY 0x4000

View File

@ -104,42 +104,42 @@
sign = 1;
}
if ( ( vertical && hinter->no_vert_snapping ) ||
( !vertical && hinter->no_horz_snapping ) )
if ( ( vertical && !hinter->do_vert_snapping ) ||
( !vertical && !hinter->do_horz_snapping ) )
{
/* smooth hinting process, very lightly quantize the stem width */
/* */
if ( dist < 64 )
dist = 64;
{
FT_Pos delta = dist - globals->stds[vertical];
if ( delta < 0 )
delta = -delta;
if ( delta < 40 )
{
dist = globals->stds[vertical];
if ( dist < 32 )
dist = 32;
if ( dist < 48 )
dist = 48;
}
if ( dist < 3 * 64 )
{
delta = ( dist & 63 );
dist &= -64;
if ( delta < 10 )
dist += delta;
else if ( delta < 32 )
dist += 10;
else if ( delta < 54 )
dist += 54;
else
dist += delta;
}
@ -154,7 +154,7 @@
if ( vertical )
{
dist = ah_snap_width( globals->heights, globals->num_heights, dist );
/* in the case of vertical hinting, always round */
/* the stem heights to integer pixels */
if ( dist >= 64 )
@ -165,7 +165,7 @@
else
{
dist = ah_snap_width( globals->widths, globals->num_widths, dist );
if ( hinter->flags & AH_HINTER_MONOCHROME )
{
/* monochrome horizontal hinting: snap widths to integer pixels */
@ -182,7 +182,7 @@
/* is between 1 and 2 pixels to an integer, otherwise nothing */
if ( dist < 48 )
dist = ( dist + 64 ) >> 1;
else if ( dist < 128 )
dist = ( dist + 22 ) & -64;
else
@ -285,10 +285,10 @@
int has_serifs = 0;
if ( hinter->no_horz_hints && !dimension )
if ( !hinter->do_horz_hints && !dimension )
goto Next_Dimension;
if ( hinter->no_vert_hints && dimension )
if ( !hinter->do_vert_hints && dimension )
goto Next_Dimension;
/* we begin by aligning all stems relative to the blue zone */
@ -1169,7 +1169,7 @@
/* perform feature detection */
ah_outline_detect_features( outline );
if ( !hinter->no_vert_hints )
if ( hinter->do_vert_hints )
{
ah_outline_compute_blue_edges( outline, hinter->globals );
ah_outline_scale_blue_edges( outline, hinter->globals );
@ -1439,23 +1439,23 @@
ah_loader_rewind( hinter->loader );
/* reset hinting flags according to load flags and current render target */
hinter->no_horz_hints = FT_BOOL( load_flags & FT_LOAD_NO_AUTOHINT );
hinter->no_vert_hints = FT_BOOL( load_flags & FT_LOAD_NO_AUTOHINT );
hinter->do_horz_hints = !FT_BOOL( load_flags & FT_LOAD_NO_AUTOHINT );
hinter->do_vert_hints = !FT_BOOL( load_flags & FT_LOAD_NO_AUTOHINT );
#ifdef DEBUG_HINTER
hinter->no_horz_hints = ah_debug_disable_vert; /* not a bug, the meaning */
hinter->no_vert_hints = ah_debug_disable_horz; /* of h/v is inverted! */
#endif
hinter->do_horz_hints = !ah_debug_disable_vert; /* not a bug, the meaning */
hinter->do_vert_hints = !ah_debug_disable_horz; /* of h/v is inverted! */
#endif
/* we snap the width of vertical stems for the monochrome and */
/* horizontal LCD rendering targets only. Corresponds to X snapping. */
hinter->no_horz_snapping = FT_BOOL( hint_mode == FT_RENDER_MODE_NORMAL ||
hint_mode == FT_RENDER_MODE_LCD_V );
hinter->do_horz_snapping = FT_BOOL( hint_mode == FT_RENDER_MODE_MONO ||
hint_mode == FT_RENDER_MODE_LCD );
/* we snap the width of horizontal stems for the monochrome and */
/* vertical LCD rendering targets only. Corresponds to Y snapping. */
hinter->no_vert_snapping = FT_BOOL( hint_mode == FT_RENDER_MODE_NORMAL ||
hint_mode == FT_RENDER_MODE_LCD );
hinter->do_vert_snapping = FT_BOOL( hint_mode == FT_RENDER_MODE_MONO ||
hint_mode == FT_RENDER_MODE_LCD_V );
#if 1
load_flags = FT_LOAD_NO_SCALE

View File

@ -492,10 +492,10 @@ FT_BEGIN_HEADER
FT_Vector trans_delta;
FT_Matrix trans_matrix;
FT_Bool no_horz_hints; /* disable X hinting */
FT_Bool no_vert_hints; /* disable Y hinting */
FT_Bool no_horz_snapping; /* disable X stem size snapping */
FT_Bool no_vert_snapping; /* disable Y stem size snapping */
FT_Bool do_horz_hints; /* disable X hinting */
FT_Bool do_vert_hints; /* disable Y hinting */
FT_Bool do_horz_snapping; /* disable X stem size snapping */
FT_Bool do_vert_snapping; /* disable Y stem size snapping */
} AH_HinterRec, *AH_Hinter;

View File

@ -444,8 +444,8 @@
hinter = library->auto_hinter;
autohint =
FT_BOOL( hinter &&
!( load_flags & ( FT_LOAD_NO_SCALE |
FT_LOAD_NO_HINTING |
!( load_flags & ( FT_LOAD_NO_SCALE |
FT_LOAD_NO_HINTING |
FT_LOAD_NO_AUTOHINT ) ) &&
FT_DRIVER_IS_SCALABLE( driver ) &&
FT_DRIVER_USES_OUTLINES( driver ) );
@ -553,10 +553,13 @@
slot->format != FT_GLYPH_FORMAT_COMPOSITE &&
load_flags & FT_LOAD_RENDER )
{
error = FT_Render_Glyph( slot,
( load_flags & FT_LOAD_MONOCHROME )
? FT_RENDER_MODE_MONO
: FT_RENDER_MODE_NORMAL );
FT_Render_Mode mode = FT_LOAD_TARGET_MODE( load_flags );
if ( mode == FT_RENDER_MODE_NORMAL &&
(load_flags & FT_LOAD_MONOCHROME ) )
mode = FT_RENDER_MODE_MONO;
error = FT_Render_Glyph( slot, mode );
}
Exit:

94
src/cache/ftcimage.c vendored
View File

@ -42,7 +42,7 @@
typedef struct FTC_ImageQueryRec_
{
FTC_GlyphQueryRec gquery;
FTC_ImageDesc desc;
FTC_ImageTypeRec type;
} FTC_ImageQueryRec, *FTC_ImageQuery;
@ -54,7 +54,7 @@
typedef struct FTC_ImageFamilyRec_
{
FTC_GlyphFamilyRec gfam;
FTC_ImageDesc desc;
FTC_ImageTypeRec type;
} FTC_ImageFamilyRec, *FTC_ImageFamily;
@ -106,41 +106,13 @@
/* we will now load the glyph image */
error = FTC_Manager_Lookup_Size( FTC_FAMILY( ifam )->cache->manager,
&ifam->desc.font,
&ifam->type.font,
&face, &size );
if ( !error )
{
FT_UInt gindex = FTC_GLYPH_NODE_GINDEX( inode );
FT_UInt load_flags = FT_LOAD_DEFAULT;
FT_UInt type = ifam->desc.type;
if ( FTC_IMAGE_FORMAT( type ) == ftc_image_format_bitmap )
{
load_flags |= FT_LOAD_RENDER;
if ( type & ftc_image_flag_monochrome )
load_flags |= FT_LOAD_MONOCHROME;
/* disable embedded bitmaps loading if necessary */
if ( type & ftc_image_flag_no_sbits )
load_flags |= FT_LOAD_NO_BITMAP;
}
else if ( FTC_IMAGE_FORMAT( type ) == ftc_image_format_outline )
{
/* disable embedded bitmaps loading */
load_flags |= FT_LOAD_NO_BITMAP;
if ( type & ftc_image_flag_unscaled )
load_flags |= FT_LOAD_NO_SCALE;
}
if ( type & ftc_image_flag_unhinted )
load_flags |= FT_LOAD_NO_HINTING;
if ( type & ftc_image_flag_autohinted )
load_flags |= FT_LOAD_FORCE_AUTOHINT;
error = FT_Load_Glyph( face, gindex, load_flags );
error = FT_Load_Glyph( face, gindex, ifam->type.flags );
if ( !error )
{
if ( face->glyph->format == FT_GLYPH_FORMAT_BITMAP ||
@ -231,16 +203,16 @@
FT_Face face;
ifam->desc = iquery->desc;
ifam->type = iquery->type;
/* we need to compute "iquery.item_total" now */
error = FTC_Manager_Lookup_Face( manager,
iquery->desc.font.face_id,
iquery->type.font.face_id,
&face );
if ( !error )
{
error = ftc_glyph_family_init( FTC_GLYPH_FAMILY( ifam ),
FTC_IMAGE_DESC_HASH( &ifam->desc ),
FTC_IMAGE_TYPE_HASH( &ifam->type ),
1,
face->num_glyphs,
FTC_GLYPH_QUERY( iquery ),
@ -258,7 +230,7 @@
FT_Bool result;
result = FT_BOOL( FTC_IMAGE_DESC_COMPARE( &ifam->desc, &iquery->desc ) );
result = FT_BOOL( FTC_IMAGE_TYPE_COMPARE( &ifam->type, &iquery->type ) );
if ( result )
FTC_GLYPH_FAMILY_FOUND( ifam, iquery );
@ -314,7 +286,7 @@
FT_EXPORT_DEF( FT_Error )
FTC_ImageCache_Lookup( FTC_ImageCache cache,
FTC_ImageDesc* desc,
FTC_ImageType type,
FT_UInt gindex,
FT_Glyph *aglyph,
FTC_Node *anode )
@ -332,7 +304,7 @@
*anode = NULL;
iquery.gquery.gindex = gindex;
iquery.desc = *desc;
iquery.type = *type;
error = ftc_cache_lookup( FTC_CACHE( cache ),
FTC_QUERY( &iquery ),
@ -368,17 +340,55 @@
FT_UInt gindex,
FT_Glyph *aglyph )
{
FTC_ImageDesc desc0;
FTC_ImageTypeRec type0;
if ( !desc )
return FTC_Err_Invalid_Argument;
desc0.font = desc->font;
desc0.type = (FT_UInt32)desc->image_type;
type0.font = desc->font;
/* convert image type flags to load flags */
{
FT_UInt load_flags = FT_LOAD_DEFAULT;
FT_UInt type = desc->image_type;
/* determine load flags, depending on the font description's */
/* image type */
if ( ftc_image_format( type ) == ftc_image_format_bitmap )
{
if ( type & ftc_image_flag_monochrome )
load_flags |= FT_LOAD_MONOCHROME;
/* disable embedded bitmaps loading if necessary */
if ( type & ftc_image_flag_no_sbits )
load_flags |= FT_LOAD_NO_BITMAP;
}
else
{
/* we want an outline, don't load embedded bitmaps */
load_flags |= FT_LOAD_NO_BITMAP;
if ( type & ftc_image_flag_unscaled )
load_flags |= FT_LOAD_NO_SCALE;
}
/* always render glyphs to bitmaps */
load_flags |= FT_LOAD_RENDER;
if ( type & ftc_image_flag_unhinted )
load_flags |= FT_LOAD_NO_HINTING;
if ( type & ftc_image_flag_autohinted )
load_flags |= FT_LOAD_FORCE_AUTOHINT;
type0.flags = load_flags;
}
return FTC_ImageCache_Lookup( (FTC_ImageCache)icache,
&desc0,
&type0,
gindex,
aglyph,
NULL );

113
src/cache/ftcsbits.c vendored
View File

@ -46,7 +46,7 @@
typedef struct FTC_SBitQueryRec_
{
FTC_GlyphQueryRec gquery;
FTC_ImageDesc desc;
FTC_ImageTypeRec type;
} FTC_SBitQueryRec, *FTC_SBitQuery;
@ -60,7 +60,7 @@
typedef struct FTC_SBitFamilyRec_
{
FTC_GlyphFamilyRec gfam;
FTC_ImageDesc desc;
FTC_ImageTypeRec type;
} FTC_SBitFamilyRec;
@ -104,8 +104,8 @@
ftc_sbit_node_done( FTC_SBitNode snode,
FTC_Cache cache )
{
FTC_SBit sbit = snode->sbits;
FT_UInt count = FTC_GLYPH_NODE( snode )->item_count;
FTC_SBit sbit = snode->sbits;
FT_UInt count = FTC_GLYPH_NODE( snode )->item_count;
FT_Memory memory = cache->memory;
@ -142,48 +142,14 @@
sbit = snode->sbits + ( gindex - gnode->item_start );
error = FTC_Manager_Lookup_Size( manager, &sfam->desc.font,
error = FTC_Manager_Lookup_Size( manager, &sfam->type.font,
&face, &size );
if ( !error )
{
FT_UInt load_flags = FT_LOAD_DEFAULT;
FT_UInt type = sfam->desc.type;
/* determine load flags, depending on the font description's */
/* image type */
if ( FTC_IMAGE_FORMAT( type ) == ftc_image_format_bitmap )
{
if ( type & ftc_image_flag_monochrome )
load_flags |= FT_LOAD_MONOCHROME;
/* disable embedded bitmaps loading if necessary */
if ( type & ftc_image_flag_no_sbits )
load_flags |= FT_LOAD_NO_BITMAP;
}
else
{
FT_ERROR((
"ftc_sbit_node_load: cannot load scalable glyphs in an"
" sbit cache, please check your arguments!\n" ));
error = FTC_Err_Invalid_Argument;
goto Exit;
}
/* always render glyphs to bitmaps */
load_flags |= FT_LOAD_RENDER;
if ( type & ftc_image_flag_unhinted )
load_flags |= FT_LOAD_NO_HINTING;
if ( type & ftc_image_flag_autohinted )
load_flags |= FT_LOAD_FORCE_AUTOHINT;
/* by default, indicates a `missing' glyph */
sbit->buffer = 0;
error = FT_Load_Glyph( face, gindex, load_flags );
error = FT_Load_Glyph( face, gindex, sfam->type.flags | FT_LOAD_RENDER );
if ( !error )
{
FT_Int temp;
@ -221,13 +187,7 @@
sbit->xadvance = (FT_Char)xadvance;
sbit->yadvance = (FT_Char)yadvance;
sbit->format = (FT_Byte)bitmap->pixel_mode;
/* XXX: Fixme: We don't handle the number of gray levels */
/* consistently -- we say num_grays == 1 for */
/* monochrome but num_grays == 256 for gray. It */
/* would be better to make this variable hold the */
/* highest possible value so that it fits into */
/* a single byte. */
sbit->num_grays = bitmap->num_grays;
sbit->max_grays = (FT_Byte)(bitmap->num_grays - 1);
/* grab the bitmap when possible - this is a hack! */
if ( slot->flags & FT_GLYPH_OWN_BITMAP )
@ -380,16 +340,16 @@
FT_Face face;
sfam->desc = squery->desc;
sfam->type = squery->type;
/* we need to compute "cquery.item_total" now */
error = FTC_Manager_Lookup_Face( manager,
squery->desc.font.face_id,
squery->type.font.face_id,
&face );
if ( !error )
{
error = ftc_glyph_family_init( FTC_GLYPH_FAMILY( sfam ),
FTC_IMAGE_DESC_HASH( &sfam->desc ),
FTC_IMAGE_TYPE_HASH( &sfam->type ),
FTC_SBIT_ITEMS_PER_NODE,
face->num_glyphs,
FTC_GLYPH_QUERY( squery ),
@ -410,7 +370,7 @@
/* we need to set the "cquery.cset" field or our query for */
/* faster glyph comparisons in ftc_sbit_node_compare */
/* */
result = FT_BOOL( FTC_IMAGE_DESC_COMPARE( &sfam->desc, &squery->desc ) );
result = FT_BOOL( FTC_IMAGE_TYPE_COMPARE( &sfam->type, &squery->type ) );
if ( result )
FTC_GLYPH_FAMILY_FOUND( sfam, squery );
@ -481,7 +441,7 @@
FT_EXPORT_DEF( FT_Error )
FTC_SBitCache_Lookup( FTC_SBitCache cache,
FTC_ImageDesc* desc,
FTC_ImageType type,
FT_UInt gindex,
FTC_SBit *ansbit,
FTC_Node *anode )
@ -501,7 +461,7 @@
*anode = NULL;
squery.gquery.gindex = gindex;
squery.desc = *desc;
squery.type = *type;
error = ftc_sbit_cache_lookup( FTC_CACHE( cache ),
FTC_QUERY( &squery ),
@ -536,17 +496,56 @@
FT_UInt gindex,
FTC_SBit *ansbit )
{
FTC_ImageDesc desc0;
FTC_ImageTypeRec type0;
if ( !desc )
return FTC_Err_Invalid_Argument;
desc0.font = desc->font;
desc0.type = (FT_UInt32)desc->image_type;
type0.font = desc->font;
type0.flags = 0;
/* convert image type flags to load flags */
{
FT_UInt load_flags = FT_LOAD_DEFAULT;
FT_UInt type = desc->image_type;
/* determine load flags, depending on the font description's */
/* image type */
if ( ftc_image_format( type ) == ftc_image_format_bitmap )
{
if ( type & ftc_image_flag_monochrome )
load_flags |= FT_LOAD_MONOCHROME;
/* disable embedded bitmaps loading if necessary */
if ( type & ftc_image_flag_no_sbits )
load_flags |= FT_LOAD_NO_BITMAP;
}
else
{
/* we want an outline, don't load embedded bitmaps */
load_flags |= FT_LOAD_NO_BITMAP;
if ( type & ftc_image_flag_unscaled )
load_flags |= FT_LOAD_NO_SCALE;
}
/* always render glyphs to bitmaps */
load_flags |= FT_LOAD_RENDER;
if ( type & ftc_image_flag_unhinted )
load_flags |= FT_LOAD_NO_HINTING;
if ( type & ftc_image_flag_autohinted )
load_flags |= FT_LOAD_FORCE_AUTOHINT;
type0.flags = load_flags;
}
return FTC_SBitCache_Lookup( (FTC_SBitCache)cache,
&desc0,
&type0,
gindex,
ansbit,
NULL );

View File

@ -332,6 +332,56 @@
/*************************************************************************/
/*************************************************************************/
static FT_Pos
psh3_dimension_quantize_len( PSH_Dimension dim,
FT_Pos len,
FT_Bool do_snapping )
{
if ( len <= 64 )
len = 64;
else
{
FT_Pos delta = len - dim->stdw.widths[0].cur;
if ( delta < 0 )
delta = -delta;
if ( delta < 40 )
{
len = dim->stdw.widths[0].cur;
if ( len < 48 )
len = 48;
}
if ( len < 3 * 64 )
{
delta = ( len & 63 );
len &= -64;
if ( delta < 10 )
len += delta;
else if ( delta < 32 )
len += 10;
else if ( delta < 54 )
len += 54;
else
len += delta;
}
else
len = ( len + 32 ) & -64;
}
if ( do_snapping )
len = ( len + 32 ) & -64;
return len;
}
#ifdef DEBUG_HINTER
static void
@ -390,15 +440,15 @@
FT_Pos pos = FT_MulFix( hint->org_pos, scale ) + delta;
FT_Pos len = FT_MulFix( hint->org_len, scale );
FT_Int no_snapping;
FT_Int do_snapping;
FT_Pos fit_center;
FT_Pos fit_len;
PSH_AlignmentRec align;
/* ignore stem alignments when requested through the hint flags */
if ( ( dimension == 0 && glyph->no_horz_hints ) ||
( dimension == 1 && glyph->no_vert_hints ) )
if ( ( dimension == 0 && !glyph->do_horz_hints ) ||
( dimension == 1 && !glyph->do_vert_hints ) )
{
hint->cur_pos = pos;
hint->cur_len = len;
@ -408,26 +458,10 @@
}
/* perform stem snapping when requested */
no_snapping = ( dimension == 0 && !glyph->no_horz_snapping ) ||
( dimension == 1 && !glyph->no_vert_snapping );
do_snapping = ( dimension == 0 && glyph->do_horz_snapping ) ||
( dimension == 1 && glyph->do_vert_snapping );
if ( !no_snapping )
{
/* compute fitted width/height */
fit_len = 0;
if ( hint->org_len )
{
fit_len = psh_dimension_snap_width( dim, hint->org_len );
if ( fit_len < 64 )
fit_len = 64;
else
fit_len = ( fit_len + 32 ) & -64;
}
}
else
fit_len = len;
hint->cur_len = fit_len;
hint->cur_len = fit_len = len;
/* check blue zones for horizontal stems */
align.align = PSH_BLUE_ALIGN_NONE;
@ -480,151 +514,64 @@
pos = par_cur_center + cur_delta - ( len >> 1 );
}
if ( !no_snapping )
hint->cur_pos = pos;
hint->cur_len = fit_len;
if ( len <= 64 )
{
/* normal processing */
if ( fit_len & 64 )
{
/* odd number of pixels */
fit_center = ( ( pos + ( len >> 1 ) ) & -64 ) + 32;
}
else
{
/* even number of pixels */
fit_center = ( pos + ( len >> 1 ) + 32 ) & -64;
}
hint->cur_pos = fit_center - ( fit_len >> 1 );
/* the stem is less than one pixel, we will center it */
/* around the nearest pixel center */
/* */
pos = ( pos + ( (len >> 1) & -64 ) );
len = 64;
}
else
{
#ifdef STRONGER
if ( len <= 64 )
{
/* the stem is less than one pixel, we will center it */
/* around the nearest pixel center */
/* */
pos = ( pos + ( (len >> 1) & -64 ) );
len = 64;
}
else
{
FT_Pos Delta = len - dim->stdw.widths[0].cur;
if ( Delta < 0 )
Delta = -Delta;
if ( Delta < 40 )
{
len = dim->stdw.widths[0].cur;
if ( len < 32 )
len = 32;
}
if ( len < 3 * 64 )
{
Delta = ( len & 63 );
len &= -64;
if ( Delta < 10 )
len += Delta;
else if ( Delta < 32 )
len += 10;
else if ( Delta < 54 )
len += 54;
else
len += Delta;
}
else
len = ( len + 32 ) & -64;
}
/* now that we have a good hinted stem width, try to position */
/* the stem along a pixel grid integer coordinate */
hint->cur_pos = pos + psh3_hint_snap_stem_side_delta( pos, len );
hint->cur_len = len;
#else /* !STRONGER */
/* Stems less than one pixel wide are easy - we want to
* make them as dark as possible, so they must fall within
* one pixel. If the stem is split between two pixels
* then snap the edge that is nearer to the pixel boundary
* to the pixel boundary
*/
if (len <= 64)
{
if ( ( pos + len + 63 ) / 64 != pos / 64 + 1 )
pos += psh3_hint_snap_stem_side_delta ( pos, len );
}
/* Position stems other to minimize the amount of mid-grays.
* There are, in general, two positions that do this,
* illustrated as A) and B) below.
*
* + + + +
*
* A) |--------------------------------|
* B) |--------------------------------|
* C) |--------------------------------|
*
* Position A) (split the excess stem equally) should be better
* for stems of width N + f where f < 0.5.
*
* Position B) (split the deficiency equally) should be better
* for stems of width N + f where f > 0.5.
*
* It turns out though that minimizing the total number of touched
* pixels is also important, so position C), with one edge
* aligned with a pixel boundary is actually preferable
* to A). There are also more possible positions for C) than
* for A) or B), so there will be less distortion of the overall
* character shape.
*/
else
{
FT_Fixed frac_len = len & 63;
FT_Fixed center = pos + ( len >> 1 );
FT_Fixed delta_a, delta_b;
if ( len & 64 )
{
delta_a = ( center & -64 ) + 32 - center;
delta_b = ( ( center + 32 ) & - 64 ) - center;
}
else
{
delta_a = ( ( center + 32 ) & - 64 ) - center;
delta_b = ( center & -64 ) + 32 - center;
}
/* We choose between B) and C) above based on the amount
* of fractional stem width: for small amounts, choose
* C) always; for large amounts, B) always; inbetween,
* pick whichever one involves less stem movement.
*/
if ( frac_len < 32 )
pos += psh3_hint_snap_stem_side_delta ( pos, len );
else if ( frac_len < 48 )
{
FT_Fixed side_delta =
psh3_hint_snap_stem_side_delta( pos, len );
if ( ABS( side_delta ) < ABS( delta_b ) )
pos += side_delta;
else
pos += delta_b;
}
else
pos += delta_b;
}
hint->cur_pos = pos;
#endif /* !STRONGER */
len = psh3_dimension_quantize_len( dim, len, 0 );
}
/* now that we have a good hinted stem width, try to position */
/* the stem along a pixel grid integer coordinate */
hint->cur_pos = pos + psh3_hint_snap_stem_side_delta( pos, len );
hint->cur_len = len;
}
}
if ( do_snapping )
{
pos = hint->cur_pos;
len = hint->cur_len;
if ( len < 64 )
len = 64;
else
len = ( len + 32 ) & -64;
switch ( align.align )
{
case PSH_BLUE_ALIGN_TOP:
hint->cur_pos = align.align_top - len;
hint->cur_len = len;
break;
case PSH_BLUE_ALIGN_BOT:
hint->cur_len = len;
break;
case PSH_BLUE_ALIGN_BOT | PSH_BLUE_ALIGN_TOP:
/* don't touch */
break;
default:
hint->cur_len = len;
if ( len & 64 )
pos = ( ( pos + ( len >> 1 ) ) & -64 ) + 32;
else
pos = ( pos + ( len >> 1 ) + 32 ) & -64;
hint->cur_pos = pos - ( len >> 1 );
hint->cur_len = len;
}
}
@ -1761,19 +1708,19 @@
#endif /* DEBUG_HINTER */
glyph->no_horz_hints = 0;
glyph->no_vert_hints = 0;
glyph->no_horz_snapping = FT_BOOL( hint_mode == FT_RENDER_MODE_NORMAL ||
hint_mode == FT_RENDER_MODE_LCD_V );
glyph->no_vert_snapping = FT_BOOL( hint_mode == FT_RENDER_MODE_NORMAL ||
hint_mode == FT_RENDER_MODE_LCD );
error = psh3_glyph_init( glyph, outline, ps_hints, globals );
if ( error )
goto Exit;
glyph->do_horz_hints = 1;
glyph->do_vert_hints = 1;
glyph->do_horz_snapping = FT_BOOL( hint_mode == FT_RENDER_MODE_MONO ||
hint_mode == FT_RENDER_MODE_LCD );
glyph->do_vert_snapping = FT_BOOL( hint_mode == FT_RENDER_MODE_MONO ||
hint_mode == FT_RENDER_MODE_LCD_V );
for ( dimension = 0; dimension < 2; dimension++ )
{
/* load outline coordinates into glyph */

View File

@ -30,7 +30,7 @@ FT_BEGIN_HEADER
/* handle to Hint structure */
typedef struct PSH3_HintRec_* PSH3_Hint;
/* hint bit-flags */
typedef enum
{
@ -217,10 +217,10 @@ FT_BEGIN_HEADER
FT_Int major_dir;
FT_Int minor_dir;
FT_Bool no_horz_hints;
FT_Bool no_vert_hints;
FT_Bool no_horz_snapping;
FT_Bool no_vert_snapping;
FT_Bool do_horz_hints;
FT_Bool do_vert_hints;
FT_Bool do_horz_snapping;
FT_Bool do_vert_snapping;
} PSH3_GlyphRec, *PSH3_Glyph;

View File

@ -249,9 +249,15 @@
FT_UInt mode,
FT_Vector* origin )
{
return ft_smooth_render_generic( render, slot, mode, origin,
FT_RENDER_MODE_LCD,
3, 0 );
FT_Error error;
error = ft_smooth_render_generic( render, slot, mode, origin,
FT_RENDER_MODE_LCD,
3, 0 );
if ( !error )
slot->bitmap.pixel_mode = FT_PIXEL_MODE_LCD;
return error;
}
@ -262,9 +268,15 @@
FT_UInt mode,
FT_Vector* origin )
{
return ft_smooth_render_generic( render, slot, mode, origin,
FT_RENDER_MODE_LCD_V,
0, 3 );
FT_Error error;
error = ft_smooth_render_generic( render, slot, mode, origin,
FT_RENDER_MODE_LCD_V,
0, 3 );
if ( !error )
slot->bitmap.pixel_mode = FT_PIXEL_MODE_LCD_V;
return error;
}