still more updates to the TrueType driver to make it more

"extensible"..
This commit is contained in:
David Turner 2000-06-23 12:26:14 +00:00
parent b51a58fae6
commit 90f68b7272
5 changed files with 190 additions and 148 deletions

View File

@ -160,7 +160,8 @@ else
#
# The list of demonstration programs to build.
#
EXES := ftlint ftview fttimer compos ftstring memtest ftmulti
# EXES := ftlint ftview fttimer compos ftstring memtest ftmulti
EXES := ftlint ftview
ifneq ($(findstring $(PLATFORM),os2 unix win32),)
EXES += ttdebug

View File

@ -92,9 +92,10 @@
the handle <tt>library</tt> to it.</p>
</li>
<li>
<p>Load each font driver that FreeType knows about in the library.
<p>Load each modules that FreeType knows about in the library.
This means that by default, your new <tt>library</tt> object is able
to handle TrueType and Type&nbsp;1 fonts gracefully.</p>
to handle TrueType, Type 1, CID-keyed & OpenType/CFF fonts
gracefully.</p>
</li>
</ul>
@ -238,6 +239,8 @@
font driver when creating the object. We advise you to refer to the
FreeType&nbsp;2 reference manual in order to learn how to use it.</p>
<p>Note that providing a custom stream might also be used to access a
TrueType font embedded in a Postscript Type42 wrapper..</p>
<hr>
<h3>
@ -435,7 +438,7 @@
<p>Note that this is one of the rare FreeType functions that do not
return an error code. However, when a given character code has no
glyph image in the face, the value&nbso;0 is returned. By convention,
glyph image in the face, the value&nbsp;0 is returned. By convention,
it always correspond to a special glyph image called the <b>missing
glyph</b>, which usually is represented as a box or a space.</p>
@ -483,16 +486,29 @@
higher-quality images of the same glyph).</p>
</li>
<li>
<p>If there is an outline for the corresponding glyph, load it
unless <tt>FT_LOAD_NO_OUTLINE</tt> is set. Otherwise, scale it to
the current size, unless the <tt>FT_LOAD_NO_SCALE</tt> flag is
set.</p>
<p>If there is a glyph image in another format (e.g. a vectorial
outline), load it in the glyph slot. Then, scale it to the
current size, unless the <tt>FT_LOAD_NO_SCALE</tt> flag is
set.</p>
</li>
<li>
<p>If the outline was loaded and scaled, try to grid-fit it (which
<p>If the glyph image was loaded and scaled, try to grid-fit it (which
dramatically improves its quality) unless the flag
<tt>FT_LOAD_NO_HINTING</tt> is set.</p>
</li>
<li>
<p>If the glyph image is scalable, transform it through the current
transform (that can be set with <tt>FT_Set_Transform</tt>).</p>
</li>
<li>
<p>Finally, if the <tt>FT_LOAD_RENDER</tt> flag is set, convert the
glyph image into a bitmap. By default, this means a 1-bit
monochrome bitmap, unless <tt>FT_LOAD_ANTI_ALIAS</tt> is set,
where an 8-bit 256-gray-levels anti-aliased bitmap is generated.
</p>
</li>
</ul>
<p>There are a few others <tt>FT_LOAD_xxx</tt> flags defined. For

View File

@ -1814,7 +1814,7 @@
/* FT_Render_Glyph. */
/* */
/* */
#define FT_LOAD_LINEAR_ANTI_ALIAS 4096
#define FT_LOAD_ANTI_ALIAS 4096
/*************************************************************************/

View File

@ -1410,6 +1410,7 @@
FT_Stream stream;
FT_Int byte_len;
FT_Short n_contours;
FT_BBox bbox;
FT_Int left_bearing;
FT_Int advance;

View File

@ -194,17 +194,63 @@
/*************************************************************************/
/* */
/* <Function> */
/* TT_Load_Simple_Glyph */
/* */
/* <Description> */
/* Loads a simple (i.e, non-composite) glyph. This function is used */
/* for the `Load_Simple' state of TT_Load_Glyph(). All composite */
/* glyphs elements will be loaded with this routine. */
/* The following functions are used by default with TrueType fonts. */
/* However, they can be replaced by alternatives if we need to support */
/* TrueType-compressed formats (like MicroType) in the future.. */
/* */
static
FT_Error TT_Access_Glyph_Frame( TT_Loader* loader,
FT_UInt glyph_index,
FT_ULong offset,
FT_UInt byte_count )
{
FT_Error error;
FT_Stream stream = loader->stream;
/* the following line sets the 'error' variable through macros !! */
(void)( FILE_Seek( offset ) || ACCESS_Frame( byte_count ) );
FT_TRACE5(( "Glyph %ld\n", glyph_index ));
return error;
}
static
void TT_Forget_Glyph_Frame( TT_Loader* loader )
{
FT_Stream stream = loader->stream;
FORGET_Frame();
}
static
FT_Error TT_Load_Glyph_Header( TT_Loader* loader )
{
FT_Stream stream = loader->stream;
loader->n_contours = GET_Short();
loader->bbox.xMin = GET_Short();
loader->bbox.yMin = GET_Short();
loader->bbox.xMax = GET_Short();
loader->bbox.yMax = GET_Short();
FT_TRACE5(( " # of contours: %d\n", loader->n_contours ));
FT_TRACE5(( " xMin: %4d xMax: %4d\n", loader->bbox.xMin,
loader->bbox.xMax ));
FT_TRACE5(( " yMin: %4d yMax: %4d\n", loader->bbox.yMin,
loader->bbox.yMax ));
return FT_Err_Ok;
}
static
FT_Error TT_Load_Simple_Glyph( TT_Loader* load,
FT_UInt byte_count,
FT_Int n_contours )
{
FT_Error error;
@ -217,9 +263,6 @@
FT_Int n, n_points;
if ( ACCESS_Frame( byte_count ) )
return error;
/* reading the contours endpoints & number of points */
{
short* cur = gloader->current.outline.contours;
@ -357,15 +400,97 @@
outline->n_points = n_points;
outline->n_contours = n_contours;
return error;
Fail:
FORGET_Frame();
Fail:
return error;
}
static
FT_Error TT_Load_Composite_Glyph( TT_Loader* loader,
FT_UInt byte_count )
{
FT_Error error;
FT_Stream stream = loader->stream;
FT_GlyphLoader* gloader = loader->gloader;
FT_SubGlyph* subglyph;
FT_UInt num_subglyphs;
num_subglyphs = 0;
do
{
FT_Fixed xx, xy, yy, yx;
/* check that we can load a new subglyph */
error = FT_GlyphLoader_Check_Subglyphs( gloader, num_subglyphs+1 );
if (error) goto Fail;
subglyph = gloader->current.subglyphs + num_subglyphs;
subglyph->arg1 = subglyph->arg2 = 0;
subglyph->flags = GET_UShort();
subglyph->index = GET_UShort();
/* read arguments */
if ( subglyph->flags & ARGS_ARE_WORDS )
{
subglyph->arg1 = GET_Short();
subglyph->arg2 = GET_Short();
}
else
{
subglyph->arg1 = GET_Char();
subglyph->arg2 = GET_Char();
}
/* read transform */
xx = yy = 0x10000L;
xy = yx = 0;
if ( subglyph->flags & WE_HAVE_A_SCALE )
{
xx = (FT_Fixed)GET_Short() << 2;
yy = xx;
}
else if ( subglyph->flags & WE_HAVE_AN_XY_SCALE )
{
xx = (FT_Fixed)GET_Short() << 2;
yy = (FT_Fixed)GET_Short() << 2;
}
else if ( subglyph->flags & WE_HAVE_A_2X2 )
{
xx = (FT_Fixed)GET_Short() << 2;
xy = (FT_Fixed)GET_Short() << 2;
yx = (FT_Fixed)GET_Short() << 2;
yy = (FT_Fixed)GET_Short() << 2;
}
subglyph->transform.xx = xx;
subglyph->transform.xy = xy;
subglyph->transform.yx = yx;
subglyph->transform.yy = yy;
num_subglyphs++;
}
while (subglyph->flags & MORE_COMPONENTS);
gloader->current.num_subglyphs = num_subglyphs;
#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER
{
/* we must undo the ACCESS_Frame in order to point to the */
/* composite instructions, if we find some. */
/* we will process them later... */
/* */
loader->ins_pos = FILE_Pos() + stream->cursor - stream->limit;
}
#endif
Fail:
return error;
}
/*************************************************************************/
@ -488,104 +613,6 @@
/*************************************************************************/
/* */
/* <Function> */
/* TT_Load_Composite_Glyph */
/* */
/* <Description> */
/* Loads a composite glyph. */
/* */
static
FT_Error TT_Load_Composite_Glyph( TT_Loader* loader,
FT_UInt byte_count )
{
FT_Error error;
FT_Stream stream = loader->stream;
FT_GlyphLoader* gloader = loader->gloader;
FT_SubGlyph* subglyph;
FT_UInt num_subglyphs;
if ( ACCESS_Frame( byte_count ) )
goto Fail;
num_subglyphs = 0;
do
{
FT_Fixed xx, xy, yy, yx;
/* check that we can load a new subglyph */
error = FT_GlyphLoader_Check_Subglyphs( gloader, num_subglyphs+1 );
if (error) goto Fail;
subglyph = gloader->current.subglyphs + num_subglyphs;
subglyph->arg1 = subglyph->arg2 = 0;
subglyph->flags = GET_UShort();
subglyph->index = GET_UShort();
/* read arguments */
if ( subglyph->flags & ARGS_ARE_WORDS )
{
subglyph->arg1 = GET_Short();
subglyph->arg2 = GET_Short();
}
else
{
subglyph->arg1 = GET_Char();
subglyph->arg2 = GET_Char();
}
/* read transform */
xx = yy = 0x10000L;
xy = yx = 0;
if ( subglyph->flags & WE_HAVE_A_SCALE )
{
xx = (FT_Fixed)GET_Short() << 2;
yy = xx;
}
else if ( subglyph->flags & WE_HAVE_AN_XY_SCALE )
{
xx = (FT_Fixed)GET_Short() << 2;
yy = (FT_Fixed)GET_Short() << 2;
}
else if ( subglyph->flags & WE_HAVE_A_2X2 )
{
xx = (FT_Fixed)GET_Short() << 2;
xy = (FT_Fixed)GET_Short() << 2;
yx = (FT_Fixed)GET_Short() << 2;
yy = (FT_Fixed)GET_Short() << 2;
}
subglyph->transform.xx = xx;
subglyph->transform.xy = xy;
subglyph->transform.yx = yx;
subglyph->transform.yy = yy;
num_subglyphs++;
}
while (subglyph->flags & MORE_COMPONENTS);
gloader->current.num_subglyphs = num_subglyphs;
#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER
{
/* we must undo the ACCESS_Frame in order to point to the */
/* composite instructions, if we find some. */
/* we will process them later... */
/* */
loader->ins_pos = FILE_Pos() + stream->cursor - stream->limit;
}
#endif
FORGET_Frame();
Fail:
return error;
}
@ -611,6 +638,7 @@
FT_Fixed x_scale, y_scale;
FT_ULong ins_offset;
FT_GlyphLoader* gloader = loader->gloader;
FT_Bool opened_frame = 0;
/* check glyph index */
@ -618,7 +646,7 @@
if ( index >= (FT_UInt)face->root.num_glyphs )
{
error = TT_Err_Invalid_Glyph_Index;
goto Fail;
goto Exit;
}
loader->glyph_index = glyph_index;
@ -650,7 +678,6 @@
loader->advance = advance_width;
}
/* load glyph header */
offset = face->glyph_locations[index];
count = 0;
@ -676,30 +703,23 @@
if ( loader->exec )
loader->exec->glyphSize = 0;
#endif
goto Load_End;
error = FT_Err_Ok;
goto Exit;
}
offset = loader->glyf_offset + offset;
/* access glyph frame */
error = TT_Access_Glyph_Frame( loader, glyph_index, offset, count );
if (error) goto Exit;
opened_frame = 1;
/* read first glyph header */
if ( FILE_Seek( offset ) || ACCESS_Frame( 10L ) )
goto Fail;
error = TT_Load_Glyph_Header( loader );
if (error) goto Fail;
contours_count = GET_Short();
loader->bbox.xMin = GET_Short();
loader->bbox.yMin = GET_Short();
loader->bbox.xMax = GET_Short();
loader->bbox.yMax = GET_Short();
FORGET_Frame();
FT_TRACE5(( "Glyph %ld\n", index ));
FT_TRACE5(( " # of contours: %d\n", contours_count ));
FT_TRACE5(( " xMin: %4d xMax: %4d\n", loader->bbox.xMin,
loader->bbox.xMax ));
FT_TRACE5(( " yMin: %4d yMax: %4d\n", loader->bbox.yMin,
loader->bbox.yMax ));
contours_count = loader->n_contours;
count -= 10;
@ -726,7 +746,7 @@
error = FT_GlyphLoader_Check_Points( gloader, 0, contours_count );
if (error) goto Fail;
error = TT_Load_Simple_Glyph( loader, count, contours_count );
error = TT_Load_Simple_Glyph( loader, contours_count );
if (error) goto Fail;
#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER
@ -764,6 +784,9 @@
error = TT_Load_Composite_Glyph( loader, count );
if (error) goto Fail;
TT_Forget_Glyph_Frame( loader );
opened_frame = 0;
/* if the flag FT_LOAD_NO_RECURSE is set, we return the subglyph */
/* `as is' in the glyph slot (the client application will be */
/* responsible for interpreting this data)... */
@ -777,7 +800,7 @@
glyph->format = ft_glyph_format_composite;
glyph->subglyphs = gloader->base.subglyphs;
goto Load_End;
goto Exit;
}
@ -1008,10 +1031,11 @@
/***********************************************************************/
/***********************************************************************/
Load_End:
error = FT_Err_Ok;
Fail:
if (opened_frame)
TT_Forget_Glyph_Frame( loader );
Exit:
return error;
}