Guesstimate Windows font metrics for Type 1 fonts
Ian Pilcher
ian.pilcher at home.com
Sat May 12 00:38:50 CDT 2001
I still can't figure out how the Windows PostScript driver calculates
line spacings for built-in fonts; they don't seem to be based on any
metrics that are in AFM files. (I'm beginning to believe that they're
simply hardcoded into the driver.) This sets it to 115% of the em
square, which at least matches up for a couple of fonts.
Modified files:
dlls/wineps: afm.c psdrv.h
Log message:
Ian Pilcher
Guesstimate Windows font metrics for Type 1 fonts
--
========================================================================
Ian Pilcher ian.pilcher at home.com
========================================================================
-------------- next part --------------
diff -urN ../wine-20010511cvs/dlls/wineps/afm.c ./dlls/wineps/afm.c
--- ../wine-20010511cvs/dlls/wineps/afm.c Fri May 11 14:54:24 2001
+++ ./dlls/wineps/afm.c Fri May 11 23:00:09 2001
@@ -29,6 +29,38 @@
typedef int (*compar_callback_fn) (const void *, const void *);
/*******************************************************************************
+ * IsWinANSI
+ *
+ * Checks whether Unicode value is part of Microsoft code page 1252
+ *
+ */
+static const INT ansiChars[21] =
+{
+ 0x0152, 0x0153, 0x0160, 0x0161, 0x0178, 0x017d, 0x017e, 0x0192, 0x02c6,
+ 0x02c9, 0x02dc, 0x03bc, 0x2013, 0x2014, 0x2026, 0x2030, 0x2039, 0x203a,
+ 0x20ac, 0x2122, 0x2219
+};
+
+static int cmpUV(const INT *a, const INT *b)
+{
+ return *a - *b;
+}
+
+inline static BOOL IsWinANSI(INT uv)
+{
+ if ((0x0020 <= uv && uv <= 0x007e) || (0x00a0 <= uv && uv <= 0x00ff) ||
+ (0x2018 <= uv && uv <= 0x201a) || (0x201c <= uv && uv <= 0x201e) ||
+ (0x2020 <= uv && uv <= 2022))
+ return TRUE;
+
+ if (bsearch(&uv, ansiChars, 21, sizeof(INT),
+ (compar_callback_fn)cmpUV) != NULL)
+ return TRUE;
+
+ return FALSE;
+}
+
+/*******************************************************************************
* CheckMetrics
*
* Check an AFMMETRICS structure to make sure all elements have been properly
@@ -751,6 +783,98 @@
return TRUE;
}
+/*******************************************************************************
+ * CalcWindowsMetrics
+ *
+ * Calculates several Windows-specific font metrics for each font. Relies on
+ * the fact that AFMs are allocated with HEAP_ZERO_MEMORY to distinguish
+ * TrueType fonts (when implemented), which already have these filled in.
+ *
+ */
+static VOID CalcWindowsMetrics()
+{
+ FONTFAMILY *family = PSDRV_AFMFontList;
+
+ while (family != NULL)
+ {
+ AFMLISTENTRY *afmle = family->afmlist;
+
+ while (afmle != NULL)
+ {
+ WINMETRICS wm;
+ AFM *afm = afmle->afm; /* should always be valid */
+ INT i;
+
+ if (afm->WinMetrics.usUnitsPerEm != 0)
+ continue; /* TrueType font */
+
+ wm.usUnitsPerEm = 1000; /* for PostScript fonts */
+ wm.sTypoAscender = (SHORT)(afm->Ascender + 0.5);
+ wm.sTypoDescender = (SHORT)(afm->Descender + 0.5);
+
+ wm.sTypoLineGap = 1200 - (wm.sTypoAscender - wm.sTypoDescender);
+ if (wm.sTypoLineGap < 0)
+ wm.sTypoLineGap = 0;
+
+ wm.usWinAscent = 0;
+ wm.usWinDescent = 0;
+
+ for (i = 0; i < afm->NumofMetrics; ++i)
+ {
+ if (IsWinANSI(afm->Metrics[i].UV) == FALSE)
+ continue;
+
+ if (afm->Metrics[i].B.ury > 0)
+ {
+ USHORT ascent = (USHORT)(afm->Metrics[i].B.ury + 0.5);
+
+ if (ascent > wm.usWinAscent)
+ wm.usWinAscent = ascent;
+ }
+
+ if (afm->Metrics[i].B.lly < 0)
+ {
+ USHORT descent = (USHORT)(-(afm->Metrics[i].B.lly) + 0.5);
+
+ if (descent > wm.usWinDescent)
+ wm.usWinDescent = descent;
+ }
+ }
+
+ if (wm.usWinAscent == 0 && afm->FontBBox.ury > 0)
+ wm.usWinAscent = (USHORT)(afm->FontBBox.ury + 0.5);
+
+ if (wm.usWinDescent == 0 && afm->FontBBox.lly < 0)
+ wm.usWinDescent = (USHORT)(-(afm->FontBBox.lly) + 0.5);
+
+ wm.sAscender = wm.usWinAscent;
+ wm.sDescender = -(wm.usWinDescent);
+
+ wm.sLineGap = 1150 - (wm.sAscender - wm.sDescender);
+ if (wm.sLineGap < 0)
+ wm.sLineGap = 0;
+
+ TRACE("Windows metrics for '%s':\n", afm->FullName);
+ TRACE("\tsAscender = %i\n", wm.sAscender);
+ TRACE("\tsDescender = %i\n", wm.sDescender);
+ TRACE("\tsLineGap = %i\n", wm.sLineGap);
+ TRACE("\tusUnitsPerEm = %u\n", wm.usUnitsPerEm);
+ TRACE("\tsTypoAscender = %i\n", wm.sTypoAscender);
+ TRACE("\tsTypoDescender = %i\n", wm.sTypoDescender);
+ TRACE("\tsTypoLineGap = %i\n", wm.sTypoLineGap);
+ TRACE("\tusWinAscent = %u\n", wm.usWinAscent);
+ TRACE("\tusWinDescent = %u\n", wm.usWinDescent);
+
+ afm->WinMetrics = wm;
+
+ afmle = afmle->next;
+ }
+
+ family = family ->next;
+ }
+}
+
+
/***********************************************************
*
* PSDRV_GetFontMetrics
@@ -845,6 +969,7 @@
PSDRV_IndexGlyphList();
if (SortFontMetrics() == FALSE)
return FALSE;
+ CalcWindowsMetrics();
PSDRV_DumpFontList();
return TRUE;
}
diff -urN ../wine-20010511cvs/dlls/wineps/psdrv.h ./dlls/wineps/psdrv.h
--- ../wine-20010511cvs/dlls/wineps/psdrv.h Wed May 9 12:11:59 2001
+++ ./dlls/wineps/psdrv.h Fri May 11 22:58:08 2001
@@ -53,12 +53,15 @@
} AFMMETRICS;
typedef struct {
- USHORT usUnitsPerEm; /* 1000 for Type 1 fonts */
- SHORT sTypoAscender; /* AFM Ascender */
- SHORT sTypoDescender; /* AFM Descender */
- SHORT sTypoLineGap; /* guess for Type 1 fonts */
- USHORT usWinAscent;
- USHORT usWinDescent;
+ USHORT usUnitsPerEm; /* head:unitsPerEm */
+ SHORT sAscender; /* hhea:Ascender */
+ SHORT sDescender; /* hhea:Descender */
+ SHORT sLineGap; /* hhea:LineGap */
+ SHORT sTypoAscender; /* OS/2:sTypoAscender */
+ SHORT sTypoDescender; /* OS/2:sTypoDescender */
+ SHORT sTypoLineGap; /* OS/2:sTypeLineGap */
+ USHORT usWinAscent; /* OS/2:usWinAscent */
+ USHORT usWinDescent; /* OS/2:usWinDescent */
} WINMETRICS;
typedef struct _tagAFM {
More information about the wine-patches
mailing list