summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorsuzuki toshiya <mpsuzuki@hiroshima-u.ac.jp>2023-05-03 01:31:37 +0000
committersuzuki toshiya <mpsuzuki@hiroshima-u.ac.jp>2023-05-03 01:31:37 +0000
commitbe15811c4602a1c2584684eb7ed5242e2bf16a5e (patch)
tree0cfafeedd801e4c66af9ba8a71a54538441c80b4
parent77bbfc5960f47412f8d433948bcb3317e9c93b7c (diff)
downloadfreetype2-be15811c4602a1c2584684eb7ed5242e2bf16a5e.tar.gz
[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.
-rw-r--r--src/cid/cidgload.c161
-rw-r--r--src/cid/cidgload.h8
-rw-r--r--src/cid/cidriver.c18
3 files changed, 128 insertions, 59 deletions
diff --git a/src/cid/cidgload.c b/src/cid/cidgload.c
index f4fe582be..babaf957c 100644
--- a/src/cid/cidgload.c
+++ b/src/cid/cidgload.c
@@ -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,67 +199,14 @@
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 ) )
- 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 );
+ error = cid_compute_fd_and_offsets( face, glyph_index,
+ &fd_select, &off1, &off2 );
+ if ( error )
goto Exit;
- }
glyph_length = off2 - off1;
diff --git a/src/cid/cidgload.h b/src/cid/cidgload.h
index 97954d418..edd622923 100644
--- a/src/cid/cidgload.h
+++ b/src/cid/cidgload.h
@@ -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_ */
diff --git a/src/cid/cidriver.c b/src/cid/cidriver.c
index f7499237d..10cb8c1fd 100644
--- a/src/cid/cidriver.c
+++ b/src/cid/cidriver.c
@@ -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;
}