* src/sfnt.c (sfnt_table_names): Introduce name of post table.
(sfnt_read_post_table): New function.
(main): New tests.
* src/sfnt.h (struct sfnt_post_table): New struct.
* src/sfntfont.c (sfnt_enum_font_1): Read post table, and set
spacing from its is_fixed_pitch value.
(sfntfont_list_1): Compare spacing between both fonts if
supplied in the font spec.
(sfntfont_open): Set FONT_FILE_INDEX as well as
FONT_FULLNAME_INDEX.
[SFNT_TABLE_CVAR] = 0x63766172,
[SFNT_TABLE_AVAR] = 0x61766172,
[SFNT_TABLE_OS_2] = 0x4f532f32,
+ [SFNT_TABLE_POST] = 0x706f7374,
};
/* Swap values from TrueType to system byte order. */
\f
+/* PostScript metadata retrieval.
+
+ TrueType fonts electively incorporate a table of miscellaneous
+ information concerning such matters as the underline position or
+ whether the font is fixed pitch. This table also assigns
+ human-readable names to glyphs, subject to the table format, but
+ these names are not read by the functions defined below. */
+
+/* Read the header of a post table from the given font FD. Refer to
+ the table directory SUBTABLE for its location.
+
+ Return the post table header if successful, NULL otherwise. */
+
+TEST_STATIC struct sfnt_post_table *
+sfnt_read_post_table (int fd, struct sfnt_offset_subtable *subtable)
+{
+ struct sfnt_post_table *post;
+ struct sfnt_table_directory *directory;
+ ssize_t rc;
+
+ /* Search for the post table within SUBTABLE. */
+
+ directory = sfnt_find_table (subtable, SFNT_TABLE_POST);
+
+ if (!directory)
+ return NULL;
+
+ /* Although the size of the table is affected by its format, this
+ function is meant to read only its header; guarantee that the
+ directory is that large. */
+
+ if (directory->length < sizeof *post)
+ return NULL;
+
+ /* Seek to the location given in the directory. */
+ if (lseek (fd, directory->offset, SEEK_SET) == (off_t) -1)
+ return NULL;
+
+ post = xmalloc (sizeof *post);
+ rc = read (fd, post, sizeof *post);
+
+ if (rc == -1 || rc != sizeof *post)
+ {
+ xfree (post);
+ return NULL;
+ }
+
+ /* Byte swap the data retrieved. */
+ sfnt_swap32 (&post->format);
+ sfnt_swap32 (&post->italic_angle);
+ sfnt_swap16 (&post->underline_position);
+ sfnt_swap16 (&post->underline_thickness);
+ sfnt_swap32 (&post->is_fixed_pitch);
+ sfnt_swap32 (&post->min_mem_type_42);
+ sfnt_swap32 (&post->max_mem_type_42);
+ sfnt_swap32 (&post->min_mem_type_1);
+ sfnt_swap32 (&post->max_mem_type_1);
+
+ return post;
+}
+
+\f
+
#ifdef TEST
struct sfnt_test_dcontext
struct sfnt_avar_table *avar;
struct sfnt_cvar_table *cvar;
struct sfnt_OS_2_table *OS_2;
+ struct sfnt_post_table *post;
sfnt_fixed scale;
char *fancy;
int *advances;
gvar = sfnt_read_gvar_table (fd, font);
avar = sfnt_read_avar_table (fd, font);
OS_2 = sfnt_read_OS_2_table (fd, font);
+ post = sfnt_read_post_table (fd, font);
cvar = NULL;
hmtx = NULL;
fprintf (stderr, "OS/2 table found!\nach_vendor_id: %.4s\n",
OS_2->ach_vendor_id);
+ if (post)
+ fprintf (stderr, "post table: format: %g; italic-angle: %g;\n"
+ "underline_position: %"PRIi16"; underline_thickness: %"
+ PRIi16";\n"
+ "is_fixed_pitch: %"PRIu32"\n",
+ sfnt_coerce_fixed (post->format),
+ sfnt_coerce_fixed (post->italic_angle),
+ post->underline_position,
+ post->underline_thickness,
+ post->is_fixed_pitch);
+
if (fvar)
{
fprintf (stderr, "FVAR table found!\n"
xfree (avar);
xfree (cvar);
xfree (OS_2);
+ xfree (post);
return 0;
}
SFNT_TABLE_CVAR,
SFNT_TABLE_AVAR,
SFNT_TABLE_OS_2,
+ SFNT_TABLE_POST,
};
#define SFNT_ENDOF(type, field, type1) \
\f
+/* PostScript metadata. */
+
+struct sfnt_post_table
+{
+ /* Format of this table. This is a fixed point number rather than
+ an integer. */
+ sfnt_fixed format;
+
+ /* Italic angle in degrees. */
+ sfnt_fixed italic_angle;
+
+ /* Underline position. */
+ sfnt_fword underline_position;
+
+ /* Underline thickness. */
+ sfnt_fword underline_thickness;
+
+ /* Whether the font is monospaced. */
+ uint32_t is_fixed_pitch;
+
+ /* Minimum memory usage (on a PostScript printer) when a TrueType
+ font is downloaded as a Type 42 font. */
+ uint32_t min_mem_type_42;
+
+ /* Maximum memory usage (on a PostScript printer) when a TrueType
+ font is downloaded as a Type 42 font. */
+ uint32_t max_mem_type_42;
+
+ /* Minimum memory usage (on a PostScript printer) when a TrueType
+ font is downloaded as a Type 42 font. */
+ uint32_t min_mem_type_1;
+
+ /* Maximum memory usage (on a PostScript printer) when a TrueType
+ font is downloaded as a Type 42 font. */
+ uint32_t max_mem_type_1;
+};
+
+\f
+
#define SFNT_CEIL_FIXED(fixed) (((fixed) + 0177777) & 037777600000)
#define SFNT_FLOOR_FIXED(fixed) ((fixed) & 037777600000)
#undef PROTOTYPE
+\f
+
+#define PROTOTYPE int, struct sfnt_offset_subtable *
+
+extern struct sfnt_post_table *sfnt_read_post_table (PROTOTYPE);
+
+#undef PROTOTYPE
+
#endif /* TEST */
\f
struct sfnt_maxp_table *maxp;
struct sfnt_fvar_table *fvar;
struct sfnt_OS_2_table *OS_2;
+ struct sfnt_post_table *post;
struct sfnt_font_desc temp;
Lisp_Object family, style, instance, style1;
int i;
if (meta)
sfnt_parse_languages (meta, desc);
- /* Figure out the spacing. Some fancy test like what Fontconfig
- does is probably in order but not really necessary. */
- if (!NILP (Fstring_search (Fdowncase (family),
- build_string ("mono"),
- Qnil)))
- desc->spacing = 100; /* FC_MONO */
+ /* Check whether the font claims to be a fixed pitch font and forgo
+ the rudimentary detection below if so. */
+
+ post = sfnt_read_post_table (fd, subtables);
+
+ if (post)
+ {
+ desc->spacing = (post->is_fixed_pitch ? 100 : 0);
+ xfree (post);
+ }
+ else
+ {
+ /* Figure out the spacing. Some fancy test like what Fontconfig
+ does is probably in order but not really necessary. */
+ if (!NILP (Fstring_search (Fdowncase (family),
+ build_string ("mono"),
+ Qnil)))
+ desc->spacing = 100; /* FC_MONO */
+ }
/* Finally add mac-style flags. Allow them to override styles that
have not been found. */
&& !sfntfont_registries_compatible_p (tem, desc->registry))
return 0;
+ /* If the font spacings disagree, reject this font also. */
+
+ tem = AREF (spec, FONT_SPACING_INDEX);
+ if (FIXNUMP (tem) && (XFIXNUM (tem) != desc->spacing))
+ return 0;
+
/* Check the style. If DESC is a fixed font, just check once.
Otherwise, check each instance. */
/* Size of 0 means the font is scalable. */
ASET (entity, FONT_SIZE_INDEX, make_fixnum (0));
ASET (entity, FONT_AVGWIDTH_INDEX, make_fixnum (0));
- ASET (entity, FONT_SPACING_INDEX,
- make_fixnum (desc->spacing));
+ ASET (entity, FONT_SPACING_INDEX, make_fixnum (desc->spacing));
if (instance >= 1)
{
/* Size of 0 means the font is scalable. */
ASET (font_object, FONT_SIZE_INDEX, make_fixnum (0));
ASET (font_object, FONT_AVGWIDTH_INDEX, make_fixnum (0));
- ASET (font_object, FONT_SPACING_INDEX,
- make_fixnum (desc->spacing));
+ ASET (font_object, FONT_SPACING_INDEX, make_fixnum (desc->spacing));
/* Set the font style. */
/* And set a reasonable full name, namely the name of the font
file. */
font->props[FONT_FULLNAME_INDEX]
+ = font->props[FONT_FILE_INDEX]
= DECODE_FILE (build_unibyte_string (desc->path));
/* All done. */