The attached patch makes a fundamental change to the way the PostScript
driver deals with character encodings -- it ignores them. Instead, the
driver now operates directly on 16-bit Unicode characters.
This should be a more robust strategy for handling non-Latin, and
especially multi-byte, character sets. I really have no idea, however,
how the rest of Wine handles non-Latin characters. As an English
speaker, I'm not well equipped to test it.
So please give me your feedback. I particularly want to know if it
breaks anything before I submit it.
Thanks!
--
========================================================================
Ian Pilcher ian.pilcher@home.com
========================================================================
diff -urN ../wine-20010714cvs/dlls/wineps/font.c ./dlls/wineps/font.c
--- ../wine-20010714cvs/dlls/wineps/font.c Sun Jul 15 16:07:36 2001
+++ ./dlls/wineps/font.c Sun Jul 15 16:27:27 2001
@@ -5,6 +5,7 @@
*
*/
#include <string.h>
+#include <stdlib.h> /* for bsearch() */
#include "winspool.h"
#include "psdrv.h"
#include "debugtools.h"
@@ -294,6 +295,7 @@
return TRUE;
}
+#if 0
/***********************************************************************
* PSDRV_UnicodeToANSI
*/
@@ -321,9 +323,52 @@
return 0xff;
}
}
+#endif
+
+/******************************************************************************
+ * PSDRV_UVMetrics
+ *
+ * Find the AFMMETRICS for a given UV. Returns first glyph in the font
+ * (space?) if the font does not have a glyph for the given UV.
+ */
+static int MetricsByUV(const void *a, const void *b)
+{
+ return (int)(((const AFMMETRICS *)a)->UV - ((const AFMMETRICS *)b)->UV);
+}
+
+const AFMMETRICS *PSDRV_UVMetrics(LONG UV, const PSDRV_PDEVICE *physDev)
+{
+ AFMMETRICS key;
+ const AFMMETRICS *needle;
+
+ /*
+ * Ugly work-around for symbol fonts. Wine is sending characters which
+ * belong in the Unicode private use range (U+F020 - U+F0FF) as ASCII
+ * characters (U+0020 - U+00FF).
+ */
+
+ if ((physDev->font.afm->Metrics->UV & 0xff00) == 0xf000 && UV < 0x100)
+ UV |= 0xf000;
+
+ key.UV = UV;
+
+ needle = bsearch(&key, physDev->font.afm->Metrics,
+ physDev->font.afm->NumofMetrics, sizeof(AFMMETRICS),
+ MetricsByUV);
+
+ if (needle == NULL)
+ {
+ WARN("No glyph for U+%.4lX in %s\n", UV, physDev->font.afm->FontName);
+ needle = physDev->font.afm->Metrics;
+ }
+
+ return needle;
+}
+
/***********************************************************************
* PSDRV_GetTextExtentPoint
*/
+#if 0
BOOL PSDRV_GetTextExtentPoint( DC *dc, LPCWSTR str, INT count,
LPSIZE size )
{
@@ -346,11 +391,30 @@
return TRUE;
}
+#endif
+BOOL PSDRV_GetTextExtentPoint(DC *dc, LPCWSTR str, INT count, LPSIZE size)
+{
+ PSDRV_PDEVICE *physDev = (PSDRV_PDEVICE *)dc->physDev;
+ int i;
+ float width = 0.0;
+
+ for (i = 0; i < count && str[i] != '\0'; ++i)
+ width += PSDRV_UVMetrics(str[i], physDev)->WX;
+
+ width *= physDev->font.scale;
+
+ size->cx = GDI_ROUND((FLOAT)width * dc->xformVport2World.eM11);
+ size->cy = GDI_ROUND((FLOAT)physDev->font.tm.tmHeight *
+ dc->xformVport2World.eM22);
+
+ return TRUE;
+}
/***********************************************************************
* PSDRV_GetCharWidth
*/
+#if 0
BOOL PSDRV_GetCharWidth( DC *dc, UINT firstChar, UINT lastChar,
LPINT buffer )
{
@@ -365,7 +429,24 @@
return TRUE;
}
+#endif
+BOOL PSDRV_GetCharWidth(DC *dc, UINT firstChar, UINT lastChar, LPINT buffer)
+{
+ PSDRV_PDEVICE *physDev = (PSDRV_PDEVICE *)dc->physDev;
+ UINT i;
+
+ if (lastChar > 0xffff || firstChar > lastChar)
+ {
+ SetLastError(ERROR_INVALID_PARAMETER);
+ return FALSE;
+ }
+
+ for (i = firstChar; i < lastChar; ++i)
+ *buffer++ = PSDRV_UVMetrics(i, physDev)->WX * physDev->font.scale;
+
+ return TRUE;
+}
/***********************************************************************
* PSDRV_SetFont
diff -urN ../wine-20010714cvs/dlls/wineps/ps.c ./dlls/wineps/ps.c
--- ../wine-20010714cvs/dlls/wineps/ps.c Sun Jul 15 16:07:36 2001
+++ ./dlls/wineps/ps.c Sun Jul 15 16:25:12 2001
@@ -115,6 +115,9 @@
static char psshow[] = /* string */
"(%s) show\n";
+static const char psglyphshow[] = /* glyph name */
+"/%s glyphshow\n";
+
static char pssetfont[] = /* fontname, xscale, yscale, ascent, escapement */
"/%s findfont\n"
"[%d 0 0 %d 0 0]\n"
@@ -634,6 +637,7 @@
return TRUE;
}
+#if 0
BOOL PSDRV_WriteShow(DC *dc, LPCWSTR str, INT count)
{
char *buf, *buf1;
@@ -671,6 +675,32 @@
return TRUE;
}
+#endif
+
+BOOL PSDRV_WriteShow(DC *dc, LPCWSTR str, INT count)
+{
+ char buf[128];
+ int i;
+
+ for (i = 0; i < count; ++i)
+ {
+ LPCSTR name;
+ int l;
+
+ name = PSDRV_UVMetrics(str[i], (PSDRV_PDEVICE *)dc->physDev)->N->sz;
+ l = snprintf(buf, sizeof(buf), psglyphshow, name);
+
+ if (l < sizeof(psglyphshow) - 2 || l > sizeof(buf) - 1)
+ {
+ WARN("Unusable glyph name '%s' - ignoring\n", name);
+ continue;
+ }
+
+ PSDRV_WriteSpool(dc, buf, l);
+ }
+
+ return TRUE;
+}
BOOL PSDRV_WriteFill(DC *dc)
{
diff -urN ../wine-20010714cvs/dlls/wineps/psdrv.h ./dlls/wineps/psdrv.h
--- ../wine-20010714cvs/dlls/wineps/psdrv.h Tue May 29 17:06:11 2001
+++ ./dlls/wineps/psdrv.h Sun Jul 15 16:11:36 2001
@@ -421,6 +421,7 @@
GLYPHNAME *PSDRV_GlyphName(LPCSTR szName);
VOID PSDRV_IndexGlyphList();
BOOL PSDRV_GetTrueTypeMetrics();
+const AFMMETRICS *PSDRV_UVMetrics(LONG UV, const PSDRV_PDEVICE *physDev);
#endif