Significant change to WINEPS - please test!

Ian Pilcher ian.pilcher at home.com
Sun Jul 15 19:29:23 CDT 2001


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 at home.com
========================================================================
-------------- next part --------------
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
 


More information about the wine-devel mailing list