parent
02701db9ce
commit
e888167e1f
15 changed files with 5400 additions and 0 deletions
@ -0,0 +1,141 @@ |
||||
#ifndef __PSGLOBALS_H__ |
||||
#define __PSGLOBALS_H__ |
||||
|
||||
/**********************************************************************/ |
||||
/**********************************************************************/ |
||||
/***** *****/ |
||||
/***** PUBLIC STRUCTURES & API *****/ |
||||
/***** *****/ |
||||
/**********************************************************************/ |
||||
/**********************************************************************/ |
||||
|
||||
#if 0 |
||||
/****************************************************************
|
||||
* |
||||
* @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; |
||||
|
||||
|
||||
#endif |
||||
/* */ |
||||
|
||||
#endif /* __PS_GLOBALS_H__ */ |
@ -0,0 +1,529 @@ |
||||
/***************************************************************************/ |
||||
/* */ |
||||
/* pshints.h */ |
||||
/* */ |
||||
/* Interface to Postscript-specific (Type 1 and Type 2) hints */ |
||||
/* recorders. These are used to support native T1/T2 hints */ |
||||
/* in the "type1", "cid" and "cff" font drivers */ |
||||
/* */ |
||||
/* 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 __PSHINTS_H__ |
||||
#define __PSHINTS_H__ |
||||
|
||||
#include <ft2build.h> |
||||
#include FT_FREETYPE_H |
||||
#include FT_TYPE1_TABLES_H |
||||
#include FT_INTERNAL_POSTSCRIPT_GLOBALS_H |
||||
|
||||
FT_BEGIN_HEADER |
||||
|
||||
/**********************************************************************/ |
||||
/**********************************************************************/ |
||||
/***** *****/ |
||||
/***** INTERNAL REPRESENTATION OF GLOBALS *****/ |
||||
/***** *****/ |
||||
/**********************************************************************/ |
||||
/**********************************************************************/ |
||||
|
||||
typedef struct PSH_GlobalsRec_* PSH_Globals; |
||||
|
||||
typedef FT_Error (*PSH_Globals_NewFunc)( FT_Memory memory, |
||||
T1_Private* private_dict, |
||||
PSH_Globals* aglobals ); |
||||
|
||||
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_SetScaleFunc set_scale; |
||||
PSH_Globals_DestroyFunc destroy; |
||||
|
||||
} PSH_Globals_FuncsRec, *PSH_Globals_Funcs; |
||||
|
||||
/**********************************************************************/ |
||||
/**********************************************************************/ |
||||
/***** *****/ |
||||
/***** PUBLIC TYPE 1 HINTS RECORDER *****/ |
||||
/***** *****/ |
||||
/**********************************************************************/ |
||||
/**********************************************************************/ |
||||
|
||||
/************************************************************************
|
||||
* |
||||
* @type: T1_Hints |
||||
* |
||||
* @description: |
||||
* this is a handle to an opaque structure used to record glyph |
||||
* hints from a Type 1 character glyph character string. |
||||
* |
||||
* the methods used to operate on this object are defined by the |
||||
* @T1_Hints_FuncsRec structure. Recording glyph hints is normally |
||||
* achieved through the following scheme: |
||||
* |
||||
* - open a new hint recording session by calling the "open" |
||||
* method. This will rewind the recorder and prepare it for |
||||
* new input |
||||
* |
||||
* - for each hint found in the glyph charstring, call the |
||||
* corresponding method ("stem", "stem3" or "reset"). |
||||
* note that these functions do not return an error code |
||||
* |
||||
* - close the recording session by calling the "close" method |
||||
* it will return an error code if the hints were invalid or |
||||
* something strange happened (e.g. memory shortage) |
||||
*
|
||||
* the hints accumulated in the object can later be used by the |
||||
* Postscript hinter |
||||
*/ |
||||
typedef struct T1_HintsRec_* T1_Hints; |
||||
|
||||
/************************************************************************
|
||||
* |
||||
* @type: T1_Hints_Funcs |
||||
* |
||||
* @description: |
||||
* a pointer to the @T1_Hints_FuncsRec structure that defines the |
||||
* API of a given @T1_Hints object |
||||
*/ |
||||
typedef const struct T1_Hints_FuncsRec_* T1_Hints_Funcs; |
||||
|
||||
|
||||
/************************************************************************
|
||||
* |
||||
* @functype: T1_Hints_OpenFunc |
||||
* |
||||
* @description: |
||||
* a method of the @T1_Hints class used to prepare it for a new |
||||
* Type 1 hints recording session |
||||
* |
||||
* @input: |
||||
* hints :: handle to Type 1 hints recorder |
||||
* |
||||
* @note: |
||||
* You should always call the @T1_Hints_CloseFunc method in order |
||||
* to close an opened recording session |
||||
*/ |
||||
typedef void (*T1_Hints_OpenFunc) ( T1_Hints hints ); |
||||
|
||||
/************************************************************************
|
||||
* |
||||
* @functype: T1_Hints_SetStemFunc |
||||
* |
||||
* @description: |
||||
* a method of the @T1_Hints class used to record a new horizontal or |
||||
* vertical stem. This corresponds to the Type 1 "hstem" and "vstem" |
||||
* operators |
||||
* |
||||
* @input: |
||||
* hints :: handle to Type 1 hints recorder |
||||
* dimension :: 0 for horizontal stems (hstem), 1 for vertical ones (vstem) |
||||
* coords :: array of 2 integers, used as (position,length) stem descriptor |
||||
* |
||||
* @note: |
||||
* use vertical coordinates (y) for horizontal stems (dim=0) |
||||
* use horizontal coordinates (x) for vertical stems (dim=1) |
||||
* |
||||
* "coords[0]" is the absolute stem position (lowest coordinate) |
||||
* "coords[1]" is the length. |
||||
* |
||||
* 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, |
||||
* according to the Type 1 specification. |
||||
* |
||||
* if the length is -21 (corresponding to a bottom ghost stem), then |
||||
* the real stem position is "coords[0]+coords[1]" |
||||
*/ |
||||
typedef void (*T1_Hints_SetStemFunc) ( T1_Hints hints, |
||||
FT_UInt dimension, |
||||
FT_Long* coords ); |
||||
|
||||
/************************************************************************
|
||||
* |
||||
* @functype: T1_Hints_SetStem3Func |
||||
* |
||||
* @description: |
||||
* a method of the @T1_Hints class used to record three counter-controlled |
||||
* horizontal or vertical stems at once |
||||
* |
||||
* @input: |
||||
* hints :: handle to Type 1 hints recorder |
||||
* dimension :: 0 for horizontal stems, 1 for vertical ones |
||||
* coords :: array of 6 integers, i.e. 3 (position,length) pairs |
||||
* for the counter-controlled stems |
||||
* |
||||
* @note: |
||||
* use vertical coordinates (y) for horizontal stems (dim=0) |
||||
* use horizontal coordinates (x) for vertical stems (dim=1) |
||||
* |
||||
* the lengths cannot be negative (ghost stems are never counter-controlled) |
||||
*/ |
||||
typedef void (*T1_Hints_SetStem3Func) ( T1_Hints hints, |
||||
FT_UInt dimension, |
||||
FT_Long* coords ); |
||||
|
||||
/************************************************************************
|
||||
* |
||||
* @functype: T1_Hints_ResetFunc |
||||
* |
||||
* @description: |
||||
* a method of the @T1_Hints class used to reset the stems hints |
||||
* in a recording session. This is equivalent to the Type 1 ... |
||||
* |
||||
* @input: |
||||
* hints :: handle to Type 1 hints recorder |
||||
* end_point :: index of last point in the input glyph in which |
||||
* the previously defined hints apply |
||||
*/ |
||||
typedef void (*T1_Hints_ResetFunc)( T1_Hints hints, |
||||
FT_UInt end_point ); |
||||
|
||||
/************************************************************************
|
||||
* |
||||
* @functype: T1_Hints_CloseFunc |
||||
* |
||||
* @description: |
||||
* a method of the @T1_Hints class used to close a hint recording |
||||
* session. |
||||
* |
||||
* @input: |
||||
* hints :: handle to Type 1 hints recorder |
||||
* end_point :: index of last point in the input glyph |
||||
* |
||||
* @return: |
||||
* error code. 0 means success |
||||
* |
||||
* @note: |
||||
* the error code will be set to indicate that an error occured |
||||
* during the recording session |
||||
*/ |
||||
typedef FT_Error (*T1_Hints_CloseFunc)( T1_Hints hints, |
||||
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 |
||||
* |
||||
* @description: |
||||
* the structure used to provide the API to @T1_Hints objects |
||||
* |
||||
* @fields: |
||||
* hints :: handle to T1 Hints recorder |
||||
* open :: open recording session |
||||
* close :: close recording session |
||||
* stem :: set simple stem |
||||
* stem3 :: set counter-controlled stems |
||||
* reset :: reset stem hints |
||||
* apply :: apply the hints to the corresponding glyph outline |
||||
*/ |
||||
typedef struct T1_Hints_FuncsRec_ |
||||
{ |
||||
T1_Hints hints; |
||||
T1_Hints_OpenFunc open; |
||||
T1_Hints_CloseFunc close; |
||||
T1_Hints_SetStemFunc stem; |
||||
T1_Hints_SetStem3Func stem3; |
||||
T1_Hints_ResetFunc reset; |
||||
T1_Hints_ApplyFunc apply; |
||||
|
||||
} T1_Hints_FuncsRec; |
||||
|
||||
|
||||
/**********************************************************************/ |
||||
/**********************************************************************/ |
||||
/***** *****/ |
||||
/***** PUBLIC TYPE 2 HINTS RECORDER *****/ |
||||
/***** *****/ |
||||
/**********************************************************************/ |
||||
/**********************************************************************/ |
||||
|
||||
|
||||
/************************************************************************
|
||||
* |
||||
* @type: T2_Hints |
||||
* |
||||
* @description: |
||||
* this is a handle to an opaque structure used to record glyph |
||||
* hints from a Type 2 character glyph character string. |
||||
* |
||||
* the methods used to operate on this object are defined by the |
||||
* @T2_Hints_FuncsRec structure. Recording glyph hints is normally |
||||
* achieved through the following scheme: |
||||
* |
||||
* - open a new hint recording session by calling the "open" |
||||
* method. This will rewind the recorder and prepare it for |
||||
* new input |
||||
* |
||||
* - for each hint found in the glyph charstring, call the |
||||
* corresponding method ("stems", "hintmask", "counters"). |
||||
* note that these functions do not return an error code |
||||
* |
||||
* - close the recording session by calling the "close" method |
||||
* it will return an error code if the hints were invalid or |
||||
* something strange happened (e.g. memory shortage) |
||||
*
|
||||
* the hints accumulated in the object can later be used by the |
||||
* Postscript hinter |
||||
*/ |
||||
typedef struct T2_HintsRec_* T2_Hints; |
||||
|
||||
/************************************************************************
|
||||
* |
||||
* @type: T2_Hints_Funcs |
||||
* |
||||
* @description: |
||||
* a pointer to the @T1_Hints_FuncsRec structure that defines the |
||||
* API of a given @T2_Hints object |
||||
*/ |
||||
typedef const struct T2_Hints_FuncsRec_* T2_Hints_Funcs; |
||||
|
||||
/************************************************************************
|
||||
* |
||||
* @functype: T2_Hints_OpenFunc |
||||
* |
||||
* @description: |
||||
* a method of the @T2_Hints class used to prepare it for a new |
||||
* Type 2 hints recording session |
||||
* |
||||
* @input: |
||||
* hints :: handle to Type 2 hints recorder |
||||
* |
||||
* @note: |
||||
* You should always call the @T2_Hints_CloseFunc method in order |
||||
* to close an opened recording session |
||||
*/ |
||||
typedef void (*T2_Hints_OpenFunc) ( T2_Hints hints );
|
||||
|
||||
|
||||
/************************************************************************
|
||||
* |
||||
* @functype: T2_Hints_StemsFunc |
||||
* |
||||
* @description: |
||||
* a method of the @T2_Hints class used to set the table of stems |
||||
* in either the vertical or horizontal dimension. Equivalent to the |
||||
* "hstem", "vstem", "hstemhm" and "vstemhm" Type 2 operators |
||||
* |
||||
* @input: |
||||
* hints :: handle to Type 2 hints recorder |
||||
* dimension :: 0 for horizontal stems (hstem), 1 for vertical ones (vstem) |
||||
* count :: number of stems |
||||
* coordinates :: an array of "count" (position,length) pairs |
||||
* |
||||
* @note: |
||||
* use vertical coordinates (y) for horizontal stems (dim=0) |
||||
* use horizontal coordinates (x) for vertical stems (dim=1) |
||||
* |
||||
* there are "2*count" elements in the "coordinates" array. Each |
||||
* even element is an absolute position in font units, each odd |
||||
* element is a length in font units |
||||
* |
||||
* a length can be negative, in which case it must be either |
||||
* -20 or -21 in order and will be interpreted as a "ghost" stem, |
||||
* according to the Type 1 specification. |
||||
*/ |
||||
typedef void (*T2_Hints_StemsFunc) ( T2_Hints hints, |
||||
FT_UInt dimension, |
||||
FT_UInt count, |
||||
FT_Fixed* coordinates ); |
||||
|
||||
/************************************************************************
|
||||
* |
||||
* @functype: T2_Hints_MaskFunc |
||||
* |
||||
* @description: |
||||
* a method of the @T2_Hints class used to set a given hintmask |
||||
* (correspond to the "hintmask" Type 2 operator) |
||||
* |
||||
* @input: |
||||
* hints :: handle to Type 2 hints recorder |
||||
* end_point :: glyph index of the last point to which the previously |
||||
* defined/active hints apply. |
||||
* bit_count :: number of bits in the hint mask. |
||||
* bytes :: an array of bytes modelling the hint mask |
||||
*
|
||||
* @note: |
||||
* if the hintmask starts the charstring (before any glyph point |
||||
* definition), the value of "end_point" should be 0 |
||||
* |
||||
* "bit_count" is the number of meaningful bits in the "bytes" array, |
||||
* and must be equal to the total number of hints defined so far |
||||
* (i.e. horizontal+verticals) |
||||
* |
||||
* the "bytes" array can come directly from the Type 2 charstring |
||||
* and respect the same format. |
||||
*/ |
||||
typedef void (*T2_Hints_MaskFunc) ( T2_Hints hints, |
||||
FT_UInt end_point, |
||||
FT_UInt bit_count, |
||||
const FT_Byte* bytes ); |
||||
|
||||
/************************************************************************
|
||||
* |
||||
* @functype: T2_Hints_CounterFunc |
||||
* |
||||
* @description: |
||||
* a method of the @T2_Hints class used to set a given counter |
||||
* mask (correspond to the "hintmask" Type 2 operator) |
||||
* |
||||
* @input: |
||||
* hints :: handle to Type 2 hints recorder |
||||
* end_point :: glyph index of the last point to which the previously |
||||
* defined/active hints apply. |
||||
* bit_count :: number of bits in the hint mask. |
||||
* bytes :: an array of bytes modelling the hint mask |
||||
*
|
||||
* @note: |
||||
* if the hintmask starts the charstring (before any glyph point |
||||
* definition), the value of "end_point" should be 0 |
||||
* |
||||
* "bit_count" is the number of meaningful bits in the "bytes" array, |
||||
* and must be equal to the total number of hints defined so far |
||||
* (i.e. horizontal+verticals) |
||||
* |
||||
* the "bytes" array can come directly from the Type 2 charstring |
||||
* and respect the same format. |
||||
*/ |
||||
typedef void (*T2_Hints_CounterFunc)( T2_Hints hints, |
||||
FT_UInt bit_count, |
||||
const FT_Byte* bytes ); |
||||
|
||||
/************************************************************************
|
||||
* |
||||
* @functype: T2_Hints_CloseFunc |
||||
* |
||||
* @description: |
||||
* a method of the @T2_Hints class used to close a hint recording |
||||
* session. |
||||
* |
||||
* @input: |
||||
* hints :: handle to Type 2 hints recorder |
||||
* end_point :: index of last point in the input glyph |
||||
* |
||||
* @return: |
||||
* error code. 0 means success |
||||
* |
||||
* @note: |
||||
* the error code will be set to indicate that an error occured |
||||
* during the recording session |
||||
*/ |
||||
typedef FT_Error (*T2_Hints_CloseFunc) ( T2_Hints hints, |
||||
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 |
||||
* |
||||
* @description: |
||||
* the structure used to provide the API to @T2_Hints objects |
||||
* |
||||
* @fields: |
||||
* hints :: handle to T2 hints recorder object |
||||
* open :: open recording session |
||||
* close :: close recording session |
||||
* stems :: set dimension's stems table |
||||
* hintmask :: set hint masks |
||||
* counter :: set counter masks |
||||
* apply :: apply the hints on the corresponding glyph outline |
||||
*/ |
||||
typedef struct T2_Hints_FuncsRec_ |
||||
{ |
||||
T2_Hints hints; |
||||
T2_Hints_OpenFunc open; |
||||
T2_Hints_CloseFunc close; |
||||
T2_Hints_StemsFunc stems; |
||||
T2_Hints_MaskFunc hintmask; |
||||
T2_Hints_CounterFunc counter; |
||||
T2_Hints_ApplyFunc apply; |
||||
|
||||
} 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 |
||||
|
||||
#endif /* __PSHINTS_H__ */ |
@ -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 pshalgo1 pshalgo2 pshmod ; |
||||
} |
||||
else |
||||
{ |
||||
_sources = pshinter ; |
||||
} |
||||
|
||||
Library $(FT2_LIB) : $(_sources).c ; |
||||
} |
||||
|
||||
# end of src/psaux Jamfile |
@ -0,0 +1,19 @@ |
||||
#ifndef __PS_HINTER_ALGO_H__ |
||||
#define __PS_HINTER_ALGO_H__ |
||||
|
||||
FT_BEGIN_HEADER |
||||
|
||||
/* define to choose hinting algorithm */ |
||||
#define PSH_ALGORITHM_2 |
||||
|
||||
#ifdef PSH_ALGORITHM_1 |
||||
# include "pshalgo1.h" |
||||
# define PS_HINTS_APPLY_FUNC ps1_hints_apply |
||||
#else |
||||
# include "pshalgo2.h" |
||||
# define PS_HINTS_APPLY_FUNC ps2_hints_apply |
||||
#endif |
||||
|
||||
FT_END_HEADER |
||||
|
||||
#endif /* __PS_HINTER_ALGO_H__ */ |
@ -0,0 +1,736 @@ |
||||
#include <ft2build.h> |
||||
#include FT_INTERNAL_OBJECTS_H |
||||
#include FT_INTERNAL_DEBUG_H |
||||
#include "pshalgo1.h" |
||||
|
||||
#ifdef DEBUG_HINTER |
||||
extern PSH1_Hint_Table ps1_debug_hint_table = 0; |
||||
extern PSH1_HintFunc ps1_debug_hint_func = 0; |
||||
#endif |
||||
|
||||
/************************************************************************/ |
||||
/************************************************************************/ |
||||
/***** *****/ |
||||
/***** BASIC HINTS RECORDINGS *****/ |
||||
/***** *****/ |
||||
/************************************************************************/ |
||||
/************************************************************************/ |
||||
|
||||
/* return true iff two stem hints overlap */ |
||||
static FT_Int |
||||
psh1_hint_overlap( PSH1_Hint hint1, |
||||
PSH1_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 |
||||
psh1_hint_table_done( PSH1_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 |
||||
psh1_hint_table_deactivate( PSH1_Hint_Table table ) |
||||
{ |
||||
FT_UInt count = table->max_hints; |
||||
PSH1_Hint hint = table->hints; |
||||
|
||||
for ( ; count > 0; count--, hint++ ) |
||||
{ |
||||
psh1_hint_deactivate(hint); |
||||
hint->order = -1; |
||||
} |
||||
} |
||||
|
||||
|
||||
/* internal function used to record a new hint */ |
||||
static void |
||||
psh1_hint_table_record( PSH1_Hint_Table table, |
||||
FT_UInt index ) |
||||
{ |
||||
PSH1_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 ( psh1_hint_is_active(hint) ) |
||||
return; |
||||
|
||||
psh1_hint_activate(hint); |
||||
|
||||
/* now scan the current active hint set in order to determine */ |
||||
/* if we're overlapping with another segment.. */ |
||||
{ |
||||
PSH1_Hint* sorted = table->sort_global; |
||||
FT_UInt count = table->num_hints; |
||||
PSH1_Hint hint2; |
||||
|
||||
hint->parent = 0;
|
||||
for ( ; count > 0; count--, sorted++ ) |
||||
{ |
||||
hint2 = sorted[0]; |
||||
|
||||
if ( psh1_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 |
||||
psh1_hint_table_record_mask( PSH1_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 ) |
||||
psh1_hint_table_record( table, index ); |
||||
|
||||
mask >>= 1; |
||||
} |
||||
} |
||||
|
||||
|
||||
/* create hints table */ |
||||
static FT_Error |
||||
psh1_hint_table_init( PSH1_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, PSH1_Hint ) || |
||||
ALLOC_ARRAY( table->hints, count, PSH1_HintRec ) || |
||||
ALLOC_ARRAY( table->zones, 2*count+1, PSH1_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 */ |
||||
{ |
||||
PSH1_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; |
||||
|
||||
table->hint_masks = hint_masks; |
||||
|
||||
for ( ; count > 0; count--, mask++ ) |
||||
psh1_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++ ) |
||||
psh1_hint_table_record( table, index ); |
||||
}
|
||||
|
||||
Exit: |
||||
return error; |
||||
} |
||||
|
||||
|
||||
|
||||
static void |
||||
psh1_hint_table_activate_mask( PSH1_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; |
||||
|
||||
psh1_hint_table_deactivate( table ); |
||||
|
||||
for ( index = 0; index < limit; index++ ) |
||||
{ |
||||
if ( mask == 0 ) |
||||
{ |
||||
val = *cursor++; |
||||
mask = 0x80; |
||||
} |
||||
|
||||
if ( val & mask ) |
||||
{ |
||||
PSH1_Hint hint = &table->hints[index]; |
||||
|
||||
if ( !psh1_hint_is_active(hint) ) |
||||
{ |
||||
PSH1_Hint* sort = table->sort; |
||||
FT_UInt count2; |
||||
PSH1_Hint hint2; |
||||
|
||||
for ( count2 = count; count2 > 0; count2--, sort++ ) |
||||
{ |
||||
hint2 = sort[0]; |
||||
if ( psh1_hint_overlap( hint, hint2 ) ) |
||||
{ |
||||
FT_ERROR(( "%s.activate_mask: found overlapping hints\n", |
||||
"psf.hint" )); |
||||
break; |
||||
} |
||||
} |
||||
|
||||
if ( count2 == 0 ) |
||||
{ |
||||
psh1_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; |
||||
PSH1_Hint hint1, hint2; |
||||
PSH1_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; |
||||
} |
||||
} |
||||
} |
||||
} |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/************************************************************************/ |
||||
/************************************************************************/ |
||||
/***** *****/ |
||||
/***** HINTS GRID-FITTING AND OPTIMISATION *****/ |
||||
/***** *****/ |
||||
/************************************************************************/ |
||||
/************************************************************************/ |
||||
|
||||
#ifdef DEBUG_HINTER |
||||
void |
||||
ps_simple_scale( PSH1_Hint_Table table, |
||||
FT_Fixed scale, |
||||
FT_Fixed delta, |
||||
FT_Bool vertical ) |
||||
{ |
||||
PSH1_Hint hint; |
||||
FT_UInt count; |
||||
|
||||
for ( count = 0; count < table->num_hints; count++ ) |
||||
{ |
||||
hint = table->sort[count]; |
||||
if ( psh1_hint_is_active(hint) ) |
||||
{ |
||||
hint->cur_pos = FT_MulFix( hint->org_pos, scale ) + delta; |
||||
hint->cur_len = FT_MulFix( hint->org_len, scale ); |
||||
|
||||
if (ps1_debug_hint_func) |
||||
ps1_debug_hint_func( hint, vertical ); |
||||
} |
||||
} |
||||
}
|
||||
#endif |
||||
|
||||
FT_LOCAL_DEF FT_Error |
||||
psh1_hint_table_optimize( PSH1_Hint_Table table, |
||||
PSH_Globals globals, |
||||
FT_Outline* outline, |
||||
FT_Bool vertical ) |
||||
{ |
||||
PSH_Dimension dim = &globals->dimension[vertical]; |
||||
FT_Fixed scale = dim->scale_mult; |
||||
FT_Fixed delta = dim->scale_delta; |
||||
|
||||
#ifdef DEBUG_HINTER |
||||
if ( ps_debug_no_vert_hints && vertical ) |
||||
{ |
||||
ps_simple_scale( table, scale, delta, vertical ); |
||||
return 0; |
||||
} |
||||
|
||||
if ( ps_debug_no_horz_hints && !vertical ) |
||||
{ |
||||
ps_simple_scale( table, scale, delta, vertical ); |
||||
return 0; |
||||
} |
||||
#endif |
||||
|
||||
/* XXXX: for now, we only scale the hints to test all other aspects */ |
||||
/* of the Postscript Hinter.. */ |
||||
{
|
||||
PSH1_Hint hint; |
||||
FT_UInt count; |
||||
|
||||
for ( count = 0; count < table->num_hints; count++ ) |
||||
{ |
||||
hint = table->sort[count]; |
||||
if ( psh1_hint_is_active(hint) ) |
||||
{ |
||||
# if 1 |
||||
FT_Pos pos = FT_MulFix( hint->org_pos, scale ) + delta; |
||||
FT_Pos len = FT_MulFix( hint->org_len, scale ); |
||||
|
||||
FT_Pos fit_center; |
||||
FT_Pos fit_len; |
||||
|
||||
PSH_AlignmentRec align; |
||||
|
||||
/* compute fitted width/height */ |
||||
fit_len = psh_dimension_snap_width( dim, hint->org_len ); |
||||
if ( fit_len < 64 ) |
||||
fit_len = 64; |
||||
else |
||||
fit_len = (fit_len + 32 ) & -64; |
||||
|
||||
hint->cur_len = fit_len; |
||||
|
||||
/* check blue zones for horizontal stems */ |
||||
align.align = 0; |
||||
if (!vertical) |
||||
{ |
||||
psh_blues_snap_stem( &globals->blues, |
||||
hint->org_pos + hint->org_len, |
||||
hint->org_pos, |
||||
&align ); |
||||
} |
||||
|
||||
switch (align.align) |
||||
{ |
||||
case PSH_BLUE_ALIGN_TOP: |
||||
{ |
||||
/* the top of the stem is aligned against a blue zone */ |
||||
hint->cur_pos = align.align_top - fit_len; |
||||
break; |
||||
} |
||||
|
||||
case PSH_BLUE_ALIGN_BOT: |
||||
{ |
||||
/* the bottom of the stem is aligned against a blue zone */ |
||||
hint->cur_pos = align.align_bot; |
||||
break; |
||||
} |
||||
|
||||
case PSH_BLUE_ALIGN_TOP | PSH_BLUE_ALIGN_BOT: |
||||
{ |
||||
/* both edges of the stem are aligned against blue zones */ |
||||
hint->cur_pos = align.align_bot; |
||||
hint->cur_len = align.align_top - align.align_bot; |
||||
} |
||||
break; |
||||
|
||||
default: |
||||
/* normal processing */ |
||||
if ( (fit_len/64) & 1 ) |
||||
{ |
||||
/* odd number of pixels */ |
||||
fit_center = ((pos + (len >> 1)) & -64) + 32; |
||||
} |
||||
else |
||||
{ |
||||
/* even number of pixels */ |
||||
fit_center = (pos + (len >> 1) + 32) & -64; |
||||
} |
||||
|
||||
hint->cur_pos = fit_center - (fit_len >> 1); |
||||
} |
||||
# else |
||||
hint->cur_pos = (FT_MulFix( hint->org_pos, scale ) + delta + 32) & -64; |
||||
hint->cur_len = FT_MulFix( hint->org_len, scale ); |
||||
# endif |
||||
|
||||
#ifdef DEBUG_HINTER |
||||
if (ps1_debug_hint_func) |
||||
ps1_debug_hint_func( hint, vertical ); |
||||
#endif |
||||
} |
||||
} |
||||
} |
||||
|
||||
return 0; |
||||
} |
||||
|
||||
|
||||
|
||||
|
||||
/************************************************************************/ |
||||
/************************************************************************/ |
||||
/***** *****/ |
||||
/***** POINTS INTERPOLATION ROUTINES *****/ |
||||
/***** *****/ |
||||
/************************************************************************/ |
||||
/************************************************************************/ |
||||
|
||||
#define PSH1_ZONE_MIN -3200000 |
||||
#define PSH1_ZONE_MAX +3200000 |
||||
|
||||
|
||||
#define xxDEBUG_ZONES |
||||
|
||||
#ifdef DEBUG_ZONES |
||||
|
||||
#include <stdio.h> |
||||
|
||||
static void |
||||
print_zone( PSH1_Zone zone ) |
||||
{ |
||||
printf( "zone [scale,delta,min,max] = [%.3f,%.3f,%d,%d]\n", |
||||
zone->scale/65536.0, |
||||
zone->delta/64.0, |
||||
zone->min, |
||||
zone->max ); |
||||
} |
||||
|
||||
#else |
||||
# define print_zone(x) do { } while (0) |
||||
#endif |
||||
|
||||
/* setup interpolation zones once the hints have been grid-fitted */ |
||||
/* by the optimizer.. */ |
||||
static void |
||||
psh1_hint_table_setup_zones( PSH1_Hint_Table table, |
||||
FT_Fixed scale, |
||||
FT_Fixed delta ) |
||||
{ |
||||
FT_UInt count; |
||||
PSH1_Zone zone; |
||||
PSH1_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 = PSH1_ZONE_MIN; |
||||
zone->max = PSH1_ZONE_MAX; |
||||
|
||||
table->num_zones = 1; |
||||
table->zone = zone; |
||||
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 = PSH1_ZONE_MIN; |
||||
zone->max = hint->org_pos; |
||||
|
||||
print_zone( zone ); |
||||
|
||||
zone++; |
||||
|
||||
for ( count = table->num_hints; count > 0; 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 ); |
||||
|
||||
print_zone( zone ); |
||||
|
||||
zone++; |
||||
} |
||||
|
||||
if ( count == 1 ) |
||||
break; |
||||
|
||||
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 - (hint->org_pos + hint->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 ); |
||||
|
||||
print_zone( zone ); |
||||
|
||||
zone++; |
||||
|
||||
hint = hint2; |
||||
} |
||||
|
||||
/* the last zone */ |
||||
zone->scale = scale; |
||||
zone->min = hint->org_pos + hint->org_len; |
||||
zone->max = PSH1_ZONE_MAX; |
||||
zone->delta = hint->cur_pos + hint->cur_len - FT_MulFix( zone->min, scale ); |
||||
|
||||
print_zone( zone ); |
||||
|
||||
zone++; |
||||
|
||||
table->num_zones = zone - table->zones; |
||||
table->zone = table->zones; |
||||
} |
||||
|
||||
|
||||
/* tune a single coordinate with the current interpolation zones */
|
||||
static FT_Pos |
||||
psh1_hint_table_tune_coord( PSH1_Hint_Table table, |
||||
FT_Int coord ) |
||||
{ |
||||
PSH1_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 FT_MulFix( coord, zone->scale ) + zone->delta; |
||||
} |
||||
|
||||
|
||||
/* tune a given outline with current interpolation zones */ |
||||
/* the function only works in a single dimension.. */ |
||||
static void |
||||
psh1_hint_table_tune_outline( PSH1_Hint_Table table, |
||||
FT_Outline* outline, |
||||
PSH_Globals globals, |
||||
FT_Bool vertical ) |
||||
|
||||
{ |
||||
FT_UInt count, first, last; |
||||
PS_Mask_Table hint_masks = table->hint_masks; |
||||
PS_Mask mask; |
||||
PSH_Dimension dim = &globals->dimension[vertical]; |
||||
FT_Fixed scale = dim->scale_mult; |
||||
FT_Fixed delta = dim->scale_delta; |
||||
|
||||
if ( hint_masks && hint_masks->num_masks > 0 ) |
||||
{ |
||||
first = 0; |
||||
mask = hint_masks->masks; |
||||
count = hint_masks->num_masks; |
||||
for ( ; count > 0; count--, mask++ ) |
||||
{ |
||||
last = mask->end_point; |
||||
|
||||
if ( last > first ) |
||||
{ |
||||
FT_Vector* vec; |
||||
FT_Int count2; |
||||
|
||||
psh1_hint_table_activate_mask( table, mask ); |
||||
psh1_hint_table_optimize( table, globals, outline, vertical ); |
||||
psh1_hint_table_setup_zones( table, scale, delta ); |
||||
last = mask->end_point; |
||||
|
||||
vec = outline->points + first; |
||||
count2 = last - first; |
||||
for ( ; count2 > 0; count2--, vec++ ) |
||||
{ |
||||
FT_Pos x, *px; |
||||
|
||||
px = vertical ? &vec->x : &vec->y; |
||||
x = *px; |
||||
|
||||
*px = psh1_hint_table_tune_coord( table, (FT_Int)x ); |
||||
} |
||||
} |
||||
|
||||
first = last; |
||||
} |
||||
} |
||||
else /* no hints in this glyph, simply scale the outline */ |
||||
{ |
||||
FT_Vector* vec; |
||||
|
||||
vec = outline->points; |
||||
count = outline->n_points; |
||||
|
||||
if ( vertical ) |
||||
{ |
||||
for ( ; count > 0; count--, vec++ ) |
||||
vec->x = FT_MulFix( vec->x, scale ) + delta; |
||||
} |
||||
else |
||||
{ |
||||
for ( ; count > 0; count--, vec++ ) |
||||
vec->y = FT_MulFix( vec->y, scale ) + delta; |
||||
} |
||||
} |
||||
} |
||||
|
||||
|
||||
/************************************************************************/ |
||||
/************************************************************************/ |
||||
/***** *****/ |
||||
/***** HIGH-LEVEL INTERFACE *****/ |
||||
/***** *****/ |
||||
/************************************************************************/ |
||||
/************************************************************************/ |
||||
|
||||
FT_Error |
||||
ps1_hints_apply( PS_Hints ps_hints, |
||||
FT_Outline* outline, |
||||
PSH_Globals globals ) |
||||
{ |
||||
PSH1_Hint_TableRec hints; |
||||
FT_Error error; |
||||
FT_Int dimension; |
||||
|
||||
for ( dimension = 1; dimension >= 0; dimension-- ) |
||||
{ |
||||
PS_Dimension dim = &ps_hints->dimension[dimension]; |
||||
|
||||
/* initialise hints table */ |
||||
memset( &hints, 0, sizeof(hints) ); |
||||
error = psh1_hint_table_init( &hints, |
||||
&dim->hints, |
||||
&dim->masks, |
||||
&dim->counters, |
||||
ps_hints->memory ); |
||||
if (error) goto Exit; |
||||
|
||||
psh1_hint_table_tune_outline( &hints, |
||||
outline, |
||||
globals, |
||||
dimension ); |
||||
|
||||
psh1_hint_table_done( &hints, ps_hints->memory ); |
||||
} |
||||
|
||||
Exit: |
||||
return error;
|
||||
} |
@ -0,0 +1,100 @@ |
||||
/***************************************************************************/ |
||||
/* */ |
||||
/* pshalgo1.h */ |
||||
/* */ |
||||
/* First (basic) Postscript hinting routines */ |
||||
/* */ |
||||
/* 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_ALGO1_H__ |
||||
#define __PS_HINTER_ALGO1_H__ |
||||
|
||||
#include "pshrec.h" |
||||
|
||||
FT_BEGIN_HEADER |
||||
|
||||
typedef struct PSH1_HintRec_* PSH1_Hint; |
||||
|
||||
typedef enum |
||||
{ |
||||
PSH1_HINT_FLAG_GHOST = PS_HINT_FLAG_GHOST, |
||||
PSH1_HINT_FLAG_BOTTOM = PS_HINT_FLAG_BOTTOM, |
||||
PSH1_HINT_FLAG_ACTIVE = 4 |
||||
|
||||
} PSH1_Hint_Flags; |
||||
|
||||
#define psh1_hint_is_active(x) (((x)->flags & PSH1_HINT_FLAG_ACTIVE) != 0) |
||||
#define psh1_hint_is_ghost(x) (((x)->flags & PSH1_HINT_FLAG_GHOST ) != 0) |
||||
|
||||
#define psh1_hint_activate(x) (x)->flags |= PSH1_HINT_FLAG_ACTIVE |
||||
#define psh1_hint_deactivate(x) (x)->flags &= ~PSH1_HINT_FLAG_ACTIVE |
||||
|
||||
typedef struct PSH1_HintRec_ |
||||
{ |
||||
FT_Int org_pos; |
||||
FT_Int org_len; |
||||
FT_Pos cur_pos; |
||||
FT_Pos cur_len; |
||||
|
||||
FT_UInt flags; |
||||
|
||||
PSH1_Hint parent; |
||||
FT_Int order; |
||||
|
||||
} PSH1_HintRec; |
||||
|
||||
|
||||
/* this is an interpolation zone used for strong points */ |
||||
/* weak points are interpolated according to their strong */ |
||||
/* neighbours.. */ |
||||
typedef struct PSH1_ZoneRec_ |
||||
{ |
||||
FT_Fixed scale; |
||||
FT_Fixed delta; |
||||
FT_Pos min; |
||||
FT_Pos max; |
||||
|
||||
} PSH1_ZoneRec, *PSH1_Zone; |
||||
|
||||
|
||||
typedef struct PSH1_Hint_TableRec_ |
||||
{ |
||||
FT_UInt max_hints; |
||||
FT_UInt num_hints; |
||||
PSH1_Hint hints; |
||||
PSH1_Hint* sort; |
||||
PSH1_Hint* sort_global; |
||||
FT_UInt num_zones; |
||||
PSH1_Zone zones; |
||||
PSH1_Zone zone; |
||||
PS_Mask_Table hint_masks; |
||||
PS_Mask_Table counter_masks; |
||||
|
||||
} PSH1_Hint_TableRec, *PSH1_Hint_Table; |
||||
|
||||
|
||||
extern FT_Error |
||||
ps1_hints_apply( PS_Hints ps_hints, |
||||
FT_Outline* outline, |
||||
PSH_Globals globals ); |
||||
|
||||
|
||||
#ifdef DEBUG_HINTER |
||||
extern PSH1_Hint_Table ps1_debug_hint_table; |
||||
|
||||
typedef void (*PSH1_HintFunc)( PSH1_Hint hint, FT_Bool vertical ); |
||||
extern PSH1_HintFunc ps1_debug_hint_func; |
||||
#endif |
||||
|
||||
FT_END_HEADER |
||||
|
||||
#endif /* __PS_HINTER_FITTER_H__ */ |
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,185 @@ |
||||
/***************************************************************************/ |
||||
/* */ |
||||
/* pshalgo2.h */ |
||||
/* */ |
||||
/* First (basic) Postscript hinting routines */ |
||||
/* */ |
||||
/* 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_ALGO2_H__ |
||||
#define __PS_HINTER_ALGO2_H__ |
||||
|
||||
#include "pshrec.h" |
||||
#include "pshglob.h" |
||||
#include FT_TRIGONOMETRY_H |
||||
|
||||
FT_BEGIN_HEADER |
||||
|
||||
typedef struct PSH2_HintRec_* PSH2_Hint; |
||||
|
||||
typedef enum |
||||
{ |
||||
PSH2_HINT_GHOST = PS_HINT_FLAG_GHOST, |
||||
PSH2_HINT_BOTTOM = PS_HINT_FLAG_BOTTOM, |
||||
PSH2_HINT_ACTIVE = 4, |
||||
PSH2_HINT_FITTED = 8
|
||||
} PSH2_Hint_Flags; |
||||
|
||||
#define psh2_hint_is_active(x) (((x)->flags & PSH2_HINT_ACTIVE) != 0) |
||||
#define psh2_hint_is_ghost(x) (((x)->flags & PSH2_HINT_GHOST) != 0) |
||||
#define psh2_hint_is_fitted(x) (((x)->flags & PSH2_HINT_FITTED) != 0) |
||||
|
||||
#define psh2_hint_activate(x) (x)->flags |= PSH2_HINT_ACTIVE |
||||
#define psh2_hint_deactivate(x) (x)->flags &= ~PSH2_HINT_ACTIVE |
||||
#define psh2_hint_set_fitted(x) (x)->flags |= PSH2_HINT_FITTED |
||||
|
||||
typedef struct PSH2_HintRec_ |
||||
{ |
||||
FT_Int org_pos; |
||||
FT_Int org_len; |
||||
FT_Pos cur_pos; |
||||
FT_Pos cur_len; |
||||
FT_UInt flags; |
||||
PSH2_Hint parent; |
||||
FT_Int order; |
||||
|
||||
} PSH2_HintRec; |
||||
|
||||
|
||||
/* this is an interpolation zone used for strong points */ |
||||
/* weak points are interpolated according to their strong */ |
||||
/* neighbours.. */ |
||||
typedef struct PSH2_ZoneRec_ |
||||
{ |
||||
FT_Fixed scale; |
||||
FT_Fixed delta; |
||||
FT_Pos min; |
||||
FT_Pos max; |
||||
|
||||
} PSH2_ZoneRec, *PSH2_Zone; |
||||
|
||||
|
||||
typedef struct PSH2_Hint_TableRec_ |
||||
{ |
||||
FT_UInt max_hints; |
||||
FT_UInt num_hints; |
||||
PSH2_Hint hints; |
||||
PSH2_Hint* sort; |
||||
PSH2_Hint* sort_global; |
||||
FT_UInt num_zones; |
||||
PSH2_Zone zones; |
||||
PSH2_Zone zone; |
||||
PS_Mask_Table hint_masks; |
||||
PS_Mask_Table counter_masks; |
||||
|
||||
} PSH2_Hint_TableRec, *PSH2_Hint_Table; |
||||
|
||||
typedef struct PSH2_PointRec_* PSH2_Point; |
||||
typedef struct PSH2_ContourRec_* PSH2_Contour; |
||||
|
||||
enum |
||||
{ |
||||
PSH2_DIR_NONE = 4, |
||||
PSH2_DIR_UP = 1, |
||||
PSH2_DIR_DOWN = -1, |
||||
PSH2_DIR_LEFT = -2, |
||||
PSH2_DIR_RIGHT = 2 |
||||
}; |
||||
|
||||
enum |
||||
{ |
||||
PSH2_POINT_OFF = 1, /* point is off the curve */ |
||||
PSH2_POINT_STRONG = 2, /* point is strong */ |
||||
PSH2_POINT_SMOOTH = 4, /* point is smooth */ |
||||
PSH2_POINT_FITTED = 8 /* point is already fitted */ |
||||
}; |
||||
|
||||
|
||||
typedef struct PSH2_PointRec_ |
||||
{ |
||||
PSH2_Point prev; |
||||
PSH2_Point next; |
||||
PSH2_Contour contour; |
||||
FT_UInt flags; |
||||
FT_Char dir_in; |
||||
FT_Char dir_out; |
||||
FT_Angle angle_in; |
||||
FT_Angle angle_out; |
||||
PSH2_Hint hint; |
||||
FT_Pos org_u; |
||||
FT_Pos cur_u; |
||||
#ifdef DEBUG_HINTER |
||||
FT_Pos org_x; |
||||
FT_Pos cur_x; |
||||
FT_Pos org_y; |
||||
FT_Pos cur_y; |
||||
FT_UInt flags_x; |
||||
FT_UInt flags_y; |
||||
#endif |
||||
|
||||
} PSH2_PointRec; |
||||
|
||||
#define psh2_point_is_strong(p) ((p)->flags & PSH2_POINT_STRONG) |
||||
#define psh2_point_is_fitted(p) ((p)->flags & PSH2_POINT_FITTED) |
||||
#define psh2_point_is_smooth(p) ((p)->flags & PSH2_POINT_SMOOTH) |
||||
|
||||
#define psh2_point_set_strong(p) (p)->flags |= PSH2_POINT_STRONG |
||||
#define psh2_point_set_fitted(p) (p)->flags |= PSH2_POINT_FITTED |
||||
#define psh2_point_set_smooth(p) (p)->flags |= PSH2_POINT_SMOOTH |
||||
|
||||
typedef struct PSH2_ContourRec_ |
||||
{ |
||||
PSH2_Point start; |
||||
FT_UInt count; |
||||
|
||||
} PSH2_ContourRec; |
||||
|
||||
|
||||
|
||||
typedef struct PSH2_GlyphRec_ |
||||
{ |
||||
FT_UInt num_points; |
||||
FT_UInt num_contours; |
||||
|
||||
PSH2_Point points; |
||||
PSH2_Contour contours; |
||||
|
||||
FT_Memory memory; |
||||
FT_Outline* outline; |
||||
PSH_Globals globals; |
||||
PSH2_Hint_TableRec hint_tables[2]; |
||||
|
||||
FT_Bool vertical; |
||||
FT_Int major_dir; |
||||
FT_Int minor_dir; |
||||
|
||||
} PSH2_GlyphRec, *PSH2_Glyph; |
||||
|
||||
|
||||
#ifdef DEBUG_HINTER |
||||
extern PSH2_Hint_Table ps2_debug_hint_table; |
||||
|
||||
typedef void (*PSH2_HintFunc)( PSH2_Hint hint, FT_Bool vertical ); |
||||
extern PSH2_HintFunc ps2_debug_hint_func; |
||||
|
||||
extern PSH2_Glyph ps2_debug_glyph; |
||||
#endif |
||||
|
||||
|
||||
extern FT_Error |
||||
ps2_hints_apply( PS_Hints ps_hints, |
||||
FT_Outline* outline, |
||||
PSH_Globals globals ); |
||||
|
||||
FT_END_HEADER |
||||
|
||||
#endif /* __PS_HINTS_ALGO_2_H__ */ |
@ -0,0 +1,553 @@ |
||||
#include <ft2build.h> |
||||
#include FT_FREETYPE_H |
||||
#include FT_INTERNAL_OBJECTS_H |
||||
#include "pshglob.h" |
||||
|
||||
#ifdef DEBUG_HINTER |
||||
extern PSH_Globals ps_debug_globals = 0; |
||||
#endif |
||||
|
||||
/* "simple" ps hinter globals management, inspired from the new auto-hinter */ |
||||
|
||||
/*************************************************************************/ |
||||
/*************************************************************************/ |
||||
/***** *****/ |
||||
/***** STANDARD WIDTHS *****/ |
||||
/***** *****/ |
||||
/*************************************************************************/ |
||||
/*************************************************************************/ |
||||
|
||||
|
||||
/* scale the widths/heights table */ |
||||
static void |
||||
psh_globals_scale_widths( PSH_Globals globals, |
||||
FT_UInt direction ) |
||||
{ |
||||
PSH_Dimension dim = &globals->dimension[direction]; |
||||
PSH_Widths std = &dim->std; |
||||
FT_UInt count = std->count; |
||||
PSH_Width width = std->widths; |
||||
FT_Fixed scale = dim->scale_mult; |
||||
|
||||
for ( ; count > 0; count--, width++ ) |
||||
{ |
||||
width->cur = FT_MulFix( width->org, scale ); |
||||
width->fit = FT_RoundFix( width->cur ); |
||||
} |
||||
} |
||||
|
||||
|
||||
|
||||
/* org_width is is font units, result in device pixels, 26.6 format */ |
||||
FT_LOCAL_DEF FT_Pos |
||||
psh_dimension_snap_width( PSH_Dimension dimension, |
||||
FT_Int org_width ) |
||||
{ |
||||
FT_UInt n; |
||||
FT_Pos width = FT_MulFix( org_width, dimension->scale_mult ); |
||||
FT_Pos best = 64 + 32 + 2; |
||||
FT_Pos reference = width; |
||||
|
||||
for ( n = 0; n < dimension->std.count; n++ ) |
||||
{ |
||||
FT_Pos w; |
||||
FT_Pos dist; |
||||
|
||||
w = dimension->std.widths[n].cur; |
||||
dist = width - w; |
||||
if ( dist < 0 ) |
||||
dist = -dist; |
||||
if ( dist < best ) |
||||
{ |
||||
best = dist; |
||||
reference = w; |
||||
} |
||||
} |
||||
|
||||
if ( width >= reference ) |
||||
{ |
||||
width -= 0x21; |
||||
if ( width < reference ) |
||||
width = reference; |
||||
} |
||||
else |
||||
{ |
||||
width += 0x21; |
||||
if ( width > reference ) |
||||
width = reference; |
||||
} |
||||
|
||||
return width; |
||||
} |
||||
|
||||
|
||||
/*************************************************************************/ |
||||
/*************************************************************************/ |
||||
/***** *****/ |
||||
/***** BLUE ZONES *****/ |
||||
/***** *****/ |
||||
/*************************************************************************/ |
||||
/*************************************************************************/ |
||||
|
||||
static void |
||||
psh_blues_set_zones_0( PSH_Blues target, |
||||
FT_Bool is_others, |
||||
FT_UInt read_count, |
||||
FT_Short* read, |
||||
PSH_Blue_Table top_table, |
||||
PSH_Blue_Table bot_table ) |
||||
{ |
||||
FT_UInt count_top = top_table->count; |
||||
FT_UInt count_bot = bot_table->count; |
||||
FT_Bool first = 1; |
||||
|
||||
for ( ; read_count > 0; read_count -= 2 ) |
||||
{ |
||||
FT_Int reference, delta; |
||||
FT_UInt count; |
||||
PSH_Blue_Zone zones, zone; |
||||
FT_Bool top; |
||||
|
||||
/* read blue zone entry, and select target top/bottom zone */ |
||||
top = 0; |
||||
if ( first || is_others ) |
||||
{ |
||||
reference = read[1]; |
||||
delta = read[0] - reference; |
||||
|
||||
zones = bot_table->zones; |
||||
count = count_bot; |
||||
first = 0; |
||||
} |
||||
else |
||||
{ |
||||
reference = read[0]; |
||||
delta = read[1] - reference; |
||||
|
||||
zones = top_table->zones; |
||||
count = count_top; |
||||
top = 1; |
||||
} |
||||
|
||||
/* insert into sorted table */ |
||||
zone = zones;
|
||||
for ( ; count > 0; count--, zone++ ) |
||||
{ |
||||
if ( reference < zone->org_ref ) |
||||
break; |
||||
|
||||
if ( reference == zone->org_ref ) |
||||
{ |
||||
FT_Int delta0 = zone->org_delta; |
||||
|
||||
/* we have two zones on the same reference position */ |
||||
/* 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 ( ; count > 0; count-- ) |
||||
zone[count] = zone[count-1]; |
||||
|
||||
zone->org_ref = reference; |
||||
zone->org_delta = delta; |
||||
|
||||
if ( top ) |
||||
count_top ++; |
||||
else |
||||
count_bot ++; |
||||
|
||||
Skip: |
||||
read += 2; |
||||
}
|
||||
|
||||
top_table->count = count_top; |
||||
bot_table->count = count_bot; |
||||
}
|
||||
|
||||
|
||||
/* re-read blue zones from the original fonts, and store them into out */ |
||||
/* private structure. This function re-orders, sanitizes and fuzz-expands */ |
||||
/* the zones as well.. */ |
||||
static void |
||||
psh_blues_set_zones( PSH_Blues target, |
||||
FT_UInt count, |
||||
FT_Short* blues, |
||||
FT_UInt count_others, |
||||
FT_Short* other_blues, |
||||
FT_Int fuzz, |
||||
FT_Int family ) |
||||
{ |
||||
PSH_Blue_Table top_table, bot_table; |
||||
FT_Int count_top, count_bot; |
||||
|
||||
if ( family ) |
||||
{ |
||||
top_table = &target->family_top; |
||||
bot_table = &target->family_bottom; |
||||
} |
||||
else |
||||
{ |
||||
top_table = &target->normal_top; |
||||
bot_table = &target->normal_bottom; |
||||
} |
||||
|
||||
/* read the input blue zones, and build two sorted tables */ |
||||
/* (one for the top zones, the other for the bottom zones */ |
||||
top_table->count = 0; |
||||
bot_table->count = 0; |
||||
|
||||
/* first, the blues */ |
||||
psh_blues_set_zones_0( target, 0, count, blues, top_table, bot_table ); |
||||
psh_blues_set_zones_0( target, 1, count_others, other_blues, top_table, bot_table ); |
||||
|
||||
count_top = top_table->count; |
||||
count_bot = bot_table->count; |
||||
|
||||
/* sanitize top table */ |
||||
if ( count_top > 0 ) |
||||
{ |
||||
PSH_Blue_Zone zone = top_table->zones; |
||||
|
||||
for ( count = count_top; count > 0; count--, zone++ ) |
||||
{ |
||||
FT_Int delta; |
||||
|
||||
if ( count > 1 ) |
||||
{ |
||||
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; |
||||
} |
||||
} |
||||
|
||||
/* sanitize bottom table */ |
||||
if ( count_bot > 0 ) |
||||
{ |
||||
PSH_Blue_Zone zone = bot_table->zones; |
||||
|
||||
for ( count = count_bot; count > 0; count--, zone++ ) |
||||
{ |
||||
FT_Int delta; |
||||
|
||||
if ( count > 1 ) |
||||
{ |
||||
delta = zone[0].org_ref - zone[1].org_ref; |
||||
if ( zone->org_delta < delta ) |
||||
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 */ |
||||
{ |
||||
FT_Int dim, top, bot, delta; |
||||
PSH_Blue_Zone zone; |
||||
|
||||
zone = top_table->zones; |
||||
count = count_top; |
||||
|
||||
for ( dim = 1; dim >= 0; dim-- ) |
||||
{ |
||||
if ( count > 0 ) |
||||
{ |
||||
/* 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-- ) |
||||
{ |
||||
bot = zone[1].org_bottom; |
||||
delta = bot - top; |
||||
if ( delta < 2*fuzz ) |
||||
{ |
||||
zone[0].org_top = zone[1].org_bottom = top + delta/2; |
||||
} |
||||
else |
||||
{ |
||||
zone[0].org_top = top + fuzz; |
||||
zone[1].org_bottom = bot - fuzz; |
||||
} |
||||
|
||||
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 when the device transform changes */ |
||||
static void |
||||
psh_blues_scale_zones( PSH_Blues blues, |
||||
FT_Fixed scale, |
||||
FT_Pos delta ) |
||||
{ |
||||
FT_UInt count; |
||||
FT_UInt num; |
||||
PSH_Blue_Table table = 0; |
||||
|
||||
for ( num = 0; num < 4; num++ ) |
||||
{ |
||||
PSH_Blue_Zone zone; |
||||
|
||||
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; |
||||
|
||||
#if 0
|
||||
if ( zone->cur_ref > zone->cur_top ) |
||||
zone->cur_ref -= 64; |
||||
else if ( zone->cur_ref < zone->cur_bottom ) |
||||
zone->cur_ref += 64; |
||||
#endif |
||||
} |
||||
} |
||||
|
||||
/* 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_Alignment 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--, zone++ ) |
||||
{ |
||||
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--, zone++ ) |
||||
{ |
||||
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; |
||||
break; |
||||
} |
||||
} |
||||
} |
||||
|
||||
|
||||
/*************************************************************************/ |
||||
/*************************************************************************/ |
||||
/***** *****/ |
||||
/***** 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 ); |
||||
|
||||
#ifdef DEBUG_HINTER |
||||
ps_debug_globals = 0; |
||||
#endif |
||||
} |
||||
} |
||||
|
||||
|
||||
static FT_Error |
||||
psh_globals_new( FT_Memory memory, |
||||
T1_Private* priv, |
||||
PSH_Globals *aglobals ) |
||||
{ |
||||
PSH_Globals globals; |
||||
FT_Error error; |
||||
|
||||
if ( !ALLOC( globals, sizeof(*globals) ) ) |
||||
{ |
||||
FT_UInt count; |
||||
FT_Short* read; |
||||
|
||||
globals->memory = memory; |
||||
|
||||
/* copy standard widths */
|
||||
{ |
||||
PSH_Dimension dim = &globals->dimension[1]; |
||||
PSH_Width write = dim->std.widths; |
||||
|
||||
write->org = priv->standard_width[1]; |
||||
write++; |
||||
|
||||
read = priv->snap_widths; |
||||
for ( count = priv->num_snap_widths; count > 0; count-- ) |
||||
{ |
||||
write->org = *read; |
||||
write++; |
||||
read++; |
||||
} |
||||
|
||||
dim->std.count = write - dim->std.widths; |
||||
} |
||||
|
||||
/* copy standard heights */ |
||||
{ |
||||
PSH_Dimension dim = &globals->dimension[0]; |
||||
PSH_Width write = dim->std.widths; |
||||
|
||||
write->org = priv->standard_height[1]; |
||||
write++; |
||||
|
||||
read = priv->snap_heights; |
||||
for ( count = priv->num_snap_heights; count > 0; count-- ) |
||||
{ |
||||
write->org = *read; |
||||
write++; |
||||
read++; |
||||
} |
||||
|
||||
dim->std.count = write - dim->std.widths; |
||||
} |
||||
|
||||
/* copy blue zones */
|
||||
psh_blues_set_zones( &globals->blues, priv->num_blue_values, |
||||
priv->blue_values, priv->num_other_blues, |
||||
priv->other_blues, priv->blue_fuzz, 0 ); |
||||
|
||||
psh_blues_set_zones( &globals->blues, priv->num_family_blues, |
||||
priv->family_blues, priv->num_family_other_blues, |
||||
priv->family_other_blues, priv->blue_fuzz, 1 ); |
||||
|
||||
globals->dimension[0].scale_mult = 0; |
||||
globals->dimension[0].scale_delta = 0; |
||||
globals->dimension[1].scale_mult = 0; |
||||
globals->dimension[1].scale_delta = 0; |
||||
|
||||
#ifdef DEBUG_HINTER |
||||
ps_debug_globals = globals; |
||||
#endif |
||||
} |
||||
|
||||
*aglobals = globals; |
||||
return error; |
||||
} |
||||
|
||||
|
||||
|
||||
static FT_Error |
||||
psh_globals_set_scale( PSH_Globals globals, |
||||
FT_Fixed x_scale, |
||||
FT_Fixed y_scale, |
||||
FT_Fixed x_delta, |
||||
FT_Fixed y_delta ) |
||||
{ |
||||
PSH_Dimension dim = &globals->dimension[0]; |
||||
|
||||
dim = &globals->dimension[0]; |
||||
if ( x_scale != dim->scale_mult || |
||||
x_delta != dim->scale_delta ) |
||||
{ |
||||
dim->scale_mult = x_scale; |
||||
dim->scale_delta = x_delta; |
||||
|
||||
psh_globals_scale_widths( globals, 0 ); |
||||
} |
||||
|
||||
dim = &globals->dimension[1]; |
||||
if ( y_scale != dim->scale_mult || |
||||
y_delta != dim->scale_delta ) |
||||
{ |
||||
dim->scale_mult = y_scale; |
||||
dim->scale_delta = y_delta; |
||||
|
||||
psh_globals_scale_widths( globals, 1 ); |
||||
psh_blues_scale_zones( &globals->blues, y_scale, y_delta ); |
||||
} |
||||
|
||||
return 0; |
||||
} |
||||
|
||||
|
||||
FT_LOCAL_DEF void |
||||
psh_globals_funcs_init( PSH_Globals_FuncsRec* funcs ) |
||||
{ |
||||
funcs->create = psh_globals_new; |
||||
funcs->set_scale = psh_globals_set_scale; |
||||
funcs->destroy = psh_globals_destroy; |
||||
} |
@ -0,0 +1,171 @@ |
||||
/***************************************************************************/ |
||||
/* */ |
||||
/* 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__ |
||||
#define __PS_HINTER_GLOBALS_H__ |
||||
|
||||
#include FT_FREETYPE_H |
||||
#include FT_INTERNAL_POSTSCRIPT_GLOBALS_H |
||||
#include FT_INTERNAL_POSTSCRIPT_HINTS_H |
||||
|
||||
FT_BEGIN_HEADER |
||||
|
||||
/**********************************************************************/ |
||||
/**********************************************************************/ |
||||
/***** *****/ |
||||
/***** GLOBAL HINTS INTERNALS *****/ |
||||
/***** *****/ |
||||
/**********************************************************************/ |
||||
/**********************************************************************/ |
||||
/****************************************************************
|
||||
* |
||||
* @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 |
||||
|
||||
|
||||
/* standard and snap width */ |
||||
typedef struct PSH_WidthRec_ |
||||
{ |
||||
FT_Int org; |
||||
FT_Pos cur; |
||||
FT_Pos fit; |
||||
|
||||
} PSH_WidthRec, *PSH_Width; |
||||
|
||||
|
||||
/* standard and snap widths table */ |
||||
typedef struct PSH_WidthsRec_ |
||||
{ |
||||
FT_UInt count; |
||||
PSH_WidthRec widths[ PS_GLOBALS_MAX_STD_WIDTHS ]; |
||||
|
||||
} PSH_WidthsRec, *PSH_Widths; |
||||
|
||||
|
||||
typedef struct PSH_DimensionRec_ |
||||
{ |
||||
PSH_WidthsRec std; |
||||
FT_Fixed scale_mult; |
||||
FT_Fixed scale_delta; |
||||
|
||||
} 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 */ |
||||
typedef struct PSH_GlobalsRec_ |
||||
{ |
||||
FT_Memory memory; |
||||
PSH_DimensionRec dimension[2]; |
||||
PSH_BluesRec blues; |
||||
|
||||
} PSH_GlobalsRec; |
||||
|
||||
|
||||
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_AlignmentRec, *PSH_Alignment; |
||||
|
||||
|
||||
FT_LOCAL void |
||||
psh_globals_funcs_init( PSH_Globals_FuncsRec* funcs ); |
||||
|
||||
|
||||
/* snap a stem width to fitter coordinates. org_width is in font units */ |
||||
/* result is in device pixels (26.6 format).. */ |
||||
FT_LOCAL FT_Pos |
||||
psh_dimension_snap_width( PSH_Dimension dimension, |
||||
FT_Int org_width ); |
||||
|
||||
/* snap a stem to one or two blue zones */ |
||||
FT_LOCAL void |
||||
psh_blues_snap_stem( PSH_Blues blues, |
||||
FT_Int stem_top, |
||||
FT_Int stem_bot, |
||||
PSH_Alignment alignment ); |
||||
/* */ |
||||
|
||||
#ifdef DEBUG_HINTER |
||||
extern PSH_Globals ps_debug_globals; |
||||
#endif |
||||
|
||||
FT_END_HEADER |
||||
|
||||
#endif __T1_FITTER_GLOBALS_H__ |
@ -0,0 +1,29 @@ |
||||
/***************************************************************************/ |
||||
/* */ |
||||
/* 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 "pshalgo1.c" |
||||
#include "pshalgo2.c" |
||||
#include "pshmod.c" |
||||
|
||||
|
||||
/* END */ |
@ -0,0 +1,116 @@ |
||||
/***************************************************************************/ |
||||
/* */ |
||||
/* 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" |
||||
#include "pshalgo.h" |
||||
|
||||
/* the Postscript Hinter module structure */ |
||||
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; |
||||
|
||||
t2_hints_funcs_init( &module->t2_funcs ); |
||||
module->t2_funcs.hints = (T2_Hints) & module->ps_hints; |
||||
|
||||
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( PS_Hinter_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 */ |
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,165 @@ |
||||
/***************************************************************************/ |
||||
/* */ |
||||
/* pshrec.h */ |
||||
/* */ |
||||
/* Postscript (Type1/Type2) 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 the 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; |
||||
|
||||
/* */ |
||||
|
||||
/* initialise hints recorder */ |
||||
FT_LOCAL FT_Error |
||||
ps_hints_init( PS_Hints hints, |
||||
FT_Memory memory ); |
||||
|
||||
/* finalize hints recorder */ |
||||
FT_LOCAL void |
||||
ps_hints_done( PS_Hints hints ); |
||||
|
||||
/* initialise Type1 hints recorder interface */
|
||||
FT_LOCAL void |
||||
t1_hints_funcs_init( T1_Hints_FuncsRec* funcs ); |
||||
|
||||
/* initialise Type2 hints recorder interface */ |
||||
FT_LOCAL void |
||||
t2_hints_funcs_init( T2_Hints_FuncsRec* funcs ); |
||||
|
||||
|
||||
#ifdef DEBUG_HINTER |
||||
extern PS_Hints ps_debug_hints; |
||||
extern int ps_debug_no_horz_hints; |
||||
extern int ps_debug_no_vert_hints; |
||||
#endif |
||||
|
||||
/* */ |
||||
|
||||
FT_END_HEADER |
||||
|
||||
#endif /* __PS_HINTER_RECORD_H__ */ |
Loading…
Reference in new issue