summaryrefslogtreecommitdiff
path: root/in_sfnt.c
diff options
context:
space:
mode:
authorBen Harris <bjh21@bjh21.me.uk>2007-02-07 00:00:06 +0000
committerBen Harris <bjh21@bjh21.me.uk>2007-02-07 00:00:06 +0000
commit250b87ad784e8b04e22cc746f67ee192011d5e1c (patch)
treebc6ba59a23cb6284d6333294f2dc40fe490ee6ed /in_sfnt.c
parentb5a4f7b65579a789743e5c039c7286cc9d8e24a1 (diff)
downloadhalibut-250b87ad784e8b04e22cc746f67ee192011d5e1c.zip
halibut-250b87ad784e8b04e22cc746f67ee192011d5e1c.tar.gz
halibut-250b87ad784e8b04e22cc746f67ee192011d5e1c.tar.bz2
halibut-250b87ad784e8b04e22cc746f67ee192011d5e1c.tar.xz
Add support for extracting some global font metrics from the 'OS/2' table
of fonts that have one. This should help with generating the FontDescriptor object in PDF. [originally from svn r7246]
Diffstat (limited to 'in_sfnt.c')
-rw-r--r--in_sfnt.c75
1 files changed, 74 insertions, 1 deletions
diff --git a/in_sfnt.c b/in_sfnt.c
index 346602b..fe16941 100644
--- a/in_sfnt.c
+++ b/in_sfnt.c
@@ -121,6 +121,7 @@ sfnt_decode offsubdir_decode[] = {
};
#define sfnt_00010000 0x00010000
+#define TAG_OS_2 0x4f532f32
#define TAG_cmap 0x636d6170
#define TAG_glyf 0x676c7966
#define TAG_head 0x68656164
@@ -147,6 +148,55 @@ sfnt_decode tabledir_decode[] = {
{ d_end }
};
+/* OS/2 and Windows compatibility table */
+typedef struct t_OS_2_Tag t_OS_2;
+struct t_OS_2_Tag {
+ unsigned version;
+ int sTypoAscender, sTypoDescender;
+ int sxHeight, sCapHeight;
+};
+sfnt_decode t_OS_2_v0_decode[] = {
+ { d_uint16, offsetof(t_OS_2, version) },
+ { d_skip(66) }, /* xAvgCharWidth, usWeightClass, usWidthClass, fsType, */
+ /* ySubscriptXSize, ySubscriptYSize, ySubscriptXOffset, */
+ /* ySubscriptYOffset, ySuperscriptXSize, ySuperscriptYSize, */
+ /* ySuperscriptXOffset, ySupercriptYOffset, sFamilyClass, panose, */
+ /* ulUnicodeRange1, ulUnicodeRange2, ulUnicodeRange3, ulUnicodeRange4, */
+ /* achVendID, fsSelection, usFirstCharIndex, usLastCharIndex */
+ { d_end }
+};
+sfnt_decode t_OS_2_v1_decode[] = {
+ { d_uint16, offsetof(t_OS_2, version) },
+ { d_skip(66) }, /* xAvgCharWidth, usWeightClass, usWidthClass, fsType, */
+ /* ySubscriptXSize, ySubscriptYSize, ySubscriptXOffset, */
+ /* ySubscriptYOffset, ySuperscriptXSize, ySuperscriptYSize, */
+ /* ySuperscriptXOffset, ySupercriptYOffset, sFamilyClass, panose, */
+ /* ulUnicodeRange1, ulUnicodeRange2, ulUnicodeRange3, ulUnicodeRange4, */
+ /* achVendID, fsSelection, usFirstCharIndex, usLastCharIndex */
+ { d_int16, offsetof(t_OS_2, sTypoAscender) },
+ { d_int16, offsetof(t_OS_2, sTypoDescender) },
+ { d_skip(14) }, /* sTypoLineGap, usWinAscent, usWinDescent, */
+ /* ulCodePageRange1, ulCodePageRange2 */
+ { d_end }
+};
+sfnt_decode t_OS_2_v2_decode[] = {
+ { d_uint16, offsetof(t_OS_2, version) },
+ { d_skip(66) }, /* xAvgCharWidth, usWeightClass, usWidthClass, fsType, */
+ /* ySubscriptXSize, ySubscriptYSize, ySubscriptXOffset, */
+ /* ySubscriptYOffset, ySuperscriptXSize, ySuperscriptYSize, */
+ /* ySuperscriptXOffset, ySupercriptYOffset, sFamilyClass, panose, */
+ /* ulUnicodeRange1, ulUnicodeRange2, ulUnicodeRange3, ulUnicodeRange4, */
+ /* achVendID, fsSelection, usFirstCharIndex, usLastCharIndex */
+ { d_int16, offsetof(t_OS_2, sTypoAscender) },
+ { d_int16, offsetof(t_OS_2, sTypoDescender) },
+ { d_skip(14) }, /* sTypoLineGap, usWinAscent, usWinDescent, */
+ /* ulCodePageRange1, ulCodePageRange2 */
+ { d_int16, offsetof(t_OS_2, sxHeight) },
+ { d_int16, offsetof(t_OS_2, sCapHeight) },
+ { d_skip(6) }, /* usDefaultChar, usBreakChar, usMaxContext */
+ { d_end }
+};
+
/* Character to Glyph ('cmap') table */
typedef struct t_cmap_Tag t_cmap;
struct t_cmap_Tag {
@@ -459,15 +509,21 @@ static unsigned short sfnt_glyphtoindex(sfnt *sf, glyph g) {
}
/*
- * Get data from 'hhea' and 'hmtx' tables
+ * Get data from 'hhea', 'hmtx', and 'OS/2' tables
*/
void sfnt_getmetrics(font_info *fi) {
sfnt *sf = fi->fontfile;
t_hhea hhea;
+ t_OS_2 OS_2;
void *ptr, *end;
unsigned i, j;
unsigned *hmtx;
+ /* First, the bounding box from the 'head' table. */
+ fi->fontbbox[0] = sf->head.xMin * FUNITS_PER_PT / sf->head.unitsPerEm;
+ fi->fontbbox[1] = sf->head.yMin * FUNITS_PER_PT / sf->head.unitsPerEm;
+ fi->fontbbox[2] = sf->head.xMax * FUNITS_PER_PT / sf->head.unitsPerEm;
+ fi->fontbbox[3] = sf->head.yMax * FUNITS_PER_PT / sf->head.unitsPerEm;
if (!sfnt_findtable(sf, TAG_hhea, &ptr, &end))
abort();
if (decode(t_hhea_decode, ptr, end, &hhea) == NULL)
@@ -491,6 +547,23 @@ void sfnt_getmetrics(font_info *fi) {
w->width = hmtx[j] * UNITS_PER_PT / sf->head.unitsPerEm;
add234(fi->widths, w);
}
+ /* Now see if the 'OS/2' table has any useful metrics */
+ if (!sfnt_findtable(sf, TAG_OS_2, &ptr, &end))
+ return;
+ if (decode(uint16_decode, ptr, end, &OS_2.version) == NULL)
+ return;
+ if (OS_2.version >= 2) {
+ if (decode(t_OS_2_v2_decode, ptr, end, &OS_2) == NULL)
+ return;
+ fi->xheight = OS_2.sxHeight * FUNITS_PER_PT / sf->head.unitsPerEm;
+ fi->capheight = OS_2.sCapHeight * FUNITS_PER_PT / sf->head.unitsPerEm;
+ } else if (OS_2.version == 1) {
+ if (decode(t_OS_2_v1_decode, ptr, end, &OS_2) == NULL)
+ return;
+ } else
+ return;
+ fi->ascent = OS_2.sTypoAscender * FUNITS_PER_PT / sf->head.unitsPerEm;
+ fi->descent = OS_2.sTypoDescender * FUNITS_PER_PT / sf->head.unitsPerEm;
}
/*