... |
... |
@@ -40,6 +40,108 @@ |
40
|
40
|
#define FT_COMPONENT cidgload
|
41
|
41
|
|
42
|
42
|
|
|
43
|
+ /*
|
|
44
|
+ * A helper function to compute FD number (fd_select),
|
|
45
|
+ * the offset to the head of the glyph data (off1),
|
|
46
|
+ * and the offset to the and of the glyph data (off2).
|
|
47
|
+ *
|
|
48
|
+ * The number how many times cid_get_offset() is invoked
|
|
49
|
+ * can be controlled by the number how many non-NULL
|
|
50
|
+ * arguments are given. If fd_select is non-NULL but
|
|
51
|
+ * off1 and off2 are NULL, cid_get_offset() is invoked
|
|
52
|
+ * only for fd_select, off1/off2 are not validated.
|
|
53
|
+ *
|
|
54
|
+ */
|
|
55
|
+ FT_LOCAL_DEF( FT_Error )
|
|
56
|
+ cid_compute_fd_and_offsets( CID_Face face,
|
|
57
|
+ FT_UInt glyph_index,
|
|
58
|
+ FT_ULong* fd_select_p,
|
|
59
|
+ FT_ULong* off1_p,
|
|
60
|
+ FT_ULong* off2_p )
|
|
61
|
+ {
|
|
62
|
+ FT_Error error = FT_Err_Ok;
|
|
63
|
+ CID_FaceInfo cid = &face->cid;
|
|
64
|
+ FT_Stream stream = face->cid_stream;
|
|
65
|
+ FT_UInt entry_len = cid->fd_bytes + cid->gd_bytes;
|
|
66
|
+ FT_Byte* p;
|
|
67
|
+ FT_Bool need_frame_exit = 0;
|
|
68
|
+ FT_ULong fd_select, off1, off2;
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+ /* For ordinary fonts read the CID font dictionary index */
|
|
72
|
+ /* and charstring offset from the CIDMap. */
|
|
73
|
+
|
|
74
|
+ if ( FT_STREAM_SEEK( cid->data_offset + cid->cidmap_offset +
|
|
75
|
+ glyph_index * entry_len ) ||
|
|
76
|
+ FT_FRAME_ENTER( 2 * entry_len ) )
|
|
77
|
+ goto Exit;
|
|
78
|
+
|
|
79
|
+ need_frame_exit = 1;
|
|
80
|
+
|
|
81
|
+ p = (FT_Byte*)stream->cursor;
|
|
82
|
+ fd_select = cid_get_offset( &p, cid->fd_bytes );
|
|
83
|
+ off1 = cid_get_offset( &p, cid->gd_bytes );
|
|
84
|
+
|
|
85
|
+ p += cid->fd_bytes;
|
|
86
|
+ off2 = cid_get_offset( &p, cid->gd_bytes );
|
|
87
|
+
|
|
88
|
+ if (fd_select_p)
|
|
89
|
+ *fd_select_p = fd_select;
|
|
90
|
+
|
|
91
|
+ if (off1_p)
|
|
92
|
+ *off1_p = off1;
|
|
93
|
+
|
|
94
|
+ if (off2_p)
|
|
95
|
+ *off2_p = off2;
|
|
96
|
+
|
|
97
|
+ if ( fd_select >= cid->num_dicts )
|
|
98
|
+ {
|
|
99
|
+ /*
|
|
100
|
+ * fd_select == 0xFF is often used to indicate that the CID
|
|
101
|
+ * has no charstring to be rendered, similar to GID = 0xFFFF
|
|
102
|
+ * in TrueType fonts.
|
|
103
|
+ */
|
|
104
|
+ if ( (cid->fd_bytes == 1 && fd_select == 0xFFU ) ||
|
|
105
|
+ (cid->fd_bytes == 2 && fd_select == 0xFFFFU ) )
|
|
106
|
+ {
|
|
107
|
+ FT_TRACE1(( "cid_load_glyph: fail for glyph_index=%d, "
|
|
108
|
+ "FD number %ld is the max integer fitting into %d byte%s\n",
|
|
109
|
+ glyph_index, fd_select, cid->fd_bytes,
|
|
110
|
+ cid->fd_bytes == 1 ? "" : "s" ));
|
|
111
|
+ }
|
|
112
|
+ else
|
|
113
|
+ {
|
|
114
|
+ FT_TRACE0(( "cid_load_glyph: fail for glyph_index=%d, "
|
|
115
|
+ "FD number %ld > number of dicts %d\n",
|
|
116
|
+ glyph_index, fd_select, cid->num_dicts ));
|
|
117
|
+ }
|
|
118
|
+ error = FT_THROW( Invalid_Offset );
|
|
119
|
+ goto Exit;
|
|
120
|
+ }
|
|
121
|
+ else if ( off2 > stream->size )
|
|
122
|
+ {
|
|
123
|
+ FT_TRACE0(( "cid_load_glyph: fail for glyph_index=%d, "
|
|
124
|
+ "end of the glyph data is beyond the data stream\n",
|
|
125
|
+ glyph_index ));
|
|
126
|
+ error = FT_THROW( Invalid_Offset );
|
|
127
|
+ goto Exit;
|
|
128
|
+ }
|
|
129
|
+ else if ( off1 > off2 )
|
|
130
|
+ {
|
|
131
|
+ FT_TRACE0(( "cid_load_glyph: fail for glyph_index=%d, "
|
|
132
|
+ "the end position of glyph data is set before the start position\n",
|
|
133
|
+ glyph_index ));
|
|
134
|
+ error = FT_THROW( Invalid_Offset );
|
|
135
|
+ }
|
|
136
|
+
|
|
137
|
+ Exit:
|
|
138
|
+ if ( need_frame_exit )
|
|
139
|
+ FT_FRAME_EXIT();
|
|
140
|
+
|
|
141
|
+ return error;
|
|
142
|
+ }
|
|
143
|
+
|
|
144
|
+
|
43
|
145
|
FT_CALLBACK_DEF( FT_Error )
|
44
|
146
|
cid_load_glyph( T1_Decoder decoder,
|
45
|
147
|
FT_UInt glyph_index )
|
... |
... |
@@ -97,67 +199,14 @@ |
97
|
199
|
else
|
98
|
200
|
|
99
|
201
|
#endif /* FT_CONFIG_OPTION_INCREMENTAL */
|
100
|
|
-
|
101
|
|
- /* For ordinary fonts read the CID font dictionary index */
|
102
|
|
- /* and charstring offset from the CIDMap. */
|
103
|
202
|
{
|
104
|
|
- FT_UInt entry_len = cid->fd_bytes + cid->gd_bytes;
|
105
|
203
|
FT_ULong off1, off2;
|
106
|
204
|
|
107
|
205
|
|
108
|
|
- if ( FT_STREAM_SEEK( cid->data_offset + cid->cidmap_offset +
|
109
|
|
- glyph_index * entry_len ) ||
|
110
|
|
- FT_FRAME_ENTER( 2 * entry_len ) )
|
111
|
|
- goto Exit;
|
112
|
|
-
|
113
|
|
- p = (FT_Byte*)stream->cursor;
|
114
|
|
- fd_select = cid_get_offset( &p, cid->fd_bytes );
|
115
|
|
- off1 = cid_get_offset( &p, cid->gd_bytes );
|
116
|
|
- p += cid->fd_bytes;
|
117
|
|
- off2 = cid_get_offset( &p, cid->gd_bytes );
|
118
|
|
- FT_FRAME_EXIT();
|
119
|
|
-
|
120
|
|
-
|
121
|
|
- if ( fd_select >= cid->num_dicts )
|
122
|
|
- {
|
123
|
|
- /*
|
124
|
|
- * fd_select == 0xFF is often used to indicate that the CID
|
125
|
|
- * has no charstring to be rendered, similar to GID = 0xFFFF
|
126
|
|
- * in TrueType fonts.
|
127
|
|
- */
|
128
|
|
- if ( (cid->fd_bytes == 1 && fd_select == 0xFFU ) ||
|
129
|
|
- (cid->fd_bytes == 2 && fd_select == 0xFFFFU ) )
|
130
|
|
- {
|
131
|
|
- FT_TRACE1(( "cid_load_glyph: fail for glyph_index=%d, "
|
132
|
|
- "FD number %ld is the max integer fitting into %d byte%s\n",
|
133
|
|
- glyph_index, fd_select, cid->fd_bytes,
|
134
|
|
- cid->fd_bytes == 1 ? "" : "s" ));
|
135
|
|
- }
|
136
|
|
- else
|
137
|
|
- {
|
138
|
|
- FT_TRACE0(( "cid_load_glyph: fail for glyph_index=%d, "
|
139
|
|
- "FD number %ld > number of dicts %d\n",
|
140
|
|
- glyph_index, fd_select, cid->num_dicts ));
|
141
|
|
- }
|
142
|
|
- error = FT_THROW( Invalid_Offset );
|
143
|
|
- goto Exit;
|
144
|
|
- }
|
145
|
|
- else if ( off2 > stream->size )
|
146
|
|
- {
|
147
|
|
- FT_TRACE0(( "cid_load_glyph: fail for glyph_index=%d, "
|
148
|
|
- "end of the glyph data is beyond the data stream\n",
|
149
|
|
- glyph_index ));
|
150
|
|
- error = FT_THROW( Invalid_Offset );
|
151
|
|
- goto Exit;
|
152
|
|
- }
|
153
|
|
- else if ( off1 > off2 )
|
154
|
|
- {
|
155
|
|
- FT_TRACE0(( "cid_load_glyph: fail for glyph_index=%d, "
|
156
|
|
- "the end position of glyph data is set before the start position\n",
|
157
|
|
- glyph_index ));
|
158
|
|
- error = FT_THROW( Invalid_Offset );
|
|
206
|
+ error = cid_compute_fd_and_offsets( face, glyph_index,
|
|
207
|
+ &fd_select, &off1, &off2 );
|
|
208
|
+ if ( error )
|
159
|
209
|
goto Exit;
|
160
|
|
- }
|
161
|
210
|
|
162
|
211
|
glyph_length = off2 - off1;
|
163
|
212
|
|