Postscript hinter advances
This commit is contained in:
parent
604d2579ad
commit
65c39c2bb5
|
@ -166,12 +166,15 @@ FT_BEGIN_HEADER
|
||||||
/* glyph_delta :: The 2d translation vector corresponding to */
|
/* glyph_delta :: The 2d translation vector corresponding to */
|
||||||
/* the glyph transformation, if necessary. */
|
/* the glyph transformation, if necessary. */
|
||||||
/* */
|
/* */
|
||||||
|
/* glyph_hints :: format-specific glyph hints management */
|
||||||
|
/* */
|
||||||
typedef struct FT_Slot_InternalRec_
|
typedef struct FT_Slot_InternalRec_
|
||||||
{
|
{
|
||||||
FT_GlyphLoader* loader;
|
FT_GlyphLoader* loader;
|
||||||
FT_Bool glyph_transformed;
|
FT_Bool glyph_transformed;
|
||||||
FT_Matrix glyph_matrix;
|
FT_Matrix glyph_matrix;
|
||||||
FT_Vector glyph_delta;
|
FT_Vector glyph_delta;
|
||||||
|
void* glyph_hints;
|
||||||
|
|
||||||
} FT_GlyphSlot_InternalRec;
|
} FT_GlyphSlot_InternalRec;
|
||||||
|
|
||||||
|
|
|
@ -506,6 +506,8 @@ FT_BEGIN_HEADER
|
||||||
FT_Error error; /* only used for memory errors */
|
FT_Error error; /* only used for memory errors */
|
||||||
FT_Bool metrics_only;
|
FT_Bool metrics_only;
|
||||||
|
|
||||||
|
T1_Hints_Funcs hints_funcs;
|
||||||
|
|
||||||
T1_Builder_Funcs funcs;
|
T1_Builder_Funcs funcs;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
/**********************************************************************/
|
/**********************************************************************/
|
||||||
/**********************************************************************/
|
/**********************************************************************/
|
||||||
|
|
||||||
|
#if 0
|
||||||
/****************************************************************
|
/****************************************************************
|
||||||
*
|
*
|
||||||
* @constant: PS_GLOBALS_MAX_BLUE_ZONES
|
* @constant: PS_GLOBALS_MAX_BLUE_ZONES
|
||||||
|
@ -134,6 +135,7 @@
|
||||||
} PS_GlobalsRec;
|
} PS_GlobalsRec;
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
||||||
/* */
|
/* */
|
||||||
|
|
||||||
#endif /* __PS_GLOBALS_H__ */
|
#endif /* __PS_GLOBALS_H__ */
|
||||||
|
|
|
@ -20,8 +20,178 @@
|
||||||
#ifndef __PSHINTS_H__
|
#ifndef __PSHINTS_H__
|
||||||
#define __PSHINTS_H__
|
#define __PSHINTS_H__
|
||||||
|
|
||||||
|
#include <ft2build.h>
|
||||||
|
#include FT_TYPES_H
|
||||||
|
#include FT_INTERNAL_POSTSCRIPT_GLOBALS_H
|
||||||
|
|
||||||
FT_BEGIN_HEADER
|
FT_BEGIN_HEADER
|
||||||
|
|
||||||
|
/**********************************************************************/
|
||||||
|
/**********************************************************************/
|
||||||
|
/***** *****/
|
||||||
|
/***** EXTERNAL REPRESENTATION OF GLOBALS *****/
|
||||||
|
/***** *****/
|
||||||
|
/**********************************************************************/
|
||||||
|
/**********************************************************************/
|
||||||
|
|
||||||
|
/****************************************************************
|
||||||
|
*
|
||||||
|
* @constant: PS_GLOBALS_MAX_BLUE_ZONES
|
||||||
|
*
|
||||||
|
* @description:
|
||||||
|
* the maximum number of blue zones in a font global hints
|
||||||
|
* structure. See @PS_Globals_BluesRec
|
||||||
|
*/
|
||||||
|
#define PS_GLOBALS_MAX_BLUE_ZONES 16
|
||||||
|
|
||||||
|
/****************************************************************
|
||||||
|
*
|
||||||
|
* @constant: PS_GLOBALS_MAX_STD_WIDTHS
|
||||||
|
*
|
||||||
|
* @description:
|
||||||
|
* the maximum number of standard and snap widths in either the
|
||||||
|
* horizontal or vertical direction. See @PS_Globals_WidthsRec
|
||||||
|
*/
|
||||||
|
#define PS_GLOBALS_MAX_STD_WIDTHS 16
|
||||||
|
|
||||||
|
/****************************************************************
|
||||||
|
*
|
||||||
|
* @type: PS_Globals
|
||||||
|
*
|
||||||
|
* @description:
|
||||||
|
* a handle to a @PS_GlobalsRec structure used to
|
||||||
|
* describe the global hints of a given font
|
||||||
|
*/
|
||||||
|
typedef struct PS_GlobalsRec_* PS_Globals;
|
||||||
|
|
||||||
|
/****************************************************************
|
||||||
|
*
|
||||||
|
* @struct: PS_Globals_BluesRec
|
||||||
|
*
|
||||||
|
* @description:
|
||||||
|
* a structure used to model the global blue zones of a given
|
||||||
|
* font
|
||||||
|
*
|
||||||
|
* @fields:
|
||||||
|
* count :: number of blue zones
|
||||||
|
* zones :: an array of (count*2) coordinates describing the zones
|
||||||
|
*
|
||||||
|
* count_family :: number of family blue zones
|
||||||
|
* zones_family :: an array of (count_family*2) coordinates describing
|
||||||
|
* the family blue zones
|
||||||
|
*
|
||||||
|
* scale :: the blue scale to be used (fixed float)
|
||||||
|
* shift :: the blue shift to be used
|
||||||
|
* fuzz :: the blue fuzz to be used
|
||||||
|
*
|
||||||
|
* @note:
|
||||||
|
* each blue zone is modeled by a (reference,overshoot) coordinate pair
|
||||||
|
* in the table. zones can be placed in any order..
|
||||||
|
*/
|
||||||
|
typedef struct PS_Globals_BluesRec
|
||||||
|
{
|
||||||
|
FT_UInt count;
|
||||||
|
FT_Int16 zones[ 2*PS_GLOBALS_MAX_BLUE_ZONES ];
|
||||||
|
|
||||||
|
FT_UInt count_family;
|
||||||
|
FT_Int16 zones_family[ 2*PS_GLOBALS_MAX_BLUE_ZONES ];
|
||||||
|
|
||||||
|
FT_Fixed scale;
|
||||||
|
FT_Int16 shift;
|
||||||
|
FT_Int16 fuzz;
|
||||||
|
|
||||||
|
} PS_Globals_BluesRec, *PS_Globals_Blues;
|
||||||
|
|
||||||
|
|
||||||
|
/****************************************************************
|
||||||
|
*
|
||||||
|
* @type: PS_Global_Widths;
|
||||||
|
*
|
||||||
|
* @description:
|
||||||
|
* a handle to a @PS_Globals_WidthsRec structure used to model
|
||||||
|
* the global standard and snap widths in a given direction
|
||||||
|
*/
|
||||||
|
typedef struct PS_Globals_WidthsRec_* PS_Globals_Widths;
|
||||||
|
|
||||||
|
|
||||||
|
/****************************************************************
|
||||||
|
*
|
||||||
|
* @struct: PS_Globals_WidthsRec
|
||||||
|
*
|
||||||
|
* @description:
|
||||||
|
* a structure used to model the global standard and snap widths
|
||||||
|
* in a given font
|
||||||
|
*
|
||||||
|
* @fields:
|
||||||
|
* count :: number of widths
|
||||||
|
* widths :: an array of 'count' widths in font units.
|
||||||
|
*
|
||||||
|
* @note:
|
||||||
|
* 'widths[0]' must be the standard width or height, while
|
||||||
|
* remaining elements of the array are snap widths or heights
|
||||||
|
*/
|
||||||
|
typedef struct PS_Globals_WidthsRec_
|
||||||
|
{
|
||||||
|
FT_UInt count;
|
||||||
|
FT_Int16 widths[ PS_GLOBALS_MAX_STD_WIDTHS ];
|
||||||
|
|
||||||
|
} PS_Globals_WidthsRec;
|
||||||
|
|
||||||
|
|
||||||
|
/****************************************************************
|
||||||
|
*
|
||||||
|
* @struct: PS_Globals_GlobalsRec
|
||||||
|
*
|
||||||
|
* @description:
|
||||||
|
* a structure used to model the global hints for a given font
|
||||||
|
*
|
||||||
|
* @fields:
|
||||||
|
* horizontal :: horizontal widths
|
||||||
|
* vertical :: vertical heights
|
||||||
|
* blues :: blue zones
|
||||||
|
*/
|
||||||
|
typedef struct PS_GlobalsRec_
|
||||||
|
{
|
||||||
|
PS_Globals_WidthsRec horizontal;
|
||||||
|
PS_Globals_WidthsRec vertical;
|
||||||
|
PS_Globals_BluesRec blues;
|
||||||
|
|
||||||
|
} PS_GlobalsRec;
|
||||||
|
|
||||||
|
|
||||||
|
/**********************************************************************/
|
||||||
|
/**********************************************************************/
|
||||||
|
/***** *****/
|
||||||
|
/***** INTERNAL REPRESENTATION OF GLOBALS *****/
|
||||||
|
/***** *****/
|
||||||
|
/**********************************************************************/
|
||||||
|
/**********************************************************************/
|
||||||
|
|
||||||
|
typedef struct PSH_GlobalsRec_* PSH_Globals;
|
||||||
|
|
||||||
|
typedef FT_Error (*PSH_Globals_NewFunc)( FT_Memory memory,
|
||||||
|
PSH_Globals* aglobals );
|
||||||
|
|
||||||
|
typedef FT_Error (*PSH_Globals_ResetFunc)( PSH_Globals globals,
|
||||||
|
PS_Globals ps_globals );
|
||||||
|
|
||||||
|
typedef FT_Error (*PSH_Globals_SetScaleFunc)( PSH_Globals globals,
|
||||||
|
FT_Fixed x_scale,
|
||||||
|
FT_Fixed y_scale,
|
||||||
|
FT_Fixed x_delta,
|
||||||
|
FT_Fixed y_delta );
|
||||||
|
|
||||||
|
typedef void (*PSH_Globals_DestroyFunc)( PSH_Globals globals );
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
PSH_Globals_NewFunc create;
|
||||||
|
PSH_Globals_ResetFunc reset;
|
||||||
|
PSH_Globals_SetScaleFunc set_scale;
|
||||||
|
PSH_Globals_DestroyFunc destroy;
|
||||||
|
|
||||||
|
} PSH_Globals_FuncsRec, *PSH_Globals_Funcs;
|
||||||
|
|
||||||
/**********************************************************************/
|
/**********************************************************************/
|
||||||
/**********************************************************************/
|
/**********************************************************************/
|
||||||
/***** *****/
|
/***** *****/
|
||||||
|
@ -106,7 +276,7 @@ FT_BEGIN_HEADER
|
||||||
* use horizontal coordinates (x) for vertical stems (dim=1)
|
* use horizontal coordinates (x) for vertical stems (dim=1)
|
||||||
*
|
*
|
||||||
* "coords[0]" is the absolute stem position (lowest coordinate)
|
* "coords[0]" is the absolute stem position (lowest coordinate)
|
||||||
* "corods[1]" is the length.
|
* "coords[1]" is the length.
|
||||||
*
|
*
|
||||||
* the length can be negative, in which case it must be either
|
* the length can be negative, in which case it must be either
|
||||||
* -20 or -21 in order and will be interpreted as a "ghost" stem,
|
* -20 or -21 in order and will be interpreted as a "ghost" stem,
|
||||||
|
@ -145,7 +315,7 @@ FT_BEGIN_HEADER
|
||||||
|
|
||||||
/************************************************************************
|
/************************************************************************
|
||||||
*
|
*
|
||||||
* @functype: T1_Hints_ResetStemsFunc
|
* @functype: T1_Hints_ResetFunc
|
||||||
*
|
*
|
||||||
* @description:
|
* @description:
|
||||||
* a method of the @T1_Hints class used to reset the stems hints
|
* a method of the @T1_Hints class used to reset the stems hints
|
||||||
|
@ -156,7 +326,7 @@ FT_BEGIN_HEADER
|
||||||
* end_point :: index of last point in the input glyph in which
|
* end_point :: index of last point in the input glyph in which
|
||||||
* the previously defined hints apply
|
* the previously defined hints apply
|
||||||
*/
|
*/
|
||||||
typedef void (*T1_Hints_ResetStemsFunc)( T1_Hints hints,
|
typedef void (*T1_Hints_ResetFunc)( T1_Hints hints,
|
||||||
FT_UInt end_point );
|
FT_UInt end_point );
|
||||||
|
|
||||||
/************************************************************************
|
/************************************************************************
|
||||||
|
@ -178,9 +348,39 @@ FT_BEGIN_HEADER
|
||||||
* the error code will be set to indicate that an error occured
|
* the error code will be set to indicate that an error occured
|
||||||
* during the recording session
|
* during the recording session
|
||||||
*/
|
*/
|
||||||
typedef FT_Error (*T1_Hint_RecordCloseFunc)( T1_Hints hints,
|
typedef FT_Error (*T1_Hints_CloseFunc)( T1_Hints hints,
|
||||||
FT_UInt end_point );
|
FT_UInt end_point );
|
||||||
|
|
||||||
|
|
||||||
|
/************************************************************************
|
||||||
|
*
|
||||||
|
* @functype: T1_Hints_ApplyFunc
|
||||||
|
*
|
||||||
|
* @description:
|
||||||
|
* a method of the @T1_Hints class used to apply hints to the
|
||||||
|
* corresponding glyph outline. Must be called once all hints
|
||||||
|
* have been recorded.
|
||||||
|
*
|
||||||
|
* @input:
|
||||||
|
* hints :: handle to Type 1 hints recorder
|
||||||
|
* outline :: pointer to target outline descriptor
|
||||||
|
* globals :: the hinter globals for this font
|
||||||
|
*
|
||||||
|
* @return:
|
||||||
|
* error code. 0 means success
|
||||||
|
*
|
||||||
|
* @note:
|
||||||
|
* on input, all points within the outline are in font coordinates.
|
||||||
|
* on output, they're in 1/64th of pixels.
|
||||||
|
*
|
||||||
|
* the scaling transform is taken from the "globals" object, which
|
||||||
|
* must correspond to the same font than the glyph
|
||||||
|
*/
|
||||||
|
typedef FT_Error (*T1_Hints_ApplyFunc)( T1_Hints hints,
|
||||||
|
FT_Outline* outline,
|
||||||
|
PSH_Globals globals );
|
||||||
|
|
||||||
|
|
||||||
/************************************************************************
|
/************************************************************************
|
||||||
*
|
*
|
||||||
* @struct: T1_Hints_FuncsRec
|
* @struct: T1_Hints_FuncsRec
|
||||||
|
@ -189,19 +389,23 @@ FT_BEGIN_HEADER
|
||||||
* the structure used to provide the API to @T1_Hints objects
|
* the structure used to provide the API to @T1_Hints objects
|
||||||
*
|
*
|
||||||
* @fields:
|
* @fields:
|
||||||
|
* hints :: handle to T1 Hints recorder
|
||||||
* open :: open recording session
|
* open :: open recording session
|
||||||
* close :: close recording session
|
* close :: close recording session
|
||||||
* stem :: set simple stem
|
* stem :: set simple stem
|
||||||
* stem3 :: set counter-controlled stems
|
* stem3 :: set counter-controlled stems
|
||||||
* reset :: reset stem hints
|
* reset :: reset stem hints
|
||||||
|
* apply :: apply the hints to the corresponding glyph outline
|
||||||
*/
|
*/
|
||||||
typedef struct T1_Hints_FuncsRec_
|
typedef struct T1_Hints_FuncsRec_
|
||||||
{
|
{
|
||||||
|
T1_Hints hints;
|
||||||
T1_Hints_OpenFunc open;
|
T1_Hints_OpenFunc open;
|
||||||
T1_Hints_CloseFunc close;
|
T1_Hints_CloseFunc close;
|
||||||
T1_Hints_SetStemFunc stem;
|
T1_Hints_SetStemFunc stem;
|
||||||
T1_Hints_SetStem3Func stem3;
|
T1_Hints_SetStem3Func stem3;
|
||||||
T1_Hints_ResetFunc reset;
|
T1_Hints_ResetFunc reset;
|
||||||
|
T1_Hints_ApplyFunc apply;
|
||||||
|
|
||||||
} T1_Hints_FuncsRec;
|
} T1_Hints_FuncsRec;
|
||||||
|
|
||||||
|
@ -387,6 +591,35 @@ FT_BEGIN_HEADER
|
||||||
typedef FT_Error (*T2_Hints_CloseFunc) ( T2_Hints hints,
|
typedef FT_Error (*T2_Hints_CloseFunc) ( T2_Hints hints,
|
||||||
FT_UInt end_point );
|
FT_UInt end_point );
|
||||||
|
|
||||||
|
|
||||||
|
/************************************************************************
|
||||||
|
*
|
||||||
|
* @functype: T2_Hints_ApplyFunc
|
||||||
|
*
|
||||||
|
* @description:
|
||||||
|
* a method of the @T2_Hints class used to apply hints to the
|
||||||
|
* corresponding glyph outline. Must be called after the "close" method
|
||||||
|
*
|
||||||
|
* @input:
|
||||||
|
* hints :: handle to Type 2 hints recorder
|
||||||
|
* outline :: pointer to target outline descriptor
|
||||||
|
* globals :: the hinter globals for this font
|
||||||
|
*
|
||||||
|
* @return:
|
||||||
|
* error code. 0 means success
|
||||||
|
*
|
||||||
|
* @note:
|
||||||
|
* on input, all points within the outline are in font coordinates.
|
||||||
|
* on output, they're in 1/64th of pixels.
|
||||||
|
*
|
||||||
|
* the scaling transform is taken from the "globals" object, which
|
||||||
|
* must correspond to the same font than the glyph
|
||||||
|
*/
|
||||||
|
typedef FT_Error (*T2_Hints_ApplyFunc)( T2_Hints hints,
|
||||||
|
FT_Outline* outline,
|
||||||
|
PSH_Globals globals );
|
||||||
|
|
||||||
|
|
||||||
/************************************************************************
|
/************************************************************************
|
||||||
*
|
*
|
||||||
* @struct: T2_Hints_FuncsRec
|
* @struct: T2_Hints_FuncsRec
|
||||||
|
@ -395,24 +628,36 @@ FT_BEGIN_HEADER
|
||||||
* the structure used to provide the API to @T2_Hints objects
|
* the structure used to provide the API to @T2_Hints objects
|
||||||
*
|
*
|
||||||
* @fields:
|
* @fields:
|
||||||
|
* hints :: handle to T2 hints recorder object
|
||||||
* open :: open recording session
|
* open :: open recording session
|
||||||
* close :: close recording session
|
* close :: close recording session
|
||||||
* stems :: set dimension's stems table
|
* stems :: set dimension's stems table
|
||||||
* hintmask :: set hint masks
|
* hintmask :: set hint masks
|
||||||
* counter :: set counter masks
|
* counter :: set counter masks
|
||||||
|
* apply :: apply the hints on the corresponding glyph outline
|
||||||
*/
|
*/
|
||||||
typedef struct T2_Hints_FuncsRec_
|
typedef struct T2_Hints_FuncsRec_
|
||||||
{
|
{
|
||||||
|
T2_Hints hints;
|
||||||
T2_Hints_OpenFunc open;
|
T2_Hints_OpenFunc open;
|
||||||
T2_Hints_CloseFunc close;
|
T2_Hints_CloseFunc close;
|
||||||
T2_Hints_StemsFunc stems;
|
T2_Hints_StemsFunc stems;
|
||||||
T2_Hints_MaskFunc hintmask;
|
T2_Hints_MaskFunc hintmask;
|
||||||
T2_Hints_CounterFunc counter;
|
T2_Hints_CounterFunc counter;
|
||||||
|
T2_Hints_ApplyFunc apply;
|
||||||
|
|
||||||
} T2_Hints_FuncsRec;
|
} T2_Hints_FuncsRec;
|
||||||
|
|
||||||
|
|
||||||
/* */
|
/* */
|
||||||
|
|
||||||
|
typedef struct PSHinter_Interface_
|
||||||
|
{
|
||||||
|
PSH_Globals_Funcs (*get_globals_funcs)( FT_Module module );
|
||||||
|
T1_Hints_Funcs (*get_t1_funcs) ( FT_Module module );
|
||||||
|
T2_Hints_Funcs (*get_t2_funcs) ( FT_Module module );
|
||||||
|
|
||||||
|
} PSHinter_Interface, *PSHinter_InterfacePtr;
|
||||||
|
|
||||||
FT_END_HEADER
|
FT_END_HEADER
|
||||||
|
|
||||||
|
|
|
@ -24,7 +24,7 @@
|
||||||
#include<ft2build.h>
|
#include<ft2build.h>
|
||||||
#include FT_TYPE1_TABLES_H
|
#include FT_TYPE1_TABLES_H
|
||||||
#include FT_INTERNAL_POSTSCRIPT_NAMES_H
|
#include FT_INTERNAL_POSTSCRIPT_NAMES_H
|
||||||
|
#include FT_INTERNAL_POSTSCRIPT_HINTS_H
|
||||||
|
|
||||||
FT_BEGIN_HEADER
|
FT_BEGIN_HEADER
|
||||||
|
|
||||||
|
@ -173,6 +173,9 @@ FT_BEGIN_HEADER
|
||||||
/* support for Multiple Masters fonts */
|
/* support for Multiple Masters fonts */
|
||||||
T1_Blend* blend;
|
T1_Blend* blend;
|
||||||
|
|
||||||
|
/* since FT 2.1 - interface to Postscript hinter */
|
||||||
|
void* pshinter;
|
||||||
|
|
||||||
} T1_FaceRec;
|
} T1_FaceRec;
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -14,6 +14,7 @@ SubDirHdrs [ FT2_SubDir src ] ;
|
||||||
#
|
#
|
||||||
HDRMACRO [ FT2_SubDir include internal internal.h ] ;
|
HDRMACRO [ FT2_SubDir include internal internal.h ] ;
|
||||||
|
|
||||||
|
SubInclude FT2_TOP src pshinter ;
|
||||||
SubInclude FT2_TOP src autohint ;
|
SubInclude FT2_TOP src autohint ;
|
||||||
SubInclude FT2_TOP src base ;
|
SubInclude FT2_TOP src base ;
|
||||||
SubInclude FT2_TOP src cache ;
|
SubInclude FT2_TOP src cache ;
|
||||||
|
|
|
@ -717,7 +717,7 @@ THE SOFTWARE.
|
||||||
else
|
else
|
||||||
encodingOffset = GET_ShortLE();
|
encodingOffset = GET_ShortLE();
|
||||||
|
|
||||||
if ( encodingOffset != (signed short)0xFFFF )
|
if ( encodingOffset != 0xFFFF )
|
||||||
{
|
{
|
||||||
tmpEncoding[j].enc = ( ( ( i / ( lastCol - firstCol + 1 ) ) +
|
tmpEncoding[j].enc = ( ( ( i / ( lastCol - firstCol + 1 ) ) +
|
||||||
firstRow ) * 256 ) +
|
firstRow ) * 256 ) +
|
||||||
|
|
|
@ -1081,6 +1081,8 @@
|
||||||
builder->base = &loader->base.outline;
|
builder->base = &loader->base.outline;
|
||||||
builder->current = &loader->current.outline;
|
builder->current = &loader->current.outline;
|
||||||
FT_GlyphLoader_Rewind( loader );
|
FT_GlyphLoader_Rewind( loader );
|
||||||
|
|
||||||
|
builder->hints_func = (T1_Hints_Funcs) glyph->internal->glyph_hints;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( size )
|
if ( size )
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
|
|
||||||
#include <ft2build.h>
|
#include <ft2build.h>
|
||||||
#include FT_INTERNAL_DEBUG_H
|
#include FT_INTERNAL_DEBUG_H
|
||||||
|
#include FT_INTERNAL_POSTSCRIPT_HINTS_H
|
||||||
#include FT_OUTLINE_H
|
#include FT_OUTLINE_H
|
||||||
|
|
||||||
#include "t1decode.h"
|
#include "t1decode.h"
|
||||||
|
@ -325,6 +326,7 @@
|
||||||
T1_Builder* builder = &decoder->builder;
|
T1_Builder* builder = &decoder->builder;
|
||||||
FT_Pos x, y;
|
FT_Pos x, y;
|
||||||
|
|
||||||
|
T1_Hints_Funcs hinter;
|
||||||
|
|
||||||
/* we don't want to touch the source code -- use macro trick */
|
/* we don't want to touch the source code -- use macro trick */
|
||||||
#define start_point T1_Builder_Start_Point
|
#define start_point T1_Builder_Start_Point
|
||||||
|
@ -341,6 +343,8 @@
|
||||||
|
|
||||||
builder->path_begun = 0;
|
builder->path_begun = 0;
|
||||||
|
|
||||||
|
hinter = builder->hints_funcs;
|
||||||
|
|
||||||
zone->base = charstring_base;
|
zone->base = charstring_base;
|
||||||
limit = zone->limit = charstring_base + charstring_len;
|
limit = zone->limit = charstring_base + charstring_len;
|
||||||
ip = zone->cursor = zone->base;
|
ip = zone->cursor = zone->base;
|
||||||
|
@ -350,6 +354,10 @@
|
||||||
x = builder->pos_x;
|
x = builder->pos_x;
|
||||||
y = builder->pos_y;
|
y = builder->pos_y;
|
||||||
|
|
||||||
|
/* begin hints recording session, if any */
|
||||||
|
if ( hinter )
|
||||||
|
hinter->open( hinter->hints );
|
||||||
|
|
||||||
/* now, execute loop */
|
/* now, execute loop */
|
||||||
while ( ip < limit )
|
while ( ip < limit )
|
||||||
{
|
{
|
||||||
|
@ -613,6 +621,10 @@
|
||||||
goto Syntax_Error;
|
goto Syntax_Error;
|
||||||
}
|
}
|
||||||
ip += 2;
|
ip += 2;
|
||||||
|
|
||||||
|
if ( hinter )
|
||||||
|
hinter->reset( hinter->hints, builder->current->n_points );
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 12:
|
case 12:
|
||||||
|
@ -708,6 +720,10 @@
|
||||||
|
|
||||||
close_contour( builder );
|
close_contour( builder );
|
||||||
|
|
||||||
|
/* close hints recording session */
|
||||||
|
if ( hinter )
|
||||||
|
hinter->close( hinter->hints, builder->current->n_points );
|
||||||
|
|
||||||
/* add current outline to the glyph slot */
|
/* add current outline to the glyph slot */
|
||||||
FT_GlyphLoader_Add( builder->loader );
|
FT_GlyphLoader_Add( builder->loader );
|
||||||
|
|
||||||
|
@ -974,21 +990,37 @@
|
||||||
case op_hstem:
|
case op_hstem:
|
||||||
FT_TRACE4(( " hstem" ));
|
FT_TRACE4(( " hstem" ));
|
||||||
|
|
||||||
|
/* record horizontal hint */
|
||||||
|
if ( hinter )
|
||||||
|
hinter->stem( hinter->hints, 0, top );
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case op_hstem3:
|
case op_hstem3:
|
||||||
FT_TRACE4(( " hstem3" ));
|
FT_TRACE4(( " hstem3" ));
|
||||||
|
|
||||||
|
/* record horizontal counter-controlled hints */
|
||||||
|
if ( hinter )
|
||||||
|
hinter->stem3( hinter->hints, 0, top );
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case op_vstem:
|
case op_vstem:
|
||||||
FT_TRACE4(( " vstem" ));
|
FT_TRACE4(( " vstem" ));
|
||||||
|
|
||||||
|
/* record vertical hint */
|
||||||
|
if ( hinter )
|
||||||
|
hinter->stem( hinter->hints, 1, top );
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case op_vstem3:
|
case op_vstem3:
|
||||||
FT_TRACE4(( " vstem3" ));
|
FT_TRACE4(( " vstem3" ));
|
||||||
|
|
||||||
|
/* record vertical counter-controlled hints */
|
||||||
|
if ( hinter )
|
||||||
|
hinter->stem3( hinter->hints, 1, top );
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case op_setcurrentpoint:
|
case op_setcurrentpoint:
|
||||||
|
@ -1011,6 +1043,7 @@
|
||||||
} /* while ip < limit */
|
} /* while ip < limit */
|
||||||
|
|
||||||
FT_TRACE4(( "..end..\n\n" ));
|
FT_TRACE4(( "..end..\n\n" ));
|
||||||
|
|
||||||
return error;
|
return error;
|
||||||
|
|
||||||
Syntax_Error:
|
Syntax_Error:
|
||||||
|
|
|
@ -0,0 +1,23 @@
|
||||||
|
# FreeType 2 src/pshinter Jamfile (c) 2001 David Turner
|
||||||
|
#
|
||||||
|
|
||||||
|
SubDir FT2_TOP src pshinter ;
|
||||||
|
|
||||||
|
SubDirHdrs [ FT2_SubDir src pshinter ] ;
|
||||||
|
|
||||||
|
{
|
||||||
|
local _sources ;
|
||||||
|
|
||||||
|
if $(FT2_MULTI)
|
||||||
|
{
|
||||||
|
_sources = pshrec pshglob pshfit pshmod ;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_sources = pshinter ;
|
||||||
|
}
|
||||||
|
|
||||||
|
Library $(FT2_LIB) : $(_sources).c ;
|
||||||
|
}
|
||||||
|
|
||||||
|
# end of src/psaux Jamfile
|
|
@ -0,0 +1,441 @@
|
||||||
|
#include <ft2build.h>
|
||||||
|
#include FT_INTERNAL_OBJECTS_H
|
||||||
|
#include "pshfit.h"
|
||||||
|
|
||||||
|
/* return true iff two hints overlap */
|
||||||
|
static FT_Int
|
||||||
|
psh_hint_overlap( PSH_Hint hint1,
|
||||||
|
PSH_Hint hint2 )
|
||||||
|
{
|
||||||
|
return ( hint1->org_pos + hint1->org_len >= hint2->org_pos &&
|
||||||
|
hint2->org_pos + hint2->org_len >= hint1->org_pos );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* destroy hints table */
|
||||||
|
static void
|
||||||
|
psh_hint_table_done( PSH_Hint_Table table,
|
||||||
|
FT_Memory memory )
|
||||||
|
{
|
||||||
|
FREE( table->zones );
|
||||||
|
table->num_zones = 0;
|
||||||
|
table->zone = 0;
|
||||||
|
|
||||||
|
FREE( table->sort );
|
||||||
|
FREE( table->hints );
|
||||||
|
table->num_hints = 0;
|
||||||
|
table->max_hints = 0;
|
||||||
|
table->sort_global = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* deactivate all hints in a table */
|
||||||
|
static void
|
||||||
|
psh_hint_table_deactivate( PSH_Hint_Table table )
|
||||||
|
{
|
||||||
|
FT_UInt count = table->max_hints;
|
||||||
|
PSH_Hint hint = table->hints;
|
||||||
|
|
||||||
|
for ( ; count > 0; count--, hint++ )
|
||||||
|
{
|
||||||
|
psh_hint_deactivate(hint);
|
||||||
|
hint->order = -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* internal function used to record a new hint */
|
||||||
|
static void
|
||||||
|
psh_hint_table_record( PSH_Hint_Table table,
|
||||||
|
FT_UInt index )
|
||||||
|
{
|
||||||
|
PSH_Hint hint = table->hints + index;
|
||||||
|
|
||||||
|
if ( index >= table->max_hints )
|
||||||
|
{
|
||||||
|
FT_ERROR(( "%s.activate: invalid hint index %d\n", index ));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ignore active hints */
|
||||||
|
if ( psh_hint_is_active(hint) )
|
||||||
|
return;
|
||||||
|
|
||||||
|
psh_hint_activate(hint);
|
||||||
|
|
||||||
|
/* now scan the current active hint set in order to determine */
|
||||||
|
/* if we're overlapping with another segment.. */
|
||||||
|
{
|
||||||
|
PSH_Hint* sorted = table->sort;
|
||||||
|
FT_UInt count = table->num_hints;
|
||||||
|
PSH_Hint hint2;
|
||||||
|
|
||||||
|
hint->parent = 0;
|
||||||
|
for ( ; count > 0; count--, sorted++ )
|
||||||
|
{
|
||||||
|
hint2 = sorted[0];
|
||||||
|
|
||||||
|
if ( psh_hint_overlap( hint, hint2 ) )
|
||||||
|
{
|
||||||
|
hint->parent = hint2;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( table->num_hints < table->max_hints )
|
||||||
|
table->sort_global[ table->num_hints++ ] = hint;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
FT_ERROR(( "%s.activate: too many sorted hints !! BUG !!\n",
|
||||||
|
"ps.fitter" ));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
psh_hint_table_record_mask( PSH_Hint_Table table,
|
||||||
|
PS_Mask hint_mask )
|
||||||
|
{
|
||||||
|
FT_Int mask = 0, val = 0;
|
||||||
|
FT_Byte* cursor = hint_mask->bytes;
|
||||||
|
FT_UInt index, limit;
|
||||||
|
|
||||||
|
limit = hint_mask->num_bits;
|
||||||
|
|
||||||
|
if ( limit != table->max_hints )
|
||||||
|
{
|
||||||
|
FT_ERROR(( "%s.activate_mask: invalid bit count (%d instead of %d)\n",
|
||||||
|
"ps.fitter", hint_mask->num_bits, table->max_hints ));
|
||||||
|
}
|
||||||
|
|
||||||
|
for ( index = 0; index < limit; index++ )
|
||||||
|
{
|
||||||
|
if ( mask == 0 )
|
||||||
|
{
|
||||||
|
val = *cursor++;
|
||||||
|
mask = 0x80;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( val & mask )
|
||||||
|
psh_hint_table_record( table, index );
|
||||||
|
|
||||||
|
mask >>= 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* create hints table */
|
||||||
|
static FT_Error
|
||||||
|
psh_hint_table_init( PSH_Hint_Table table,
|
||||||
|
PS_Hint_Table hints,
|
||||||
|
PS_Mask_Table hint_masks,
|
||||||
|
PS_Mask_Table counter_masks,
|
||||||
|
FT_Memory memory )
|
||||||
|
{
|
||||||
|
FT_UInt count = hints->num_hints;
|
||||||
|
FT_Error error;
|
||||||
|
|
||||||
|
FT_UNUSED(counter_masks);
|
||||||
|
|
||||||
|
/* allocate our tables */
|
||||||
|
if ( ALLOC_ARRAY( table->sort, 2*count, PSH_Hint ) ||
|
||||||
|
ALLOC_ARRAY( table->hints, count, PSH_HintRec ) ||
|
||||||
|
ALLOC_ARRAY( table->zones, 2*count+1, PSH_ZoneRec ) )
|
||||||
|
goto Exit;
|
||||||
|
|
||||||
|
table->max_hints = count;
|
||||||
|
table->sort_global = table->sort + count;
|
||||||
|
table->num_hints = 0;
|
||||||
|
table->num_zones = 0;
|
||||||
|
table->zone = 0;
|
||||||
|
|
||||||
|
/* now, initialise the "hints" array */
|
||||||
|
{
|
||||||
|
PSH_Hint write = table->hints;
|
||||||
|
PS_Hint read = hints->hints;
|
||||||
|
|
||||||
|
for ( ; count > 0; count--, write++, read++ )
|
||||||
|
{
|
||||||
|
write->org_pos = read->pos;
|
||||||
|
write->org_len = read->len;
|
||||||
|
write->flags = read->flags;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* we now need to determine the initial "parent" stems, first */
|
||||||
|
/* activate the hints that are given by the initial hint masks */
|
||||||
|
if ( hint_masks )
|
||||||
|
{
|
||||||
|
FT_UInt count = hint_masks->num_masks;
|
||||||
|
PS_Mask mask = hint_masks->masks;
|
||||||
|
|
||||||
|
for ( ; count > 0; count--, mask++ )
|
||||||
|
psh_hint_table_record_mask( table, mask );
|
||||||
|
}
|
||||||
|
|
||||||
|
/* now, do a linear parse in case some hints were left alone */
|
||||||
|
if ( table->num_hints != table->max_hints )
|
||||||
|
{
|
||||||
|
FT_UInt index, count;
|
||||||
|
|
||||||
|
FT_ERROR(( "%s.init: missing/incorrect hint masks !!\n" ));
|
||||||
|
count = table->max_hints;
|
||||||
|
for ( index = 0; index < count; index++ )
|
||||||
|
psh_hint_table_record( table, index );
|
||||||
|
}
|
||||||
|
|
||||||
|
Exit:
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
psh_hint_table_activate_mask( PSH_Hint_Table table,
|
||||||
|
PS_Mask hint_mask )
|
||||||
|
{
|
||||||
|
FT_Int mask = 0, val = 0;
|
||||||
|
FT_Byte* cursor = hint_mask->bytes;
|
||||||
|
FT_UInt index, limit, count;
|
||||||
|
|
||||||
|
limit = hint_mask->num_bits;
|
||||||
|
count = 0;
|
||||||
|
|
||||||
|
psh_hint_table_deactivate( table );
|
||||||
|
|
||||||
|
for ( index = 0; index < limit; index++ )
|
||||||
|
{
|
||||||
|
if ( mask == 0 )
|
||||||
|
{
|
||||||
|
val = *cursor++;
|
||||||
|
mask = 0x80;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( val & mask )
|
||||||
|
{
|
||||||
|
PSH_Hint hint = &table->hints[index];
|
||||||
|
|
||||||
|
if ( !psh_hint_is_active(hint) )
|
||||||
|
{
|
||||||
|
PSH_Hint* sort = table->sort;
|
||||||
|
FT_UInt count2;
|
||||||
|
PSH_Hint hint2;
|
||||||
|
|
||||||
|
for ( count2 = count; count2 > 0; count2--, sort++ )
|
||||||
|
{
|
||||||
|
hint2 = sort[0];
|
||||||
|
if ( psh_hint_overlap( hint, hint2 ) )
|
||||||
|
{
|
||||||
|
FT_ERROR(( "%s.activate_mask: found overlapping hints\n",
|
||||||
|
"psf.hint" ));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( count2 == 0 )
|
||||||
|
{
|
||||||
|
psh_hint_activate( hint );
|
||||||
|
if ( count < table->max_hints )
|
||||||
|
table->sort[count++] = hint;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
FT_ERROR(( "%s.activate_mask: too many active hints\n",
|
||||||
|
"psf.hint" ));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mask >>= 1;
|
||||||
|
}
|
||||||
|
table->num_hints = count;
|
||||||
|
|
||||||
|
/* now, sort the hints, they're guaranteed to not overlap */
|
||||||
|
/* so we can compare their "org_pos" field directly.. */
|
||||||
|
{
|
||||||
|
FT_Int i1, i2;
|
||||||
|
PSH_Hint hint1, hint2;
|
||||||
|
PSH_Hint* sort = table->sort;
|
||||||
|
|
||||||
|
/* a simple bubble sort will do, since in 99% of cases, the hints */
|
||||||
|
/* will be already sorted.. and the sort will be linear */
|
||||||
|
for ( i1 = 1; i1 < (FT_Int)count; i1++ )
|
||||||
|
{
|
||||||
|
hint1 = sort[i1];
|
||||||
|
for ( i2 = i1-1; i2 >= 0; i2-- )
|
||||||
|
{
|
||||||
|
hint2 = sort[i2];
|
||||||
|
if ( hint2->org_pos < hint1->org_pos )
|
||||||
|
break;
|
||||||
|
|
||||||
|
sort[i1] = hint2;
|
||||||
|
sort[i2] = hint1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#define PSH_ZONE_MIN -3200000
|
||||||
|
#define PSH_ZONE_MAX +3200000
|
||||||
|
|
||||||
|
/* setup interpolation zones once the hints have been grid-fitted */
|
||||||
|
static void
|
||||||
|
psh_hint_table_setup_zones( PSH_Hint_Table table,
|
||||||
|
FT_Fixed scale,
|
||||||
|
FT_Fixed delta )
|
||||||
|
{
|
||||||
|
FT_UInt count;
|
||||||
|
PSH_Zone zone;
|
||||||
|
PSH_Hint *sort, hint, hint2;
|
||||||
|
|
||||||
|
zone = table->zones;
|
||||||
|
|
||||||
|
/* special case, no hints defined */
|
||||||
|
if ( table->num_hints == 0 )
|
||||||
|
{
|
||||||
|
zone->scale = scale;
|
||||||
|
zone->delta = delta;
|
||||||
|
zone->min = PSH_ZONE_MIN;
|
||||||
|
zone->max = PSH_ZONE_MAX;
|
||||||
|
table->num_zones = 1;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* the first zone is before the first hint */
|
||||||
|
/* x' = (x-x0)*s + x0' = x*s + ( x0' - x0*s ) */
|
||||||
|
sort = table->sort;
|
||||||
|
hint = sort[0];
|
||||||
|
|
||||||
|
zone->scale = scale;
|
||||||
|
zone->delta = hint->cur_pos - FT_MulFix( hint->org_pos, scale );
|
||||||
|
zone->min = PSH_ZONE_MIN;
|
||||||
|
zone->max = hint->org_pos;
|
||||||
|
zone++;
|
||||||
|
|
||||||
|
for ( count = table->num_hints; count > 1; count-- )
|
||||||
|
{
|
||||||
|
FT_Fixed scale2;
|
||||||
|
|
||||||
|
if ( hint->org_len > 0 )
|
||||||
|
{
|
||||||
|
/* setup a zone for inner-stem interpolation */
|
||||||
|
/* (x' - x0') = (x - x0)*(x1'-x0')/(x1-x0) */
|
||||||
|
/* x' = x*s2 + x0' - x0*s2 */
|
||||||
|
|
||||||
|
scale2 = FT_DivFix( hint->cur_len, hint->org_len );
|
||||||
|
zone->scale = scale2;
|
||||||
|
zone->min = hint->org_pos;
|
||||||
|
zone->max = hint->org_pos + hint->org_len;
|
||||||
|
zone->delta = hint->cur_pos - FT_MulFix( zone->min, scale2 );
|
||||||
|
zone++;
|
||||||
|
}
|
||||||
|
|
||||||
|
sort++;
|
||||||
|
hint2 = sort[0];
|
||||||
|
|
||||||
|
/* setup zone for inter-stem interpolation */
|
||||||
|
/* (x'-x1') = (x-x1)*(x2'-x1')/(x2-x1) */
|
||||||
|
/* x' = x*s3 + x1' - x1*s3 */
|
||||||
|
scale2 = FT_DivFix( hint2->cur_pos - (hint->cur_pos + hint->cur_len),
|
||||||
|
hint2->org_pos - (hint2->org_pos + hint2->org_len) );
|
||||||
|
zone->scale = scale2;
|
||||||
|
zone->min = hint->org_pos + hint->org_len;
|
||||||
|
zone->max = hint2->org_pos;
|
||||||
|
zone->delta = hint->cur_pos + hint->cur_len - FT_MulFix( zone->min, scale2 );
|
||||||
|
zone++;
|
||||||
|
|
||||||
|
hint = hint2;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* the last zone */
|
||||||
|
zone->scale = scale;
|
||||||
|
zone->min = hint->org_pos + hint->org_len;
|
||||||
|
zone->max = PSH_ZONE_MAX;
|
||||||
|
zone->delta = hint->cur_pos - FT_MulFix( zone->min, scale );
|
||||||
|
zone++;
|
||||||
|
|
||||||
|
table->num_zones = zone - table->zones;
|
||||||
|
table->zone = table->zones;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* tune a single coordinate with the current interpolation zones */
|
||||||
|
static FT_Pos
|
||||||
|
psh_hint_table_tune_coord( PSH_Hint_Table table,
|
||||||
|
FT_Int coord )
|
||||||
|
{
|
||||||
|
PSH_Zone zone;
|
||||||
|
|
||||||
|
zone = table->zone;
|
||||||
|
|
||||||
|
if ( coord < zone->min )
|
||||||
|
{
|
||||||
|
do
|
||||||
|
{
|
||||||
|
if ( zone == table->zones )
|
||||||
|
break;
|
||||||
|
|
||||||
|
zone--;
|
||||||
|
}
|
||||||
|
while ( coord < zone->min );
|
||||||
|
table->zone = zone;
|
||||||
|
}
|
||||||
|
else if ( coord > zone->max )
|
||||||
|
{
|
||||||
|
do
|
||||||
|
{
|
||||||
|
if ( zone == table->zones + table->num_zones - 1 )
|
||||||
|
break;
|
||||||
|
|
||||||
|
zone++;
|
||||||
|
}
|
||||||
|
while ( coord > zone->max );
|
||||||
|
table->zone = zone;
|
||||||
|
}
|
||||||
|
|
||||||
|
return zone->delta + FT_MulFix( coord, zone->scale );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* tune a given outline with current interpolation zones */
|
||||||
|
static void
|
||||||
|
psh_hint_table_tune_outline( PSH_Hint_Table table,
|
||||||
|
FT_Outline* outline,
|
||||||
|
FT_Fixed scale,
|
||||||
|
FT_Fixed delta,
|
||||||
|
FT_Bool vertical )
|
||||||
|
|
||||||
|
{
|
||||||
|
FT_UInt count, first, last;
|
||||||
|
PS_Mask_Table hint_masks;
|
||||||
|
PS_Mask mask;
|
||||||
|
|
||||||
|
first = 0;
|
||||||
|
mask = hint_masks->masks;
|
||||||
|
count = hint_masks->num_masks;
|
||||||
|
for ( ; count > 0; count--, mask++ )
|
||||||
|
{
|
||||||
|
FT_Vector* vec;
|
||||||
|
FT_Int count2;
|
||||||
|
|
||||||
|
psh_hint_table_activate_mask( table, mask );
|
||||||
|
psh_hint_table_setup_zones( table, scale, delta );
|
||||||
|
last = mask->end_point;
|
||||||
|
|
||||||
|
vec = outline->points + first;
|
||||||
|
count2 = last - first + 1;
|
||||||
|
for ( ; count2 > 0; count2--, vec++ )
|
||||||
|
{
|
||||||
|
FT_Pos x, *px;
|
||||||
|
|
||||||
|
px = vertical ? &vec->y : &vec->y;
|
||||||
|
x = *px;
|
||||||
|
|
||||||
|
*px = psh_hint_table_tune_coord( table, (FT_Int)x );
|
||||||
|
}
|
||||||
|
|
||||||
|
first = (FT_UInt)(last+1);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,90 @@
|
||||||
|
/***************************************************************************/
|
||||||
|
/* */
|
||||||
|
/* pshfit.h */
|
||||||
|
/* */
|
||||||
|
/* Postscript (Type 1/CFF) outline grid-fitter */
|
||||||
|
/* */
|
||||||
|
/* Copyright 2001 by */
|
||||||
|
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
|
||||||
|
/* */
|
||||||
|
/* This file is part of the FreeType project, and may only be used, */
|
||||||
|
/* modified, and distributed under the terms of the FreeType project */
|
||||||
|
/* license, LICENSE.TXT. By continuing to use, modify, or distribute */
|
||||||
|
/* this file you indicate that you have read the license and */
|
||||||
|
/* understand and accept it fully. */
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/* process the hints provided by the Postscript hints recorder. This */
|
||||||
|
/* means sorting and scaling the hints, calling the "optimiser" to */
|
||||||
|
/* process them, then grid-fitting the glyph outline based on the */
|
||||||
|
/* optimised hints information. */
|
||||||
|
/* */
|
||||||
|
/* (the real hinting "intelligence" is in "pshoptim.h", not here) */
|
||||||
|
/* */
|
||||||
|
/***************************************************************************/
|
||||||
|
|
||||||
|
#ifndef __PS_HINTER_FITTER_H__
|
||||||
|
#define __PS_HINTER_FITTER_H__
|
||||||
|
|
||||||
|
#include "pshrec.h"
|
||||||
|
|
||||||
|
FT_BEGIN_HEADER
|
||||||
|
|
||||||
|
typedef struct PSH_HintRec_* PSH_Hint;
|
||||||
|
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
PSH_HINT_FLAG_GHOST = PS_HINT_FLAG_GHOST,
|
||||||
|
PSH_HINT_FLAG_BOTTOM = PS_HINT_FLAG_BOTTOM,
|
||||||
|
PSH_HINT_FLAG_ACTIVE = 4
|
||||||
|
|
||||||
|
} PSH_Hint_Flags;
|
||||||
|
|
||||||
|
#define psh_hint_is_active(x) (((x)->flags & PSH_HINT_FLAG_ACTIVE) != 0)
|
||||||
|
#define psh_hint_activate(x) (x)->flags |= PSH_HINT_FLAG_ACTIVE
|
||||||
|
#define psh_hint_deactivate(x) (x)->flags &= ~PSH_HINT_FLAG_ACTIVE
|
||||||
|
|
||||||
|
typedef struct PSH_HintRec_
|
||||||
|
{
|
||||||
|
FT_Int org_pos;
|
||||||
|
FT_Int org_len;
|
||||||
|
FT_Pos cur_pos;
|
||||||
|
FT_Pos cur_len;
|
||||||
|
|
||||||
|
FT_UInt flags;
|
||||||
|
|
||||||
|
PSH_Hint parent;
|
||||||
|
FT_Int order;
|
||||||
|
|
||||||
|
} PSH_HintRec;
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct PSH_ZoneRec_
|
||||||
|
{
|
||||||
|
FT_Fixed scale;
|
||||||
|
FT_Fixed delta;
|
||||||
|
FT_Pos min;
|
||||||
|
FT_Pos max;
|
||||||
|
|
||||||
|
} PSH_ZoneRec, *PSH_Zone;
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct PSH_Hint_TableRec_
|
||||||
|
{
|
||||||
|
FT_UInt max_hints;
|
||||||
|
FT_UInt num_hints;
|
||||||
|
PSH_Hint hints;
|
||||||
|
PSH_Hint* sort;
|
||||||
|
PSH_Hint* sort_global;
|
||||||
|
FT_UInt num_zones;
|
||||||
|
PSH_Zone zones;
|
||||||
|
PSH_Zone zone;
|
||||||
|
PS_Mask_Table hint_masks;
|
||||||
|
PS_Mask_Table counter_masks;
|
||||||
|
|
||||||
|
} PSH_Hint_TableRec, *PSH_Hint_Table;
|
||||||
|
|
||||||
|
|
||||||
|
FT_END_HEADER
|
||||||
|
|
||||||
|
#endif /* __PS_HINTER_FITTER_H__ */
|
|
@ -1,27 +1,24 @@
|
||||||
|
#include <ft2build.h>
|
||||||
#include "pshglob.h"
|
#include "pshglob.h"
|
||||||
|
|
||||||
/* "simple" ps hinter globals management, inspired from the new auto-hinter */
|
/* "simple" ps hinter globals management, inspired from the new auto-hinter */
|
||||||
|
|
||||||
FT_LOCAL void
|
/*************************************************************************/
|
||||||
psh_globals_init( PSH_Globals globals,
|
/*************************************************************************/
|
||||||
FT_Memory memory )
|
/***** *****/
|
||||||
{
|
/***** STANDARD WIDTHS *****/
|
||||||
memset( globals, 0, sizeof(*globals) );
|
/***** *****/
|
||||||
globals->memory = memory;
|
/*************************************************************************/
|
||||||
globals->x_scale = 0x10000L;
|
/*************************************************************************/
|
||||||
globals->y_scale = 0x10000L;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* reset the widths/heights table */
|
/* reset the widths/heights table */
|
||||||
static FT_Error
|
static void
|
||||||
psh_globals_reset_widths( PSH_Globals globals,
|
psh_globals_reset_widths( PSH_Globals globals,
|
||||||
FT_UInt direction,
|
FT_UInt direction,
|
||||||
PS_Globals_Widths widths )
|
PS_Globals_Widths widths )
|
||||||
{
|
{
|
||||||
PSH_Dimension dim = &globals->dim[direction];
|
PSH_Dimension dim = &globals->dimension[direction];
|
||||||
FT_Memory memory = globals->memory;
|
|
||||||
FT_Error error = 0;
|
|
||||||
|
|
||||||
/* simple copy of the original widths values - no sorting */
|
/* simple copy of the original widths values - no sorting */
|
||||||
{
|
{
|
||||||
|
@ -37,8 +34,6 @@
|
||||||
read++;
|
read++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return error;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -47,10 +42,11 @@
|
||||||
psh_globals_scale_widths( PSH_Globals globals,
|
psh_globals_scale_widths( PSH_Globals globals,
|
||||||
FT_UInt direction )
|
FT_UInt direction )
|
||||||
{
|
{
|
||||||
PSH_Widths std = &globals->std[direction];
|
PSH_Dimension dim = &globals->dimension[direction];
|
||||||
|
PSH_Widths std = &dim->std;
|
||||||
FT_UInt count = std->count;
|
FT_UInt count = std->count;
|
||||||
PSH_Width width = std->widths;
|
PSH_Width width = std->widths;
|
||||||
FT_Fixed scale = globals->scale[direction];
|
FT_Fixed scale = dim->scale_mult;
|
||||||
|
|
||||||
for ( ; count > 0; count--, width++ )
|
for ( ; count > 0; count--, width++ )
|
||||||
{
|
{
|
||||||
|
@ -60,218 +56,415 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* reset the blues table */
|
|
||||||
static FT_Error
|
FT_LOCAL_DEF FT_Pos
|
||||||
psh_globals_reset_blues( PSH_Globals globals,
|
psh_dimension_snap_width( PSH_Dimension dimension,
|
||||||
PS_Globals_Blues blues )
|
FT_Int org_width )
|
||||||
{
|
{
|
||||||
FT_Error error = 0;
|
FT_UInt n;
|
||||||
FT_Memory memory = globals->memory;
|
FT_Pos width = FT_MulFix( org_width, dimension->scale_mult );
|
||||||
|
FT_Pos best = 64 + 32 + 2;
|
||||||
|
FT_Pos reference = width;
|
||||||
|
|
||||||
if ( !FT_REALLOC_ARRAY( globals->blues.zones, globals->blues.count,
|
for ( n = 0; n < dimension->std.count; n++ )
|
||||||
blues->count, PSH_Blue_ZoneRec ) )
|
|
||||||
{
|
{
|
||||||
FT_UInt count = 0;
|
FT_Pos w;
|
||||||
|
FT_Pos dist;
|
||||||
|
|
||||||
globals->blyes.count = blues->count;
|
w = dimension->std.widths[n].cur;
|
||||||
|
dist = width - w;
|
||||||
/* first of all, build a sorted table of blue zones */
|
if ( dist < 0 )
|
||||||
|
dist = -dist;
|
||||||
|
if ( dist < best )
|
||||||
{
|
{
|
||||||
FT_Int16* read = blue->zones;
|
best = dist;
|
||||||
FT_UInt n, i, j;
|
reference = w;
|
||||||
FT_Pos reference, overshoot, delta;
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for ( n = 0; n < blues->count; n++, read++ )
|
if ( width >= reference )
|
||||||
{
|
{
|
||||||
PSH_Blue_Zone zone;
|
width -= 0x21;
|
||||||
|
if ( width < reference )
|
||||||
|
width = reference;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
width += 0x21;
|
||||||
|
if ( width > reference )
|
||||||
|
width = reference;
|
||||||
|
}
|
||||||
|
|
||||||
/* read new blue zone entry, find top and bottom coordinates */
|
return width;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*************************************************************************/
|
||||||
|
/*************************************************************************/
|
||||||
|
/***** *****/
|
||||||
|
/***** BLUE ZONES *****/
|
||||||
|
/***** *****/
|
||||||
|
/*************************************************************************/
|
||||||
|
/*************************************************************************/
|
||||||
|
|
||||||
|
static void
|
||||||
|
psh_blues_reset_zones( PSH_Blues target,
|
||||||
|
PS_Globals_Blues source,
|
||||||
|
FT_Int family )
|
||||||
|
{
|
||||||
|
PSH_Blue_Table top_table, bot_table;
|
||||||
|
FT_Int16* read;
|
||||||
|
FT_Int read_count, count, count_top, count_bot;
|
||||||
|
|
||||||
|
if ( family )
|
||||||
|
{
|
||||||
|
top_table = &target->family_top;
|
||||||
|
bot_table = &target->family_bottom;
|
||||||
|
read = source->zones_family;
|
||||||
|
read_count = (FT_Int)source->count_family;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
top_table = &target->normal_top;
|
||||||
|
bot_table = &target->normal_bottom;
|
||||||
|
read = source->zones;
|
||||||
|
read_count = (FT_Int)source->count;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* read the input blue zones, and build two sorted tables */
|
||||||
|
/* (one for the top zones, the other for the bottom zones */
|
||||||
|
count_top = 0;
|
||||||
|
count_bot = 0;
|
||||||
|
for ( ; read_count > 0; read_count-- )
|
||||||
|
{
|
||||||
|
FT_Int reference, delta;
|
||||||
|
PSH_Blue_Zone zones, zone;
|
||||||
|
|
||||||
|
/* read blue zone entry, and select target top/bottom zone */
|
||||||
reference = read[0];
|
reference = read[0];
|
||||||
overshoot = read[1];
|
delta = read[1] - reference;
|
||||||
delta = overshoot - reference;
|
|
||||||
|
|
||||||
/* now, insert in the blue zone table, sorted by reference position */
|
if ( delta >= 0 )
|
||||||
zone = globals->blues.zones;
|
|
||||||
for ( i = 0; i < count; i++, zone++ )
|
|
||||||
{
|
{
|
||||||
if ( reference > zone->org_ref )
|
zones = top_table->zones;
|
||||||
|
count = count_top;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
zones = bot_table->zones;
|
||||||
|
count = count_bot;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* insert into sorted table */
|
||||||
|
zone = zones;
|
||||||
|
for ( ; count > 0; count--, zone++ )
|
||||||
|
{
|
||||||
|
if ( reference < zone->org_ref )
|
||||||
break;
|
break;
|
||||||
|
|
||||||
if ( reference == zone->org_ref )
|
if ( reference == zone->org_ref )
|
||||||
{
|
{
|
||||||
/* on the same reference coordinate, place bottom zones */
|
FT_Int delta0 = zone->org_delta;
|
||||||
/* before top zones.. */
|
|
||||||
if ( delta < 0 || zone->org_delta >= 0 )
|
/* we have two zones on the same reference position */
|
||||||
break;
|
/* only keep the largest one.. */
|
||||||
|
if ( delta < 0 )
|
||||||
|
{
|
||||||
|
if ( delta < delta0 )
|
||||||
|
zone->org_delta = delta;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if ( delta > delta0 )
|
||||||
|
zone->org_delta = delta;
|
||||||
|
}
|
||||||
|
goto Skip;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for ( j = count - i; j > 0; j-- )
|
for ( ; count > 0; count-- )
|
||||||
zone[j+1] = zone[j];
|
zone[count] = zone[count-1];
|
||||||
|
|
||||||
zone->org_ref = reference;
|
zone->org_ref = reference;
|
||||||
zone->org_delta = delta;
|
zone->org_delta = delta;
|
||||||
|
|
||||||
count++;
|
if ( delta >= 0 )
|
||||||
|
count_top ++;
|
||||||
|
else
|
||||||
|
count_bot ++;
|
||||||
|
|
||||||
|
Skip:
|
||||||
|
read += 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
top_table->count = count_top;
|
||||||
|
bot_table->count = count_bot;
|
||||||
|
|
||||||
|
/* sanitize top table */
|
||||||
|
{
|
||||||
|
PSH_Blue_Zone zone = top_table->zones;
|
||||||
|
|
||||||
|
for ( count = count_top-1; count > 0; count--, zone++ )
|
||||||
|
{
|
||||||
|
FT_Int delta;
|
||||||
|
|
||||||
|
delta = zone[1].org_ref - zone[0].org_ref;
|
||||||
|
if ( zone->org_delta > delta )
|
||||||
|
zone->org_delta = delta;
|
||||||
|
|
||||||
|
zone->org_bottom = zone->org_ref;
|
||||||
|
zone->org_top = zone->org_delta + zone->org_ref;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* now, get rid of blue zones located on the same reference position */
|
/* sanitize bottom table */
|
||||||
/* (only keep the largest zone).. */
|
|
||||||
{
|
{
|
||||||
PSH_Blue_Zone zone, limit;
|
PSH_Blue_Zone zone = bot_table->zones;
|
||||||
|
|
||||||
zone = globals->blues.zones;
|
for ( count = count_bot-1; count > 0; count--, zone++ )
|
||||||
limit = zone + count;
|
|
||||||
for ( ; zone+1 < limit; zone++ )
|
|
||||||
{
|
{
|
||||||
if ( zone[0].org_ref == zone[1].org_ref )
|
FT_Int delta;
|
||||||
{
|
|
||||||
FT_Int delta0 = zone[0].org_delta;
|
|
||||||
FT_Int delta1 = zone[1].org_delta;
|
|
||||||
|
|
||||||
/* these two zones are located on the same reference coordinate */
|
delta = zone[0].org_ref - zone[1].org_ref;
|
||||||
/* we need to merge them when they're in the same direction.. */
|
if ( zone->org_delta < delta )
|
||||||
if ( ( delta0 < 0 ) ^ ( delta1 < 0 ) ) == 0 )
|
zone->org_delta = delta;
|
||||||
|
|
||||||
|
zone->org_top = zone->org_ref;
|
||||||
|
zone->org_bottom = zone->org_delta + zone->org_ref;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* expand top and bottom tables with blue fuzz */
|
||||||
{
|
{
|
||||||
/* ok, take the biggest one */
|
FT_Int dim, top, bot, delta, fuzz;
|
||||||
if ( delta0 < 0 )
|
PSH_Blue_Zone zone;
|
||||||
|
|
||||||
|
fuzz = source->fuzz;
|
||||||
|
zone = top_table->zones;
|
||||||
|
count = count_top;
|
||||||
|
|
||||||
|
for ( dim = 1; dim >= 0; dim-- )
|
||||||
{
|
{
|
||||||
if ( delta1 < delta0 )
|
if ( count > 0 )
|
||||||
delta0 = delta1;
|
{
|
||||||
|
/* expand the bottom of the lowest zone normally */
|
||||||
|
zone->org_bottom -= fuzz;
|
||||||
|
|
||||||
|
/* expand the top and bottom of intermediate zones */
|
||||||
|
/* checking that the interval is smaller than the fuzz */
|
||||||
|
top = zone->org_top;
|
||||||
|
|
||||||
|
for ( count--; count > 0; count--, zone++ )
|
||||||
|
{
|
||||||
|
bot = zone[1].org_bottom;
|
||||||
|
delta = bot - top;
|
||||||
|
if ( delta < 2*fuzz )
|
||||||
|
{
|
||||||
|
zone[0].org_top = zone[1].org_bottom = top + delta/2;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if ( delta1 > delta0 )
|
zone[0].org_top = top + fuzz;
|
||||||
delta0 = delta1;
|
zone[1].org_bottom = bot - fuzz;
|
||||||
}
|
}
|
||||||
|
|
||||||
zone[0].org_delta = delta0;
|
zone++;
|
||||||
|
top = zone->org_top;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* expand the top of the highest zone normally */
|
||||||
|
zone->org_top = top + fuzz;
|
||||||
|
}
|
||||||
|
zone = bot_table->zones;
|
||||||
|
count = count_bot;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* reset the blues table */
|
||||||
|
static void
|
||||||
|
psh_blues_scale_zones( PSH_Blues blues,
|
||||||
|
FT_Fixed scale,
|
||||||
|
FT_Pos delta )
|
||||||
{
|
{
|
||||||
PSH_Blue_Zone cur = zone+1;
|
FT_UInt count;
|
||||||
FT_UInt count2 = limit - cur;
|
FT_UInt num;
|
||||||
|
PSH_Blue_Table table = 0;
|
||||||
|
|
||||||
for ( ; count2 > 0; count2--, cur++ )
|
for ( num = 0; num < 4; num++ )
|
||||||
{
|
{
|
||||||
cur[0].org_ref = cur[1].org_ref;
|
PSH_Blue_Zone zone;
|
||||||
cur[0].org_delta = cur[1].org_delta;
|
|
||||||
|
switch (num)
|
||||||
|
{
|
||||||
|
case 0: table = &blues->normal_top; break;
|
||||||
|
case 1: table = &blues->normal_bottom; break;
|
||||||
|
case 2: table = &blues->family_top; break;
|
||||||
|
default: table = &blues->family_bottom;
|
||||||
|
}
|
||||||
|
|
||||||
|
zone = table->zones;
|
||||||
|
count = table->count;
|
||||||
|
for ( ; count > 0; count--, zone++ )
|
||||||
|
{
|
||||||
|
zone->cur_top = FT_MulFix( zone->org_top, scale ) + delta;
|
||||||
|
zone->cur_bottom = FT_MulFix( zone->org_bottom, scale ) + delta;
|
||||||
|
zone->cur_ref = FT_MulFix( zone->org_ref, scale ) + delta;
|
||||||
|
zone->cur_delta = FT_MulFix( zone->org_delta, scale );
|
||||||
|
|
||||||
|
/* round scaled reference position */
|
||||||
|
zone->cur_ref = ( zone->cur_ref + 32 ) & -64;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
count--;
|
|
||||||
limit--;
|
/* XXX: we should process the family / normal tables here !! */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
FT_LOCAL_DEF void
|
||||||
|
psh_blues_snap_stem( PSH_Blues blues,
|
||||||
|
FT_Int stem_top,
|
||||||
|
FT_Int stem_bot,
|
||||||
|
PSH_Blue_Alignement alignment )
|
||||||
|
{
|
||||||
|
PSH_Blue_Table table;
|
||||||
|
FT_UInt count;
|
||||||
|
PSH_Blue_Zone zone;
|
||||||
|
|
||||||
|
alignment->align = 0;
|
||||||
|
|
||||||
|
/* lookup stem top in top zones table */
|
||||||
|
table = &blues->normal_top;
|
||||||
|
count = table->count;
|
||||||
|
zone = table->zones;
|
||||||
|
for ( ; count > 0; count-- )
|
||||||
|
{
|
||||||
|
if ( stem_top < zone->org_bottom )
|
||||||
|
break;
|
||||||
|
|
||||||
|
if ( stem_top <= zone->org_top )
|
||||||
|
{
|
||||||
|
alignment->align |= PSH_BLUE_ALIGN_TOP;
|
||||||
|
alignment->align_top = zone->cur_ref;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* lookup stem bottom in bottom zones table */
|
||||||
|
table = &blues->normal_bottom;
|
||||||
|
count = table->count;
|
||||||
|
zone = table->zones;
|
||||||
|
for ( ; count > 0; count-- )
|
||||||
|
{
|
||||||
|
if ( stem_bot < zone->org_bottom )
|
||||||
|
break;
|
||||||
|
|
||||||
|
if ( stem_bot <= zone->org_top )
|
||||||
|
{
|
||||||
|
alignment->align |= PSH_BLUE_ALIGN_BOT;
|
||||||
|
alignment->align_bot = zone->cur_ref;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
globals->blues.count = count;
|
/*************************************************************************/
|
||||||
globals->blues.org_shift = blues->shift;
|
/*************************************************************************/
|
||||||
globals->blues.org_fuzz = blues->fuzz;
|
/***** *****/
|
||||||
|
/***** GLOBAL HINTS *****/
|
||||||
|
/***** *****/
|
||||||
|
/*************************************************************************/
|
||||||
|
/*************************************************************************/
|
||||||
|
|
||||||
|
static void
|
||||||
|
psh_globals_destroy( PSH_Globals globals )
|
||||||
|
{
|
||||||
|
if (globals)
|
||||||
|
{
|
||||||
|
FT_Memory memory;
|
||||||
|
|
||||||
|
memory = globals->memory;
|
||||||
|
globals->dimension[0].std.count = 0;
|
||||||
|
globals->dimension[1].std.count = 0;
|
||||||
|
|
||||||
|
globals->blues.normal_top.count = 0;
|
||||||
|
globals->blues.normal_bottom.count = 0;
|
||||||
|
globals->blues.family_top.count = 0;
|
||||||
|
globals->blues.family_bottom.count = 0;
|
||||||
|
|
||||||
|
FREE( globals );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static FT_Error
|
||||||
|
psh_globals_new( FT_Memory memory, PSH_Globals *aglobals )
|
||||||
|
{
|
||||||
|
PSH_Globals globals;
|
||||||
|
FT_Error error;
|
||||||
|
|
||||||
|
if ( !ALLOC( globals, sizeof(*globals) ) )
|
||||||
|
globals->memory = memory;
|
||||||
|
|
||||||
|
*aglobals = globals;
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static FT_Error
|
||||||
psh_globals_scale_blues( PSH_Globals globals,
|
|
||||||
PS_Globals_Blues blues )
|
|
||||||
{
|
|
||||||
FT_Fixed y_scale = globals->scale[1];
|
|
||||||
FT_Fixed y_delta = globals->delta[1];
|
|
||||||
FT_Pos prev_top;
|
|
||||||
PSH_Blue_Zone zone, prev;
|
|
||||||
FT_UInt count;
|
|
||||||
|
|
||||||
zone = globals->blues.zones;
|
|
||||||
prev = 0;
|
|
||||||
prev_top = 0;
|
|
||||||
for ( count = globals->blues.count; count > 0; count-- )
|
|
||||||
{
|
|
||||||
FT_Pos ref, delta, top, bottom;
|
|
||||||
|
|
||||||
ref = FT_MulFix( zone->org_ref, y_scale ) + y_delta;
|
|
||||||
delta = FT_MulFix( zone->org_delta, y_scale );
|
|
||||||
ref = (ref+32) & -64;
|
|
||||||
|
|
||||||
if ( delta < 0 )
|
|
||||||
{
|
|
||||||
top = ref;
|
|
||||||
bottom = ref + delta;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
bottom = ref;
|
|
||||||
top = ref + delta;
|
|
||||||
}
|
|
||||||
|
|
||||||
zone->cur_ref = ref;
|
|
||||||
zone->cur_delta = delta;
|
|
||||||
zone->cur_top = top;
|
|
||||||
zone->cur_bottom = bottom;
|
|
||||||
|
|
||||||
if
|
|
||||||
prev = zone;
|
|
||||||
zone++;
|
|
||||||
}
|
|
||||||
/* XXXX: test overshoot supression !! */
|
|
||||||
}
|
|
||||||
|
|
||||||
FT_LOCAL FT_Error
|
|
||||||
psh_globals_reset( PSH_Globals globals,
|
psh_globals_reset( PSH_Globals globals,
|
||||||
T1_Fitter_Globals public_globals )
|
PS_Globals ps_globals )
|
||||||
{
|
{
|
||||||
psh_globals_reset_widths( globals, 0, &public_globals->horizontal );
|
psh_globals_reset_widths( globals, 0, &ps_globals->horizontal );
|
||||||
psh_globals_scale_widths( globals, 0 );
|
psh_globals_reset_widths( globals, 1, &ps_globals->vertical );
|
||||||
|
psh_blues_reset_zones( &globals->blues, &ps_globals->blues, 0 );
|
||||||
|
psh_blues_reset_zones( &globals->blues, &ps_globals->blues, 1 );
|
||||||
|
|
||||||
psh_globals_reset_widths( globals, 1, &public_globals->vertical );
|
globals->dimension[0].scale_mult = 0;
|
||||||
psh_globals_scale_widths( globals, 1 );
|
globals->dimension[0].scale_delta = 0;
|
||||||
|
globals->dimension[1].scale_mult = 0;
|
||||||
|
globals->dimension[1].scale_delta = 0;
|
||||||
|
|
||||||
psh_globals_reset_blues( globals, public_globals );
|
return 0;
|
||||||
psh_globals_scale_blues( globals );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
FT_LOCAL void
|
static FT_Error
|
||||||
psh_globals_set_scale( PSH_Globals globals,
|
psh_globals_set_scale( PSH_Globals globals,
|
||||||
FT_Fixed x_scale,
|
FT_Fixed x_scale,
|
||||||
FT_Fixed x_delta,
|
FT_Fixed x_delta,
|
||||||
FT_Fixed y_scale,
|
FT_Fixed y_scale,
|
||||||
FT_Fixed y_delta )
|
FT_Fixed y_delta )
|
||||||
{
|
{
|
||||||
FT_Memory memory = globals->memory;
|
PSH_Dimension dim = &globals->dimension[0];
|
||||||
|
|
||||||
if ( x_scale != globals->scale[0] ||
|
dim = &globals->dimension[0];
|
||||||
y_scale != globals->scale[1] ||
|
if ( x_scale != dim->scale_mult ||
|
||||||
x_delta != globals->delta[0] ||
|
x_delta != dim->scale_delta )
|
||||||
y_delta != globals->delta[1] )
|
|
||||||
{
|
{
|
||||||
globals->scale[0] = x_scale;
|
dim->scale_mult = x_scale;
|
||||||
globals->scale[1] = y_scale;
|
dim->scale_delta = x_delta;
|
||||||
globals->delta[0] = x_delta;
|
|
||||||
globals->delta[1] = y_delta;
|
|
||||||
|
|
||||||
psh_globals_scale_widths( globals, 0 );
|
psh_globals_scale_widths( globals, 0 );
|
||||||
|
}
|
||||||
|
|
||||||
|
dim = &globals->dimension[1];
|
||||||
|
if ( y_scale != dim->scale_mult ||
|
||||||
|
y_delta != dim->scale_delta )
|
||||||
|
{
|
||||||
psh_globals_scale_widths( globals, 1 );
|
psh_globals_scale_widths( globals, 1 );
|
||||||
psh_globals_scale_blues ( globals );
|
psh_blues_scale_zones( &globals->blues, y_scale, y_delta );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
FT_LOCAL void
|
FT_LOCAL_DEF void
|
||||||
psh_globals_done( PSH_Globals globals )
|
psh_globals_funcs_init( PSH_Globals_FuncsRec* funcs )
|
||||||
{
|
{
|
||||||
if (globals)
|
funcs->create = psh_globals_new;
|
||||||
{
|
funcs->reset = psh_globals_reset;
|
||||||
FT_Memory memory = globals->memory;
|
funcs->set_scale = psh_globals_set_scale;
|
||||||
|
funcs->destroy = psh_globals_destroy;
|
||||||
FT_FREE( globals->std[0].widths );
|
|
||||||
globals->std[0].count = 0;
|
|
||||||
|
|
||||||
FT_FREE( globals->std[1].widths );
|
|
||||||
globals->std[1].count = 0;
|
|
||||||
|
|
||||||
FT_FREE( globals->blues.zones );
|
|
||||||
globals->blues.count = 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,26 @@
|
||||||
|
/***************************************************************************/
|
||||||
|
/* */
|
||||||
|
/* pshglob.h */
|
||||||
|
/* */
|
||||||
|
/* Postscript hinter globals hints management. */
|
||||||
|
/* */
|
||||||
|
/* Copyright 2001 by */
|
||||||
|
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
|
||||||
|
/* */
|
||||||
|
/* This file is part of the FreeType project, and may only be used, */
|
||||||
|
/* modified, and distributed under the terms of the FreeType project */
|
||||||
|
/* license, LICENSE.TXT. By continuing to use, modify, or distribute */
|
||||||
|
/* this file you indicate that you have read the license and */
|
||||||
|
/* understand and accept it fully. */
|
||||||
|
/* */
|
||||||
|
/***************************************************************************/
|
||||||
|
|
||||||
#ifndef __PS_HINTER_GLOBALS_H__
|
#ifndef __PS_HINTER_GLOBALS_H__
|
||||||
#define __PS_HINTER_GLOBALS_H__
|
#define __PS_HINTER_GLOBALS_H__
|
||||||
|
|
||||||
|
#include FT_FREETYPE_H
|
||||||
|
#include FT_INTERNAL_POSTSCRIPT_GLOBALS_H
|
||||||
|
|
||||||
FT_BEGIN_HEADER
|
FT_BEGIN_HEADER
|
||||||
|
|
||||||
/**********************************************************************/
|
/**********************************************************************/
|
||||||
|
@ -11,37 +31,6 @@ FT_BEGIN_HEADER
|
||||||
/**********************************************************************/
|
/**********************************************************************/
|
||||||
/**********************************************************************/
|
/**********************************************************************/
|
||||||
|
|
||||||
/* blue zone descriptor */
|
|
||||||
typedef struct PSH_Blue_ZoneRec_
|
|
||||||
{
|
|
||||||
FT_Int org_ref;
|
|
||||||
FT_Int org_delta;
|
|
||||||
FT_Pos cur_ref;
|
|
||||||
FT_Pos cur_delta;
|
|
||||||
FT_Pos cur_bottom;
|
|
||||||
FT_Pos cur_top;
|
|
||||||
|
|
||||||
} PSH_Blue_ZoneRec, *PSH_Blue_Zone;
|
|
||||||
|
|
||||||
|
|
||||||
/* blue zones table */
|
|
||||||
typedef struct PSH_BluesRec_
|
|
||||||
{
|
|
||||||
FT_UInt count;
|
|
||||||
PSH_Blue_ZoneRec zones[ PS_GLOBALS_MAX_BLUE_ZONES ];
|
|
||||||
|
|
||||||
FT_UInt count_family;
|
|
||||||
PSH_Blue_ZoneRec zones_family[ PS_GLOBALS_MAX_BLUE_ZONES ];
|
|
||||||
|
|
||||||
FT_Fixed scale;
|
|
||||||
FT_Int org_shift;
|
|
||||||
FT_Int org_fuzz;
|
|
||||||
FT_Pos cur_shift;
|
|
||||||
FT_Pos cur_fuzz;
|
|
||||||
|
|
||||||
} PSH_BluesRec, *PSH_Blues;
|
|
||||||
|
|
||||||
|
|
||||||
/* standard and snap width */
|
/* standard and snap width */
|
||||||
typedef struct PSH_WidthRec_
|
typedef struct PSH_WidthRec_
|
||||||
{
|
{
|
||||||
|
@ -49,7 +38,7 @@ FT_BEGIN_HEADER
|
||||||
FT_Pos cur;
|
FT_Pos cur;
|
||||||
FT_Pos fit;
|
FT_Pos fit;
|
||||||
|
|
||||||
} PSH_WidthRec;
|
} PSH_WidthRec, *PSH_Width;
|
||||||
|
|
||||||
|
|
||||||
/* standard and snap widths table */
|
/* standard and snap widths table */
|
||||||
|
@ -69,6 +58,44 @@ FT_BEGIN_HEADER
|
||||||
|
|
||||||
} PSH_DimensionRec, *PSH_Dimension;
|
} PSH_DimensionRec, *PSH_Dimension;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* blue zone descriptor */
|
||||||
|
typedef struct PSH_Blue_ZoneRec_
|
||||||
|
{
|
||||||
|
FT_Int org_ref;
|
||||||
|
FT_Int org_delta;
|
||||||
|
FT_Int org_top;
|
||||||
|
FT_Int org_bottom;
|
||||||
|
|
||||||
|
FT_Pos cur_ref;
|
||||||
|
FT_Pos cur_delta;
|
||||||
|
FT_Pos cur_bottom;
|
||||||
|
FT_Pos cur_top;
|
||||||
|
|
||||||
|
} PSH_Blue_ZoneRec, *PSH_Blue_Zone;
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct PSH_Blue_TableRec_
|
||||||
|
{
|
||||||
|
FT_UInt count;
|
||||||
|
PSH_Blue_ZoneRec zones[ PS_GLOBALS_MAX_BLUE_ZONES ];
|
||||||
|
|
||||||
|
} PSH_Blue_TableRec, *PSH_Blue_Table;
|
||||||
|
|
||||||
|
|
||||||
|
/* blue zones table */
|
||||||
|
typedef struct PSH_BluesRec_
|
||||||
|
{
|
||||||
|
PSH_Blue_TableRec normal_top;
|
||||||
|
PSH_Blue_TableRec normal_bottom;
|
||||||
|
PSH_Blue_TableRec family_top;
|
||||||
|
PSH_Blue_TableRec family_bottom;
|
||||||
|
FT_Fixed blue_scale;
|
||||||
|
|
||||||
|
} PSH_BluesRec, *PSH_Blues;
|
||||||
|
|
||||||
|
|
||||||
/* font globals */
|
/* font globals */
|
||||||
typedef struct PSH_GlobalsRec_
|
typedef struct PSH_GlobalsRec_
|
||||||
{
|
{
|
||||||
|
@ -79,30 +106,38 @@ FT_BEGIN_HEADER
|
||||||
} PSH_GlobalsRec, *PSH_Globals;
|
} PSH_GlobalsRec, *PSH_Globals;
|
||||||
|
|
||||||
|
|
||||||
/* initialise font globals */
|
typedef enum
|
||||||
|
{
|
||||||
|
PSH_BLUE_ALIGN_TOP = 1,
|
||||||
|
PSH_BLUE_ALIGN_BOT = 2
|
||||||
|
|
||||||
|
} PSH_Blue_Align;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
PSH_Blue_Align align;
|
||||||
|
FT_Pos align_top;
|
||||||
|
FT_Pos align_bot;
|
||||||
|
|
||||||
|
} PSH_Blue_AlignementRec, *PSH_Blue_Alignement;
|
||||||
|
|
||||||
FT_LOCAL void
|
FT_LOCAL void
|
||||||
psh_globals_init( PSH_Globals globals,
|
psh_globals_funcs_init( PSH_Globals_FuncsRec* funcs );
|
||||||
FT_Memory memory );
|
|
||||||
|
|
||||||
/* reset font globals to new values */
|
/* snap a stem width to fitter coordinates */
|
||||||
FT_LOCAL FT_Error
|
FT_LOCAL FT_Pos
|
||||||
psh_globals_reset( PSH_Globals globals_hinter,
|
psh_dimension_snap_width( PSH_Dimension dimension,
|
||||||
PS_Globals globals );
|
FT_Int org_width );
|
||||||
|
|
||||||
/* change current scale transform */
|
/* snap a stem to one or two blue zones */
|
||||||
FT_LOCAL void
|
FT_LOCAL void
|
||||||
psh_globals_set_scale( PSH_Globals globals_hinter,
|
psh_blues_snap_stem( PSH_Blues blues,
|
||||||
FT_Fixed x_scale,
|
FT_Int stem_top,
|
||||||
FT_Fixed x_delta,
|
FT_Int stem_bot,
|
||||||
FT_Fixed y_scale,
|
PSH_Blue_Alignement alignment );
|
||||||
FT_Fixed y_delta );
|
|
||||||
|
|
||||||
/* finalize font globals */
|
|
||||||
FT_LOCAL void
|
|
||||||
psh_globals_done( PSH_Globals globals );
|
|
||||||
|
|
||||||
/* */
|
/* */
|
||||||
|
|
||||||
|
|
||||||
FT_END_HEADER
|
FT_END_HEADER
|
||||||
|
|
||||||
#endif __T1_FITTER_GLOBALS_H__
|
#endif __T1_FITTER_GLOBALS_H__
|
||||||
|
|
|
@ -0,0 +1,27 @@
|
||||||
|
/***************************************************************************/
|
||||||
|
/* */
|
||||||
|
/* pshinter.c */
|
||||||
|
/* */
|
||||||
|
/* FreeType Postscript Hinting module */
|
||||||
|
/* */
|
||||||
|
/* Copyright 1996-2000 by */
|
||||||
|
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
|
||||||
|
/* */
|
||||||
|
/* This file is part of the FreeType project, and may only be used, */
|
||||||
|
/* modified, and distributed under the terms of the FreeType project */
|
||||||
|
/* license, LICENSE.TXT. By continuing to use, modify, or distribute */
|
||||||
|
/* this file you indicate that you have read the license and */
|
||||||
|
/* understand and accept it fully. */
|
||||||
|
/* */
|
||||||
|
/***************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
#define FT_MAKE_OPTION_SINGLE_OBJECT
|
||||||
|
|
||||||
|
#include <ft2build.h>
|
||||||
|
#include "pshrec.c"
|
||||||
|
#include "pshglob.c"
|
||||||
|
#include "pshfit.c"
|
||||||
|
#include "pshmod.c"
|
||||||
|
|
||||||
|
/* END */
|
|
@ -0,0 +1,114 @@
|
||||||
|
/***************************************************************************/
|
||||||
|
/* */
|
||||||
|
/* pshmod.c */
|
||||||
|
/* */
|
||||||
|
/* FreeType Postscript hinter module implementation (body). */
|
||||||
|
/* */
|
||||||
|
/* Copyright 2000 by */
|
||||||
|
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
|
||||||
|
/* */
|
||||||
|
/* This file is part of the FreeType project, and may only be used, */
|
||||||
|
/* modified, and distributed under the terms of the FreeType project */
|
||||||
|
/* license, LICENSE.TXT. By continuing to use, modify, or distribute */
|
||||||
|
/* this file you indicate that you have read the license and */
|
||||||
|
/* understand and accept it fully. */
|
||||||
|
/* */
|
||||||
|
/***************************************************************************/
|
||||||
|
|
||||||
|
#include <ft2build.h>
|
||||||
|
#include FT_INTERNAL_OBJECTS_H
|
||||||
|
#include "pshrec.h"
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
FT_ModuleRec root;
|
||||||
|
PS_HintsRec ps_hints;
|
||||||
|
|
||||||
|
PSH_Globals_FuncsRec globals_funcs;
|
||||||
|
T1_Hints_FuncsRec t1_funcs;
|
||||||
|
T2_Hints_FuncsRec t2_funcs;
|
||||||
|
|
||||||
|
} PS_Hinter_ModuleRec, *PS_Hinter_Module;
|
||||||
|
|
||||||
|
|
||||||
|
/* finalize module */
|
||||||
|
FT_CALLBACK_DEF void
|
||||||
|
ps_hinter_done( PS_Hinter_Module module )
|
||||||
|
{
|
||||||
|
module->t1_funcs.hints = NULL;
|
||||||
|
module->t2_funcs.hints = NULL;
|
||||||
|
|
||||||
|
ps_hints_done( &module->ps_hints );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* initialise module, create hints recorder and the interface */
|
||||||
|
FT_CALLBACK_DEF FT_Error
|
||||||
|
ps_hinter_init( PS_Hinter_Module module )
|
||||||
|
{
|
||||||
|
FT_Memory memory = module->root.memory;
|
||||||
|
|
||||||
|
ps_hints_init( &module->ps_hints, memory );
|
||||||
|
|
||||||
|
psh_globals_funcs_init( &module->globals_funcs );
|
||||||
|
|
||||||
|
t1_hints_funcs_init( &module->t1_funcs );
|
||||||
|
module->t1_funcs.hints = (T1_Hints) & module->ps_hints;
|
||||||
|
/* XXX: module->t1_funcs.apply = .... */
|
||||||
|
|
||||||
|
t2_hints_funcs_init( &module->t2_funcs );
|
||||||
|
module->t2_funcs.hints = (T2_Hints) & module->ps_hints;
|
||||||
|
/* XXX: module->t2_funcs.apply = .... */
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* returns global hints interface */
|
||||||
|
FT_CALLBACK_DEF PSH_Globals_Funcs
|
||||||
|
pshinter_get_globals_funcs( FT_Module module )
|
||||||
|
{
|
||||||
|
return &((PS_Hinter_Module)module)->globals_funcs;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* return Type 1 hints interface */
|
||||||
|
FT_CALLBACK_DEF T1_Hints_Funcs
|
||||||
|
pshinter_get_t1_funcs( FT_Module module )
|
||||||
|
{
|
||||||
|
return &((PS_Hinter_Module)module)->t1_funcs;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* return Type 2 hints interface */
|
||||||
|
FT_CALLBACK_DEF T2_Hints_Funcs
|
||||||
|
pshinter_get_t2_funcs( FT_Module module )
|
||||||
|
{
|
||||||
|
return &((PS_Hinter_Module)module)->t2_funcs;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
FT_CALLBACK_DEF
|
||||||
|
PSHinter_Interface pshinter_interface =
|
||||||
|
{
|
||||||
|
pshinter_get_globals_funcs,
|
||||||
|
pshinter_get_t1_funcs,
|
||||||
|
pshinter_get_t2_funcs
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
FT_CALLBACK_TABLE_DEF
|
||||||
|
const FT_Module_Class pshinter_module_class =
|
||||||
|
{
|
||||||
|
0,
|
||||||
|
sizeof( FT_ModuleRec ),
|
||||||
|
"pshinter",
|
||||||
|
0x10000L,
|
||||||
|
0x20000L,
|
||||||
|
|
||||||
|
&pshinter_interface, /* module-specific interface */
|
||||||
|
|
||||||
|
(FT_Module_Constructor) ps_hinter_init,
|
||||||
|
(FT_Module_Destructor) ps_hinter_done,
|
||||||
|
(FT_Module_Requester) 0 /* no additional interface for now */
|
||||||
|
};
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,37 @@
|
||||||
|
/***************************************************************************/
|
||||||
|
/* */
|
||||||
|
/* pshmod.h */
|
||||||
|
/* */
|
||||||
|
/* Postscript hinter module interface */
|
||||||
|
/* */
|
||||||
|
/* Copyright 1996-2000 by */
|
||||||
|
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
|
||||||
|
/* */
|
||||||
|
/* This file is part of the FreeType project, and may only be used, */
|
||||||
|
/* modified, and distributed under the terms of the FreeType project */
|
||||||
|
/* license, LICENSE.TXT. By continuing to use, modify, or distribute */
|
||||||
|
/* this file you indicate that you have read the license and */
|
||||||
|
/* understand and accept it fully. */
|
||||||
|
/* */
|
||||||
|
/***************************************************************************/
|
||||||
|
|
||||||
|
#ifndef __PS_HINTER_MODULE_H__
|
||||||
|
#define __PS_HINTER_MODULE_H__
|
||||||
|
|
||||||
|
|
||||||
|
#include <ft2build.h>
|
||||||
|
#include FT_MODULE_H
|
||||||
|
|
||||||
|
|
||||||
|
FT_BEGIN_HEADER
|
||||||
|
|
||||||
|
|
||||||
|
FT_EXPORT_VAR( const FT_Module_Class ) pshinter_module_class;
|
||||||
|
|
||||||
|
|
||||||
|
FT_END_HEADER
|
||||||
|
|
||||||
|
#endif /* __PS_HINTER_MODULE_H__ */
|
||||||
|
|
||||||
|
|
||||||
|
/* END */
|
|
@ -1,4 +1,8 @@
|
||||||
#include "psrecord.h"
|
#include <ft2build.h>
|
||||||
|
#include FT_FREETYPE_H
|
||||||
|
#include FT_INTERNAL_OBJECTS_H
|
||||||
|
#include FT_INTERNAL_DEBUG_H
|
||||||
|
#include "pshrec.h"
|
||||||
|
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
|
@ -13,7 +17,7 @@
|
||||||
ps_hint_table_done( PS_Hint_Table table,
|
ps_hint_table_done( PS_Hint_Table table,
|
||||||
FT_Memory memory )
|
FT_Memory memory )
|
||||||
{
|
{
|
||||||
FT_FREE( table->hints );
|
FREE( table->hints );
|
||||||
table->num_hints = 0;
|
table->num_hints = 0;
|
||||||
table->max_hints = 0;
|
table->max_hints = 0;
|
||||||
}
|
}
|
||||||
|
@ -33,7 +37,7 @@
|
||||||
{
|
{
|
||||||
/* try to grow the table */
|
/* try to grow the table */
|
||||||
new_max = ( new_max + 7 ) & -8;
|
new_max = ( new_max + 7 ) & -8;
|
||||||
if ( !FT_REALLOC_ARRAY( table->hints, old_max, new_max, PS_HintRec ) )
|
if ( !REALLOC_ARRAY( table->hints, old_max, new_max, PS_HintRec ) )
|
||||||
table->max_hints = new_max;
|
table->max_hints = new_max;
|
||||||
}
|
}
|
||||||
return error;
|
return error;
|
||||||
|
@ -59,8 +63,8 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
hint = table->hints + count-1;
|
hint = table->hints + count-1;
|
||||||
hint->org_pos = 0;
|
hint->pos = 0;
|
||||||
hint->org_len = 0;
|
hint->len = 0;
|
||||||
hint->flags = 0;
|
hint->flags = 0;
|
||||||
|
|
||||||
table->num_hints = count;
|
table->num_hints = count;
|
||||||
|
@ -84,7 +88,7 @@
|
||||||
ps_mask_done( PS_Mask mask,
|
ps_mask_done( PS_Mask mask,
|
||||||
FT_Memory memory )
|
FT_Memory memory )
|
||||||
{
|
{
|
||||||
FT_FREE( mask->bytes );
|
FREE( mask->bytes );
|
||||||
mask->num_bits = 0;
|
mask->num_bits = 0;
|
||||||
mask->max_bits = 0;
|
mask->max_bits = 0;
|
||||||
mask->end_point = 0;
|
mask->end_point = 0;
|
||||||
|
@ -104,7 +108,7 @@
|
||||||
if ( new_max > old_max )
|
if ( new_max > old_max )
|
||||||
{
|
{
|
||||||
new_max = ( new_max + 7 ) & -8;
|
new_max = ( new_max + 7 ) & -8;
|
||||||
if ( !FT_REALLOC_ARRAY( mask->bytes, old_max, new_max, FT_Byte ) )
|
if ( !REALLOC_ARRAY( mask->bytes, old_max, new_max, FT_Byte ) )
|
||||||
mask->max_bits = new_max*8;
|
mask->max_bits = new_max*8;
|
||||||
}
|
}
|
||||||
return error;
|
return error;
|
||||||
|
@ -117,7 +121,7 @@
|
||||||
ps_mask_test_bit( PS_Mask mask,
|
ps_mask_test_bit( PS_Mask mask,
|
||||||
FT_Int index )
|
FT_Int index )
|
||||||
{
|
{
|
||||||
if ( index < 0 || index >= mask->num_bits )
|
if ( (FT_UInt)index >= mask->num_bits )
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
return mask->bytes[index >> 3] & (0x80 >> (index & 7));
|
return mask->bytes[index >> 3] & (0x80 >> (index & 7));
|
||||||
|
@ -131,7 +135,7 @@
|
||||||
{
|
{
|
||||||
FT_Byte* p;
|
FT_Byte* p;
|
||||||
|
|
||||||
if ( index < 0 || index >= mask->num_bits )
|
if ( (FT_UInt)index >= mask->num_bits )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
p = mask->bytes + (index >> 3);
|
p = mask->bytes + (index >> 3);
|
||||||
|
@ -151,7 +155,7 @@
|
||||||
if ( index < 0 )
|
if ( index < 0 )
|
||||||
goto Exit;
|
goto Exit;
|
||||||
|
|
||||||
if ( index >= mask->num_bits )
|
if ( (FT_UInt)index >= mask->num_bits )
|
||||||
{
|
{
|
||||||
error = ps_mask_ensure( mask, index, memory );
|
error = ps_mask_ensure( mask, index, memory );
|
||||||
if (error) goto Exit;
|
if (error) goto Exit;
|
||||||
|
@ -176,7 +180,7 @@
|
||||||
for ( ; count > 0; count--, mask++ )
|
for ( ; count > 0; count--, mask++ )
|
||||||
ps_mask_done( mask, memory );
|
ps_mask_done( mask, memory );
|
||||||
|
|
||||||
FT_FREE( table->masks );
|
FREE( table->masks );
|
||||||
table->num_masks = 0;
|
table->num_masks = 0;
|
||||||
table->max_masks = 0;
|
table->max_masks = 0;
|
||||||
}
|
}
|
||||||
|
@ -195,7 +199,7 @@
|
||||||
if ( new_max > old_max )
|
if ( new_max > old_max )
|
||||||
{
|
{
|
||||||
new_max = (new_max+7) & -8;
|
new_max = (new_max+7) & -8;
|
||||||
if ( !FT_REALLOC_ARRAY( table->masks, old_max, new_max, PS_MaskRec ) )
|
if ( !REALLOC_ARRAY( table->masks, old_max, new_max, PS_MaskRec ) )
|
||||||
table->max_masks = new_max;
|
table->max_masks = new_max;
|
||||||
}
|
}
|
||||||
return error;
|
return error;
|
||||||
|
@ -238,7 +242,7 @@
|
||||||
FT_Memory memory,
|
FT_Memory memory,
|
||||||
PS_Mask *amask )
|
PS_Mask *amask )
|
||||||
{
|
{
|
||||||
FT_Error error;
|
FT_Error error = 0;
|
||||||
FT_UInt count;
|
FT_UInt count;
|
||||||
PS_Mask mask;
|
PS_Mask mask;
|
||||||
|
|
||||||
|
@ -267,7 +271,6 @@
|
||||||
{
|
{
|
||||||
FT_Error error = 0;
|
FT_Error error = 0;
|
||||||
PS_Mask mask;
|
PS_Mask mask;
|
||||||
FT_UInt count;
|
|
||||||
|
|
||||||
/* allocate new mask, and grow it to "bit_count" bits */
|
/* allocate new mask, and grow it to "bit_count" bits */
|
||||||
error = ps_mask_table_alloc( table, memory, &mask );
|
error = ps_mask_table_alloc( table, memory, &mask );
|
||||||
|
@ -286,7 +289,7 @@
|
||||||
FT_Int wmask = 0x80;
|
FT_Int wmask = 0x80;
|
||||||
FT_Int val;
|
FT_Int val;
|
||||||
|
|
||||||
for ( ; source_bits > 0; source_bits-- )
|
for ( ; bit_count > 0; bit_count-- )
|
||||||
{
|
{
|
||||||
val = write[0] & ~wmask;
|
val = write[0] & ~wmask;
|
||||||
|
|
||||||
|
@ -325,7 +328,7 @@
|
||||||
PS_Mask mask1 = table->masks + index1;
|
PS_Mask mask1 = table->masks + index1;
|
||||||
PS_Mask mask2 = table->masks + index2;
|
PS_Mask mask2 = table->masks + index2;
|
||||||
FT_Byte* p1 = mask1->bytes;
|
FT_Byte* p1 = mask1->bytes;
|
||||||
FT_Byte* p2 = mask2->bytes,
|
FT_Byte* p2 = mask2->bytes;
|
||||||
FT_UInt count1 = mask1->num_bits;
|
FT_UInt count1 = mask1->num_bits;
|
||||||
FT_UInt count2 = mask2->num_bits;
|
FT_UInt count2 = mask2->num_bits;
|
||||||
FT_UInt count;
|
FT_UInt count;
|
||||||
|
@ -365,7 +368,7 @@
|
||||||
index2 = index1;
|
index2 = index1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( index1 < index2 && index1 >= 0 && index2 < table->num_masks )
|
if ( index1 < index2 && index1 >= 0 && index2 < (FT_Int)table->num_masks )
|
||||||
{
|
{
|
||||||
/* we need to merge the bitsets of index1 and index2 with a */
|
/* we need to merge the bitsets of index1 and index2 with a */
|
||||||
/* simple union.. */
|
/* simple union.. */
|
||||||
|
@ -406,7 +409,7 @@
|
||||||
|
|
||||||
/* now, remove "mask2" from the list, we need to keep the masks */
|
/* now, remove "mask2" from the list, we need to keep the masks */
|
||||||
/* sorted in order of importance, so move table elements.. */
|
/* sorted in order of importance, so move table elements.. */
|
||||||
mask2->num_bytes = 0;
|
mask2->num_bits = 0;
|
||||||
mask2->end_point = 0;
|
mask2->end_point = 0;
|
||||||
|
|
||||||
delta = table->num_masks-1 - index2; /* number of masks to move */
|
delta = table->num_masks-1 - index2; /* number of masks to move */
|
||||||
|
@ -445,7 +448,7 @@
|
||||||
{
|
{
|
||||||
if ( ps_mask_table_test_intersect( table, index1, index2 ) )
|
if ( ps_mask_table_test_intersect( table, index1, index2 ) )
|
||||||
{
|
{
|
||||||
error = ps_mask_table_merge( table, index2, index1, memory ) );
|
error = ps_mask_table_merge( table, index2, index1, memory );
|
||||||
if (error) goto Exit;
|
if (error) goto Exit;
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
@ -487,6 +490,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#if 0
|
||||||
/* set a bit at a given index in the current hint mask */
|
/* set a bit at a given index in the current hint mask */
|
||||||
static FT_Error
|
static FT_Error
|
||||||
ps_dimension_set_mask_bit( PS_Dimension dim,
|
ps_dimension_set_mask_bit( PS_Dimension dim,
|
||||||
|
@ -505,14 +509,14 @@
|
||||||
Exit:
|
Exit:
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/* set the end point in a mask, called from "End" & "Reset" methods */
|
/* set the end point in a mask, called from "End" & "Reset" methods */
|
||||||
static void
|
static void
|
||||||
ps_dimension_end_mask( PS_Dimension dim,
|
ps_dimension_end_mask( PS_Dimension dim,
|
||||||
FT_UInt end_point )
|
FT_UInt end_point )
|
||||||
{
|
{
|
||||||
FT_UInt count = dimension->masks.num_masks;
|
FT_UInt count = dim->masks.num_masks;
|
||||||
PS_Mask mask;
|
PS_Mask mask;
|
||||||
|
|
||||||
if ( count > 0 )
|
if ( count > 0 )
|
||||||
|
@ -536,7 +540,7 @@
|
||||||
ps_dimension_end_mask( dim, end_point );
|
ps_dimension_end_mask( dim, end_point );
|
||||||
|
|
||||||
/* allocate new one */
|
/* allocate new one */
|
||||||
return ps_mask_table_alloc( dim->masks, memory, &mask );
|
return ps_mask_table_alloc( &dim->masks, memory, &mask );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -550,7 +554,6 @@
|
||||||
FT_Memory memory )
|
FT_Memory memory )
|
||||||
{
|
{
|
||||||
FT_Error error = 0;
|
FT_Error error = 0;
|
||||||
PS_Mask mask;
|
|
||||||
|
|
||||||
/* reset current mask, if any */
|
/* reset current mask, if any */
|
||||||
error = ps_dimension_reset_mask( dim, end_point, memory );
|
error = ps_dimension_reset_mask( dim, end_point, memory );
|
||||||
|
@ -585,6 +588,7 @@
|
||||||
flags |= PS_HINT_FLAG_BOTTOM;
|
flags |= PS_HINT_FLAG_BOTTOM;
|
||||||
pos += len;
|
pos += len;
|
||||||
}
|
}
|
||||||
|
len = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (aindex)
|
if (aindex)
|
||||||
|
@ -599,7 +603,7 @@
|
||||||
|
|
||||||
for ( index = 0; index < max; index++, hint++ )
|
for ( index = 0; index < max; index++, hint++ )
|
||||||
{
|
{
|
||||||
if ( hint->org_pos == pos && hint->org_len == len )
|
if ( hint->pos == pos && hint->len == len )
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -609,8 +613,8 @@
|
||||||
error = ps_hint_table_alloc( &dim->hints, memory, &hint );
|
error = ps_hint_table_alloc( &dim->hints, memory, &hint );
|
||||||
if (error) goto Exit;
|
if (error) goto Exit;
|
||||||
|
|
||||||
hint->org_pos = pos;
|
hint->pos = pos;
|
||||||
hint->org_len = len;
|
hint->len = len;
|
||||||
hint->flags = flags;
|
hint->flags = flags;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -697,25 +701,36 @@
|
||||||
|
|
||||||
|
|
||||||
/* destroy hints */
|
/* destroy hints */
|
||||||
static void
|
FT_LOCAL void
|
||||||
ps_hints_done( PS_Hints hints,
|
ps_hints_done( PS_Hints hints )
|
||||||
FT_Memory memory )
|
|
||||||
{
|
{
|
||||||
|
FT_Memory memory = hints->memory;
|
||||||
|
|
||||||
ps_dimension_done( &hints->dimension[0], memory );
|
ps_dimension_done( &hints->dimension[0], memory );
|
||||||
ps_dimension_done( &hints->dimension[1], memory );
|
ps_dimension_done( &hints->dimension[1], memory );
|
||||||
|
|
||||||
hints->error = 0;
|
hints->error = 0;
|
||||||
|
hints->memory = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FT_LOCAL FT_Error
|
||||||
|
ps_hints_init( PS_Hints hints,
|
||||||
|
FT_Memory memory )
|
||||||
|
{
|
||||||
|
memset( hints, 0, sizeof(*hints) );
|
||||||
|
hints->memory = memory;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/* initialise a hints for a new session */
|
/* initialise a hints for a new session */
|
||||||
static void
|
static void
|
||||||
ps_hints_rewind( PS_Hints hints,
|
ps_hints_open( PS_Hints hints,
|
||||||
PS_Hint_Type hint_type )
|
PS_Hint_Type hint_type )
|
||||||
{
|
{
|
||||||
switch (hint_type)
|
switch (hint_type)
|
||||||
{
|
{
|
||||||
case PS_Hint_Type_1:
|
case PS_HINT_TYPE_1:
|
||||||
case PS_Hint_Type_2:
|
case PS_HINT_TYPE_2:
|
||||||
{
|
{
|
||||||
hints->error = 0;
|
hints->error = 0;
|
||||||
hints->hint_type = hint_type;
|
hints->hint_type = hint_type;
|
||||||
|
@ -755,14 +770,15 @@
|
||||||
/* record the stems in the current hints/masks table */
|
/* record the stems in the current hints/masks table */
|
||||||
switch ( hints->hint_type )
|
switch ( hints->hint_type )
|
||||||
{
|
{
|
||||||
case PS_Hint_Type_1: /* Type 1 "hstem" or "vstem" operator */
|
case PS_HINT_TYPE_1: /* Type 1 "hstem" or "vstem" operator */
|
||||||
case PS_Hint_Type_2: /* Type 2 "hstem" or "vstem" operator */
|
case PS_HINT_TYPE_2: /* Type 2 "hstem" or "vstem" operator */
|
||||||
{
|
{
|
||||||
PS_Dimension dim = &hints->dimension[dimension];
|
PS_Dimension dim = &hints->dimension[dimension];
|
||||||
|
|
||||||
for ( ; count > 0; count--, stems += 2 )
|
for ( ; count > 0; count--, stems += 2 )
|
||||||
{
|
{
|
||||||
FT_Error error;
|
FT_Error error;
|
||||||
|
FT_Memory memory = hints->memory;
|
||||||
|
|
||||||
error = ps_dimension_add_t1stem( dim, stems[0], stems[1],
|
error = ps_dimension_add_t1stem( dim, stems[0], stems[1],
|
||||||
memory, NULL );
|
memory, NULL );
|
||||||
|
@ -784,6 +800,7 @@
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* add one Type1 counter stem to the current hints table */
|
/* add one Type1 counter stem to the current hints table */
|
||||||
|
@ -792,6 +809,8 @@
|
||||||
FT_Int dimension,
|
FT_Int dimension,
|
||||||
FT_Int* stems )
|
FT_Int* stems )
|
||||||
{
|
{
|
||||||
|
FT_Error error = 0;
|
||||||
|
|
||||||
if (!hints->error)
|
if (!hints->error)
|
||||||
{
|
{
|
||||||
PS_Dimension dim;
|
PS_Dimension dim;
|
||||||
|
@ -810,13 +829,13 @@
|
||||||
dim = &hints->dimension[dimension];
|
dim = &hints->dimension[dimension];
|
||||||
|
|
||||||
/* there must be 6 elements in the 'stem' array */
|
/* there must be 6 elements in the 'stem' array */
|
||||||
if ( hints->hint_type == PS_Hint_Type_1 )
|
if ( hints->hint_type == PS_HINT_TYPE_1 )
|
||||||
{
|
{
|
||||||
/* add the three stems to our hints/masks table */
|
/* add the three stems to our hints/masks table */
|
||||||
for ( count = 0; count < 3; count++, stems += 2 )
|
for ( count = 0; count < 3; count++, stems += 2 )
|
||||||
{
|
{
|
||||||
error = ps_dimension_add_t1stem( dim, stems[0], stems[1],
|
error = ps_dimension_add_t1stem( dim, stems[0], stems[1],
|
||||||
&index[count], memory );
|
memory, &index[count] );
|
||||||
if (error) goto Fail;
|
if (error) goto Fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -847,11 +866,13 @@
|
||||||
ps_hints_t1reset( PS_Hints hints,
|
ps_hints_t1reset( PS_Hints hints,
|
||||||
FT_UInt end_point )
|
FT_UInt end_point )
|
||||||
{
|
{
|
||||||
|
FT_Error error = 0;
|
||||||
|
|
||||||
if ( !hints->error )
|
if ( !hints->error )
|
||||||
{
|
{
|
||||||
FT_Memory memory = hints->memory;
|
FT_Memory memory = hints->memory;
|
||||||
|
|
||||||
if ( hints->hint_type == PS_Hint_Type_1 )
|
if ( hints->hint_type == PS_HINT_TYPE_1 )
|
||||||
{
|
{
|
||||||
error = ps_dimension_reset_mask( &hints->dimension[0],
|
error = ps_dimension_reset_mask( &hints->dimension[0],
|
||||||
end_point, memory );
|
end_point, memory );
|
||||||
|
@ -892,7 +913,7 @@
|
||||||
FT_UInt count2 = dim[1].hints.num_hints;
|
FT_UInt count2 = dim[1].hints.num_hints;
|
||||||
|
|
||||||
/* check bit count, must be equal to current total hint count */
|
/* check bit count, must be equal to current total hint count */
|
||||||
if ( (FT_Int)bit_count != count1 + count2 )
|
if ( bit_count != count1 + count2 )
|
||||||
{
|
{
|
||||||
error = FT_Err_Invalid_Argument;
|
error = FT_Err_Invalid_Argument;
|
||||||
FT_ERROR(( "%s: called with invalid bitcount %d (instead of %d)\n",
|
FT_ERROR(( "%s: called with invalid bitcount %d (instead of %d)\n",
|
||||||
|
@ -901,11 +922,11 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
/* set-up new horizontal and vertical hint mask now */
|
/* set-up new horizontal and vertical hint mask now */
|
||||||
error = ps_dimension_set_mask( &dim[0], mask, 0, count1,
|
error = ps_dimension_set_mask_bits( &dim[0], bytes, 0, count1,
|
||||||
end_point, memory );
|
end_point, memory );
|
||||||
if (error) goto Fail;
|
if (error) goto Fail;
|
||||||
|
|
||||||
error = ps_dimension_set_mask( &dim[1], mask, count1, count2,
|
error = ps_dimension_set_mask_bits( &dim[1], bytes, count1, count2,
|
||||||
end_point, memory );
|
end_point, memory );
|
||||||
if (error) goto Fail;
|
if (error) goto Fail;
|
||||||
}
|
}
|
||||||
|
@ -919,7 +940,7 @@
|
||||||
static void
|
static void
|
||||||
ps_hints_t2counter( PS_Hints hints,
|
ps_hints_t2counter( PS_Hints hints,
|
||||||
FT_UInt bit_count,
|
FT_UInt bit_count,
|
||||||
const FT_Byte* mask )
|
const FT_Byte* bytes )
|
||||||
{
|
{
|
||||||
FT_Error error;
|
FT_Error error;
|
||||||
|
|
||||||
|
@ -931,7 +952,7 @@
|
||||||
FT_UInt count2 = dim[1].hints.num_hints;
|
FT_UInt count2 = dim[1].hints.num_hints;
|
||||||
|
|
||||||
/* check bit count, must be equal to current total hint count */
|
/* check bit count, must be equal to current total hint count */
|
||||||
if ( (FT_Int)bit_count != count1 + count2 )
|
if ( bit_count != count1 + count2 )
|
||||||
{
|
{
|
||||||
error = FT_Err_Invalid_Argument;
|
error = FT_Err_Invalid_Argument;
|
||||||
FT_ERROR(( "%s: called with invalid bitcount %d (instead of %d)\n",
|
FT_ERROR(( "%s: called with invalid bitcount %d (instead of %d)\n",
|
||||||
|
@ -940,12 +961,12 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
/* set-up new horizontal and vertical hint mask now */
|
/* set-up new horizontal and vertical hint mask now */
|
||||||
error = ps_dimension_set_mask_bits( &dim[0], mask, 0, count1,
|
error = ps_dimension_set_mask_bits( &dim[0], bytes, 0, count1,
|
||||||
end_point, memory );
|
0, memory );
|
||||||
if (error) goto Fail;
|
if (error) goto Fail;
|
||||||
|
|
||||||
error = ps_dimension_set_mask_bits( &dim[1], mask, count1, count2,
|
error = ps_dimension_set_mask_bits( &dim[1], bytes, count1, count2,
|
||||||
end_point, memory );
|
0, memory );
|
||||||
if (error) goto Fail;
|
if (error) goto Fail;
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
|
@ -990,7 +1011,7 @@
|
||||||
static void
|
static void
|
||||||
t1_hints_open( T1_Hints hints )
|
t1_hints_open( T1_Hints hints )
|
||||||
{
|
{
|
||||||
ps_hints_open( (PS_Hints)hints, ps_hints_type_1 );
|
ps_hints_open( (PS_Hints)hints, PS_HINT_TYPE_1 );
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -1002,15 +1023,20 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
FT_LOCAL_DEF void
|
||||||
static const T1_Hints_FuncsRec pshinter_t1_hints_funcs =
|
t1_hints_funcs_init( T1_Hints_FuncsRec* funcs )
|
||||||
{
|
{
|
||||||
(T1_Hints_OpenFunc) t1_hints_open,
|
memset( (char*)funcs, 0, sizeof(*funcs) );
|
||||||
(T1_Hints_CloseFunc) ps_hints_close,
|
|
||||||
(T1_Hints_SetStemFunc) t1_hints_set_stem,
|
funcs->open = (T1_Hints_OpenFunc) t1_hints_open;
|
||||||
(T1_Hints_SetStem3Func) ps_hints_t1stem3,
|
funcs->close = (T1_Hints_CloseFunc) ps_hints_close;
|
||||||
(T1_Hints_ResetFunc) ps_hints_t1reset
|
funcs->stem = (T1_Hints_SetStemFunc) t1_hints_stem;
|
||||||
};
|
funcs->stem3 = (T1_Hints_SetStem3Func) ps_hints_t1stem3;
|
||||||
|
funcs->reset = (T1_Hints_ResetFunc) ps_hints_t1reset;
|
||||||
|
|
||||||
|
/* funcs->apply = .... */
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
|
@ -1024,7 +1050,7 @@
|
||||||
static void
|
static void
|
||||||
t2_hints_open( T2_Hints hints )
|
t2_hints_open( T2_Hints hints )
|
||||||
{
|
{
|
||||||
ps_hints_open( (PS_Hints)hints, ps_hints_type_2 );
|
ps_hints_open( (PS_Hints)hints, PS_HINT_TYPE_2 );
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -1034,7 +1060,6 @@
|
||||||
FT_Fixed* coords )
|
FT_Fixed* coords )
|
||||||
{
|
{
|
||||||
FT_Int stems[32], n, total = count;
|
FT_Int stems[32], n, total = count;
|
||||||
FT_Fixed* read;
|
|
||||||
|
|
||||||
while (total > 0)
|
while (total > 0)
|
||||||
{
|
{
|
||||||
|
@ -1055,13 +1080,18 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static const T2_Hints_FuncsRec pshinter_t2_hints_funcs =
|
FT_LOCAL_DEF void
|
||||||
|
t2_hints_funcs_init( T2_Hints_FuncsRec* funcs )
|
||||||
{
|
{
|
||||||
(T2_Hints_OpenFunc) t2_hints_open,
|
memset( funcs, 0, sizeof(*funcs) );
|
||||||
(T2_Hints_CloseFunc) ps_hints_close,
|
|
||||||
(T2_Hints_StemsFunc) t2_hints_stems,
|
funcs->open = (T2_Hints_OpenFunc) t2_hints_open;
|
||||||
(T2_Hints_MaskFunc) ps_hints_t2mask,
|
funcs->close = (T2_Hints_CloseFunc) ps_hints_close;
|
||||||
(T2_Hints_CounterFunc) ps_hints_t2counter
|
funcs->stems = (T2_Hints_StemsFunc) t2_hints_stems;
|
||||||
};
|
funcs->hintmask = (T2_Hints_MaskFunc) ps_hints_t2mask;
|
||||||
|
funcs->counter = ( T2_Hints_CounterFunc) ps_hints_t2counter;
|
||||||
|
|
||||||
|
/* funcs->apply = .... */
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,152 @@
|
||||||
|
/***************************************************************************/
|
||||||
|
/* */
|
||||||
|
/* pshrec.h */
|
||||||
|
/* */
|
||||||
|
/* Postscript (Type 1/Type 2) hints recorder. */
|
||||||
|
/* */
|
||||||
|
/* Copyright 2001 by */
|
||||||
|
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
|
||||||
|
/* */
|
||||||
|
/* This file is part of the FreeType project, and may only be used, */
|
||||||
|
/* modified, and distributed under the terms of the FreeType project */
|
||||||
|
/* license, LICENSE.TXT. By continuing to use, modify, or distribute */
|
||||||
|
/* this file you indicate that you have read the license and */
|
||||||
|
/* understand and accept it fully. */
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/* The functions defined here are called from hte Type 1, CID and CFF */
|
||||||
|
/* font drivers to record the hints of a given character/glyph. */
|
||||||
|
/* */
|
||||||
|
/* The hints are recorded in a unified format, and are later processed */
|
||||||
|
/* by the "optimiser" and "fitter" to adjust the outlines to the pixel */
|
||||||
|
/* grid. */
|
||||||
|
/* */
|
||||||
|
/***************************************************************************/
|
||||||
|
|
||||||
|
#ifndef __PS_HINTER_RECORD_H__
|
||||||
|
#define __PS_HINTER_RECORD_H__
|
||||||
|
|
||||||
|
#include <ft2build.h>
|
||||||
|
#include FT_INTERNAL_POSTSCRIPT_HINTS_H
|
||||||
|
#include "pshglob.h"
|
||||||
|
|
||||||
|
FT_BEGIN_HEADER
|
||||||
|
|
||||||
|
/**********************************************************************/
|
||||||
|
/**********************************************************************/
|
||||||
|
/***** *****/
|
||||||
|
/***** GLYPH HINTS RECORDER INTERNALS *****/
|
||||||
|
/***** *****/
|
||||||
|
/**********************************************************************/
|
||||||
|
/**********************************************************************/
|
||||||
|
|
||||||
|
/* handle to hint record */
|
||||||
|
typedef struct PS_HintRec_* PS_Hint;
|
||||||
|
|
||||||
|
/* hint types */
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
PS_HINT_TYPE_1 = 1,
|
||||||
|
PS_HINT_TYPE_2 = 2
|
||||||
|
|
||||||
|
} PS_Hint_Type;
|
||||||
|
|
||||||
|
/* hint flags */
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
PS_HINT_FLAG_GHOST = 1,
|
||||||
|
PS_HINT_FLAG_BOTTOM = 2
|
||||||
|
|
||||||
|
} PS_Hint_Flags;
|
||||||
|
|
||||||
|
/* hint descriptor */
|
||||||
|
typedef struct PS_HintRec_
|
||||||
|
{
|
||||||
|
FT_Int pos;
|
||||||
|
FT_Int len;
|
||||||
|
FT_UInt flags;
|
||||||
|
|
||||||
|
} PS_HintRec;
|
||||||
|
|
||||||
|
|
||||||
|
#define ps_hint_is_active(x) ((x)->flags & PS_HINT_FLAG_ACTIVE)
|
||||||
|
#define ps_hint_is_ghost(x) ((x)->flags & PS_HINT_FLAG_GHOST)
|
||||||
|
#define ps_hint_is_bottom(x) ((x)->flags & PS_HINT_FLAG_BOTTOM)
|
||||||
|
|
||||||
|
|
||||||
|
/* hints table descriptor */
|
||||||
|
typedef struct PS_Hint_TableRec_
|
||||||
|
{
|
||||||
|
FT_UInt num_hints;
|
||||||
|
FT_UInt max_hints;
|
||||||
|
PS_Hint hints;
|
||||||
|
|
||||||
|
} PS_Hint_TableRec, *PS_Hint_Table;
|
||||||
|
|
||||||
|
|
||||||
|
/* hint and counter mask descriptor */
|
||||||
|
typedef struct PS_MaskRec_
|
||||||
|
{
|
||||||
|
FT_UInt num_bits;
|
||||||
|
FT_UInt max_bits;
|
||||||
|
FT_Byte* bytes;
|
||||||
|
FT_UInt end_point;
|
||||||
|
|
||||||
|
} PS_MaskRec, *PS_Mask;
|
||||||
|
|
||||||
|
|
||||||
|
/* masks and counters table descriptor */
|
||||||
|
typedef struct PS_Mask_TableRec_
|
||||||
|
{
|
||||||
|
FT_UInt num_masks;
|
||||||
|
FT_UInt max_masks;
|
||||||
|
PS_Mask masks;
|
||||||
|
|
||||||
|
} PS_Mask_TableRec, *PS_Mask_Table;
|
||||||
|
|
||||||
|
|
||||||
|
/* dimension-specific hints descriptor */
|
||||||
|
typedef struct PS_DimensionRec_
|
||||||
|
{
|
||||||
|
PS_Hint_TableRec hints;
|
||||||
|
PS_Mask_TableRec masks;
|
||||||
|
PS_Mask_TableRec counters;
|
||||||
|
|
||||||
|
} PS_DimensionRec, *PS_Dimension;
|
||||||
|
|
||||||
|
|
||||||
|
/* magic value used within PS_HintsRec */
|
||||||
|
#define PS_HINTS_MAGIC 0x68696e74 /* "hint" */
|
||||||
|
|
||||||
|
|
||||||
|
/* glyph hints descriptor */
|
||||||
|
typedef struct PS_HintsRec_
|
||||||
|
{
|
||||||
|
FT_Memory memory;
|
||||||
|
FT_Error error;
|
||||||
|
FT_UInt32 magic;
|
||||||
|
PS_Hint_Type hint_type;
|
||||||
|
PS_DimensionRec dimension[2];
|
||||||
|
|
||||||
|
} PS_HintsRec, *PS_Hints;
|
||||||
|
|
||||||
|
/* */
|
||||||
|
|
||||||
|
FT_LOCAL void
|
||||||
|
ps_hints_done( PS_Hints hints );
|
||||||
|
|
||||||
|
FT_LOCAL FT_Error
|
||||||
|
ps_hints_init( PS_Hints hints,
|
||||||
|
FT_Memory memory );
|
||||||
|
|
||||||
|
FT_LOCAL void
|
||||||
|
t1_hints_funcs_init( T1_Hints_FuncsRec* funcs );
|
||||||
|
|
||||||
|
FT_LOCAL void
|
||||||
|
t2_hints_funcs_init( T2_Hints_FuncsRec* funcs );
|
||||||
|
|
||||||
|
/* */
|
||||||
|
|
||||||
|
FT_END_HEADER
|
||||||
|
|
||||||
|
#endif /* __PS_HINTER_RECORD_H__ */
|
|
@ -1,113 +0,0 @@
|
||||||
#ifndef __PSRECORD_H_
|
|
||||||
#define __PSRECORD_H__
|
|
||||||
|
|
||||||
#include FT_INTERNAL_POSTSCRIPT_HINTS_H
|
|
||||||
|
|
||||||
FT_BEGIN_HEADER
|
|
||||||
|
|
||||||
/**********************************************************************/
|
|
||||||
/**********************************************************************/
|
|
||||||
/***** *****/
|
|
||||||
/***** GLYPH HINTS RECORDER INTERNALS *****/
|
|
||||||
/***** *****/
|
|
||||||
/**********************************************************************/
|
|
||||||
/**********************************************************************/
|
|
||||||
|
|
||||||
/* handle to hint record */
|
|
||||||
typedef struct PS_HintRec_* PS_Hint;
|
|
||||||
|
|
||||||
/* hint flags */
|
|
||||||
typedef enum
|
|
||||||
{
|
|
||||||
PS_HINT_FLAG_ACTIVE = 1,
|
|
||||||
PS_HINT_FLAG_GHOST = 2,
|
|
||||||
PS_HINT_FLAG_BOTTOM = 4
|
|
||||||
|
|
||||||
} PS_Hint_Flags;
|
|
||||||
|
|
||||||
/* hint descriptor */
|
|
||||||
typedef struct PS_HintRec_
|
|
||||||
{
|
|
||||||
FT_Int org_pos;
|
|
||||||
FT_Int org_len;
|
|
||||||
FT_UInt flags;
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
FT_Pos cur_pos;
|
|
||||||
FT_Pos cur_len;
|
|
||||||
|
|
||||||
PS_Hint parent;
|
|
||||||
|
|
||||||
FT_Fixed interp_scale;
|
|
||||||
FT_Fixed interp_delta;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
} PS_HintRec;
|
|
||||||
|
|
||||||
|
|
||||||
#define ps_hint_is_active(x) ((x)->flags & PS_HINT_FLAG_ACTIVE)
|
|
||||||
#define ps_hint_is_ghost(x) ((x)->flags & PS_HINT_FLAG_GHOST)
|
|
||||||
#define ps_hint_is_bottom(x) ((x)->flags & PS_HINT_FLAG_BOTTOM)
|
|
||||||
|
|
||||||
|
|
||||||
/* hints table descriptor */
|
|
||||||
typedef struct PS_Hint_TableRec_
|
|
||||||
{
|
|
||||||
FT_UInt num_hints;
|
|
||||||
FT_UInt max_hints;
|
|
||||||
PS_Hint hints;
|
|
||||||
|
|
||||||
} PS_Hint_TableRec, *PS_Hint_Table;
|
|
||||||
|
|
||||||
|
|
||||||
/* hint and counter mask descriptor */
|
|
||||||
typedef struct PS_MaskRec_
|
|
||||||
{
|
|
||||||
FT_UInt num_bits;
|
|
||||||
FT_UInt max_bits;
|
|
||||||
FT_Byte* bytes;
|
|
||||||
FT_UInt end_point;
|
|
||||||
|
|
||||||
} PS_MaskRec, *PS_Mask;
|
|
||||||
|
|
||||||
|
|
||||||
/* masks and counters table descriptor */
|
|
||||||
typedef struct PS_Mask_TableRec_
|
|
||||||
{
|
|
||||||
FT_UInt num_masks;
|
|
||||||
FT_UInt max_masks;
|
|
||||||
PS_Mask masks;
|
|
||||||
|
|
||||||
} PS_Mask_TableRec, *PS_Mask_Table;
|
|
||||||
|
|
||||||
|
|
||||||
/* dimension-specific hints descriptor */
|
|
||||||
typedef struct PS_DimensionRec_
|
|
||||||
{
|
|
||||||
PS_Hint_TableRec hints;
|
|
||||||
PS_Mask_TableRec masks;
|
|
||||||
PS_Mask_TableRec counters;
|
|
||||||
|
|
||||||
} PS_DimensionRec, *PS_Dimension;
|
|
||||||
|
|
||||||
|
|
||||||
/* magic value used within PS_HintsRec */
|
|
||||||
#define PS_HINTS_MAGIC 0x68696e74 /* "hint" */
|
|
||||||
|
|
||||||
|
|
||||||
/* glyph hints descriptor */
|
|
||||||
typedef struct PS_HintsRec_
|
|
||||||
{
|
|
||||||
FT_Memory memory;
|
|
||||||
FT_Error error;
|
|
||||||
FT_UInt32 magic;
|
|
||||||
PS_Hint_Type hint_type;
|
|
||||||
PS_DimensionRec dimension[2];
|
|
||||||
|
|
||||||
} PS_HintsRec;
|
|
||||||
|
|
||||||
/* */
|
|
||||||
|
|
||||||
FT_END_HEADER
|
|
||||||
|
|
||||||
#endif /* __T1_FITTER_HINTS_H__ */
|
|
|
@ -301,10 +301,10 @@
|
||||||
|
|
||||||
(FTDriver_initFace) T1_Init_Face,
|
(FTDriver_initFace) T1_Init_Face,
|
||||||
(FTDriver_doneFace) T1_Done_Face,
|
(FTDriver_doneFace) T1_Done_Face,
|
||||||
(FTDriver_initSize) 0,
|
(FTDriver_initSize) T1_Init_Size,
|
||||||
(FTDriver_doneSize) 0,
|
(FTDriver_doneSize) T1_Done_Size,
|
||||||
(FTDriver_initGlyphSlot)0,
|
(FTDriver_initGlyphSlot)T1_Init_GlyphSlot,
|
||||||
(FTDriver_doneGlyphSlot)0,
|
(FTDriver_doneGlyphSlot)T1_Done_GlyphSlot,
|
||||||
|
|
||||||
(FTDriver_setCharSizes) 0,
|
(FTDriver_setCharSizes) 0,
|
||||||
(FTDriver_setPixelSizes)0,
|
(FTDriver_setPixelSizes)0,
|
||||||
|
|
|
@ -45,6 +45,88 @@
|
||||||
#define FT_COMPONENT trace_t1objs
|
#define FT_COMPONENT trace_t1objs
|
||||||
|
|
||||||
|
|
||||||
|
/*************************************************************************/
|
||||||
|
/* */
|
||||||
|
/* SIZE FUNCTIONS */
|
||||||
|
/* */
|
||||||
|
/*************************************************************************/
|
||||||
|
|
||||||
|
FT_LOCAL_DEF
|
||||||
|
void T1_Done_Size( T1_Size size )
|
||||||
|
{
|
||||||
|
if ( size->size_hints )
|
||||||
|
{
|
||||||
|
PSHinter_Interface* pshinter;
|
||||||
|
PSH_Globals_Funcs funcs;
|
||||||
|
T1_Face face;
|
||||||
|
|
||||||
|
face = (T1_Face) size->root.face;
|
||||||
|
pshinter = face->pshinter;
|
||||||
|
funcs = pshinter->get_globals_funcs( (FT_Module) face->root.driver );
|
||||||
|
funcs->destroy( (PSH_Globals) size->size_hints );
|
||||||
|
|
||||||
|
size->size_hints = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
FT_LOCAL_DEF
|
||||||
|
FT_Error T1_Init_Size( T1_Size size )
|
||||||
|
{
|
||||||
|
PSHinter_Interface* pshinter;
|
||||||
|
T1_Face face;
|
||||||
|
FT_Error error = 0;
|
||||||
|
|
||||||
|
face = (T1_Face) size->root.face;
|
||||||
|
pshinter = face->pshinter;
|
||||||
|
if ( pshinter && pshinter->get_globals_funcs )
|
||||||
|
{
|
||||||
|
PSH_Globals_Funcs funcs;
|
||||||
|
PSH_Globals globals;
|
||||||
|
|
||||||
|
funcs = pshinter->get_globals_funcs( (FT_Module) face->root.driver );
|
||||||
|
if (funcs)
|
||||||
|
{
|
||||||
|
error = funcs->create( face->root.memory, &globals );
|
||||||
|
if (!error)
|
||||||
|
size->size_hints = globals;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*************************************************************************/
|
||||||
|
/* */
|
||||||
|
/* SLOT FUNCTIONS */
|
||||||
|
/* */
|
||||||
|
/*************************************************************************/
|
||||||
|
|
||||||
|
FT_LOCAL_DEF void
|
||||||
|
T1_Done_GlyphSlot( T1_GlyphSlot slot )
|
||||||
|
{
|
||||||
|
slot->root.internal->glyph_hints = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
FT_LOCAL_DEF FT_Error
|
||||||
|
T1_Init_GlyphSlot( T1_GlyphSlot slot )
|
||||||
|
{
|
||||||
|
T1_Face face;
|
||||||
|
PSHinter_Interface* pshinter;
|
||||||
|
|
||||||
|
face = (T1_Face) slot->root.face;
|
||||||
|
pshinter = face->pshinter;
|
||||||
|
if (pshinter)
|
||||||
|
{
|
||||||
|
T1_Hints_Funcs funcs;
|
||||||
|
|
||||||
|
funcs = pshinter->get_t1_funcs( (FT_Module)face->root.driver );
|
||||||
|
slot->root.internal->glyph_hints = (void*)funcs;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************/
|
/*************************************************************************/
|
||||||
/* */
|
/* */
|
||||||
/* FACE FUNCTIONS */
|
/* FACE FUNCTIONS */
|
||||||
|
@ -124,6 +206,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************/
|
/*************************************************************************/
|
||||||
/* */
|
/* */
|
||||||
/* <Function> */
|
/* <Function> */
|
||||||
|
@ -157,6 +240,7 @@
|
||||||
FT_Error error;
|
FT_Error error;
|
||||||
PSNames_Interface* psnames;
|
PSNames_Interface* psnames;
|
||||||
PSAux_Interface* psaux;
|
PSAux_Interface* psaux;
|
||||||
|
PSHinter_Interface* pshinter;
|
||||||
|
|
||||||
FT_UNUSED( num_params );
|
FT_UNUSED( num_params );
|
||||||
FT_UNUSED( params );
|
FT_UNUSED( params );
|
||||||
|
@ -184,6 +268,15 @@
|
||||||
face->psaux = psaux;
|
face->psaux = psaux;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pshinter = (PSHinter_Interface*)face->pshinter;
|
||||||
|
if ( !pshinter )
|
||||||
|
{
|
||||||
|
pshinter = (PSHinter_Interface*)
|
||||||
|
FT_Get_Module_Interface( FT_FACE_LIBRARY( face ), "pshinter" );
|
||||||
|
|
||||||
|
face->pshinter = pshinter;
|
||||||
|
}
|
||||||
|
|
||||||
/* open the tokenizer, this will also check the font format */
|
/* open the tokenizer, this will also check the font format */
|
||||||
error = T1_Open_Face( face );
|
error = T1_Open_Face( face );
|
||||||
if ( error )
|
if ( error )
|
||||||
|
|
|
@ -101,11 +101,8 @@ FT_BEGIN_HEADER
|
||||||
typedef struct T1_SizeRec_
|
typedef struct T1_SizeRec_
|
||||||
{
|
{
|
||||||
FT_SizeRec root;
|
FT_SizeRec root;
|
||||||
FT_Bool valid;
|
void* size_hints; /* defined for hinting engines */
|
||||||
T1_Size_Hints* hints; /* defined in the hinter. This allows */
|
|
||||||
/* us to experiment with different */
|
|
||||||
/* hinting schemes without having to */
|
|
||||||
/* change `t1objs' each time. */
|
|
||||||
} T1_SizeRec;
|
} T1_SizeRec;
|
||||||
|
|
||||||
|
|
||||||
|
@ -130,8 +127,6 @@ FT_BEGIN_HEADER
|
||||||
FT_Fixed x_scale;
|
FT_Fixed x_scale;
|
||||||
FT_Fixed y_scale;
|
FT_Fixed y_scale;
|
||||||
|
|
||||||
T1_Glyph_Hints* hints; /* defined in the hinter */
|
|
||||||
|
|
||||||
} T1_GlyphSlotRec;
|
} T1_GlyphSlotRec;
|
||||||
|
|
||||||
|
|
||||||
|
@ -145,6 +140,18 @@ FT_BEGIN_HEADER
|
||||||
FT_LOCAL
|
FT_LOCAL
|
||||||
void T1_Done_Face( T1_Face face );
|
void T1_Done_Face( T1_Face face );
|
||||||
|
|
||||||
|
FT_LOCAL
|
||||||
|
FT_Error T1_Init_Size( T1_Size size );
|
||||||
|
|
||||||
|
FT_LOCAL
|
||||||
|
void T1_Done_Size( T1_Size size );
|
||||||
|
|
||||||
|
FT_LOCAL
|
||||||
|
FT_Error T1_Init_GlyphSlot( T1_GlyphSlot slot );
|
||||||
|
|
||||||
|
FT_LOCAL
|
||||||
|
void T1_Done_GlyphSlot( T1_GlyphSlot slot );
|
||||||
|
|
||||||
FT_LOCAL
|
FT_LOCAL
|
||||||
FT_Error T1_Init_Driver( T1_Driver driver );
|
FT_Error T1_Init_Driver( T1_Driver driver );
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue