forked from minhngoc25a/freetype2
Compare commits
5 Commits
master
...
hdmx-advan
Author | SHA1 | Date |
---|---|---|
Alexei Podtelezhnikov | 0dc811b548 | |
Alexei Podtelezhnikov | eaa10b993b | |
Alexei Podtelezhnikov | fa35370135 | |
Alexei Podtelezhnikov | 2e3455b135 | |
Alexei Podtelezhnikov | 34fc55de47 |
|
@ -1390,8 +1390,8 @@ FT_BEGIN_HEADER
|
|||
* hdmx_record_size ::
|
||||
* The size of a single hdmx record.
|
||||
*
|
||||
* hdmx_record_sizes ::
|
||||
* An array holding the ppem sizes available in the 'hdmx' table.
|
||||
* hdmx_records ::
|
||||
* A array of pointers to the 'hdmx' table records sorted by ppem.
|
||||
*
|
||||
* sbit_table ::
|
||||
* A pointer to the font's embedded bitmap location table.
|
||||
|
@ -1605,7 +1605,7 @@ FT_BEGIN_HEADER
|
|||
FT_ULong hdmx_table_size;
|
||||
FT_UInt hdmx_record_count;
|
||||
FT_ULong hdmx_record_size;
|
||||
FT_Byte* hdmx_record_sizes;
|
||||
FT_Byte** hdmx_records;
|
||||
|
||||
FT_Byte* sbit_table;
|
||||
FT_ULong sbit_table_size;
|
||||
|
@ -1769,6 +1769,9 @@ FT_BEGIN_HEADER
|
|||
/* since version 2.6.2 */
|
||||
FT_ListRec composites;
|
||||
|
||||
/* since version 2.11.2 */
|
||||
FT_Byte* widthp;
|
||||
|
||||
} TT_LoaderRec;
|
||||
|
||||
|
||||
|
|
|
@ -2230,10 +2230,6 @@
|
|||
FT_UInt glyph_index )
|
||||
{
|
||||
TT_Face face = loader->face;
|
||||
#if defined TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY || \
|
||||
defined TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL
|
||||
TT_Driver driver = (TT_Driver)FT_FACE_DRIVER( face );
|
||||
#endif
|
||||
|
||||
FT_BBox bbox;
|
||||
FT_Fixed y_scale;
|
||||
|
@ -2256,37 +2252,10 @@
|
|||
|
||||
glyph->metrics.horiBearingX = bbox.xMin;
|
||||
glyph->metrics.horiBearingY = bbox.yMax;
|
||||
glyph->metrics.horiAdvance = SUB_LONG(loader->pp2.x, loader->pp1.x);
|
||||
|
||||
/* Adjust advance width to the value contained in the hdmx table */
|
||||
/* unless FT_LOAD_COMPUTE_METRICS is set or backward compatibility */
|
||||
/* mode of the v40 interpreter is active. See `ttinterp.h' for */
|
||||
/* details on backward compatibility mode. */
|
||||
if ( IS_HINTED( loader->load_flags ) &&
|
||||
!( loader->load_flags & FT_LOAD_COMPUTE_METRICS ) &&
|
||||
#ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL
|
||||
!( driver->interpreter_version == TT_INTERPRETER_VERSION_40 &&
|
||||
( loader->exec && loader->exec->backward_compatibility ) ) &&
|
||||
#endif
|
||||
#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
|
||||
!( driver->interpreter_version == TT_INTERPRETER_VERSION_38 &&
|
||||
!SPH_OPTION_BITMAP_WIDTHS &&
|
||||
FT_LOAD_TARGET_MODE( loader->load_flags ) !=
|
||||
FT_RENDER_MODE_MONO &&
|
||||
( loader->exec && !loader->exec->compatible_widths ) ) &&
|
||||
#endif
|
||||
!face->postscript.isFixedPitch )
|
||||
{
|
||||
FT_Byte* widthp;
|
||||
|
||||
|
||||
widthp = tt_face_get_device_metrics( face,
|
||||
size->metrics->x_ppem,
|
||||
glyph_index );
|
||||
|
||||
if ( widthp )
|
||||
glyph->metrics.horiAdvance = *widthp * 64;
|
||||
}
|
||||
if ( loader->widthp )
|
||||
glyph->metrics.horiAdvance = loader->widthp[glyph_index] * 64;
|
||||
else
|
||||
glyph->metrics.horiAdvance = SUB_LONG(loader->pp2.x, loader->pp1.x);
|
||||
|
||||
/* set glyph dimensions */
|
||||
glyph->metrics.width = SUB_LONG( bbox.xMax, bbox.xMin );
|
||||
|
@ -2720,11 +2689,64 @@
|
|||
if ( driver->interpreter_version == TT_INTERPRETER_VERSION_38 &&
|
||||
exec->GS.instruct_control & 4 )
|
||||
exec->ignore_x_mode = 0;
|
||||
#endif
|
||||
|
||||
exec->iup_called = FALSE;
|
||||
#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */
|
||||
|
||||
#ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL
|
||||
/*
|
||||
* Toggle backward compatibility according to what font wants, except
|
||||
* when
|
||||
*
|
||||
* 1) we have a `tricky' font that heavily relies on the interpreter to
|
||||
* render glyphs correctly, for example DFKai-SB, or
|
||||
* 2) FT_RENDER_MODE_MONO (i.e, monochome rendering) is requested.
|
||||
*
|
||||
* In those cases, backward compatibility needs to be turned off to get
|
||||
* correct rendering. The rendering is then completely up to the
|
||||
* font's programming.
|
||||
*
|
||||
*/
|
||||
if ( driver->interpreter_version == TT_INTERPRETER_VERSION_38 &&
|
||||
subpixel_hinting_lean &&
|
||||
!FT_IS_TRICKY( glyph->face ) )
|
||||
exec->backward_compatibility = !( exec->GS.instruct_control & 4 );
|
||||
else
|
||||
exec->backward_compatibility = FALSE;
|
||||
|
||||
exec->iupx_called = FALSE;
|
||||
exec->iupy_called = FALSE;
|
||||
#endif /* TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL */
|
||||
|
||||
exec->pedantic_hinting = FT_BOOL( load_flags & FT_LOAD_PEDANTIC );
|
||||
loader->exec = exec;
|
||||
loader->instructions = exec->glyphIns;
|
||||
|
||||
/* Use the hdmx table if any unless FT_LOAD_COMPUTE_METRICS */
|
||||
/* is set or backward compatibility mode of the v38 or v40 */
|
||||
/* interpreters is active. See `ttinterp.h' for details on */
|
||||
/* backward compatibility mode. */
|
||||
if ( IS_HINTED( loader->load_flags ) &&
|
||||
!( loader->load_flags & FT_LOAD_COMPUTE_METRICS ) &&
|
||||
#ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL
|
||||
!( driver->interpreter_version == TT_INTERPRETER_VERSION_40 &&
|
||||
exec->backward_compatibility ) &&
|
||||
#endif
|
||||
#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
|
||||
!( driver->interpreter_version == TT_INTERPRETER_VERSION_38 &&
|
||||
!SPH_OPTION_BITMAP_WIDTHS &&
|
||||
FT_LOAD_TARGET_MODE( loader->load_flags ) !=
|
||||
FT_RENDER_MODE_MONO &&
|
||||
exec->compatible_widths ) &&
|
||||
#endif
|
||||
!face->postscript.isFixedPitch )
|
||||
{
|
||||
loader->widthp = tt_face_get_device_metrics( face,
|
||||
size->metrics->x_ppem,
|
||||
0 );
|
||||
}
|
||||
else
|
||||
loader->widthp = NULL;
|
||||
}
|
||||
|
||||
#endif /* TT_USE_BYTECODE_INTERPRETER */
|
||||
|
@ -2923,6 +2945,15 @@
|
|||
if ( error )
|
||||
goto Exit;
|
||||
|
||||
/* done if we are only interested in the `hdmx` advance */
|
||||
if ( load_flags & FT_LOAD_ADVANCE_ONLY &&
|
||||
!( load_flags & FT_LOAD_VERTICAL_LAYOUT ) &&
|
||||
loader.widthp )
|
||||
{
|
||||
glyph->metrics.horiAdvance = loader.widthp[glyph_index] * 64;
|
||||
goto Done;
|
||||
}
|
||||
|
||||
glyph->format = FT_GLYPH_FORMAT_OUTLINE;
|
||||
glyph->num_subglyphs = 0;
|
||||
glyph->outline.flags = 0;
|
||||
|
@ -3001,6 +3032,7 @@
|
|||
glyph->outline.n_points,
|
||||
glyph->outline.flags ));
|
||||
|
||||
Done:
|
||||
tt_loader_done( &loader );
|
||||
|
||||
Exit:
|
||||
|
|
|
@ -5260,10 +5260,15 @@
|
|||
}
|
||||
}
|
||||
|
||||
exc->GS.instruct_control &= ~(FT_Byte)Kf;
|
||||
exc->GS.instruct_control |= (FT_Byte)L;
|
||||
/* INSTCTRL should only be used in the CVT program */
|
||||
if ( exc->iniRange == tt_coderange_cvt )
|
||||
{
|
||||
exc->GS.instruct_control &= ~(FT_Byte)Kf;
|
||||
exc->GS.instruct_control |= (FT_Byte)L;
|
||||
}
|
||||
|
||||
if ( K == 3 )
|
||||
/* except to change the subpixel flags temporarily */
|
||||
else if ( exc->iniRange == tt_coderange_glyph && K == 3 )
|
||||
{
|
||||
#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
|
||||
/* INSTCTRL modifying flag 3 also has an effect */
|
||||
|
@ -7755,35 +7760,6 @@
|
|||
#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */
|
||||
|
||||
|
||||
#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
|
||||
exc->iup_called = FALSE;
|
||||
#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */
|
||||
|
||||
#ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL
|
||||
/*
|
||||
* Toggle backward compatibility according to what font wants, except
|
||||
* when
|
||||
*
|
||||
* 1) we have a `tricky' font that heavily relies on the interpreter to
|
||||
* render glyphs correctly, for example DFKai-SB, or
|
||||
* 2) FT_RENDER_MODE_MONO (i.e, monochome rendering) is requested.
|
||||
*
|
||||
* In those cases, backward compatibility needs to be turned off to get
|
||||
* correct rendering. The rendering is then completely up to the
|
||||
* font's programming.
|
||||
*
|
||||
*/
|
||||
if ( SUBPIXEL_HINTING_MINIMAL &&
|
||||
exc->subpixel_hinting_lean &&
|
||||
!FT_IS_TRICKY( &exc->face->root ) )
|
||||
exc->backward_compatibility = !( exc->GS.instruct_control & 4 );
|
||||
else
|
||||
exc->backward_compatibility = FALSE;
|
||||
|
||||
exc->iupx_called = FALSE;
|
||||
exc->iupy_called = FALSE;
|
||||
#endif
|
||||
|
||||
/* We restrict the number of twilight points to a reasonable, */
|
||||
/* heuristic value to avoid slow execution of malformed bytecode. */
|
||||
num_twilight_points = FT_MAX( 30,
|
||||
|
|
|
@ -498,6 +498,14 @@
|
|||
}
|
||||
|
||||
|
||||
FT_COMPARE_DEF( int )
|
||||
compare_ppem( const void* a,
|
||||
const void* b )
|
||||
{
|
||||
return **(FT_Byte**)a - **(FT_Byte**)b;
|
||||
}
|
||||
|
||||
|
||||
/**************************************************************************
|
||||
*
|
||||
* @Function:
|
||||
|
@ -574,20 +582,21 @@
|
|||
goto Fail;
|
||||
}
|
||||
|
||||
if ( FT_QNEW_ARRAY( face->hdmx_record_sizes, num_records ) )
|
||||
if ( FT_QNEW_ARRAY( face->hdmx_records, num_records ) )
|
||||
goto Fail;
|
||||
|
||||
/* XXX: We do not check if the records are sorted by ppem */
|
||||
/* and cannot use binary search later. */
|
||||
for ( nn = 0; nn < num_records; nn++ )
|
||||
{
|
||||
if ( p + record_size > limit )
|
||||
break;
|
||||
|
||||
face->hdmx_record_sizes[nn] = p[0];
|
||||
p += record_size;
|
||||
face->hdmx_records[nn] = p;
|
||||
p += record_size;
|
||||
}
|
||||
|
||||
/* The records must be already sorted by ppem but it does not */
|
||||
/* hurt to make sure so that the binary search works later. */
|
||||
ft_qsort( face->hdmx_records, nn, sizeof ( FT_Byte* ), compare_ppem );
|
||||
|
||||
face->hdmx_record_count = nn;
|
||||
face->hdmx_table_size = table_size;
|
||||
face->hdmx_record_size = record_size;
|
||||
|
@ -611,7 +620,7 @@
|
|||
FT_Memory memory = stream->memory;
|
||||
|
||||
|
||||
FT_FREE( face->hdmx_record_sizes );
|
||||
FT_FREE( face->hdmx_records );
|
||||
FT_FRAME_RELEASE( face->hdmx_table );
|
||||
}
|
||||
|
||||
|
@ -619,27 +628,34 @@
|
|||
/**************************************************************************
|
||||
*
|
||||
* Return the advance width table for a given pixel size if it is found
|
||||
* in the font's `hdmx' table (if any).
|
||||
* in the font's `hdmx' table (if any). The records must be sorted for
|
||||
* the binary search to work properly.
|
||||
*/
|
||||
FT_LOCAL_DEF( FT_Byte* )
|
||||
tt_face_get_device_metrics( TT_Face face,
|
||||
FT_UInt ppem,
|
||||
FT_UInt gindex )
|
||||
{
|
||||
FT_UInt nn;
|
||||
FT_Byte* result = NULL;
|
||||
FT_ULong record_size = face->hdmx_record_size;
|
||||
FT_Byte* record = FT_OFFSET( face->hdmx_table, 8 );
|
||||
FT_UInt min = 0;
|
||||
FT_UInt max = face->hdmx_record_count;
|
||||
FT_UInt mid;
|
||||
FT_Byte* result = NULL;
|
||||
|
||||
|
||||
for ( nn = 0; nn < face->hdmx_record_count; nn++ )
|
||||
if ( face->hdmx_record_sizes[nn] == ppem )
|
||||
while ( min < max )
|
||||
{
|
||||
mid = ( min + max ) >> 1;
|
||||
|
||||
if ( face->hdmx_records[mid][0] > ppem )
|
||||
max = mid;
|
||||
else if ( face->hdmx_records[mid][0] < ppem )
|
||||
min = mid + 1;
|
||||
else
|
||||
{
|
||||
gindex += 2;
|
||||
if ( gindex < record_size )
|
||||
result = record + nn * record_size + gindex;
|
||||
result = face->hdmx_records[mid] + 2 + gindex;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue