[t1cid] Improve cid_get_cid_from_glyph_index().
Update cid_get_cid_from_glyph_index() to return an error and CID=0 in the case that the specified glyph index points to an invalid entry. cidgload.h (cid_compute_fd_and_offsets): Declare new helper function to set the fd_select and 2 offsets to access the glyph description data. cidgload.c (cid_compute_fd_and_offsets): Move the part loading fd_select and 2 offsets from cid_load_glyph() to here. If the loaded parameters are broken, return the Invalid_Offset error. This function does not load the glyph data, only fills these parameters. (cid_load_glyph): Use new helper function in above. cidriver.c (cid_get_cid_from_glyph_index): Check whether the requested glyph index points to a valid entry, by calling cid_compute_fd_and_offsets(). If it is valid, fill the cid by the glyph index (=CID). If it is invalid, return an error and fill the cid by 0.
This commit is contained in:
parent
77bbfc5960
commit
be15811c46
|
@ -40,6 +40,108 @@
|
|||
#define FT_COMPONENT cidgload
|
||||
|
||||
|
||||
/*
|
||||
* A helper function to compute FD number (fd_select),
|
||||
* the offset to the head of the glyph data (off1),
|
||||
* and the offset to the and of the glyph data (off2).
|
||||
*
|
||||
* The number how many times cid_get_offset() is invoked
|
||||
* can be controlled by the number how many non-NULL
|
||||
* arguments are given. If fd_select is non-NULL but
|
||||
* off1 and off2 are NULL, cid_get_offset() is invoked
|
||||
* only for fd_select, off1/off2 are not validated.
|
||||
*
|
||||
*/
|
||||
FT_LOCAL_DEF( FT_Error )
|
||||
cid_compute_fd_and_offsets( CID_Face face,
|
||||
FT_UInt glyph_index,
|
||||
FT_ULong* fd_select_p,
|
||||
FT_ULong* off1_p,
|
||||
FT_ULong* off2_p )
|
||||
{
|
||||
FT_Error error = FT_Err_Ok;
|
||||
CID_FaceInfo cid = &face->cid;
|
||||
FT_Stream stream = face->cid_stream;
|
||||
FT_UInt entry_len = cid->fd_bytes + cid->gd_bytes;
|
||||
FT_Byte* p;
|
||||
FT_Bool need_frame_exit = 0;
|
||||
FT_ULong fd_select, off1, off2;
|
||||
|
||||
|
||||
/* For ordinary fonts read the CID font dictionary index */
|
||||
/* and charstring offset from the CIDMap. */
|
||||
|
||||
if ( FT_STREAM_SEEK( cid->data_offset + cid->cidmap_offset +
|
||||
glyph_index * entry_len ) ||
|
||||
FT_FRAME_ENTER( 2 * entry_len ) )
|
||||
goto Exit;
|
||||
|
||||
need_frame_exit = 1;
|
||||
|
||||
p = (FT_Byte*)stream->cursor;
|
||||
fd_select = cid_get_offset( &p, cid->fd_bytes );
|
||||
off1 = cid_get_offset( &p, cid->gd_bytes );
|
||||
|
||||
p += cid->fd_bytes;
|
||||
off2 = cid_get_offset( &p, cid->gd_bytes );
|
||||
|
||||
if (fd_select_p)
|
||||
*fd_select_p = fd_select;
|
||||
|
||||
if (off1_p)
|
||||
*off1_p = off1;
|
||||
|
||||
if (off2_p)
|
||||
*off2_p = off2;
|
||||
|
||||
if ( fd_select >= cid->num_dicts )
|
||||
{
|
||||
/*
|
||||
* fd_select == 0xFF is often used to indicate that the CID
|
||||
* has no charstring to be rendered, similar to GID = 0xFFFF
|
||||
* in TrueType fonts.
|
||||
*/
|
||||
if ( (cid->fd_bytes == 1 && fd_select == 0xFFU ) ||
|
||||
(cid->fd_bytes == 2 && fd_select == 0xFFFFU ) )
|
||||
{
|
||||
FT_TRACE1(( "cid_load_glyph: fail for glyph_index=%d, "
|
||||
"FD number %ld is the max integer fitting into %d byte%s\n",
|
||||
glyph_index, fd_select, cid->fd_bytes,
|
||||
cid->fd_bytes == 1 ? "" : "s" ));
|
||||
}
|
||||
else
|
||||
{
|
||||
FT_TRACE0(( "cid_load_glyph: fail for glyph_index=%d, "
|
||||
"FD number %ld > number of dicts %d\n",
|
||||
glyph_index, fd_select, cid->num_dicts ));
|
||||
}
|
||||
error = FT_THROW( Invalid_Offset );
|
||||
goto Exit;
|
||||
}
|
||||
else if ( off2 > stream->size )
|
||||
{
|
||||
FT_TRACE0(( "cid_load_glyph: fail for glyph_index=%d, "
|
||||
"end of the glyph data is beyond the data stream\n",
|
||||
glyph_index ));
|
||||
error = FT_THROW( Invalid_Offset );
|
||||
goto Exit;
|
||||
}
|
||||
else if ( off1 > off2 )
|
||||
{
|
||||
FT_TRACE0(( "cid_load_glyph: fail for glyph_index=%d, "
|
||||
"the end position of glyph data is set before the start position\n",
|
||||
glyph_index ));
|
||||
error = FT_THROW( Invalid_Offset );
|
||||
}
|
||||
|
||||
Exit:
|
||||
if ( need_frame_exit )
|
||||
FT_FRAME_EXIT();
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
FT_CALLBACK_DEF( FT_Error )
|
||||
cid_load_glyph( T1_Decoder decoder,
|
||||
FT_UInt glyph_index )
|
||||
|
@ -97,68 +199,15 @@
|
|||
else
|
||||
|
||||
#endif /* FT_CONFIG_OPTION_INCREMENTAL */
|
||||
|
||||
/* For ordinary fonts read the CID font dictionary index */
|
||||
/* and charstring offset from the CIDMap. */
|
||||
{
|
||||
FT_UInt entry_len = cid->fd_bytes + cid->gd_bytes;
|
||||
FT_ULong off1, off2;
|
||||
|
||||
|
||||
if ( FT_STREAM_SEEK( cid->data_offset + cid->cidmap_offset +
|
||||
glyph_index * entry_len ) ||
|
||||
FT_FRAME_ENTER( 2 * entry_len ) )
|
||||
error = cid_compute_fd_and_offsets( face, glyph_index,
|
||||
&fd_select, &off1, &off2 );
|
||||
if ( error )
|
||||
goto Exit;
|
||||
|
||||
p = (FT_Byte*)stream->cursor;
|
||||
fd_select = cid_get_offset( &p, cid->fd_bytes );
|
||||
off1 = cid_get_offset( &p, cid->gd_bytes );
|
||||
p += cid->fd_bytes;
|
||||
off2 = cid_get_offset( &p, cid->gd_bytes );
|
||||
FT_FRAME_EXIT();
|
||||
|
||||
|
||||
if ( fd_select >= cid->num_dicts )
|
||||
{
|
||||
/*
|
||||
* fd_select == 0xFF is often used to indicate that the CID
|
||||
* has no charstring to be rendered, similar to GID = 0xFFFF
|
||||
* in TrueType fonts.
|
||||
*/
|
||||
if ( (cid->fd_bytes == 1 && fd_select == 0xFFU ) ||
|
||||
(cid->fd_bytes == 2 && fd_select == 0xFFFFU ) )
|
||||
{
|
||||
FT_TRACE1(( "cid_load_glyph: fail for glyph_index=%d, "
|
||||
"FD number %ld is the max integer fitting into %d byte%s\n",
|
||||
glyph_index, fd_select, cid->fd_bytes,
|
||||
cid->fd_bytes == 1 ? "" : "s" ));
|
||||
}
|
||||
else
|
||||
{
|
||||
FT_TRACE0(( "cid_load_glyph: fail for glyph_index=%d, "
|
||||
"FD number %ld > number of dicts %d\n",
|
||||
glyph_index, fd_select, cid->num_dicts ));
|
||||
}
|
||||
error = FT_THROW( Invalid_Offset );
|
||||
goto Exit;
|
||||
}
|
||||
else if ( off2 > stream->size )
|
||||
{
|
||||
FT_TRACE0(( "cid_load_glyph: fail for glyph_index=%d, "
|
||||
"end of the glyph data is beyond the data stream\n",
|
||||
glyph_index ));
|
||||
error = FT_THROW( Invalid_Offset );
|
||||
goto Exit;
|
||||
}
|
||||
else if ( off1 > off2 )
|
||||
{
|
||||
FT_TRACE0(( "cid_load_glyph: fail for glyph_index=%d, "
|
||||
"the end position of glyph data is set before the start position\n",
|
||||
glyph_index ));
|
||||
error = FT_THROW( Invalid_Offset );
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
glyph_length = off2 - off1;
|
||||
|
||||
if ( glyph_length == 0 ||
|
||||
|
|
|
@ -42,6 +42,14 @@ FT_BEGIN_HEADER
|
|||
FT_Int32 load_flags );
|
||||
|
||||
|
||||
FT_LOCAL( FT_Error )
|
||||
cid_compute_fd_and_offsets( CID_Face face,
|
||||
FT_UInt glyph_index,
|
||||
FT_ULong* fd_select_p,
|
||||
FT_ULong* off1_p,
|
||||
FT_ULong* off2_p );
|
||||
|
||||
|
||||
FT_END_HEADER
|
||||
|
||||
#endif /* CIDGLOAD_H_ */
|
||||
|
|
|
@ -150,11 +150,23 @@
|
|||
FT_UInt *cid )
|
||||
{
|
||||
FT_Error error = FT_Err_Ok;
|
||||
FT_UNUSED( face );
|
||||
|
||||
|
||||
if ( cid )
|
||||
*cid = glyph_index; /* identity mapping */
|
||||
/*
|
||||
* Currently, FreeType does not support an incrementally-
|
||||
* defined CID-keyed font that stores the glyph description
|
||||
* data in /GlyphDirectory array or dictionary.
|
||||
* Thus the font loaded by the incremental loading feature
|
||||
* is not handled in here.
|
||||
*/
|
||||
error = cid_compute_fd_and_offsets( face, glyph_index,
|
||||
NULL, NULL, NULL );
|
||||
|
||||
|
||||
if ( error )
|
||||
*cid = 0;
|
||||
else
|
||||
*cid = glyph_index;
|
||||
|
||||
return error;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue