forked from minhngoc25a/freetype2
Add vertical phantom points.
* include/freetype/internal/tttypes.h (TT_LoaderRec): Add `top_bearing', `vadvance', `pp3, and `pp4'. * src/autofit/afloader.c (af_loader_load_g): Handle two more points. * src/autohint/ahhint.c (ah_hinter_load): Handle two more points. * src/truetype/ttgload.c (Get_VMetrics): New function. (TT_Load_Simple_Glyph, TT_Process_Simple_Glyph): Handle two more points. (load_truetype_glyph): Use Get_VMetrics. Handle two more points. (compute_glyph_metrics): Thanks to vertical phantom points we now can always compute `advance_height' and `top_bearing'. * src/truetype/ttobjs.h (TT_SubglyphRec): Add vertical phantom points. * src/autohint/ahglyph.c (ah_outline_load): Fix allocation of `news'. Converting some files to Unix end-of-line convention.
This commit is contained in:
parent
60e0a4d5db
commit
8bb07e6386
24
ChangeLog
24
ChangeLog
|
@ -1,3 +1,27 @@
|
|||
2004-13-26 George Williams <gww@silcom.com>
|
||||
|
||||
Add vertical phantom points.
|
||||
|
||||
* include/freetype/internal/tttypes.h (TT_LoaderRec): Add
|
||||
`top_bearing', `vadvance', `pp3, and `pp4'.
|
||||
|
||||
* src/autofit/afloader.c (af_loader_load_g): Handle two more points.
|
||||
|
||||
* src/autohint/ahhint.c (ah_hinter_load): Handle two more points.
|
||||
* src/truetype/ttgload.c (Get_VMetrics): New function.
|
||||
(TT_Load_Simple_Glyph, TT_Process_Simple_Glyph): Handle two more
|
||||
points.
|
||||
(load_truetype_glyph): Use Get_VMetrics.
|
||||
Handle two more points.
|
||||
(compute_glyph_metrics): Thanks to vertical phantom points we now
|
||||
can always compute `advance_height' and `top_bearing'.
|
||||
* src/truetype/ttobjs.h (TT_SubglyphRec): Add vertical phantom
|
||||
points.
|
||||
|
||||
|
||||
* src/autohint/ahglyph.c (ah_outline_load): Fix allocation of
|
||||
`news'.
|
||||
|
||||
2004-03-21 Werner Lemberg <wl@gnu.org>
|
||||
|
||||
* src/bdf/bdfdrivr.c (BDF_Glyph_Load): Fix left side bearing.
|
||||
|
|
|
@ -1342,11 +1342,15 @@ FT_BEGIN_HEADER
|
|||
FT_BBox bbox;
|
||||
FT_Int left_bearing;
|
||||
FT_Int advance;
|
||||
FT_Int top_bearing;
|
||||
FT_Int vadvance;
|
||||
FT_Int linear;
|
||||
FT_Bool linear_def;
|
||||
FT_Bool preserve_pps;
|
||||
FT_Vector pp1;
|
||||
FT_Vector pp2;
|
||||
FT_Vector pp3;
|
||||
FT_Vector pp4;
|
||||
|
||||
FT_ULong glyf_offset;
|
||||
|
||||
|
|
|
@ -1,35 +1,35 @@
|
|||
#include "afdummy.h"
|
||||
|
||||
|
||||
static FT_Error
|
||||
af_dummy_hints_init( AF_GlyphHints hints,
|
||||
FT_Outline* outline,
|
||||
AF_ScriptMetrics metrics )
|
||||
{
|
||||
return af_glyph_hints_reset( hints,
|
||||
&metrics->scaler,
|
||||
metrics,
|
||||
outline );
|
||||
}
|
||||
|
||||
static FT_Error
|
||||
af_dummy_hints_apply( AF_GlyphHints hints,
|
||||
FT_Outline* outline )
|
||||
{
|
||||
af_glyph_hints_save( hints, outline );
|
||||
}
|
||||
|
||||
|
||||
FT_LOCAL_DEF( const AF_ScriptClassRec ) af_dummy_script_class =
|
||||
{
|
||||
AF_SCRIPT_NONE,
|
||||
NULL,
|
||||
|
||||
sizeof( AF_ScriptMetricsRec ),
|
||||
(AF_Script_InitMetricsFunc) NULL,
|
||||
(AF_Script_ScaleMetricsFunc) NULL,
|
||||
(AF_Script_DoneMetricsFunc) NULL,
|
||||
|
||||
(AF_Script_InitHintsFunc) af_dummy_hints_init,
|
||||
(AF_Script_ApplyHintsFunc) af_dummy_hints_apply
|
||||
};
|
||||
#include "afdummy.h"
|
||||
|
||||
|
||||
static FT_Error
|
||||
af_dummy_hints_init( AF_GlyphHints hints,
|
||||
FT_Outline* outline,
|
||||
AF_ScriptMetrics metrics )
|
||||
{
|
||||
return af_glyph_hints_reset( hints,
|
||||
&metrics->scaler,
|
||||
metrics,
|
||||
outline );
|
||||
}
|
||||
|
||||
static FT_Error
|
||||
af_dummy_hints_apply( AF_GlyphHints hints,
|
||||
FT_Outline* outline )
|
||||
{
|
||||
af_glyph_hints_save( hints, outline );
|
||||
}
|
||||
|
||||
|
||||
FT_LOCAL_DEF( const AF_ScriptClassRec ) af_dummy_script_class =
|
||||
{
|
||||
AF_SCRIPT_NONE,
|
||||
NULL,
|
||||
|
||||
sizeof( AF_ScriptMetricsRec ),
|
||||
(AF_Script_InitMetricsFunc) NULL,
|
||||
(AF_Script_ScaleMetricsFunc) NULL,
|
||||
(AF_Script_DoneMetricsFunc) NULL,
|
||||
|
||||
(AF_Script_InitHintsFunc) af_dummy_hints_init,
|
||||
(AF_Script_ApplyHintsFunc) af_dummy_hints_apply
|
||||
};
|
||||
|
|
|
@ -1,18 +1,18 @@
|
|||
#ifndef __AFDUMMY_H__
|
||||
#define __AFDUMMY_H__
|
||||
|
||||
#include "aftypes.h"
|
||||
|
||||
FT_BEGIN_HEADER
|
||||
|
||||
/* a dummy script metrics class used when no hinting should
|
||||
* be performed. This is the default for non-latin glyphs !
|
||||
*/
|
||||
|
||||
FT_LOCAL( const AF_ScriptClassRec ) af_dummy_script_class;
|
||||
|
||||
/* */
|
||||
|
||||
FT_END_HEADER
|
||||
|
||||
#endif /* __AFDUMMY_H__ */
|
||||
#ifndef __AFDUMMY_H__
|
||||
#define __AFDUMMY_H__
|
||||
|
||||
#include "aftypes.h"
|
||||
|
||||
FT_BEGIN_HEADER
|
||||
|
||||
/* a dummy script metrics class used when no hinting should
|
||||
* be performed. This is the default for non-latin glyphs !
|
||||
*/
|
||||
|
||||
FT_LOCAL( const AF_ScriptClassRec ) af_dummy_script_class;
|
||||
|
||||
/* */
|
||||
|
||||
FT_END_HEADER
|
||||
|
||||
#endif /* __AFDUMMY_H__ */
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,246 +1,246 @@
|
|||
#ifndef __AFHINTS_H__
|
||||
#define __AFHINTS_H__
|
||||
|
||||
#include "aftypes.h"
|
||||
|
||||
FT_BEGIN_HEADER
|
||||
|
||||
/*
|
||||
* The definition of outline glyph hints. These are shared by all
|
||||
* script analysis routines (until now)
|
||||
*
|
||||
*/
|
||||
|
||||
typedef enum
|
||||
{
|
||||
AF_DIMENSION_HORZ = 0, /* x coordinates, i.e. vertical segments & edges */
|
||||
AF_DIMENSION_VERT = 1, /* y coordinates, i.e. horizontal segments & edges */
|
||||
|
||||
AF_DIMENSION_MAX /* do not remove */
|
||||
|
||||
} AF_Dimension;
|
||||
|
||||
|
||||
/* hint directions -- the values are computed so that two vectors are */
|
||||
/* in opposite directions iff `dir1+dir2 == 0' */
|
||||
typedef enum
|
||||
{
|
||||
AF_DIR_NONE = 4,
|
||||
AF_DIR_RIGHT = 1,
|
||||
AF_DIR_LEFT = -1,
|
||||
AF_DIR_UP = 2,
|
||||
AF_DIR_DOWN = -2
|
||||
|
||||
} AF_Direction;
|
||||
|
||||
|
||||
/* point hint flags */
|
||||
typedef enum
|
||||
{
|
||||
AF_FLAG_NONE = 0,
|
||||
|
||||
/* point type flags */
|
||||
AF_FLAG_CONIC = (1 << 0),
|
||||
AF_FLAG_CUBIC = (1 << 1),
|
||||
AF_FLAG_CONTROL = AF_FLAG_CONIC | AF_FLAG_CUBIC,
|
||||
|
||||
/* point extremum flags */
|
||||
AF_FLAG_EXTREMA_X = (1 << 2),
|
||||
AF_FLAG_EXTREMA_Y = (1 << 3),
|
||||
|
||||
/* point roundness flags */
|
||||
AF_FLAG_ROUND_X = (1 << 4),
|
||||
AF_FLAG_ROUND_Y = (1 << 5),
|
||||
|
||||
/* point touch flags */
|
||||
AF_FLAG_TOUCH_X = (1 << 6),
|
||||
AF_FLAG_TOUCH_Y = (1 << 7),
|
||||
|
||||
/* candidates for weak interpolation have this flag set */
|
||||
AF_FLAG_WEAK_INTERPOLATION = (1 << 8),
|
||||
|
||||
/* all inflection points in the outline have this flag set */
|
||||
AF_FLAG_INFLECTION = (1 << 9)
|
||||
|
||||
} AF_Flags;
|
||||
|
||||
|
||||
/* edge hint flags */
|
||||
typedef enum
|
||||
{
|
||||
AF_EDGE_NORMAL = 0,
|
||||
AF_EDGE_ROUND = (1 << 0),
|
||||
AF_EDGE_SERIF = (1 << 1),
|
||||
AF_EDGE_DONE = (1 << 2)
|
||||
|
||||
} AF_Edge_Flags;
|
||||
|
||||
|
||||
|
||||
typedef struct AF_PointRec_* AF_Point;
|
||||
typedef struct AF_SegmentRec_* AF_Segment;
|
||||
typedef struct AF_EdgeRec_* AF_Edge;
|
||||
|
||||
|
||||
typedef struct AF_PointRec_
|
||||
{
|
||||
AF_Flags flags; /* point flags used by hinter */
|
||||
FT_Pos ox, oy; /* original, scaled position */
|
||||
FT_Pos fx, fy; /* original, unscaled position (font units) */
|
||||
FT_Pos x, y; /* current position */
|
||||
FT_Pos u, v; /* current (x,y) or (y,x) depending on context */
|
||||
|
||||
AF_Direction in_dir; /* direction of inwards vector */
|
||||
AF_Direction out_dir; /* direction of outwards vector */
|
||||
|
||||
AF_Point next; /* next point in contour */
|
||||
AF_Point prev; /* previous point in contour */
|
||||
|
||||
} AF_PointRec;
|
||||
|
||||
|
||||
typedef struct AF_SegmentRec_
|
||||
{
|
||||
AF_Edge_Flags flags; /* edge/segment flags for this segment */
|
||||
AF_Direction dir; /* segment direction */
|
||||
FT_Pos pos; /* position of segment */
|
||||
FT_Pos min_coord; /* minimum coordinate of segment */
|
||||
FT_Pos max_coord; /* maximum coordinate of segment */
|
||||
|
||||
AF_Edge edge; /* the segment's parent edge */
|
||||
AF_Segment edge_next; /* link to next segment in parent edge */
|
||||
|
||||
AF_Segment link; /* (stem) link segment */
|
||||
AF_Segment serif; /* primary segment for serifs */
|
||||
FT_Pos num_linked; /* number of linked segments */
|
||||
FT_Pos score; /* used during stem matching */
|
||||
|
||||
AF_Point first; /* first point in edge segment */
|
||||
AF_Point last; /* last point in edge segment */
|
||||
AF_Point* contour; /* ptr to first point of segment's contour */
|
||||
|
||||
} AF_SegmentRec;
|
||||
|
||||
|
||||
typedef struct AF_EdgeRec_
|
||||
{
|
||||
FT_Pos fpos; /* original, unscaled position (font units) */
|
||||
FT_Pos opos; /* original, scaled position */
|
||||
FT_Pos pos; /* current position */
|
||||
|
||||
AF_Edge_Flags flags; /* edge flags */
|
||||
AF_Direction dir; /* edge direction */
|
||||
FT_Fixed scale; /* used to speed up interpolation between edges */
|
||||
AF_Width blue_edge; /* non-NULL if this is a blue edge */
|
||||
|
||||
AF_Edge link;
|
||||
AF_Edge serif;
|
||||
FT_Int num_linked;
|
||||
|
||||
FT_Int score;
|
||||
|
||||
AF_Segment first;
|
||||
AF_Segment last;
|
||||
|
||||
} AF_EdgeRec;
|
||||
|
||||
|
||||
typedef struct AF_AxisHintsRec_
|
||||
{
|
||||
FT_Int num_segments;
|
||||
AF_Segment segments;
|
||||
|
||||
FT_Int num_edges;
|
||||
AF_Edge edges;
|
||||
|
||||
AF_Direction major_dir;
|
||||
|
||||
} AF_AxisHintsRec, *AF_AxisHints;
|
||||
|
||||
|
||||
typedef struct AF_GlyphHintsRec_
|
||||
{
|
||||
FT_Memory memory;
|
||||
|
||||
FT_Fixed x_scale;
|
||||
FT_Pos x_delta;
|
||||
|
||||
FT_Fixed y_scale;
|
||||
FT_Pos y_delta;
|
||||
|
||||
FT_Pos edge_distance_threshold;
|
||||
|
||||
FT_Int max_points;
|
||||
FT_Int num_points;
|
||||
AF_Point points;
|
||||
|
||||
FT_Int max_contours;
|
||||
FT_Int num_contours;
|
||||
AF_Point* contours;
|
||||
|
||||
AF_AxisHintsRec axis[ AF_DIMENSION_MAX ];
|
||||
|
||||
FT_UInt32 scaler_flags; /* copy of scaler flags */
|
||||
FT_UInt32 other_flags; /* free for script-specific implementations */
|
||||
AF_ScriptMetrics metrics;
|
||||
|
||||
} AF_GlyphHintsRec;
|
||||
|
||||
|
||||
#define AF_HINTS_TEST_SCALER(h,f) ( (h)->scaler_flags & (f) )
|
||||
#define AF_HINTS_TEST_OTHER(h,f) ( (h)->other_flags & (f) )
|
||||
|
||||
#define AF_HINTS_DO_HORIZONTAL(h) \
|
||||
!AF_HINTS_TEST_SCALER(h,AF_SCALER_FLAG_NO_HORIZONTAL)
|
||||
|
||||
#define AF_HINTS_DO_VERTICAL(h) \
|
||||
!AF_HINTS_TEST_SCALER(h,AF_SCALER_FLAG_NO_VERTICAL)
|
||||
|
||||
#define AF_HINTS_DO_ADVANCE(h) \
|
||||
!AF_HINTS_TEST_SCALER(h,AF_SCALER_FLAG_NO_ADVANCE)
|
||||
|
||||
|
||||
FT_LOCAL( AF_Direction )
|
||||
af_direction_compute( FT_Pos dx,
|
||||
FT_Pos dy );
|
||||
|
||||
|
||||
FT_LOCAL( void )
|
||||
af_glyph_hints_init( AF_GlyphHints hints,
|
||||
FT_Memory memory );
|
||||
|
||||
|
||||
|
||||
/* recomputes all AF_Point in a AF_GlyphHints from the definitions
|
||||
* in a source outline
|
||||
*/
|
||||
FT_LOCAL( FT_Error )
|
||||
af_glyph_hints_reset( AF_GlyphHints hints,
|
||||
AF_Scaler scaler,
|
||||
AF_ScriptMetrics metrics,
|
||||
FT_Outline* outline );
|
||||
|
||||
FT_LOCAL( void )
|
||||
af_glyph_hints_save( AF_GlyphHints hints,
|
||||
FT_Outline* outline );
|
||||
|
||||
FT_LOCAL( void )
|
||||
af_glyph_hints_align_edge_points( AF_GlyphHints hints,
|
||||
AF_Dimension dim );
|
||||
|
||||
FT_LOCAL( void )
|
||||
af_glyph_hints_align_strong_points( AF_GlyphHints hints,
|
||||
AF_Dimension dim );
|
||||
|
||||
FT_LOCAL( void )
|
||||
af_glyph_hints_align_weak_points( AF_GlyphHints hints,
|
||||
AF_Dimension dim );
|
||||
|
||||
FT_LOCAL( void )
|
||||
af_glyph_hints_done( AF_GlyphHints hints );
|
||||
|
||||
/* */
|
||||
|
||||
FT_END_HEADER
|
||||
|
||||
#endif /* __AFHINTS_H__ */
|
||||
#ifndef __AFHINTS_H__
|
||||
#define __AFHINTS_H__
|
||||
|
||||
#include "aftypes.h"
|
||||
|
||||
FT_BEGIN_HEADER
|
||||
|
||||
/*
|
||||
* The definition of outline glyph hints. These are shared by all
|
||||
* script analysis routines (until now)
|
||||
*
|
||||
*/
|
||||
|
||||
typedef enum
|
||||
{
|
||||
AF_DIMENSION_HORZ = 0, /* x coordinates, i.e. vertical segments & edges */
|
||||
AF_DIMENSION_VERT = 1, /* y coordinates, i.e. horizontal segments & edges */
|
||||
|
||||
AF_DIMENSION_MAX /* do not remove */
|
||||
|
||||
} AF_Dimension;
|
||||
|
||||
|
||||
/* hint directions -- the values are computed so that two vectors are */
|
||||
/* in opposite directions iff `dir1+dir2 == 0' */
|
||||
typedef enum
|
||||
{
|
||||
AF_DIR_NONE = 4,
|
||||
AF_DIR_RIGHT = 1,
|
||||
AF_DIR_LEFT = -1,
|
||||
AF_DIR_UP = 2,
|
||||
AF_DIR_DOWN = -2
|
||||
|
||||
} AF_Direction;
|
||||
|
||||
|
||||
/* point hint flags */
|
||||
typedef enum
|
||||
{
|
||||
AF_FLAG_NONE = 0,
|
||||
|
||||
/* point type flags */
|
||||
AF_FLAG_CONIC = (1 << 0),
|
||||
AF_FLAG_CUBIC = (1 << 1),
|
||||
AF_FLAG_CONTROL = AF_FLAG_CONIC | AF_FLAG_CUBIC,
|
||||
|
||||
/* point extremum flags */
|
||||
AF_FLAG_EXTREMA_X = (1 << 2),
|
||||
AF_FLAG_EXTREMA_Y = (1 << 3),
|
||||
|
||||
/* point roundness flags */
|
||||
AF_FLAG_ROUND_X = (1 << 4),
|
||||
AF_FLAG_ROUND_Y = (1 << 5),
|
||||
|
||||
/* point touch flags */
|
||||
AF_FLAG_TOUCH_X = (1 << 6),
|
||||
AF_FLAG_TOUCH_Y = (1 << 7),
|
||||
|
||||
/* candidates for weak interpolation have this flag set */
|
||||
AF_FLAG_WEAK_INTERPOLATION = (1 << 8),
|
||||
|
||||
/* all inflection points in the outline have this flag set */
|
||||
AF_FLAG_INFLECTION = (1 << 9)
|
||||
|
||||
} AF_Flags;
|
||||
|
||||
|
||||
/* edge hint flags */
|
||||
typedef enum
|
||||
{
|
||||
AF_EDGE_NORMAL = 0,
|
||||
AF_EDGE_ROUND = (1 << 0),
|
||||
AF_EDGE_SERIF = (1 << 1),
|
||||
AF_EDGE_DONE = (1 << 2)
|
||||
|
||||
} AF_Edge_Flags;
|
||||
|
||||
|
||||
|
||||
typedef struct AF_PointRec_* AF_Point;
|
||||
typedef struct AF_SegmentRec_* AF_Segment;
|
||||
typedef struct AF_EdgeRec_* AF_Edge;
|
||||
|
||||
|
||||
typedef struct AF_PointRec_
|
||||
{
|
||||
AF_Flags flags; /* point flags used by hinter */
|
||||
FT_Pos ox, oy; /* original, scaled position */
|
||||
FT_Pos fx, fy; /* original, unscaled position (font units) */
|
||||
FT_Pos x, y; /* current position */
|
||||
FT_Pos u, v; /* current (x,y) or (y,x) depending on context */
|
||||
|
||||
AF_Direction in_dir; /* direction of inwards vector */
|
||||
AF_Direction out_dir; /* direction of outwards vector */
|
||||
|
||||
AF_Point next; /* next point in contour */
|
||||
AF_Point prev; /* previous point in contour */
|
||||
|
||||
} AF_PointRec;
|
||||
|
||||
|
||||
typedef struct AF_SegmentRec_
|
||||
{
|
||||
AF_Edge_Flags flags; /* edge/segment flags for this segment */
|
||||
AF_Direction dir; /* segment direction */
|
||||
FT_Pos pos; /* position of segment */
|
||||
FT_Pos min_coord; /* minimum coordinate of segment */
|
||||
FT_Pos max_coord; /* maximum coordinate of segment */
|
||||
|
||||
AF_Edge edge; /* the segment's parent edge */
|
||||
AF_Segment edge_next; /* link to next segment in parent edge */
|
||||
|
||||
AF_Segment link; /* (stem) link segment */
|
||||
AF_Segment serif; /* primary segment for serifs */
|
||||
FT_Pos num_linked; /* number of linked segments */
|
||||
FT_Pos score; /* used during stem matching */
|
||||
|
||||
AF_Point first; /* first point in edge segment */
|
||||
AF_Point last; /* last point in edge segment */
|
||||
AF_Point* contour; /* ptr to first point of segment's contour */
|
||||
|
||||
} AF_SegmentRec;
|
||||
|
||||
|
||||
typedef struct AF_EdgeRec_
|
||||
{
|
||||
FT_Pos fpos; /* original, unscaled position (font units) */
|
||||
FT_Pos opos; /* original, scaled position */
|
||||
FT_Pos pos; /* current position */
|
||||
|
||||
AF_Edge_Flags flags; /* edge flags */
|
||||
AF_Direction dir; /* edge direction */
|
||||
FT_Fixed scale; /* used to speed up interpolation between edges */
|
||||
AF_Width blue_edge; /* non-NULL if this is a blue edge */
|
||||
|
||||
AF_Edge link;
|
||||
AF_Edge serif;
|
||||
FT_Int num_linked;
|
||||
|
||||
FT_Int score;
|
||||
|
||||
AF_Segment first;
|
||||
AF_Segment last;
|
||||
|
||||
} AF_EdgeRec;
|
||||
|
||||
|
||||
typedef struct AF_AxisHintsRec_
|
||||
{
|
||||
FT_Int num_segments;
|
||||
AF_Segment segments;
|
||||
|
||||
FT_Int num_edges;
|
||||
AF_Edge edges;
|
||||
|
||||
AF_Direction major_dir;
|
||||
|
||||
} AF_AxisHintsRec, *AF_AxisHints;
|
||||
|
||||
|
||||
typedef struct AF_GlyphHintsRec_
|
||||
{
|
||||
FT_Memory memory;
|
||||
|
||||
FT_Fixed x_scale;
|
||||
FT_Pos x_delta;
|
||||
|
||||
FT_Fixed y_scale;
|
||||
FT_Pos y_delta;
|
||||
|
||||
FT_Pos edge_distance_threshold;
|
||||
|
||||
FT_Int max_points;
|
||||
FT_Int num_points;
|
||||
AF_Point points;
|
||||
|
||||
FT_Int max_contours;
|
||||
FT_Int num_contours;
|
||||
AF_Point* contours;
|
||||
|
||||
AF_AxisHintsRec axis[ AF_DIMENSION_MAX ];
|
||||
|
||||
FT_UInt32 scaler_flags; /* copy of scaler flags */
|
||||
FT_UInt32 other_flags; /* free for script-specific implementations */
|
||||
AF_ScriptMetrics metrics;
|
||||
|
||||
} AF_GlyphHintsRec;
|
||||
|
||||
|
||||
#define AF_HINTS_TEST_SCALER(h,f) ( (h)->scaler_flags & (f) )
|
||||
#define AF_HINTS_TEST_OTHER(h,f) ( (h)->other_flags & (f) )
|
||||
|
||||
#define AF_HINTS_DO_HORIZONTAL(h) \
|
||||
!AF_HINTS_TEST_SCALER(h,AF_SCALER_FLAG_NO_HORIZONTAL)
|
||||
|
||||
#define AF_HINTS_DO_VERTICAL(h) \
|
||||
!AF_HINTS_TEST_SCALER(h,AF_SCALER_FLAG_NO_VERTICAL)
|
||||
|
||||
#define AF_HINTS_DO_ADVANCE(h) \
|
||||
!AF_HINTS_TEST_SCALER(h,AF_SCALER_FLAG_NO_ADVANCE)
|
||||
|
||||
|
||||
FT_LOCAL( AF_Direction )
|
||||
af_direction_compute( FT_Pos dx,
|
||||
FT_Pos dy );
|
||||
|
||||
|
||||
FT_LOCAL( void )
|
||||
af_glyph_hints_init( AF_GlyphHints hints,
|
||||
FT_Memory memory );
|
||||
|
||||
|
||||
|
||||
/* recomputes all AF_Point in a AF_GlyphHints from the definitions
|
||||
* in a source outline
|
||||
*/
|
||||
FT_LOCAL( FT_Error )
|
||||
af_glyph_hints_reset( AF_GlyphHints hints,
|
||||
AF_Scaler scaler,
|
||||
AF_ScriptMetrics metrics,
|
||||
FT_Outline* outline );
|
||||
|
||||
FT_LOCAL( void )
|
||||
af_glyph_hints_save( AF_GlyphHints hints,
|
||||
FT_Outline* outline );
|
||||
|
||||
FT_LOCAL( void )
|
||||
af_glyph_hints_align_edge_points( AF_GlyphHints hints,
|
||||
AF_Dimension dim );
|
||||
|
||||
FT_LOCAL( void )
|
||||
af_glyph_hints_align_strong_points( AF_GlyphHints hints,
|
||||
AF_Dimension dim );
|
||||
|
||||
FT_LOCAL( void )
|
||||
af_glyph_hints_align_weak_points( AF_GlyphHints hints,
|
||||
AF_Dimension dim );
|
||||
|
||||
FT_LOCAL( void )
|
||||
af_glyph_hints_done( AF_GlyphHints hints );
|
||||
|
||||
/* */
|
||||
|
||||
FT_END_HEADER
|
||||
|
||||
#endif /* __AFHINTS_H__ */
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,441 +1,442 @@
|
|||
#include "afloader.h"
|
||||
#include "afhints.h"
|
||||
#include "afglobal.h"
|
||||
#include "aflatin.h"
|
||||
|
||||
FT_LOCAL_DEF( FT_Error )
|
||||
af_loader_init( AF_Loader loader,
|
||||
FT_Memory memory )
|
||||
{
|
||||
FT_Error error;
|
||||
|
||||
FT_ZERO( loader );
|
||||
|
||||
af_glyph_hints_init( &loader->hints, memory );
|
||||
|
||||
error = FT_GlyphLoader_New( memory, &loader->gloader );
|
||||
if ( !error )
|
||||
{
|
||||
error = FT_GlyphLoader_CreateExtra( loader->gloader );
|
||||
if ( error )
|
||||
{
|
||||
FT_GlyphLoader_Done( loader->gloader );
|
||||
loader->gloader = NULL;
|
||||
}
|
||||
}
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
FT_LOCAL_DEF( FT_Error )
|
||||
af_loader_reset( AF_Loader loader,
|
||||
FT_Face face )
|
||||
{
|
||||
FT_Error error = 0;
|
||||
|
||||
loader->face = face;
|
||||
loader->globals = (AF_FaceGlobals) face->autohint.data;
|
||||
|
||||
FT_GlyphLoader_Rewind( loader->gloader );
|
||||
|
||||
if ( loader->globals == NULL )
|
||||
{
|
||||
error = af_face_globals_new( face, &loader->globals );
|
||||
if ( !error )
|
||||
{
|
||||
face->autohint.data = (FT_Pointer) loader->globals;
|
||||
face->autohint.finalizer = (FT_Generic_Finalizer) af_face_globals_free;
|
||||
}
|
||||
}
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
FT_LOCAL_DEF( void )
|
||||
af_loader_done( AF_Loader loader )
|
||||
{
|
||||
loader->face = NULL;
|
||||
loader->globals = NULL;
|
||||
|
||||
FT_GlyphLoader_Done( loader->gloader );
|
||||
loader->gloader = NULL;
|
||||
}
|
||||
|
||||
|
||||
static FT_Error
|
||||
af_loader_load_g( AF_Loader loader,
|
||||
AF_Scaler scaler,
|
||||
FT_UInt glyph_index,
|
||||
FT_Int32 load_flags,
|
||||
FT_UInt depth )
|
||||
{
|
||||
FT_Error error = 0;
|
||||
FT_Face face = loader->face;
|
||||
AF_FaceGlobals globals = loader->globals;
|
||||
FT_GlyphLoader gloader = loader->gloader;
|
||||
AF_ScriptMetrics metrics = loader->metrics;
|
||||
AF_GlyphHints hints = &loader->hints;
|
||||
FT_GlyphSlot slot = face->glyph;
|
||||
FT_Slot_Internal internal = slot->internal;
|
||||
|
||||
error = FT_Load_Glyph( face, glyph_index, load_flags );
|
||||
if ( error )
|
||||
goto Exit;
|
||||
|
||||
loader->transformed = internal->glyph_transformed;
|
||||
if ( loader->transformed )
|
||||
{
|
||||
FT_Matrix inverse;
|
||||
|
||||
loader->trans_matrix = internal->glyph_matrix;
|
||||
loader->trans_delta = internal->glyph_delta;
|
||||
|
||||
inverse = loader->trans_matrix;
|
||||
FT_Matrix_Invert( &inverse );
|
||||
FT_Vector_Transform( &loader->trans_delta, &inverse );
|
||||
}
|
||||
|
||||
/* set linear metrics */
|
||||
slot->linearHoriAdvance = slot->metrics.horiAdvance;
|
||||
slot->linearVertAdvance = slot->metrics.vertAdvance;
|
||||
|
||||
switch ( slot->format )
|
||||
{
|
||||
case FT_GLYPH_FORMAT_OUTLINE:
|
||||
/* translate the loaded glyph when an internal transform
|
||||
* is needed
|
||||
*/
|
||||
if ( loader->transformed )
|
||||
{
|
||||
FT_Vector* point = slot->outline.points;
|
||||
FT_Vector* limit = point + slot->outline.n_points;
|
||||
|
||||
for ( ; point < limit; point++ )
|
||||
{
|
||||
point->x += loader->trans_delta.x;
|
||||
point->y += loader->trans_delta.y;
|
||||
}
|
||||
}
|
||||
|
||||
/* copy the outline points in the loader's current */
|
||||
/* extra points which is used to keep original glyph coordinates */
|
||||
error = FT_GlyphLoader_CheckPoints( gloader,
|
||||
slot->outline.n_points + 2,
|
||||
slot->outline.n_contours );
|
||||
if ( error )
|
||||
goto Exit;
|
||||
|
||||
FT_ARRAY_COPY( gloader->current.outline.points,
|
||||
slot->outline.points,
|
||||
slot->outline.n_points );
|
||||
|
||||
FT_ARRAY_COPY( gloader->current.extra_points,
|
||||
slot->outline.points,
|
||||
slot->outline.n_points );
|
||||
|
||||
FT_ARRAY_COPY( gloader->current.outline.contours,
|
||||
slot->outline.contours,
|
||||
slot->outline.n_contours );
|
||||
|
||||
FT_ARRAY_COPY( gloader->current.outline.tags,
|
||||
slot->outline.tags,
|
||||
slot->outline.n_points );
|
||||
|
||||
gloader->current.outline.n_points = slot->outline.n_points;
|
||||
gloader->current.outline.n_contours = slot->outline.n_contours;
|
||||
|
||||
/* compute original phantom points */
|
||||
loader->pp1.x = hints->x_delta;
|
||||
loader->pp1.y = hints->y_delta;
|
||||
loader->pp2.x = FT_MulFix( slot->metrics.horiAdvance,
|
||||
hints->x_scale ) + hints->x_delta;
|
||||
loader->pp2.y = hints->y_delta;
|
||||
|
||||
/* be sure to check for spacing glyphs */
|
||||
if ( slot->outline.n_points == 0 )
|
||||
goto Hint_Metrics;
|
||||
|
||||
/* now load the slot image into the auto-outline and run the */
|
||||
/* automatic hinting process */
|
||||
error = metrics->clazz->script_hints_init( hints,
|
||||
&gloader->current.outline,
|
||||
metrics );
|
||||
if ( error )
|
||||
goto Exit;
|
||||
|
||||
/* apply the hints */
|
||||
metrics->clazz->script_hints_apply( hints,
|
||||
&gloader->current.outline,
|
||||
metrics );
|
||||
/* we now need to hint the metrics according to the change in */
|
||||
/* width/positioning that occured during the hinting process */
|
||||
{
|
||||
FT_Pos old_advance, old_rsb, old_lsb, new_lsb;
|
||||
AF_AxisHints axis = &hints->axis[ AF_DIMENSION_HORZ ];
|
||||
AF_Edge edge1 = axis->edges; /* leftmost edge */
|
||||
AF_Edge edge2 = edge1 + axis->num_edges - 1; /* rightmost edge */
|
||||
|
||||
|
||||
old_advance = loader->pp2.x;
|
||||
old_rsb = old_advance - edge2->opos;
|
||||
old_lsb = edge1->opos;
|
||||
new_lsb = edge1->pos;
|
||||
|
||||
loader->pp1.x = FT_PIX_ROUND( new_lsb - old_lsb );
|
||||
loader->pp2.x = FT_PIX_ROUND( edge2->pos + old_rsb );
|
||||
|
||||
#if 0
|
||||
/* try to fix certain bad advance computations */
|
||||
if ( loader->pp2.x + loader->pp1.x == edge2->pos && old_rsb > 4 )
|
||||
loader->pp2.x += 64;
|
||||
#endif
|
||||
}
|
||||
|
||||
/* good, we simply add the glyph to our loader's base */
|
||||
FT_GlyphLoader_Add( gloader );
|
||||
break;
|
||||
|
||||
case FT_GLYPH_FORMAT_COMPOSITE:
|
||||
{
|
||||
FT_UInt nn, num_subglyphs = slot->num_subglyphs;
|
||||
FT_UInt num_base_subgs, start_point;
|
||||
FT_SubGlyph subglyph;
|
||||
|
||||
|
||||
start_point = gloader->base.outline.n_points;
|
||||
|
||||
/* first of all, copy the subglyph descriptors in the glyph loader */
|
||||
error = FT_GlyphLoader_CheckSubGlyphs( gloader, num_subglyphs );
|
||||
if ( error )
|
||||
goto Exit;
|
||||
|
||||
FT_ARRAY_COPY( gloader->current.subglyphs,
|
||||
slot->subglyphs,
|
||||
num_subglyphs );
|
||||
|
||||
gloader->current.num_subglyphs = num_subglyphs;
|
||||
num_base_subgs = gloader->base.num_subglyphs;
|
||||
|
||||
/* now, read each subglyph independently */
|
||||
for ( nn = 0; nn < num_subglyphs; nn++ )
|
||||
{
|
||||
FT_Vector pp1, pp2;
|
||||
FT_Pos x, y;
|
||||
FT_UInt num_points, num_new_points, num_base_points;
|
||||
|
||||
|
||||
/* gloader.current.subglyphs can change during glyph loading due */
|
||||
/* to re-allocation -- we must recompute the current subglyph on */
|
||||
/* each iteration */
|
||||
subglyph = gloader->base.subglyphs + num_base_subgs + nn;
|
||||
|
||||
pp1 = loader->pp1;
|
||||
pp2 = loader->pp2;
|
||||
|
||||
num_base_points = gloader->base.outline.n_points;
|
||||
|
||||
error = af_loader_load_g( loader, scaler, subglyph->index,
|
||||
load_flags, depth + 1 );
|
||||
if ( error )
|
||||
goto Exit;
|
||||
|
||||
/* recompute subglyph pointer */
|
||||
subglyph = gloader->base.subglyphs + num_base_subgs + nn;
|
||||
|
||||
if ( subglyph->flags & FT_SUBGLYPH_FLAG_USE_MY_METRICS )
|
||||
{
|
||||
pp1 = loader->pp1;
|
||||
pp2 = loader->pp2;
|
||||
}
|
||||
else
|
||||
{
|
||||
loader->pp1 = pp1;
|
||||
loader->pp2 = pp2;
|
||||
}
|
||||
|
||||
num_points = gloader->base.outline.n_points;
|
||||
num_new_points = num_points - num_base_points;
|
||||
|
||||
/* now perform the transform required for this subglyph */
|
||||
|
||||
if ( subglyph->flags & ( FT_SUBGLYPH_FLAG_SCALE |
|
||||
FT_SUBGLYPH_FLAG_XY_SCALE |
|
||||
FT_SUBGLYPH_FLAG_2X2 ) )
|
||||
{
|
||||
FT_Vector* cur = gloader->base.outline.points +
|
||||
num_base_points;
|
||||
FT_Vector* org = gloader->base.extra_points +
|
||||
num_base_points;
|
||||
FT_Vector* limit = cur + num_new_points;
|
||||
|
||||
|
||||
for ( ; cur < limit; cur++, org++ )
|
||||
{
|
||||
FT_Vector_Transform( cur, &subglyph->transform );
|
||||
FT_Vector_Transform( org, &subglyph->transform );
|
||||
}
|
||||
}
|
||||
|
||||
/* apply offset */
|
||||
|
||||
if ( !( subglyph->flags & FT_SUBGLYPH_FLAG_ARGS_ARE_XY_VALUES ) )
|
||||
{
|
||||
FT_Int k = subglyph->arg1;
|
||||
FT_UInt l = subglyph->arg2;
|
||||
FT_Vector* p1;
|
||||
FT_Vector* p2;
|
||||
|
||||
|
||||
if ( start_point + k >= num_base_points ||
|
||||
l >= (FT_UInt)num_new_points )
|
||||
{
|
||||
error = FT_Err_Invalid_Composite;
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
l += num_base_points;
|
||||
|
||||
/* for now, only use the current point coordinates; */
|
||||
/* we may consider another approach in the near future */
|
||||
p1 = gloader->base.outline.points + start_point + k;
|
||||
p2 = gloader->base.outline.points + start_point + l;
|
||||
|
||||
x = p1->x - p2->x;
|
||||
y = p1->y - p2->y;
|
||||
}
|
||||
else
|
||||
{
|
||||
x = FT_MulFix( subglyph->arg1, hints->x_scale ) + hints->x_delta;
|
||||
y = FT_MulFix( subglyph->arg2, hints->y_scale ) + hints->y_delta;
|
||||
|
||||
x = FT_PIX_ROUND(x);
|
||||
y = FT_PIX_ROUND(y);
|
||||
}
|
||||
|
||||
{
|
||||
FT_Outline dummy = gloader->base.outline;
|
||||
|
||||
|
||||
dummy.points += num_base_points;
|
||||
dummy.n_points = (short)num_new_points;
|
||||
|
||||
FT_Outline_Translate( &dummy, x, y );
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
/* we don't support other formats (yet?) */
|
||||
error = FT_Err_Unimplemented_Feature;
|
||||
}
|
||||
|
||||
Hint_Metrics:
|
||||
if ( depth == 0 )
|
||||
{
|
||||
FT_BBox bbox;
|
||||
|
||||
|
||||
/* transform the hinted outline if needed */
|
||||
if ( loader->transformed )
|
||||
FT_Outline_Transform( &gloader->base.outline, &loader->trans_matrix );
|
||||
|
||||
/* we must translate our final outline by -pp1.x and compute */
|
||||
/* the new metrics */
|
||||
if ( loader->pp1.x )
|
||||
FT_Outline_Translate( &gloader->base.outline, -loader->pp1.x, 0 );
|
||||
|
||||
FT_Outline_Get_CBox( &gloader->base.outline, &bbox );
|
||||
|
||||
bbox.xMin = FT_PIX_FLOOR( bbox.xMin );
|
||||
bbox.yMin = FT_PIX_FLOOR( bbox.yMin );
|
||||
bbox.xMax = FT_PIX_CEIL( bbox.xMax );
|
||||
bbox.yMax = FT_PIX_CEIL( bbox.yMax );
|
||||
|
||||
slot->metrics.width = bbox.xMax - bbox.xMin;
|
||||
slot->metrics.height = bbox.yMax - bbox.yMin;
|
||||
slot->metrics.horiBearingX = bbox.xMin;
|
||||
slot->metrics.horiBearingY = bbox.yMax;
|
||||
|
||||
/* for mono-width fonts (like Andale, Courier, etc.) we need */
|
||||
/* to keep the original rounded advance width */
|
||||
#if 0
|
||||
if ( !FT_IS_FIXED_WIDTH( slot->face ) )
|
||||
slot->metrics.horiAdvance = loader->pp2.x - loader->pp1.x;
|
||||
else
|
||||
slot->metrics.horiAdvance = FT_MulFix( slot->metrics.horiAdvance,
|
||||
x_scale );
|
||||
#else
|
||||
slot->metrics.horiAdvance = loader->pp2.x - loader->pp1.x;
|
||||
#endif
|
||||
|
||||
slot->metrics.horiAdvance = FT_PIX_ROUND( slot->metrics.horiAdvance );
|
||||
|
||||
/* now copy outline into glyph slot */
|
||||
FT_GlyphLoader_Rewind( internal->loader );
|
||||
error = FT_GlyphLoader_CopyPoints( internal->loader, gloader );
|
||||
if ( error )
|
||||
goto Exit;
|
||||
|
||||
slot->outline = internal->loader->base.outline;
|
||||
slot->format = FT_GLYPH_FORMAT_OUTLINE;
|
||||
}
|
||||
|
||||
#ifdef DEBUG_HINTER
|
||||
af_debug_hinter = hinter;
|
||||
#endif
|
||||
|
||||
Exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
FT_LOCAL_DEF( FT_Error )
|
||||
af_loader_load_glyph( AF_Loader loader,
|
||||
FT_Face face,
|
||||
FT_UInt gindex,
|
||||
FT_UInt32 load_flags )
|
||||
{
|
||||
FT_Error error;
|
||||
FT_Size size = face->size;
|
||||
AF_ScalerRec scaler;
|
||||
|
||||
if ( !size )
|
||||
return FT_Err_Invalid_Argument;
|
||||
|
||||
FT_ZERO( &scaler );
|
||||
|
||||
scaler.face = face;
|
||||
scaler.x_scale = size->metrics.x_scale;
|
||||
scaler.x_delta = 0; /* XXX: TODO: add support for sub-pixel hinting */
|
||||
scaler.y_scale = size->metrics.y_scale;
|
||||
scaler.y_delta = 0; /* XXX: TODO: add support for sub-pixel hinting */
|
||||
|
||||
scaler.render_mode = FT_LOAD_TARGET_MODE( load_flags );
|
||||
scaler.flags = 0; /* XXX: fix this */
|
||||
|
||||
error = af_loader_reset( loader, face );
|
||||
if ( !error )
|
||||
{
|
||||
AF_ScriptMetrics metrics;
|
||||
|
||||
error = af_face_globals_get_metrics( loader->globals, gindex, &metrics );
|
||||
if ( !error )
|
||||
{
|
||||
loader->metrics = metrics;
|
||||
|
||||
metrics->scaler = scaler;
|
||||
|
||||
if ( metrics->clazz->script_metrics_scale )
|
||||
metrics->clazz->script_metrics_scale( metrics, &scaler );
|
||||
|
||||
load_flags |= FT_LOAD_NO_SCALE | FT_LOAD_IGNORE_TRANSFORM;
|
||||
load_flags &= ~FT_LOAD_RENDER;
|
||||
|
||||
error = af_loader_load_g( loader, &scaler, gindex, load_flags, 0 );
|
||||
}
|
||||
}
|
||||
return error;
|
||||
}
|
||||
#include "afloader.h"
|
||||
#include "afhints.h"
|
||||
#include "afglobal.h"
|
||||
#include "aflatin.h"
|
||||
|
||||
FT_LOCAL_DEF( FT_Error )
|
||||
af_loader_init( AF_Loader loader,
|
||||
FT_Memory memory )
|
||||
{
|
||||
FT_Error error;
|
||||
|
||||
FT_ZERO( loader );
|
||||
|
||||
af_glyph_hints_init( &loader->hints, memory );
|
||||
|
||||
error = FT_GlyphLoader_New( memory, &loader->gloader );
|
||||
if ( !error )
|
||||
{
|
||||
error = FT_GlyphLoader_CreateExtra( loader->gloader );
|
||||
if ( error )
|
||||
{
|
||||
FT_GlyphLoader_Done( loader->gloader );
|
||||
loader->gloader = NULL;
|
||||
}
|
||||
}
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
FT_LOCAL_DEF( FT_Error )
|
||||
af_loader_reset( AF_Loader loader,
|
||||
FT_Face face )
|
||||
{
|
||||
FT_Error error = 0;
|
||||
|
||||
loader->face = face;
|
||||
loader->globals = (AF_FaceGlobals) face->autohint.data;
|
||||
|
||||
FT_GlyphLoader_Rewind( loader->gloader );
|
||||
|
||||
if ( loader->globals == NULL )
|
||||
{
|
||||
error = af_face_globals_new( face, &loader->globals );
|
||||
if ( !error )
|
||||
{
|
||||
face->autohint.data = (FT_Pointer) loader->globals;
|
||||
face->autohint.finalizer = (FT_Generic_Finalizer) af_face_globals_free;
|
||||
}
|
||||
}
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
FT_LOCAL_DEF( void )
|
||||
af_loader_done( AF_Loader loader )
|
||||
{
|
||||
loader->face = NULL;
|
||||
loader->globals = NULL;
|
||||
|
||||
FT_GlyphLoader_Done( loader->gloader );
|
||||
loader->gloader = NULL;
|
||||
}
|
||||
|
||||
|
||||
static FT_Error
|
||||
af_loader_load_g( AF_Loader loader,
|
||||
AF_Scaler scaler,
|
||||
FT_UInt glyph_index,
|
||||
FT_Int32 load_flags,
|
||||
FT_UInt depth )
|
||||
{
|
||||
FT_Error error = 0;
|
||||
FT_Face face = loader->face;
|
||||
AF_FaceGlobals globals = loader->globals;
|
||||
FT_GlyphLoader gloader = loader->gloader;
|
||||
AF_ScriptMetrics metrics = loader->metrics;
|
||||
AF_GlyphHints hints = &loader->hints;
|
||||
FT_GlyphSlot slot = face->glyph;
|
||||
FT_Slot_Internal internal = slot->internal;
|
||||
|
||||
error = FT_Load_Glyph( face, glyph_index, load_flags );
|
||||
if ( error )
|
||||
goto Exit;
|
||||
|
||||
loader->transformed = internal->glyph_transformed;
|
||||
if ( loader->transformed )
|
||||
{
|
||||
FT_Matrix inverse;
|
||||
|
||||
loader->trans_matrix = internal->glyph_matrix;
|
||||
loader->trans_delta = internal->glyph_delta;
|
||||
|
||||
inverse = loader->trans_matrix;
|
||||
FT_Matrix_Invert( &inverse );
|
||||
FT_Vector_Transform( &loader->trans_delta, &inverse );
|
||||
}
|
||||
|
||||
/* set linear metrics */
|
||||
slot->linearHoriAdvance = slot->metrics.horiAdvance;
|
||||
slot->linearVertAdvance = slot->metrics.vertAdvance;
|
||||
|
||||
switch ( slot->format )
|
||||
{
|
||||
case FT_GLYPH_FORMAT_OUTLINE:
|
||||
/* translate the loaded glyph when an internal transform
|
||||
* is needed
|
||||
*/
|
||||
if ( loader->transformed )
|
||||
{
|
||||
FT_Vector* point = slot->outline.points;
|
||||
FT_Vector* limit = point + slot->outline.n_points;
|
||||
|
||||
for ( ; point < limit; point++ )
|
||||
{
|
||||
point->x += loader->trans_delta.x;
|
||||
point->y += loader->trans_delta.y;
|
||||
}
|
||||
}
|
||||
|
||||
/* copy the outline points in the loader's current */
|
||||
/* extra points which is used to keep original glyph coordinates */
|
||||
error = FT_GlyphLoader_CheckPoints( gloader,
|
||||
slot->outline.n_points + 4,
|
||||
slot->outline.n_contours );
|
||||
if ( error )
|
||||
goto Exit;
|
||||
|
||||
FT_ARRAY_COPY( gloader->current.outline.points,
|
||||
slot->outline.points,
|
||||
slot->outline.n_points );
|
||||
|
||||
FT_ARRAY_COPY( gloader->current.extra_points,
|
||||
slot->outline.points,
|
||||
slot->outline.n_points );
|
||||
|
||||
FT_ARRAY_COPY( gloader->current.outline.contours,
|
||||
slot->outline.contours,
|
||||
slot->outline.n_contours );
|
||||
|
||||
FT_ARRAY_COPY( gloader->current.outline.tags,
|
||||
slot->outline.tags,
|
||||
slot->outline.n_points );
|
||||
|
||||
gloader->current.outline.n_points = slot->outline.n_points;
|
||||
gloader->current.outline.n_contours = slot->outline.n_contours;
|
||||
|
||||
/* compute original horizontal phantom points (and ignore */
|
||||
/* vertical ones) */
|
||||
loader->pp1.x = hints->x_delta;
|
||||
loader->pp1.y = hints->y_delta;
|
||||
loader->pp2.x = FT_MulFix( slot->metrics.horiAdvance,
|
||||
hints->x_scale ) + hints->x_delta;
|
||||
loader->pp2.y = hints->y_delta;
|
||||
|
||||
/* be sure to check for spacing glyphs */
|
||||
if ( slot->outline.n_points == 0 )
|
||||
goto Hint_Metrics;
|
||||
|
||||
/* now load the slot image into the auto-outline and run the */
|
||||
/* automatic hinting process */
|
||||
error = metrics->clazz->script_hints_init( hints,
|
||||
&gloader->current.outline,
|
||||
metrics );
|
||||
if ( error )
|
||||
goto Exit;
|
||||
|
||||
/* apply the hints */
|
||||
metrics->clazz->script_hints_apply( hints,
|
||||
&gloader->current.outline,
|
||||
metrics );
|
||||
/* we now need to hint the metrics according to the change in */
|
||||
/* width/positioning that occured during the hinting process */
|
||||
{
|
||||
FT_Pos old_advance, old_rsb, old_lsb, new_lsb;
|
||||
AF_AxisHints axis = &hints->axis[ AF_DIMENSION_HORZ ];
|
||||
AF_Edge edge1 = axis->edges; /* leftmost edge */
|
||||
AF_Edge edge2 = edge1 + axis->num_edges - 1; /* rightmost edge */
|
||||
|
||||
|
||||
old_advance = loader->pp2.x;
|
||||
old_rsb = old_advance - edge2->opos;
|
||||
old_lsb = edge1->opos;
|
||||
new_lsb = edge1->pos;
|
||||
|
||||
loader->pp1.x = FT_PIX_ROUND( new_lsb - old_lsb );
|
||||
loader->pp2.x = FT_PIX_ROUND( edge2->pos + old_rsb );
|
||||
|
||||
#if 0
|
||||
/* try to fix certain bad advance computations */
|
||||
if ( loader->pp2.x + loader->pp1.x == edge2->pos && old_rsb > 4 )
|
||||
loader->pp2.x += 64;
|
||||
#endif
|
||||
}
|
||||
|
||||
/* good, we simply add the glyph to our loader's base */
|
||||
FT_GlyphLoader_Add( gloader );
|
||||
break;
|
||||
|
||||
case FT_GLYPH_FORMAT_COMPOSITE:
|
||||
{
|
||||
FT_UInt nn, num_subglyphs = slot->num_subglyphs;
|
||||
FT_UInt num_base_subgs, start_point;
|
||||
FT_SubGlyph subglyph;
|
||||
|
||||
|
||||
start_point = gloader->base.outline.n_points;
|
||||
|
||||
/* first of all, copy the subglyph descriptors in the glyph loader */
|
||||
error = FT_GlyphLoader_CheckSubGlyphs( gloader, num_subglyphs );
|
||||
if ( error )
|
||||
goto Exit;
|
||||
|
||||
FT_ARRAY_COPY( gloader->current.subglyphs,
|
||||
slot->subglyphs,
|
||||
num_subglyphs );
|
||||
|
||||
gloader->current.num_subglyphs = num_subglyphs;
|
||||
num_base_subgs = gloader->base.num_subglyphs;
|
||||
|
||||
/* now, read each subglyph independently */
|
||||
for ( nn = 0; nn < num_subglyphs; nn++ )
|
||||
{
|
||||
FT_Vector pp1, pp2;
|
||||
FT_Pos x, y;
|
||||
FT_UInt num_points, num_new_points, num_base_points;
|
||||
|
||||
|
||||
/* gloader.current.subglyphs can change during glyph loading due */
|
||||
/* to re-allocation -- we must recompute the current subglyph on */
|
||||
/* each iteration */
|
||||
subglyph = gloader->base.subglyphs + num_base_subgs + nn;
|
||||
|
||||
pp1 = loader->pp1;
|
||||
pp2 = loader->pp2;
|
||||
|
||||
num_base_points = gloader->base.outline.n_points;
|
||||
|
||||
error = af_loader_load_g( loader, scaler, subglyph->index,
|
||||
load_flags, depth + 1 );
|
||||
if ( error )
|
||||
goto Exit;
|
||||
|
||||
/* recompute subglyph pointer */
|
||||
subglyph = gloader->base.subglyphs + num_base_subgs + nn;
|
||||
|
||||
if ( subglyph->flags & FT_SUBGLYPH_FLAG_USE_MY_METRICS )
|
||||
{
|
||||
pp1 = loader->pp1;
|
||||
pp2 = loader->pp2;
|
||||
}
|
||||
else
|
||||
{
|
||||
loader->pp1 = pp1;
|
||||
loader->pp2 = pp2;
|
||||
}
|
||||
|
||||
num_points = gloader->base.outline.n_points;
|
||||
num_new_points = num_points - num_base_points;
|
||||
|
||||
/* now perform the transform required for this subglyph */
|
||||
|
||||
if ( subglyph->flags & ( FT_SUBGLYPH_FLAG_SCALE |
|
||||
FT_SUBGLYPH_FLAG_XY_SCALE |
|
||||
FT_SUBGLYPH_FLAG_2X2 ) )
|
||||
{
|
||||
FT_Vector* cur = gloader->base.outline.points +
|
||||
num_base_points;
|
||||
FT_Vector* org = gloader->base.extra_points +
|
||||
num_base_points;
|
||||
FT_Vector* limit = cur + num_new_points;
|
||||
|
||||
|
||||
for ( ; cur < limit; cur++, org++ )
|
||||
{
|
||||
FT_Vector_Transform( cur, &subglyph->transform );
|
||||
FT_Vector_Transform( org, &subglyph->transform );
|
||||
}
|
||||
}
|
||||
|
||||
/* apply offset */
|
||||
|
||||
if ( !( subglyph->flags & FT_SUBGLYPH_FLAG_ARGS_ARE_XY_VALUES ) )
|
||||
{
|
||||
FT_Int k = subglyph->arg1;
|
||||
FT_UInt l = subglyph->arg2;
|
||||
FT_Vector* p1;
|
||||
FT_Vector* p2;
|
||||
|
||||
|
||||
if ( start_point + k >= num_base_points ||
|
||||
l >= (FT_UInt)num_new_points )
|
||||
{
|
||||
error = FT_Err_Invalid_Composite;
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
l += num_base_points;
|
||||
|
||||
/* for now, only use the current point coordinates; */
|
||||
/* we may consider another approach in the near future */
|
||||
p1 = gloader->base.outline.points + start_point + k;
|
||||
p2 = gloader->base.outline.points + start_point + l;
|
||||
|
||||
x = p1->x - p2->x;
|
||||
y = p1->y - p2->y;
|
||||
}
|
||||
else
|
||||
{
|
||||
x = FT_MulFix( subglyph->arg1, hints->x_scale ) + hints->x_delta;
|
||||
y = FT_MulFix( subglyph->arg2, hints->y_scale ) + hints->y_delta;
|
||||
|
||||
x = FT_PIX_ROUND(x);
|
||||
y = FT_PIX_ROUND(y);
|
||||
}
|
||||
|
||||
{
|
||||
FT_Outline dummy = gloader->base.outline;
|
||||
|
||||
|
||||
dummy.points += num_base_points;
|
||||
dummy.n_points = (short)num_new_points;
|
||||
|
||||
FT_Outline_Translate( &dummy, x, y );
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
/* we don't support other formats (yet?) */
|
||||
error = FT_Err_Unimplemented_Feature;
|
||||
}
|
||||
|
||||
Hint_Metrics:
|
||||
if ( depth == 0 )
|
||||
{
|
||||
FT_BBox bbox;
|
||||
|
||||
|
||||
/* transform the hinted outline if needed */
|
||||
if ( loader->transformed )
|
||||
FT_Outline_Transform( &gloader->base.outline, &loader->trans_matrix );
|
||||
|
||||
/* we must translate our final outline by -pp1.x and compute */
|
||||
/* the new metrics */
|
||||
if ( loader->pp1.x )
|
||||
FT_Outline_Translate( &gloader->base.outline, -loader->pp1.x, 0 );
|
||||
|
||||
FT_Outline_Get_CBox( &gloader->base.outline, &bbox );
|
||||
|
||||
bbox.xMin = FT_PIX_FLOOR( bbox.xMin );
|
||||
bbox.yMin = FT_PIX_FLOOR( bbox.yMin );
|
||||
bbox.xMax = FT_PIX_CEIL( bbox.xMax );
|
||||
bbox.yMax = FT_PIX_CEIL( bbox.yMax );
|
||||
|
||||
slot->metrics.width = bbox.xMax - bbox.xMin;
|
||||
slot->metrics.height = bbox.yMax - bbox.yMin;
|
||||
slot->metrics.horiBearingX = bbox.xMin;
|
||||
slot->metrics.horiBearingY = bbox.yMax;
|
||||
|
||||
/* for mono-width fonts (like Andale, Courier, etc.) we need */
|
||||
/* to keep the original rounded advance width */
|
||||
#if 0
|
||||
if ( !FT_IS_FIXED_WIDTH( slot->face ) )
|
||||
slot->metrics.horiAdvance = loader->pp2.x - loader->pp1.x;
|
||||
else
|
||||
slot->metrics.horiAdvance = FT_MulFix( slot->metrics.horiAdvance,
|
||||
x_scale );
|
||||
#else
|
||||
slot->metrics.horiAdvance = loader->pp2.x - loader->pp1.x;
|
||||
#endif
|
||||
|
||||
slot->metrics.horiAdvance = FT_PIX_ROUND( slot->metrics.horiAdvance );
|
||||
|
||||
/* now copy outline into glyph slot */
|
||||
FT_GlyphLoader_Rewind( internal->loader );
|
||||
error = FT_GlyphLoader_CopyPoints( internal->loader, gloader );
|
||||
if ( error )
|
||||
goto Exit;
|
||||
|
||||
slot->outline = internal->loader->base.outline;
|
||||
slot->format = FT_GLYPH_FORMAT_OUTLINE;
|
||||
}
|
||||
|
||||
#ifdef DEBUG_HINTER
|
||||
af_debug_hinter = hinter;
|
||||
#endif
|
||||
|
||||
Exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
FT_LOCAL_DEF( FT_Error )
|
||||
af_loader_load_glyph( AF_Loader loader,
|
||||
FT_Face face,
|
||||
FT_UInt gindex,
|
||||
FT_UInt32 load_flags )
|
||||
{
|
||||
FT_Error error;
|
||||
FT_Size size = face->size;
|
||||
AF_ScalerRec scaler;
|
||||
|
||||
if ( !size )
|
||||
return FT_Err_Invalid_Argument;
|
||||
|
||||
FT_ZERO( &scaler );
|
||||
|
||||
scaler.face = face;
|
||||
scaler.x_scale = size->metrics.x_scale;
|
||||
scaler.x_delta = 0; /* XXX: TODO: add support for sub-pixel hinting */
|
||||
scaler.y_scale = size->metrics.y_scale;
|
||||
scaler.y_delta = 0; /* XXX: TODO: add support for sub-pixel hinting */
|
||||
|
||||
scaler.render_mode = FT_LOAD_TARGET_MODE( load_flags );
|
||||
scaler.flags = 0; /* XXX: fix this */
|
||||
|
||||
error = af_loader_reset( loader, face );
|
||||
if ( !error )
|
||||
{
|
||||
AF_ScriptMetrics metrics;
|
||||
|
||||
error = af_face_globals_get_metrics( loader->globals, gindex, &metrics );
|
||||
if ( !error )
|
||||
{
|
||||
loader->metrics = metrics;
|
||||
|
||||
metrics->scaler = scaler;
|
||||
|
||||
if ( metrics->clazz->script_metrics_scale )
|
||||
metrics->clazz->script_metrics_scale( metrics, &scaler );
|
||||
|
||||
load_flags |= FT_LOAD_NO_SCALE | FT_LOAD_IGNORE_TRANSFORM;
|
||||
load_flags &= ~FT_LOAD_RENDER;
|
||||
|
||||
error = af_loader_load_g( loader, &scaler, gindex, load_flags, 0 );
|
||||
}
|
||||
}
|
||||
return error;
|
||||
}
|
||||
|
|
|
@ -18,6 +18,7 @@ FT_BEGIN_HEADER
|
|||
FT_Vector trans_delta;
|
||||
FT_Vector pp1;
|
||||
FT_Vector pp2;
|
||||
/* we don't handle vertical phantom points */
|
||||
|
||||
} AF_LoaderRec, *AF_Loader;
|
||||
|
||||
|
|
|
@ -1,268 +1,268 @@
|
|||
#ifndef __AFTYPES_H__
|
||||
#define __AFTYPES_H__
|
||||
|
||||
#include <ft2build.h>
|
||||
#include FT_FREETYPE_H
|
||||
#include FT_OUTLINE_H
|
||||
#include FT_INTERNAL_OBJECTS_H
|
||||
#include FT_INTERNAL_DEBUG_H
|
||||
|
||||
FT_BEGIN_HEADER
|
||||
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
/***** *****/
|
||||
/***** D E B U G G I N G *****/
|
||||
/***** *****/
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
|
||||
#define AF_DEBUG
|
||||
|
||||
#ifdef AF_DEBUG
|
||||
|
||||
# include <stdio.h>
|
||||
# define AF_LOG( x ) printf x
|
||||
|
||||
#else
|
||||
|
||||
# define AF_LOG( x ) do ; while ( 0 ) /* nothing */
|
||||
|
||||
#endif /* AF_DEBUG */
|
||||
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
/***** *****/
|
||||
/***** U T I L I T Y *****/
|
||||
/***** *****/
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
|
||||
typedef struct AF_WidthRec_
|
||||
{
|
||||
FT_Pos org; /* original position/width in font units */
|
||||
FT_Pos cur; /* current/scaled position/width in device sub-pixels */
|
||||
FT_Pos fit; /* current/fitted position/width in device sub-pixels */
|
||||
|
||||
} AF_WidthRec, *AF_Width;
|
||||
|
||||
|
||||
FT_LOCAL( void )
|
||||
af_sort_pos( FT_UInt count,
|
||||
FT_Pos* table );
|
||||
|
||||
FT_LOCAL( void )
|
||||
af_sort_widths( FT_UInt count,
|
||||
AF_Width widths );
|
||||
|
||||
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
/***** *****/
|
||||
/***** A N G L E T Y P E S *****/
|
||||
/***** *****/
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
|
||||
/*
|
||||
* Angle type. The auto-fitter doesn't need a very high angular accuracy,
|
||||
* and this allows us to speed up some computations considerably with a
|
||||
* light Cordic algorithm (see afangles.c)
|
||||
*
|
||||
*/
|
||||
|
||||
typedef FT_Int AF_Angle;
|
||||
|
||||
#define AF_ANGLE_PI 128
|
||||
#define AF_ANGLE_2PI (AF_ANGLE_PI*2)
|
||||
#define AF_ANGLE_PI2 (AF_ANGLE_PI/2)
|
||||
#define AF_ANGLE_PI4 (AF_ANGLE_PI/4)
|
||||
|
||||
/*
|
||||
* compute the angle of a given 2-D vector
|
||||
*
|
||||
*/
|
||||
FT_LOCAL( AF_Angle )
|
||||
af_angle_atan( FT_Pos dx,
|
||||
FT_Pos dy );
|
||||
|
||||
|
||||
/*
|
||||
* computes "angle2 - angle1", the result is always within
|
||||
* the range [ -AF_ANGLE_PI .. AF_ANGLE_PI-1 ]
|
||||
*
|
||||
*/
|
||||
FT_LOCAL( AF_Angle )
|
||||
af_angle_diff( AF_Angle angle1,
|
||||
AF_Angle angle2 );
|
||||
|
||||
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
/***** *****/
|
||||
/***** O U T L I N E S *****/
|
||||
/***** *****/
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
|
||||
/* opaque handle to glyph-specific hints. see "afhints.h" for more
|
||||
* details
|
||||
*/
|
||||
typedef struct AF_GlyphHintsRec_* AF_GlyphHints;
|
||||
|
||||
/* this structure is used to model an input glyph outline to
|
||||
* the auto-hinter. The latter will set the "hints" field
|
||||
* depending on the glyph's script
|
||||
*/
|
||||
typedef struct AF_OutlineRec_
|
||||
{
|
||||
FT_Face face;
|
||||
FT_Outline outline;
|
||||
FT_UInt outline_resolution;
|
||||
|
||||
FT_Int advance;
|
||||
FT_UInt metrics_resolution;
|
||||
|
||||
AF_GlyphHints hints;
|
||||
|
||||
} AF_OutlineRec;
|
||||
|
||||
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
/***** *****/
|
||||
/***** S C A L E R S *****/
|
||||
/***** *****/
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
|
||||
/*
|
||||
* A scaler models the target pixel device that will receive the
|
||||
* auto-hinted glyph image
|
||||
*
|
||||
*/
|
||||
|
||||
typedef enum
|
||||
{
|
||||
AF_SCALER_FLAG_NO_HORIZONTAL = 1, /* disable horizontal hinting */
|
||||
AF_SCALER_FLAG_NO_VERTICAL = 2, /* disable vertical hinting */
|
||||
AF_SCALER_FLAG_NO_ADVANCE = 4 /* disable advance hinting */
|
||||
|
||||
} AF_ScalerFlags;
|
||||
|
||||
|
||||
typedef struct AF_ScalerRec_
|
||||
{
|
||||
FT_Face face; /* source font face */
|
||||
FT_Fixed x_scale; /* from font units to 1/64th device pixels */
|
||||
FT_Fixed y_scale; /* from font units to 1/64th device pixels */
|
||||
FT_Pos x_delta; /* in 1/64th device pixels */
|
||||
FT_Pos y_delta; /* in 1/64th device pixels */
|
||||
FT_Render_Mode render_mode; /* monochrome, anti-aliased, LCD, etc.. */
|
||||
FT_UInt32 flags; /* additionnal control flags, see above */
|
||||
|
||||
} AF_ScalerRec, *AF_Scaler;
|
||||
|
||||
|
||||
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
/***** *****/
|
||||
/***** S C R I P T S *****/
|
||||
/***** *****/
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
|
||||
/*
|
||||
* the list of know scripts. Each different script correspond to the
|
||||
* following information:
|
||||
*
|
||||
* - a set of Unicode ranges to test weither the face supports the
|
||||
* script
|
||||
*
|
||||
* - a specific global analyzer that will compute global metrics
|
||||
* specific to the script.
|
||||
*
|
||||
* - a specific glyph analyzer that will compute segments and
|
||||
* edges for each glyph covered by the script
|
||||
*
|
||||
* - a specific grid-fitting algorithm that will distort the
|
||||
* scaled glyph outline according to the results of the glyph
|
||||
* analyzer
|
||||
*
|
||||
* note that a given analyzer and/or grid-fitting algorithm can be
|
||||
* used by more than one script
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
AF_SCRIPT_NONE = 0,
|
||||
AF_SCRIPT_LATIN = 1,
|
||||
/* add new scripts here. don't forget to update the list in "afglobal.c" */
|
||||
|
||||
AF_SCRIPT_MAX /* do not remove */
|
||||
|
||||
} AF_Script;
|
||||
|
||||
|
||||
|
||||
typedef struct AF_ScriptClassRec_ const* AF_ScriptClass;
|
||||
|
||||
typedef struct AF_ScriptMetricsRec_
|
||||
{
|
||||
AF_ScriptClass clazz;
|
||||
AF_ScalerRec scaler;
|
||||
|
||||
} AF_ScriptMetricsRec, *AF_ScriptMetrics;
|
||||
|
||||
|
||||
/* this function parses a FT_Face to compute global metrics for
|
||||
* a specific script
|
||||
*/
|
||||
typedef FT_Error (*AF_Script_InitMetricsFunc)( AF_ScriptMetrics metrics,
|
||||
FT_Face face );
|
||||
|
||||
typedef void (*AF_Script_ScaleMetricsFunc)( AF_ScriptMetrics metrics,
|
||||
AF_Scaler scaler );
|
||||
|
||||
typedef void (*AF_Script_DoneMetricsFunc)( AF_ScriptMetrics metrics );
|
||||
|
||||
|
||||
typedef FT_Error (*AF_Script_InitHintsFunc)( AF_GlyphHints hints,
|
||||
FT_Outline* outline,
|
||||
AF_ScriptMetrics metrics );
|
||||
|
||||
typedef void (*AF_Script_ApplyHintsFunc)( AF_GlyphHints hints,
|
||||
FT_Outline* outline,
|
||||
AF_ScriptMetrics metrics );
|
||||
|
||||
|
||||
typedef struct AF_Script_UniRangeRec_
|
||||
{
|
||||
FT_UInt32 first;
|
||||
FT_UInt32 last;
|
||||
|
||||
} AF_Script_UniRangeRec;
|
||||
|
||||
typedef const AF_Script_UniRangeRec * AF_Script_UniRange;
|
||||
|
||||
typedef struct AF_ScriptClassRec_
|
||||
{
|
||||
AF_Script script;
|
||||
AF_Script_UniRange script_uni_ranges; /* last must be { 0, 0 } */
|
||||
|
||||
FT_UInt script_metrics_size;
|
||||
AF_Script_InitMetricsFunc script_metrics_init;
|
||||
AF_Script_ScaleMetricsFunc script_metrics_scale;
|
||||
AF_Script_DoneMetricsFunc script_metrics_done;
|
||||
|
||||
AF_Script_InitHintsFunc script_hints_init;
|
||||
AF_Script_ApplyHintsFunc script_hints_apply;
|
||||
|
||||
} AF_ScriptClassRec;
|
||||
|
||||
|
||||
/* */
|
||||
|
||||
FT_END_HEADER
|
||||
|
||||
#endif /* __AFTYPES_H__ */
|
||||
#ifndef __AFTYPES_H__
|
||||
#define __AFTYPES_H__
|
||||
|
||||
#include <ft2build.h>
|
||||
#include FT_FREETYPE_H
|
||||
#include FT_OUTLINE_H
|
||||
#include FT_INTERNAL_OBJECTS_H
|
||||
#include FT_INTERNAL_DEBUG_H
|
||||
|
||||
FT_BEGIN_HEADER
|
||||
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
/***** *****/
|
||||
/***** D E B U G G I N G *****/
|
||||
/***** *****/
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
|
||||
#define AF_DEBUG
|
||||
|
||||
#ifdef AF_DEBUG
|
||||
|
||||
# include <stdio.h>
|
||||
# define AF_LOG( x ) printf x
|
||||
|
||||
#else
|
||||
|
||||
# define AF_LOG( x ) do ; while ( 0 ) /* nothing */
|
||||
|
||||
#endif /* AF_DEBUG */
|
||||
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
/***** *****/
|
||||
/***** U T I L I T Y *****/
|
||||
/***** *****/
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
|
||||
typedef struct AF_WidthRec_
|
||||
{
|
||||
FT_Pos org; /* original position/width in font units */
|
||||
FT_Pos cur; /* current/scaled position/width in device sub-pixels */
|
||||
FT_Pos fit; /* current/fitted position/width in device sub-pixels */
|
||||
|
||||
} AF_WidthRec, *AF_Width;
|
||||
|
||||
|
||||
FT_LOCAL( void )
|
||||
af_sort_pos( FT_UInt count,
|
||||
FT_Pos* table );
|
||||
|
||||
FT_LOCAL( void )
|
||||
af_sort_widths( FT_UInt count,
|
||||
AF_Width widths );
|
||||
|
||||
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
/***** *****/
|
||||
/***** A N G L E T Y P E S *****/
|
||||
/***** *****/
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
|
||||
/*
|
||||
* Angle type. The auto-fitter doesn't need a very high angular accuracy,
|
||||
* and this allows us to speed up some computations considerably with a
|
||||
* light Cordic algorithm (see afangles.c)
|
||||
*
|
||||
*/
|
||||
|
||||
typedef FT_Int AF_Angle;
|
||||
|
||||
#define AF_ANGLE_PI 128
|
||||
#define AF_ANGLE_2PI (AF_ANGLE_PI*2)
|
||||
#define AF_ANGLE_PI2 (AF_ANGLE_PI/2)
|
||||
#define AF_ANGLE_PI4 (AF_ANGLE_PI/4)
|
||||
|
||||
/*
|
||||
* compute the angle of a given 2-D vector
|
||||
*
|
||||
*/
|
||||
FT_LOCAL( AF_Angle )
|
||||
af_angle_atan( FT_Pos dx,
|
||||
FT_Pos dy );
|
||||
|
||||
|
||||
/*
|
||||
* computes "angle2 - angle1", the result is always within
|
||||
* the range [ -AF_ANGLE_PI .. AF_ANGLE_PI-1 ]
|
||||
*
|
||||
*/
|
||||
FT_LOCAL( AF_Angle )
|
||||
af_angle_diff( AF_Angle angle1,
|
||||
AF_Angle angle2 );
|
||||
|
||||
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
/***** *****/
|
||||
/***** O U T L I N E S *****/
|
||||
/***** *****/
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
|
||||
/* opaque handle to glyph-specific hints. see "afhints.h" for more
|
||||
* details
|
||||
*/
|
||||
typedef struct AF_GlyphHintsRec_* AF_GlyphHints;
|
||||
|
||||
/* this structure is used to model an input glyph outline to
|
||||
* the auto-hinter. The latter will set the "hints" field
|
||||
* depending on the glyph's script
|
||||
*/
|
||||
typedef struct AF_OutlineRec_
|
||||
{
|
||||
FT_Face face;
|
||||
FT_Outline outline;
|
||||
FT_UInt outline_resolution;
|
||||
|
||||
FT_Int advance;
|
||||
FT_UInt metrics_resolution;
|
||||
|
||||
AF_GlyphHints hints;
|
||||
|
||||
} AF_OutlineRec;
|
||||
|
||||
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
/***** *****/
|
||||
/***** S C A L E R S *****/
|
||||
/***** *****/
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
|
||||
/*
|
||||
* A scaler models the target pixel device that will receive the
|
||||
* auto-hinted glyph image
|
||||
*
|
||||
*/
|
||||
|
||||
typedef enum
|
||||
{
|
||||
AF_SCALER_FLAG_NO_HORIZONTAL = 1, /* disable horizontal hinting */
|
||||
AF_SCALER_FLAG_NO_VERTICAL = 2, /* disable vertical hinting */
|
||||
AF_SCALER_FLAG_NO_ADVANCE = 4 /* disable advance hinting */
|
||||
|
||||
} AF_ScalerFlags;
|
||||
|
||||
|
||||
typedef struct AF_ScalerRec_
|
||||
{
|
||||
FT_Face face; /* source font face */
|
||||
FT_Fixed x_scale; /* from font units to 1/64th device pixels */
|
||||
FT_Fixed y_scale; /* from font units to 1/64th device pixels */
|
||||
FT_Pos x_delta; /* in 1/64th device pixels */
|
||||
FT_Pos y_delta; /* in 1/64th device pixels */
|
||||
FT_Render_Mode render_mode; /* monochrome, anti-aliased, LCD, etc.. */
|
||||
FT_UInt32 flags; /* additionnal control flags, see above */
|
||||
|
||||
} AF_ScalerRec, *AF_Scaler;
|
||||
|
||||
|
||||
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
/***** *****/
|
||||
/***** S C R I P T S *****/
|
||||
/***** *****/
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
|
||||
/*
|
||||
* the list of know scripts. Each different script correspond to the
|
||||
* following information:
|
||||
*
|
||||
* - a set of Unicode ranges to test weither the face supports the
|
||||
* script
|
||||
*
|
||||
* - a specific global analyzer that will compute global metrics
|
||||
* specific to the script.
|
||||
*
|
||||
* - a specific glyph analyzer that will compute segments and
|
||||
* edges for each glyph covered by the script
|
||||
*
|
||||
* - a specific grid-fitting algorithm that will distort the
|
||||
* scaled glyph outline according to the results of the glyph
|
||||
* analyzer
|
||||
*
|
||||
* note that a given analyzer and/or grid-fitting algorithm can be
|
||||
* used by more than one script
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
AF_SCRIPT_NONE = 0,
|
||||
AF_SCRIPT_LATIN = 1,
|
||||
/* add new scripts here. don't forget to update the list in "afglobal.c" */
|
||||
|
||||
AF_SCRIPT_MAX /* do not remove */
|
||||
|
||||
} AF_Script;
|
||||
|
||||
|
||||
|
||||
typedef struct AF_ScriptClassRec_ const* AF_ScriptClass;
|
||||
|
||||
typedef struct AF_ScriptMetricsRec_
|
||||
{
|
||||
AF_ScriptClass clazz;
|
||||
AF_ScalerRec scaler;
|
||||
|
||||
} AF_ScriptMetricsRec, *AF_ScriptMetrics;
|
||||
|
||||
|
||||
/* this function parses a FT_Face to compute global metrics for
|
||||
* a specific script
|
||||
*/
|
||||
typedef FT_Error (*AF_Script_InitMetricsFunc)( AF_ScriptMetrics metrics,
|
||||
FT_Face face );
|
||||
|
||||
typedef void (*AF_Script_ScaleMetricsFunc)( AF_ScriptMetrics metrics,
|
||||
AF_Scaler scaler );
|
||||
|
||||
typedef void (*AF_Script_DoneMetricsFunc)( AF_ScriptMetrics metrics );
|
||||
|
||||
|
||||
typedef FT_Error (*AF_Script_InitHintsFunc)( AF_GlyphHints hints,
|
||||
FT_Outline* outline,
|
||||
AF_ScriptMetrics metrics );
|
||||
|
||||
typedef void (*AF_Script_ApplyHintsFunc)( AF_GlyphHints hints,
|
||||
FT_Outline* outline,
|
||||
AF_ScriptMetrics metrics );
|
||||
|
||||
|
||||
typedef struct AF_Script_UniRangeRec_
|
||||
{
|
||||
FT_UInt32 first;
|
||||
FT_UInt32 last;
|
||||
|
||||
} AF_Script_UniRangeRec;
|
||||
|
||||
typedef const AF_Script_UniRangeRec * AF_Script_UniRange;
|
||||
|
||||
typedef struct AF_ScriptClassRec_
|
||||
{
|
||||
AF_Script script;
|
||||
AF_Script_UniRange script_uni_ranges; /* last must be { 0, 0 } */
|
||||
|
||||
FT_UInt script_metrics_size;
|
||||
AF_Script_InitMetricsFunc script_metrics_init;
|
||||
AF_Script_ScaleMetricsFunc script_metrics_scale;
|
||||
AF_Script_DoneMetricsFunc script_metrics_done;
|
||||
|
||||
AF_Script_InitHintsFunc script_hints_init;
|
||||
AF_Script_ApplyHintsFunc script_hints_apply;
|
||||
|
||||
} AF_ScriptClassRec;
|
||||
|
||||
|
||||
/* */
|
||||
|
||||
FT_END_HEADER
|
||||
|
||||
#endif /* __AFTYPES_H__ */
|
||||
|
|
|
@ -435,7 +435,7 @@
|
|||
/* */
|
||||
if ( num_points + 2 > outline->max_points )
|
||||
{
|
||||
FT_Int news = FT_PAD_CEIL( num_points, 8 );
|
||||
FT_Int news = FT_PAD_CEIL( num_points + 2, 8 );
|
||||
FT_Int max = outline->max_points;
|
||||
|
||||
|
||||
|
|
|
@ -1489,7 +1489,7 @@
|
|||
|
||||
/* copy the outline points in the loader's current */
|
||||
/* extra points which is used to keep original glyph coordinates */
|
||||
error = ah_loader_check_points( gloader, slot->outline.n_points + 2,
|
||||
error = ah_loader_check_points( gloader, slot->outline.n_points + 4,
|
||||
slot->outline.n_contours );
|
||||
if ( error )
|
||||
goto Exit;
|
||||
|
@ -1506,7 +1506,7 @@
|
|||
gloader->current.outline.n_points = slot->outline.n_points;
|
||||
gloader->current.outline.n_contours = slot->outline.n_contours;
|
||||
|
||||
/* compute original phantom points */
|
||||
/* compute original horizontal phantom points, ignoring vertical ones */
|
||||
hinter->pp1.x = 0;
|
||||
hinter->pp1.y = 0;
|
||||
hinter->pp2.x = FT_MulFix( slot->metrics.horiAdvance, x_scale );
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
/* General types and definitions for the auto-hint module */
|
||||
/* (specification only). */
|
||||
/* */
|
||||
/* Copyright 2000-2001, 2002, 2003 Catharon Productions Inc. */
|
||||
/* Copyright 2000-2001, 2002, 2003, 2004 Catharon Productions Inc. */
|
||||
/* Author: David Turner */
|
||||
/* */
|
||||
/* This file is part of the Catharon Typography Project and shall only */
|
||||
|
@ -492,8 +492,9 @@ FT_BEGIN_HEADER
|
|||
AH_Outline glyph;
|
||||
|
||||
AH_Loader loader;
|
||||
FT_Vector pp1;
|
||||
FT_Vector pp1; /* horizontal phantom points */
|
||||
FT_Vector pp2;
|
||||
/* we ignore vertical phantom points */
|
||||
|
||||
FT_Bool transformed;
|
||||
FT_Vector trans_delta;
|
||||
|
|
|
@ -162,6 +162,57 @@
|
|||
}
|
||||
|
||||
|
||||
/*************************************************************************/
|
||||
/* */
|
||||
/* Returns the vertical metrics in font units for a given glyph. */
|
||||
/* Greg Hitchcock from Microsoft told us that if there were no `vmtx' */
|
||||
/* table, typoAscender/Descender from the `OS/2' table would be used */
|
||||
/* instead, and if there were no `OS/2' table, use ascender/descender */
|
||||
/* from the `hhea' table. But that is not what Microsoft's rasterizer */
|
||||
/* apparently does: It uses the ppem value as the advance height, and */
|
||||
/* sets the top side bearing to be zero. */
|
||||
/* */
|
||||
/* The monospace `check' is probably not meaningful here, but we leave */
|
||||
/* it in for a consistent interface. */
|
||||
/* */
|
||||
static void
|
||||
Get_VMetrics( TT_Face face,
|
||||
FT_UInt idx,
|
||||
FT_Bool check,
|
||||
FT_Short* tsb,
|
||||
FT_UShort* ah )
|
||||
{
|
||||
FT_UNUSED( check );
|
||||
|
||||
if ( face->vertical_info )
|
||||
TT_Get_Metrics( (TT_HoriHeader *)&face->vertical, idx, tsb, ah );
|
||||
|
||||
#if 1 /* Emperically determined, at variance with what MS said */
|
||||
|
||||
else
|
||||
{
|
||||
*tsb = 0;
|
||||
*ah = face->root.units_per_EM;
|
||||
}
|
||||
|
||||
#else /* This is what MS said to do. It isn't what they do, however. */
|
||||
|
||||
else if ( face->os2.version != 0xFFFFU )
|
||||
{
|
||||
*tsb = face->os2.sTypoAscender;
|
||||
*ah = face->os2.sTypoAscender - face->os2.sTypoDescender;
|
||||
}
|
||||
else
|
||||
{
|
||||
*tsb = face->horizontal.Ascender;
|
||||
*ah = face->horizontal.Ascender - face->horizontal.Descender;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
|
||||
#define cur_to_org( n, zone ) \
|
||||
FT_ARRAY_COPY( (zone)->org, (zone)->cur, (n) )
|
||||
|
||||
|
@ -317,7 +368,7 @@
|
|||
if ( n_contours > 0 )
|
||||
n_points = cont[-1] + 1;
|
||||
|
||||
error = FT_GlyphLoader_CheckPoints( gloader, n_points + 2, 0 );
|
||||
error = FT_GlyphLoader_CheckPoints( gloader, n_points + 4, 0 );
|
||||
if ( error )
|
||||
goto Fail;
|
||||
|
||||
|
@ -635,12 +686,16 @@
|
|||
|
||||
/* add shadow points */
|
||||
|
||||
/* Now add the two shadow points at n and n + 1. */
|
||||
/* Add two horizontal shadow points at n and n+1. */
|
||||
/* We need the left side bearing and advance width. */
|
||||
/* Add two vertical shadow points at n+2 and n+3. */
|
||||
/* We need the top side bearing and advance height. */
|
||||
|
||||
{
|
||||
FT_Vector* pp1;
|
||||
FT_Vector* pp2;
|
||||
FT_Vector* pp3;
|
||||
FT_Vector* pp4;
|
||||
|
||||
|
||||
/* pp1 = xMin - lsb */
|
||||
|
@ -653,14 +708,26 @@
|
|||
pp2->x = pp1->x + load->advance;
|
||||
pp2->y = 0;
|
||||
|
||||
/* pp3 = top side bearing */
|
||||
pp3 = pp1 + 2;
|
||||
pp3->x = 0;
|
||||
pp3->y = load->top_bearing + load->bbox.yMax;
|
||||
|
||||
/* pp4 = pp3 - ah */
|
||||
pp4 = pp1 + 3;
|
||||
pp4->x = 0;
|
||||
pp4->y = pp3->y - load->vadvance;
|
||||
|
||||
outline->tags[n_points ] = 0;
|
||||
outline->tags[n_points + 1] = 0;
|
||||
outline->tags[n_points + 2] = 0;
|
||||
outline->tags[n_points + 3] = 0;
|
||||
}
|
||||
|
||||
/* Note that we return two more points that are not */
|
||||
/* part of the glyph outline. */
|
||||
|
||||
n_points += 2;
|
||||
n_points += 4;
|
||||
|
||||
/* set up zone for hinting */
|
||||
tt_prepare_zone( zone, &gloader->current, 0, 0 );
|
||||
|
@ -687,15 +754,18 @@
|
|||
/* eventually hint the glyph */
|
||||
if ( IS_HINTED( load->load_flags ) )
|
||||
{
|
||||
FT_Pos x = zone->org[n_points-2].x;
|
||||
FT_Pos x = zone->org[n_points-4].x;
|
||||
FT_Pos y = zone->org[n_points-2].y;
|
||||
|
||||
|
||||
x = FT_PIX_ROUND( x ) - x;
|
||||
translate_array( n_points, zone->org, x, 0 );
|
||||
y = FT_PIX_ROUND( y ) - y;
|
||||
translate_array( n_points, zone->org, x, y );
|
||||
|
||||
org_to_cur( n_points, zone );
|
||||
|
||||
zone->cur[n_points - 1].x = FT_PIX_ROUND( zone->cur[n_points - 1].x );
|
||||
zone->cur[n_points - 3].x = FT_PIX_ROUND( zone->cur[n_points - 3].x );
|
||||
zone->cur[n_points - 1].y = FT_PIX_ROUND( zone->cur[n_points - 1].y );
|
||||
|
||||
#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER
|
||||
|
||||
|
@ -711,7 +781,7 @@
|
|||
load->exec->pedantic_hinting = (FT_Bool)( load->load_flags &
|
||||
FT_LOAD_PEDANTIC );
|
||||
load->exec->pts = *zone;
|
||||
load->exec->pts.n_points += 2;
|
||||
load->exec->pts.n_points += 4;
|
||||
|
||||
error = TT_Run_Context( load->exec, debug );
|
||||
if ( error && load->exec->pedantic_hinting )
|
||||
|
@ -727,8 +797,10 @@
|
|||
/* save glyph phantom points */
|
||||
if ( !load->preserve_pps )
|
||||
{
|
||||
load->pp1 = zone->cur[n_points - 2];
|
||||
load->pp2 = zone->cur[n_points - 1];
|
||||
load->pp1 = zone->cur[n_points - 4];
|
||||
load->pp2 = zone->cur[n_points - 3];
|
||||
load->pp3 = zone->cur[n_points - 2];
|
||||
load->pp4 = zone->cur[n_points - 1];
|
||||
}
|
||||
|
||||
#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER
|
||||
|
@ -797,16 +869,22 @@
|
|||
y_scale = loader->size->metrics.y_scale;
|
||||
}
|
||||
|
||||
/* get horizontal metrics */
|
||||
/* get metrics, horizontal and vertical */
|
||||
{
|
||||
FT_Short left_bearing = 0;
|
||||
FT_UShort advance_width = 0;
|
||||
FT_Short left_bearing = 0, top_bearing = 0;
|
||||
FT_UShort advance_width = 0, advance_height = 0;
|
||||
|
||||
|
||||
Get_HMetrics( face, glyph_index,
|
||||
(FT_Bool)!( loader->load_flags &
|
||||
FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH ),
|
||||
&left_bearing,
|
||||
&advance_width );
|
||||
Get_VMetrics( face, glyph_index,
|
||||
(FT_Bool)!( loader->load_flags &
|
||||
FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH ),
|
||||
&top_bearing,
|
||||
&advance_height );
|
||||
|
||||
#ifdef FT_CONFIG_OPTION_INCREMENTAL
|
||||
|
||||
|
@ -830,10 +908,33 @@
|
|||
advance_width = (FT_UShort)metrics.advance;
|
||||
}
|
||||
|
||||
# if 0
|
||||
/* GWW: Do I do the same for vertical metrics ??? */
|
||||
if ( face->root.internal->incremental_interface &&
|
||||
face->root.internal->incremental_interface->funcs->get_glyph_metrics )
|
||||
{
|
||||
FT_Incremental_MetricsRec metrics;
|
||||
|
||||
|
||||
metrics.bearing_x = 0;
|
||||
metrics.bearing_y = top_bearing;
|
||||
metrics.advance = advance_height;
|
||||
error = face->root.internal->incremental_interface->funcs->get_glyph_metrics(
|
||||
face->root.internal->incremental_interface->object,
|
||||
glyph_index, TRUE, &metrics );
|
||||
if ( error )
|
||||
goto Exit;
|
||||
top_bearing = (FT_Short)metrics.bearing_y;
|
||||
advance_height = (FT_UShort)metrics.advance;
|
||||
}
|
||||
# endif
|
||||
|
||||
#endif /* FT_CONFIG_OPTION_INCREMENTAL */
|
||||
|
||||
loader->left_bearing = left_bearing;
|
||||
loader->advance = advance_width;
|
||||
loader->top_bearing = top_bearing;
|
||||
loader->vadvance = advance_height;
|
||||
|
||||
if ( !loader->linear_def )
|
||||
{
|
||||
|
@ -893,9 +994,14 @@
|
|||
|
||||
loader->pp1.x = 0;
|
||||
loader->pp2.x = loader->advance;
|
||||
loader->pp3.y = 0;
|
||||
loader->pp4.y = loader->pp3.y-loader->vadvance;
|
||||
|
||||
if ( ( loader->load_flags & FT_LOAD_NO_SCALE ) == 0 )
|
||||
{
|
||||
loader->pp2.x = FT_MulFix( loader->pp2.x, x_scale );
|
||||
loader->pp4.y = FT_MulFix( loader->pp4.y, y_scale );
|
||||
}
|
||||
|
||||
#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER
|
||||
|
||||
|
@ -933,10 +1039,17 @@
|
|||
loader->pp2.x = loader->pp1.x + loader->advance;
|
||||
loader->pp2.y = 0;
|
||||
|
||||
loader->pp3.x = 0;
|
||||
loader->pp3.y = loader->top_bearing + loader->bbox.yMax;
|
||||
loader->pp4.x = 0;
|
||||
loader->pp4.y = loader->pp3.y - loader->vadvance;
|
||||
|
||||
if ( ( loader->load_flags & FT_LOAD_NO_SCALE ) == 0 )
|
||||
{
|
||||
loader->pp1.x = FT_MulFix( loader->pp1.x, x_scale );
|
||||
loader->pp2.x = FT_MulFix( loader->pp2.x, x_scale );
|
||||
loader->pp3.y = FT_MulFix( loader->pp3.y, y_scale );
|
||||
loader->pp4.y = FT_MulFix( loader->pp4.y, y_scale );
|
||||
}
|
||||
|
||||
/***********************************************************************/
|
||||
|
@ -1045,7 +1158,7 @@
|
|||
|
||||
for ( n = 0; n < (FT_Int)num_subglyphs; n++ )
|
||||
{
|
||||
FT_Vector pp1, pp2;
|
||||
FT_Vector pp1, pp2, pp3, pp4;
|
||||
FT_Pos x, y;
|
||||
|
||||
|
||||
|
@ -1057,6 +1170,8 @@
|
|||
|
||||
pp1 = loader->pp1;
|
||||
pp2 = loader->pp2;
|
||||
pp3 = loader->pp3;
|
||||
pp4 = loader->pp4;
|
||||
|
||||
num_base_points = gloader->base.outline.n_points;
|
||||
|
||||
|
@ -1072,11 +1187,15 @@
|
|||
{
|
||||
pp1 = loader->pp1;
|
||||
pp2 = loader->pp2;
|
||||
pp3 = loader->pp3;
|
||||
pp4 = loader->pp4;
|
||||
}
|
||||
else
|
||||
{
|
||||
loader->pp1 = pp1;
|
||||
loader->pp2 = pp2;
|
||||
loader->pp3 = pp3;
|
||||
loader->pp4 = pp4;
|
||||
}
|
||||
|
||||
num_points = gloader->base.outline.n_points;
|
||||
|
@ -1273,7 +1392,7 @@
|
|||
if ( error )
|
||||
goto Fail;
|
||||
|
||||
error = FT_GlyphLoader_CheckPoints( gloader, num_points + 2, 0 );
|
||||
error = FT_GlyphLoader_CheckPoints( gloader, num_points + 4, 0 );
|
||||
if ( error )
|
||||
goto Fail;
|
||||
|
||||
|
@ -1282,22 +1401,28 @@
|
|||
start_point, start_contour );
|
||||
pts = &exec->pts;
|
||||
|
||||
pts->n_points = (short)(num_points + 2);
|
||||
pts->n_points = (short)( num_points + 4 );
|
||||
pts->n_contours = gloader->base.outline.n_contours;
|
||||
|
||||
/* add phantom points */
|
||||
pp1 = pts->cur + num_points;
|
||||
pp1[0] = loader->pp1;
|
||||
pp1[1] = loader->pp2;
|
||||
pp1[2] = loader->pp3;
|
||||
pp1[3] = loader->pp4;
|
||||
|
||||
pts->tags[num_points ] = 0;
|
||||
pts->tags[num_points + 1] = 0;
|
||||
pts->tags[num_points + 2] = 0;
|
||||
pts->tags[num_points + 3] = 0;
|
||||
|
||||
/* if hinting, round the phantom points */
|
||||
if ( IS_HINTED( loader->load_flags ) )
|
||||
{
|
||||
pp1[0].x = FT_PIX_ROUND( loader->pp1.x );
|
||||
pp1[1].x = FT_PIX_ROUND( loader->pp2.x );
|
||||
pp1[2].y = FT_PIX_ROUND( loader->pp3.y );
|
||||
pp1[3].y = FT_PIX_ROUND( loader->pp4.y );
|
||||
}
|
||||
|
||||
{
|
||||
|
@ -1308,7 +1433,7 @@
|
|||
pts->tags[k] &= FT_CURVE_TAG_ON;
|
||||
}
|
||||
|
||||
cur_to_org( num_points + 2, pts );
|
||||
cur_to_org( num_points + 4, pts );
|
||||
|
||||
/* now consider hinting */
|
||||
if ( IS_HINTED( loader->load_flags ) && n_ins > 0 )
|
||||
|
@ -1324,6 +1449,8 @@
|
|||
/* save glyph origin and advance points */
|
||||
loader->pp1 = pp1[0];
|
||||
loader->pp2 = pp1[1];
|
||||
loader->pp3 = pp1[2];
|
||||
loader->pp4 = pp1[3];
|
||||
}
|
||||
|
||||
#endif /* TT_CONFIG_OPTION_BYTECODE_INTERPRETER */
|
||||
|
@ -1443,13 +1570,9 @@
|
|||
if ( face->vertical_info &&
|
||||
face->vertical.number_Of_VMetrics > 0 )
|
||||
{
|
||||
/* Don't assume that both the vertical header and vertical */
|
||||
/* metrics are present in the same font :-) */
|
||||
advance_height = loader->pp4.y - loader->pp3.y;
|
||||
top_bearing = loader->pp3.y - bbox.yMax;
|
||||
|
||||
TT_Get_Metrics( (TT_HoriHeader*)&face->vertical,
|
||||
glyph_index,
|
||||
&top_bearing,
|
||||
&advance_height );
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1465,6 +1588,12 @@
|
|||
/* here with: */
|
||||
/* ascender - descender + linegap */
|
||||
/* */
|
||||
/* NOTE3: This is different from what MS's rasterizer */
|
||||
/* appears to do when getting default values */
|
||||
/* for the vertical phantom points. We leave */
|
||||
/* the old code untouched, but relying on */
|
||||
/* phantom points alone might be reasonable */
|
||||
/* (i.e., removing the `if' above). */
|
||||
if ( face->os2.version != 0xFFFFU )
|
||||
{
|
||||
top_bearing = (FT_Short)( face->os2.sTypoLineGap / 2 );
|
||||
|
@ -1507,6 +1636,8 @@
|
|||
advance_height = (FT_UShort)metrics.advance;
|
||||
}
|
||||
|
||||
/* GWW: Do vertical metrics get loaded incrementally too? */
|
||||
|
||||
#endif /* FT_CONFIG_OPTION_INCREMENTAL */
|
||||
|
||||
/* We must adjust the top_bearing value from the bounding box given */
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
/* */
|
||||
/* Objects manager (specification). */
|
||||
/* */
|
||||
/* Copyright 1996-2001, 2002, 2003 by */
|
||||
/* Copyright 1996-2001, 2002, 2003, 2004 by */
|
||||
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
|
||||
/* */
|
||||
/* This file is part of the FreeType project, and may only be used, */
|
||||
|
@ -216,7 +216,8 @@ FT_BEGIN_HEADER
|
|||
|
||||
TT_Transform transform; /* transformation matrix */
|
||||
|
||||
FT_Vector pp1, pp2; /* phantom points */
|
||||
FT_Vector pp1, pp2; /* phantom points (horizontal) */
|
||||
FT_Vector pp3, pp4; /* phantom points (vertical) */
|
||||
|
||||
} TT_SubGlyphRec, *TT_SubGlyph_Stack;
|
||||
|
||||
|
|
Loading…
Reference in New Issue