+Check if the given characters are defined by the font. Note that len
+is the number of bytes, not the number of characters (when utf8 is
+non-zero).
+
+out[char index] will be true if the character exists.
+
+Accepts UTF-8, but since T1 can only have 256 characters, any chars
+with values over 255 will simply be returned as false.
+
+Returns the number of characters that were checked.
+
+=cut
+*/
+
+int
+i_t1_has_chars(int font_num, const char *text, size_t len, int utf8,
+ char *out) {
+ int count = 0;
+
+ mm_log((1, "i_t1_has_chars(font_num %d, text %p, len %d, utf8 %d)\n",
+ font_num, text, len, utf8));
+
+ i_clear_error();
+ if (T1_LoadFont(font_num)) {
+ t1_push_error();
+ return 0;
+ }
+
+ while (len) {
+ unsigned long c;
+ if (utf8) {
+ c = i_utf8_advance(&text, &len);
+ if (c == ~0UL) {
+ i_push_error(0, "invalid UTF8 character");
+ return 0;
+ }
+ }
+ else {
+ c = (unsigned char)*text++;
+ --len;
+ }
+
+ if (c >= 0x100) {
+ /* limit of 256 characters for T1 */
+ *out++ = 0;
+ }
+ else {
+ char const * name = T1_GetCharName(font_num, (unsigned char)c);
+
+ if (name) {
+ *out++ = strcmp(name, ".notdef") != 0;
+ }
+ else {
+ mm_log((2, " No name found for character %lx\n", c));
+ *out++ = 0;
+ }
+ }
+ ++count;
+ }
+
+ return count;
+}
+
+/*
+=item i_t1_face_name(font_num, name_buf, name_buf_size)
+
+Copies the face name of the given C<font_num> to C<name_buf>. Returns
+the number of characters required to store the name (which can be
+larger than C<name_buf_size>, including the space required to store
+the terminating NUL).
+
+If name_buf is too small (as specified by name_buf_size) then the name
+will be truncated. name_buf will always be NUL termintaed.
+
+=cut
+*/
+
+int
+i_t1_face_name(int font_num, char *name_buf, size_t name_buf_size) {
+ char *name;
+
+ T1_errno = 0;
+ if (T1_LoadFont(font_num)) {
+ t1_push_error();
+ return 0;
+ }
+ name = T1_GetFontName(font_num);
+
+ if (name) {
+ strncpy(name_buf, name, name_buf_size);
+ name_buf[name_buf_size-1] = '\0';
+ return strlen(name) + 1;
+ }
+ else {
+ t1_push_error();
+ return 0;
+ }
+}
+
+int
+i_t1_glyph_name(int font_num, unsigned long ch, char *name_buf,
+ size_t name_buf_size) {
+ char *name;
+
+ i_clear_error();
+ if (ch > 0xFF) {
+ return 0;
+ }
+ if (T1_LoadFont(font_num)) {
+ t1_push_error();
+ return 0;
+ }
+ name = T1_GetCharName(font_num, (unsigned char)ch);
+ if (name) {
+ if (strcmp(name, ".notdef")) {
+ strncpy(name_buf, name, name_buf_size);
+ name_buf[name_buf_size-1] = '\0';
+ return strlen(name) + 1;
+ }
+ else {
+ return 0;
+ }
+ }
+ else {
+ t1_push_error();
+ return 0;
+ }
+}
+
+static void
+t1_push_error(void) {
+ switch (T1_errno) {
+ case 0:
+ i_push_error(0, "No error");
+ break;
+
+#ifdef T1ERR_SCAN_FONT_FORMAT
+ case T1ERR_SCAN_FONT_FORMAT:
+ i_push_error(T1ERR_SCAN_FONT_FORMAT, "SCAN_FONT_FORMAT");
+ break;
+#endif
+
+#ifdef T1ERR_SCAN_FILE_OPEN_ERR
+ case T1ERR_SCAN_FILE_OPEN_ERR:
+ i_push_error(T1ERR_SCAN_FILE_OPEN_ERR, "SCAN_FILE_OPEN_ERR");
+ break;
+#endif
+
+#ifdef T1ERR_SCAN_OUT_OF_MEMORY
+ case T1ERR_SCAN_OUT_OF_MEMORY:
+ i_push_error(T1ERR_SCAN_OUT_OF_MEMORY, "SCAN_OUT_OF_MEMORY");
+ break;
+#endif
+
+#ifdef T1ERR_SCAN_ERROR
+ case T1ERR_SCAN_ERROR:
+ i_push_error(T1ERR_SCAN_ERROR, "SCAN_ERROR");
+ break;
+#endif
+
+#ifdef T1ERR_SCAN_FILE_EOF
+ case T1ERR_SCAN_FILE_EOF:
+ i_push_error(T1ERR_SCAN_FILE_EOF, "SCAN_FILE_EOF");
+ break;
+#endif
+
+#ifdef T1ERR_PATH_ERROR
+ case T1ERR_PATH_ERROR:
+ i_push_error(T1ERR_PATH_ERROR, "PATH_ERROR");
+ break;
+#endif
+
+#ifdef T1ERR_PARSE_ERROR
+ case T1ERR_PARSE_ERROR:
+ i_push_error(T1ERR_PARSE_ERROR, "PARSE_ERROR");
+ break;
+#endif
+
+#ifdef T1ERR_TYPE1_ABORT
+ case T1ERR_TYPE1_ABORT:
+ i_push_error(T1ERR_TYPE1_ABORT, "TYPE1_ABORT");
+ break;
+#endif
+
+#ifdef T1ERR_INVALID_FONTID
+ case T1ERR_INVALID_FONTID:
+ i_push_error(T1ERR_INVALID_FONTID, "INVALID_FONTID");
+ break;
+#endif
+
+#ifdef T1ERR_INVALID_PARAMETER
+ case T1ERR_INVALID_PARAMETER:
+ i_push_error(T1ERR_INVALID_PARAMETER, "INVALID_PARAMETER");
+ break;
+#endif
+
+#ifdef T1ERR_OP_NOT_PERMITTED
+ case T1ERR_OP_NOT_PERMITTED:
+ i_push_error(T1ERR_OP_NOT_PERMITTED, "OP_NOT_PERMITTED");
+ break;
+#endif
+
+#ifdef T1ERR_ALLOC_MEM
+ case T1ERR_ALLOC_MEM:
+ i_push_error(T1ERR_ALLOC_MEM, "ALLOC_MEM");
+ break;
+#endif
+
+#ifdef T1ERR_FILE_OPEN_ERR
+ case T1ERR_FILE_OPEN_ERR:
+ i_push_error(T1ERR_FILE_OPEN_ERR, "FILE_OPEN_ERR");
+ break;
+#endif
+
+#ifdef T1ERR_UNSPECIFIED
+ case T1ERR_UNSPECIFIED:
+ i_push_error(T1ERR_UNSPECIFIED, "UNSPECIFIED");
+ break;
+#endif
+
+#ifdef T1ERR_NO_AFM_DATA
+ case T1ERR_NO_AFM_DATA:
+ i_push_error(T1ERR_NO_AFM_DATA, "NO_AFM_DATA");
+ break;
+#endif
+
+#ifdef T1ERR_X11
+ case T1ERR_X11:
+ i_push_error(T1ERR_X11, "X11");
+ break;
+#endif
+
+#ifdef T1ERR_COMPOSITE_CHAR
+ case T1ERR_COMPOSITE_CHAR:
+ i_push_error(T1ERR_COMPOSITE_CHAR, "COMPOSITE_CHAR");
+ break;
+#endif
+
+ default:
+ i_push_errorf(T1_errno, "unknown error %d", (int)T1_errno);
+ }
+}
+
+#endif /* HAVE_LIBT1 */