📄 pshinter.c
字号:
PS_Dimension dim;
FT_Memory memory = hints->memory;
FT_Int count;
FT_Int idx[3];
/* limit "dimension" to 0..1 */
if ( dimension < 0 || dimension > 1 )
{
FT_ERROR(( "ps_hints_t1stem3: invalid dimension (%d) used\n",
dimension ));
dimension = ( dimension != 0 );
}
dim = &hints->dimension[dimension];
/* there must be 6 elements in the 'stem' array */
if ( hints->hint_type == PS_HINT_TYPE_1 )
{
/* add the three stems to our hints/masks table */
for ( count = 0; count < 3; count++, stems += 2 )
{
error = ps_dimension_add_t1stem(
dim, (FT_Int)stems[0], (FT_Int)stems[1],
memory, &idx[count] );
if ( error )
goto Fail;
}
/* now, add the hints to the counters table */
error = ps_dimension_add_counter( dim, idx[0], idx[1], idx[2],
memory );
if ( error )
goto Fail;
}
else
{
FT_ERROR(( "ps_hints_t1stem3: called with invalid hint type!\n" ));
error = PSH_Err_Invalid_Argument;
goto Fail;
}
}
return;
Fail:
FT_ERROR(( "ps_hints_t1stem3: could not add counter stems to table\n" ));
hints->error = error;
}
/* reset hints (only with Type 1 hints) */
static void
ps_hints_t1reset( PS_Hints hints,
FT_UInt end_point )
{
FT_Error error = 0;
if ( !hints->error )
{
FT_Memory memory = hints->memory;
if ( hints->hint_type == PS_HINT_TYPE_1 )
{
error = ps_dimension_reset_mask( &hints->dimension[0],
end_point, memory );
if ( error )
goto Fail;
error = ps_dimension_reset_mask( &hints->dimension[1],
end_point, memory );
if ( error )
goto Fail;
}
else
{
/* invalid hint type */
error = PSH_Err_Invalid_Argument;
goto Fail;
}
}
return;
Fail:
hints->error = error;
}
/* Type2 "hintmask" operator, add a new hintmask to each direction */
static void
ps_hints_t2mask( PS_Hints hints,
FT_UInt end_point,
FT_UInt bit_count,
const FT_Byte* bytes )
{
FT_Error error;
if ( !hints->error )
{
PS_Dimension dim = hints->dimension;
FT_Memory memory = hints->memory;
FT_UInt count1 = dim[0].hints.num_hints;
FT_UInt count2 = dim[1].hints.num_hints;
/* check bit count; must be equal to current total hint count */
if ( bit_count != count1 + count2 )
{
FT_ERROR(( "ps_hints_t2mask: "
"called with invalid bitcount %d (instead of %d)\n",
bit_count, count1 + count2 ));
/* simply ignore the operator */
return;
}
/* set-up new horizontal and vertical hint mask now */
error = ps_dimension_set_mask_bits( &dim[0], bytes, count2, count1,
end_point, memory );
if ( error )
goto Fail;
error = ps_dimension_set_mask_bits( &dim[1], bytes, 0, count2,
end_point, memory );
if ( error )
goto Fail;
}
return;
Fail:
hints->error = error;
}
static void
ps_hints_t2counter( PS_Hints hints,
FT_UInt bit_count,
const FT_Byte* bytes )
{
FT_Error error;
if ( !hints->error )
{
PS_Dimension dim = hints->dimension;
FT_Memory memory = hints->memory;
FT_UInt count1 = dim[0].hints.num_hints;
FT_UInt count2 = dim[1].hints.num_hints;
/* check bit count, must be equal to current total hint count */
if ( bit_count != count1 + count2 )
{
FT_ERROR(( "ps_hints_t2counter: "
"called with invalid bitcount %d (instead of %d)\n",
bit_count, count1 + count2 ));
/* simply ignore the operator */
return;
}
/* set-up new horizontal and vertical hint mask now */
error = ps_dimension_set_mask_bits( &dim[0], bytes, 0, count1,
0, memory );
if ( error )
goto Fail;
error = ps_dimension_set_mask_bits( &dim[1], bytes, count1, count2,
0, memory );
if ( error )
goto Fail;
}
return;
Fail:
hints->error = error;
}
/* end recording session */
static FT_Error
ps_hints_close( PS_Hints hints,
FT_UInt end_point )
{
FT_Error error;
error = hints->error;
if ( !error )
{
FT_Memory memory = hints->memory;
PS_Dimension dim = hints->dimension;
error = ps_dimension_end( &dim[0], end_point, memory );
if ( !error )
{
error = ps_dimension_end( &dim[1], end_point, memory );
}
}
#ifdef DEBUG_HINTER
if ( !error )
ps_debug_hints = hints;
#endif
return error;
}
/*************************************************************************/
/*************************************************************************/
/***** *****/
/***** TYPE 1 HINTS RECORDING INTERFACE *****/
/***** *****/
/*************************************************************************/
/*************************************************************************/
static void
t1_hints_open( T1_Hints hints )
{
ps_hints_open( (PS_Hints)hints, PS_HINT_TYPE_1 );
}
static void
t1_hints_stem( T1_Hints hints,
FT_Int dimension,
FT_Long* coords )
{
ps_hints_stem( (PS_Hints)hints, dimension, 1, coords );
}
FT_LOCAL_DEF( void )
t1_hints_funcs_init( T1_Hints_FuncsRec* funcs )
{
FT_MEM_ZERO( (char*)funcs, sizeof ( *funcs ) );
funcs->open = (T1_Hints_OpenFunc) t1_hints_open;
funcs->close = (T1_Hints_CloseFunc) ps_hints_close;
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 = (T1_Hints_ApplyFunc) ps_hints_apply;
}
/*************************************************************************/
/*************************************************************************/
/***** *****/
/***** TYPE 2 HINTS RECORDING INTERFACE *****/
/***** *****/
/*************************************************************************/
/*************************************************************************/
static void
t2_hints_open( T2_Hints hints )
{
ps_hints_open( (PS_Hints)hints, PS_HINT_TYPE_2 );
}
static void
t2_hints_stems( T2_Hints hints,
FT_Int dimension,
FT_Int count,
FT_Fixed* coords )
{
FT_Pos stems[32], y, n;
FT_Int total = count;
y = 0;
while ( total > 0 )
{
/* determine number of stems to write */
count = total;
if ( count > 16 )
count = 16;
/* compute integer stem positions in font units */
for ( n = 0; n < count * 2; n++ )
{
y += coords[n];
stems[n] = ( y + 0x8000L ) >> 16;
}
/* compute lengths */
for ( n = 0; n < count * 2; n += 2 )
stems[n + 1] = stems[n + 1] - stems[n];
/* add them to the current dimension */
ps_hints_stem( (PS_Hints)hints, dimension, count, stems );
total -= count;
}
}
FT_LOCAL_DEF( void )
t2_hints_funcs_init( T2_Hints_FuncsRec* funcs )
{
FT_MEM_ZERO( funcs, sizeof ( *funcs ) );
funcs->open = (T2_Hints_OpenFunc) t2_hints_open;
funcs->close = (T2_Hints_CloseFunc) ps_hints_close;
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 = (T2_Hints_ApplyFunc) ps_hints_apply;
}
/* END */
/***************************************************************************/
/* */
/* pshglob.c */
/* */
/* PostScript hinter global hinting management (body). */
/* Inspired by the new auto-hinter module. */
/* */
/* Copyright 2001, 2002, 2003, 2004, 2006 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_FREETYPE_H
#include FT_INTERNAL_OBJECTS_H
#include "pshglob.h"
#ifdef DEBUG_HINTER
PSH_Globals ps_debug_globals = 0;
#endif
/*************************************************************************/
/*************************************************************************/
/***** *****/
/***** 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 stdw = &dim->stdw;
FT_UInt count = stdw->count;
PSH_Width width = stdw->widths;
PSH_Width stand = width; /* standard width/height */
FT_Fixed scale = dim->scale_mult;
if ( count > 0 )
{
width->cur = FT_MulFix( width->org, scale );
width->fit = FT_PIX_ROUND( width->cur );
width++;
count--;
for ( ; count > 0; count--, width++ )
{
FT_Pos w, dist;
w = FT_MulFix( width->org, scale );
dist = w - stand->cur;
if ( dist < 0 )
dist = -dist;
if ( dist < 128 )
w = stand->cur;
width->cur = w;
width->fit = FT_PIX_ROUND( w );
}
}
}
#if 0
/* 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->stdw.count; n++ )
{
FT_Pos w;
FT_Pos dist;
w = dimension->stdw.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;
}
#endif /* 0 */
/*************************************************************************/
/*************************************************************************/
/***** *****/
/***** 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,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -