[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.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234
diff --git a/src/cid/cidgload.c b/src/cid/cidgload.c
index f4fe582..babaf95 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 97954d4..edd6229 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 f749923..10cb8c1 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;
}