Use show instead of glyphshow because glyphshow is very slow on kyocera

Wolfgang Walter wine at stwm.de
Sat Dec 6 12:56:35 CST 2008


Hello,

this is is a proposed change to the wineps driver.

Problem: wine uses the postscript command glyphshow to print characters. At
least all Postscript Printers from Kyocera are very slow when showglyph is
used.  Even simple pages with only one downloaded truetype font slow down fast
printers as the Kyocera FS-4000DN or FS-9520DN so that they print not more
then 3 pages/minute - often only one to two.

I can only speculate why glyphshow is such bad for performance. The generic
windows postscript printer driver does usually not use showglyph. Nor do the
driver from Kyocera. Applications as OpenOffice don't do either.

The following patch changes wineps.drv such that it uses show (for downloaded
truetype fonts). It still contains code which inserts postscript comments in
its output for debugging purpose. It's meant for discussion.




Regards,

Wolfgang Walter

-- 
Wolfgang Walter
Studentenwerk München
Anstalt des öffentlichen Rechts
Leiter EDV
Leopoldstraße 15
80802 München



From e3cfd6d376bb397f8378fe65127496d7b30b4826 Mon Sep 17 00:00:00 2001
From: Wolfgang Walter <wine at stwm.de>
Date: Sat, 6 Dec 2008 17:43:35 +0100
Subject: Use show instead of glyphshow

On many postscript printers glyphshow is slow. Especially all Kyocera models
from FS-1020 up to FS-4000DN or FS-9520DN are very slow when glyphshow is used
with downloaded truetype fonts. Even simple text-only pages are rendered at 1/6
to 1/10 of the usual time (i.e. reached under windows with the generic window
postscript driver).

I don't know why glyphshow is slow but I suppose that its usage is not optimised
as the eneric windows postscript printer driver seems not to use glyphshow. Nor
do the driver from Kyocera. Applications as OpenOffice don't do either.

This change modifies wineps.drv such that it uses show for downloaded fonts as
other the window printer drivers do.

Show accesses glyphs of base fonts by there character code in the encoding array
of the font. Only 256 glyphs may be encoded. Therefor I clone the font if
necessary. As the clones share all resources but their encoding array with the
original font this is not expensive.

Actually I limit the number of clones (by undefining older ones) but it's
probably not worth the code:

* the gylphs themselves are the really expensive part

* all fonts are released when a page is rendered

I had to modify how font setting works as I have to set the clone with the
correct encoding for each character.

With this modification printing perfomance is up to what one would expect. I
tested this on several Kyocera laser printers (FS-1010, FS-1030, FS-1300,
FS-C5025, FS-4000DN, FS-9520DN) and also on a HP Laserjet and a Minolta
Laserprinter. And of course with ghostscript.

This patch still contains code which creates comments in the generated
postscript file for debugging purpose.
---
 dlls/wineps.drv/download.c |  337 +++++++++++++++++++++++++++++++++++++++-----
 dlls/wineps.drv/font.c     |    4 +-
 dlls/wineps.drv/ps.c       |   14 ++
 dlls/wineps.drv/psdrv.h    |   16 ++
 dlls/wineps.drv/type1.c    |   27 +---
 dlls/wineps.drv/type42.c   |   27 +---
 6 files changed, 347 insertions(+), 78 deletions(-)

diff --git a/dlls/wineps.drv/download.c b/dlls/wineps.drv/download.c
index e794af6..bd40ef0 100644
--- a/dlls/wineps.drv/download.c
+++ b/dlls/wineps.drv/download.c
@@ -42,6 +42,23 @@ WINE_DEFAULT_DEBUG_CHANNEL(psdrv);
 #define GET_BE_DWORD(ptr) ((DWORD)MAKELONG( GET_BE_WORD(&((WORD *)(ptr))[1]), \
                                             GET_BE_WORD(&((WORD *)(ptr))[0]) ))
 
+#define GLYPH_SENT_INC 128
+#define MAX_ENC_PER_FONT 16  /* must be <= 0xfe */
+#define OPT_ENC_PER_FONT 10  /* when we should start to undefine clones */
+#define MIN_ENC_PER_FONT  4  /* when we undefine: how agressive */
+
+static const char fontname[] = "%s_wine_%04X";
+static const char undefinefont[] = "/%s_wine_%04X undefinefont\n";
+static const char setdeffont[] = "/%s findfont 40 scalefont setfont\n";
+
+
+#if DOWNLOAD_SPOOLBUF_MINPLUS <= 1000
+#error "DOWNLOAD_SPOOLBUF_MINPLUS must be greater then 1000"
+#endif
+#if MAX_ENC_PER_FONT > 0xfe
+#error "MAX_ENC_PER_FONT must not exceed 0xfe"
+#endif
+
 /****************************************************************************
  *  get_download_name
  */
@@ -192,7 +209,7 @@ static BOOL get_bbox(PSDRV_PDEVICE *physDev, RECT *rc, UINT *emsize)
  */
 BOOL PSDRV_SelectDownloadFont(PSDRV_PDEVICE *physDev)
 {
-    char *ps_name;
+    char *ps_name = NULL;
     LPOUTLINETEXTMETRICA potm;
     DWORD len = GetOutlineTextMetricsA(physDev->hdc, 0, NULL);
 
@@ -219,6 +236,44 @@ BOOL PSDRV_SelectDownloadFont(PSDRV_PDEVICE *physDev)
 }
 
 /****************************************************************************
+ *  Download_WriteSetFont
+ *
+ *  If <force> == TRUE or <g_enc> != pdl->glyph_enc_last_used:
+ *  write postscript code to select the clone of font <pdl>
+ *  where encoding g_enc is mapped as character code (<g_enc> & 0xff)
+ *
+ */
+static BOOL Download_WriteSetFont(PSDRV_PDEVICE *physDev, DOWNLOAD *pdl,
+                                  WORD g_enc, BOOL force)
+{
+    BOOL ret;
+
+    UINT fontnr = (g_enc & 0xff00);
+
+    if(!force && pdl->glyph_enc_last_used == fontnr)
+        return TRUE;
+
+    sprintf(pdl->spoolbuf, fontname, pdl->ps_name, fontnr);
+    ret = PSDRV_WriteSetFont(physDev, pdl->spoolbuf, physDev->font.size,
+                             physDev->font.escapement);
+    if (ret)
+       pdl->glyph_enc_last_used = fontnr;
+
+    return ret;
+}
+
+/****************************************************************************
+ *  Download_WriteUndefineFont
+ *
+ */
+static BOOL Download_WriteUndefineFont(PSDRV_PDEVICE *physDev, DOWNLOAD *pdl,
+                                       WORD fontnr)
+{
+    sprintf(pdl->spoolbuf, undefinefont, pdl->ps_name, fontnr);
+    return PSDRV_WriteSpool(physDev, pdl->spoolbuf, strlen(pdl->spoolbuf));
+}
+
+/****************************************************************************
  *  PSDRV_WriteSetDownloadFont
  *
  *  Write setfont for download font.
@@ -226,24 +281,24 @@ BOOL PSDRV_SelectDownloadFont(PSDRV_PDEVICE *physDev)
  */
 BOOL PSDRV_WriteSetDownloadFont(PSDRV_PDEVICE *physDev)
 {
-    char *ps_name;
-    LPOUTLINETEXTMETRICA potm;
-    DWORD len = GetOutlineTextMetricsA(physDev->hdc, 0, NULL);
     DOWNLOAD *pdl;
 
     assert(physDev->font.fontloc == Download);
 
-    potm = HeapAlloc(GetProcessHeap(), 0, len);
-    GetOutlineTextMetricsA(physDev->hdc, len, potm);
-
-    get_download_name(physDev, potm, &ps_name);
-
     if(physDev->font.fontinfo.Download == NULL) {
+        char *ps_name;
+        DWORD len = GetOutlineTextMetricsA(physDev->hdc, 0, NULL);
+        LPOUTLINETEXTMETRICA potm;
         RECT bbox;
         UINT emsize;
 
+        potm = HeapAlloc(GetProcessHeap(), 0, len);
+        GetOutlineTextMetricsA(physDev->hdc, len, potm);
+        get_download_name(physDev, potm, &ps_name);
+
         if (!get_bbox(physDev, &bbox, &emsize)) {
 	    HeapFree(GetProcessHeap(), 0, potm);
+            HeapFree(GetProcessHeap(), 0, ps_name);
 	    return FALSE;
 	}
         if(!is_room_for_font(physDev))
@@ -254,6 +309,15 @@ BOOL PSDRV_WriteSetDownloadFont(PSDRV_PDEVICE *physDev)
 	strcpy(pdl->ps_name, ps_name);
 	pdl->next = NULL;
 
+	pdl->spoolbuf_len = 2*strlen(ps_name) + DOWNLOAD_SPOOLBUF_MINPLUS;
+        pdl->spoolbuf = HeapAlloc(GetProcessHeap(), 0, pdl->spoolbuf_len);
+	pdl->glyph_sent_size = GLYPH_SENT_INC;
+        pdl->glyph_sent = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
+                                    pdl->glyph_sent_size * sizeof(*(pdl->glyph_sent)));
+        pdl->glyph_enc_first_valid = 0x100;
+        pdl->glyph_enc_next_free = 0x100;
+        pdl->glyph_enc_last_used = 0;
+
         if(physDev->pi->ppd->TTRasterizer == RO_Type42) {
 	    pdl->typeinfo.Type42 = T42_download_header(physDev, ps_name, &bbox, emsize);
 	    pdl->type = Type42;
@@ -271,14 +335,18 @@ BOOL PSDRV_WriteSetDownloadFont(PSDRV_PDEVICE *physDev)
             get_glyph_name(physDev->hdc, 0, g_name);
             T42_download_glyph(physDev, pdl, 0, g_name);
         }
+        HeapFree(GetProcessHeap(), 0, ps_name);
+        HeapFree(GetProcessHeap(), 0, potm);
+        PSDRV_WriteSpool(physDev, "% servus1a\n", strlen("% servus1a\n"));
+    } else {
+        PSDRV_WriteSpool(physDev, "% servus1a\n", strlen("% servus1b\n"));
+        pdl = physDev->font.fontinfo.Download;
+        assert(physDev->font.fontinfo.Download);
     }
 
+    PSDRV_WriteSpool(physDev, "% servus2\n", strlen("% servus1\n"));
+    Download_WriteSetFont(physDev, pdl, 0, TRUE);
 
-    PSDRV_WriteSetFont(physDev, ps_name, physDev->font.size,
-		       physDev->font.escapement);
-
-    HeapFree(GetProcessHeap(), 0, ps_name);
-    HeapFree(GetProcessHeap(), 0, potm);
     return TRUE;
 }
 
@@ -289,6 +357,191 @@ void get_glyph_name(HDC hdc, WORD index, char *name)
     return;
 }
 
+/*
+ * download_glyph
+ *
+ * Downloads the glyph <index> of font <pdl> if necessary and naming it
+ * <glyph_name>.
+ *
+ * Defines an encoding for <glyph_name>.
+ *
+ * As a base font in postscript may only have up to 256 entries it clones the
+ * font if necessary. The name of the font will be <pdl->ps_name>_wine_<XX>00
+ * where 0x<XX>00 == <return value> & 0xff00
+ * The character code is <return value> & 0xff
+ *
+ * If it fails it returns (<return value> & 0xffff) <= 0xff
+ * or in other words <XX> == 0.
+ *
+ * As font <pdl->ps_name>_wine_0000 always exists and every character code of
+ * it is mapped to .notdef you may ignore errors and print then the undefined
+ * symbol of the font.
+ *
+ * If you call download_glyph with <may_free_encs> = TRUE earlier encodings you
+ * got for this font may not be valid any more because download_glyph may
+ * undefine older clones when more than OPT_ENC_PER_FONT clones exist.
+ *
+ * As long as you call it with <may_free_encs> = FALSE older encodings beginning
+ * with the last call with <may_free_encs> = TRUE remain valid.
+ * But download_glyph will not make more then MAX_ENC_PER_FONT clones and may
+ * fail then with <return value> == 1
+ *
+ * But you can be sure that
+ *    If you got 0x<XX><YY>
+ *    and you get next 0x<XX><ZZ> or 0x00<WW>
+ *    then 0x<XX><YY> is still valid
+ *
+ */
+static WORD download_glyph(PSDRV_PDEVICE *physDev, DOWNLOAD *pdl, DWORD index,
+                    char *glyph_name, BOOL may_free_encs)
+{
+    DWORD encoding = 0;
+    DWORD first_valid;
+    DWORD next_free;
+    DWORD used;
+    BOOL ret;
+
+    const char glyph_enc[] =
+      "/%s_wine_%04X findfont /Encoding get\n"
+      "dup %u /%s put\n"
+      "pop\n";
+
+    const char font_clone[] =
+      "/%s_wine_0000 findfont\n"
+      "dup length dict begin\n"
+      "{ 1 index /FID ne\n"
+      "  {def} {pop pop} ifelse\n"
+      "} forall\n"
+      "/Encoding 256 array 0 1 255 {1 index exch /.notdef put} for def\n"
+      "currentdict\n"
+      "end\n"
+      "/%s_wine_%04X exch definefont pop\n";
+
+    TRACE("%d %s\n", index, glyph_name);
+
+    first_valid = pdl->glyph_enc_first_valid;
+    next_free = pdl->glyph_enc_next_free;
+    assert(first_valid <= next_free);
+    assert( (first_valid & 0xff00) != 0);
+
+    used = ((next_free - first_valid) & 0xff00)>>8;
+    if (next_free > 0xffff)
+        used--;
+
+    if(index < pdl->glyph_sent_size) {
+        encoding = pdl->glyph_sent[index];
+        assert(encoding < next_free);
+        if( encoding >= 0x100 &&
+           ( first_valid <= encoding || first_valid < (next_free & 0x10000) + encoding))
+           goto encset;
+    }
+
+    if( used > MAX_ENC_PER_FONT && !may_free_encs) {
+        /* we need a new clone of the font but we must not create one */
+        return 1;
+    }
+
+    PSDRV_WriteSpool(physDev, "% hallo1\n", strlen("% hallo1\n"));
+    if(index >= pdl->glyph_sent_size) {
+        pdl->glyph_sent_size = (index / GLYPH_SENT_INC + 1) * GLYPH_SENT_INC;
+        pdl->glyph_sent = HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
+                                      pdl->glyph_sent,
+                                      pdl->glyph_sent_size * sizeof(*(pdl->glyph_sent)));
+        encoding = 0;
+        PSDRV_WriteSpool(physDev, "% hallo1a\n", strlen("% hallo1a\n"));
+    }
+
+    PSDRV_WriteSpool(physDev, "% hallo2\n", strlen("% hallo2\n"));
+    if(!encoding) {
+        /* download glyph */
+        switch(pdl->type) {
+	case Type42:
+	    ret = T42_download_glyph(physDev, pdl, index, glyph_name);
+	    break;
+
+	case Type1:
+	    ret = T1_download_glyph(physDev, pdl, index, glyph_name);
+	    break;
+
+	default:
+	    ERR("Type = %d\n", pdl->type);
+	    assert(0);
+	}
+        if (! ret)
+           return 0;
+        /* we never assign 0x0000 through 0x00ff as valid encoding.
+         * If we fail to assign a valid encoding later on we
+         * still know that we downloaded the glyph already and
+         * only need to assign an encoding.
+         */
+        pdl->glyph_sent[index] = 1;
+        PSDRV_WriteSpool(physDev, "% hallo2c\n", strlen("% hallo2c\n"));
+    }
+
+    PSDRV_WriteSpool(physDev, "% hallo3\n", strlen("% hallo3\n"));
+    if( (next_free & 0xff) == 0) {
+        PSDRV_WriteSpool(physDev, "% hallo3a\n", strlen("% hallo3a\n"));
+        /* we need a new clone of the font */
+        if ( (next_free & 0xffff) == 0) {
+            /* we overflow: we must mark encodings < first_valid as
+               downloaded but unencoded */
+            DWORD i;
+            for(i = 0; i < pdl->glyph_sent_size; i++) {
+                if (pdl->glyph_sent[i] < first_valid)
+                    pdl->glyph_sent[i] = 1;
+            }
+            next_free += 0x100;
+            PSDRV_WriteSpool(physDev, "% hallo3b\n", strlen("% hallo3b\n"));
+        }
+        /* now clone the font */
+        sprintf(pdl->spoolbuf, font_clone, pdl->ps_name, pdl->ps_name, next_free & 0xff00);
+        PSDRV_WriteSpool(physDev, pdl->spoolbuf, strlen(pdl->spoolbuf));
+
+        /* reserve character 0 for .notdef */
+        next_free++;
+    }
+    encoding = next_free++;
+    used++;
+
+    PSDRV_WriteSpool(physDev, "% hallo4\n", strlen("% hallo4\n"));
+    pdl->glyph_enc_next_free = next_free;
+    pdl->glyph_sent[index] = encoding;
+    /* define encoding */
+    sprintf(pdl->spoolbuf,  glyph_enc, pdl->ps_name,
+            (encoding & 0xff00), (encoding & 0xff), glyph_name);
+    PSDRV_WriteSpool(physDev, pdl->spoolbuf, strlen(pdl->spoolbuf));
+
+encset:
+    PSDRV_WriteSpool(physDev, "% hallo5\n", strlen("% hallo5\n"));
+    if (used > OPT_ENC_PER_FONT && !may_free_encs) {
+        int i;
+
+        PSDRV_WriteSpool(physDev, "% hallo5a\n", strlen("% hallo5a\n"));
+        Download_WriteSetFont(physDev, pdl, 0, TRUE);
+
+        used += (next_free > 0xffff);
+        for(i = 0; i < used - MIN_ENC_PER_FONT; i++) {
+            DWORD fontnr = (first_valid & 0xff00);
+            if (fontnr == (encoding & 0xff00))
+                break;
+            if (fontnr)
+                Download_WriteUndefineFont(physDev, pdl, fontnr);
+            first_valid += 0x100;
+            PSDRV_WriteSpool(physDev, "% hallo5b\n", strlen("% hallo5b\n"));
+        }
+        if (first_valid > 0xffff) {
+            first_valid = 0x100;
+            next_free &= 0xffff;
+            pdl->glyph_enc_next_free = next_free;
+            PSDRV_WriteSpool(physDev, "% hallo5c\n", strlen("% hallo5c\n"));
+        }
+        pdl->glyph_enc_first_valid = first_valid;
+    }
+
+    PSDRV_WriteSpool(physDev, "% hallo6\n", strlen("% hallo6\n"));
+    return encoding;
+}
+
 /****************************************************************************
  *  PSDRV_WriteDownloadGlyphShow
  *
@@ -298,36 +551,26 @@ void get_glyph_name(HDC hdc, WORD index, char *name)
 BOOL PSDRV_WriteDownloadGlyphShow(PSDRV_PDEVICE *physDev, WORD *glyphs,
 				  UINT count)
 {
+    DOWNLOAD *pdl;
     UINT i;
     char g_name[MAX_G_NAME + 1];
+    DWORD g_enc;
+
     assert(physDev->font.fontloc == Download);
 
-    switch(physDev->font.fontinfo.Download->type) {
-    case Type42:
-    for(i = 0; i < count; i++) {
-        get_glyph_name(physDev->hdc, glyphs[i], g_name);
-	T42_download_glyph(physDev, physDev->font.fontinfo.Download,
-			   glyphs[i], g_name);
-	PSDRV_WriteGlyphShow(physDev, g_name);
-    }
-    break;
+    pdl = physDev->font.fontinfo.Download;
+    assert(pdl);
 
-    case Type1:
     for(i = 0; i < count; i++) {
         get_glyph_name(physDev->hdc, glyphs[i], g_name);
-	T1_download_glyph(physDev, physDev->font.fontinfo.Download,
-			  glyphs[i], g_name);
-	PSDRV_WriteGlyphShow(physDev, g_name);
-    }
-    break;
-
-    default:
-        ERR("Type = %d\n", physDev->font.fontinfo.Download->type);
-	assert(0);
+        g_enc = download_glyph(physDev, pdl, glyphs[i], g_name, TRUE) & 0xffff;
+        Download_WriteSetFont(physDev, pdl, g_enc, FALSE);
+        PSDRV_WriteShow1(physDev, (g_enc & 0xff));
     }
     return TRUE;
 }
 
+
 /****************************************************************************
  *  PSDRV_EmptyDownloadList
  *
@@ -337,8 +580,7 @@ BOOL PSDRV_WriteDownloadGlyphShow(PSDRV_PDEVICE *physDev, WORD *glyphs,
 BOOL PSDRV_EmptyDownloadList(PSDRV_PDEVICE *physDev, BOOL write_undef)
 {
     DOWNLOAD *pdl, *old;
-    static const char undef[] = "/%s findfont 40 scalefont setfont /%s undefinefont\n";
-    char buf[sizeof(undef) + 200];
+
     const char *default_font = physDev->pi->ppd->DefaultFont ?
         physDev->pi->ppd->DefaultFont : "Courier";
 
@@ -349,11 +591,30 @@ BOOL PSDRV_EmptyDownloadList(PSDRV_PDEVICE *physDev, BOOL write_undef)
 
     pdl = physDev->downloaded_fonts;
     physDev->downloaded_fonts = NULL;
+
+    if (write_undef) {
+        pdl->spoolbuf[pdl->spoolbuf_len-1] = '\0';
+        snprintf(pdl->spoolbuf, pdl->spoolbuf_len, setdeffont, default_font);
+        if (pdl->spoolbuf[pdl->spoolbuf_len-1]) {
+            default_font = "Courier";
+            sprintf(pdl->spoolbuf, setdeffont, default_font);
+        }
+        PSDRV_WriteSpool(physDev, pdl->spoolbuf, strlen(pdl->spoolbuf));
+    }
+
     while(pdl) {
         if(write_undef) {
-            sprintf(buf, undef, default_font, pdl->ps_name);
-            PSDRV_WriteSpool(physDev, buf, strlen(buf));
+            DWORD i;
+            /* free derived fonts */
+            for(i = pdl->glyph_enc_first_valid; i < pdl->glyph_enc_next_free; i += 0x0100) {
+                int fontnr = (i & 0xff00);
+                if (fontnr) {
+                    Download_WriteUndefineFont(physDev, pdl, fontnr);
+                }
+            }
+            Download_WriteUndefineFont(physDev, pdl, 0);
         }
+	HeapFree(GetProcessHeap(), 0, pdl->glyph_sent);
 
         switch(pdl->type) {
 	case Type42:
@@ -370,6 +631,8 @@ BOOL PSDRV_EmptyDownloadList(PSDRV_PDEVICE *physDev, BOOL write_undef)
 	}
 
 	HeapFree(GetProcessHeap(), 0, pdl->ps_name);
+	HeapFree(GetProcessHeap(), 0, pdl->glyph_sent);
+	HeapFree(GetProcessHeap(), 0, pdl->spoolbuf);
 	old = pdl;
 	pdl = pdl->next;
 	HeapFree(GetProcessHeap(), 0, old);
diff --git a/dlls/wineps.drv/font.c b/dlls/wineps.drv/font.c
index 9e0ae39..1a6bf8e 100644
--- a/dlls/wineps.drv/font.c
+++ b/dlls/wineps.drv/font.c
@@ -125,11 +125,14 @@ HFONT PSDRV_SelectFont( PSDRV_PDEVICE *physDev, HFONT hfont, HANDLE gdiFont )
 BOOL PSDRV_SetFont( PSDRV_PDEVICE *physDev )
 {
     PSDRV_WriteSetColor(physDev, &physDev->font.color);
+    PSDRV_WriteSpool(physDev, "% salve1\n", strlen("% salve1\n"));
     if(physDev->font.set) return TRUE;
 
+    PSDRV_WriteSpool(physDev, "% salve2\n", strlen("% salve2\n"));
     switch(physDev->font.fontloc) {
     case Builtin:
         PSDRV_WriteSetBuiltinFont(physDev);
+        physDev->font.set = TRUE;
 	break;
     case Download:
         PSDRV_WriteSetDownloadFont(physDev);
@@ -139,6 +142,5 @@ BOOL PSDRV_SetFont( PSDRV_PDEVICE *physDev )
         assert(1);
 	break;
     }
-    physDev->font.set = TRUE;
     return TRUE;
 }
diff --git a/dlls/wineps.drv/ps.c b/dlls/wineps.drv/ps.c
index fdebf46..4d7769a 100644
--- a/dlls/wineps.drv/ps.c
+++ b/dlls/wineps.drv/ps.c
@@ -122,6 +122,9 @@ static const char psrrectangle[] = /* x, y, width, height, -width */
 static const char psglyphshow[] = /* glyph name */
 "/%s glyphshow\n";
 
+static const char psshow[] = /* encoding name */
+"<%02X> show\n";
+
 static const char pssetfont[] = /* fontname, xscale, yscale, ascent, escapement */
 "/%s findfont\n"
 "[%d 0 0 %d 0 0]\n"
@@ -611,6 +614,17 @@ BOOL PSDRV_WriteGlyphShow(PSDRV_PDEVICE *physDev, LPCSTR g_name)
     return TRUE;
 }
 
+BOOL PSDRV_WriteShow1(PSDRV_PDEVICE *physDev, BYTE g_encoding)
+{
+    char    buf[128];
+    int     l;
+
+    l = sprintf(buf, psshow, g_encoding);
+
+    PSDRV_WriteSpool(physDev, buf, l);
+    return TRUE;
+}
+
 BOOL PSDRV_WriteFill(PSDRV_PDEVICE *physDev)
 {
     return PSDRV_WriteSpool(physDev, psfill, sizeof(psfill)-1);
diff --git a/dlls/wineps.drv/psdrv.h b/dlls/wineps.drv/psdrv.h
index fcdc78d..4e30238 100644
--- a/dlls/wineps.drv/psdrv.h
+++ b/dlls/wineps.drv/psdrv.h
@@ -292,8 +292,23 @@ typedef struct _tagDOWNLOAD {
     TYPE42 *Type42;
   } typeinfo;
   char *ps_name;
+  char *spoolbuf;
+  size_t spoolbuf_len;
+  DWORD glyph_sent_size;
+  WORD *glyph_sent;
+  WORD glyph_enc_first_valid;
+  DWORD glyph_enc_next_free;
+  WORD glyph_enc_last_used;
   struct _tagDOWNLOAD *next;
 } DOWNLOAD;
+#define DOWNLOAD_SPOOLBUF_MINPLUS 1001
+/* tmp_spool_buf is quaranteed to hold at least
+   2*strlen(psname) + DOWNLOAD_TMPBUF_MINPLUS bytes
+   Attention:
+       spoolbuf may be changed by any function
+       of WINE   BUT  those from ps.c
+       Never give it as parameter to a WINE function
+       but those from ps.c */
 
 enum fontloc {
   Builtin, Download
@@ -444,6 +459,7 @@ extern BOOL PSDRV_WriteRRectangle(PSDRV_PDEVICE *physDev, INT x, INT y, INT widt
 extern BOOL PSDRV_WriteSetFont(PSDRV_PDEVICE *physDev, const char *name, INT size,
                                INT escapement);
 extern BOOL PSDRV_WriteGlyphShow(PSDRV_PDEVICE *physDev, LPCSTR g_name);
+extern BOOL PSDRV_WriteShow1(PSDRV_PDEVICE *physDev, BYTE g_encoding);
 extern BOOL PSDRV_WriteSetPen(PSDRV_PDEVICE *physDev);
 extern BOOL PSDRV_WriteArc(PSDRV_PDEVICE *physDev, INT x, INT y, INT w, INT h,
 			     double ang1, double ang2);
diff --git a/dlls/wineps.drv/type1.c b/dlls/wineps.drv/type1.c
index fe8c8ba..c74bb88 100644
--- a/dlls/wineps.drv/type1.c
+++ b/dlls/wineps.drv/type1.c
@@ -37,8 +37,6 @@
 WINE_DEFAULT_DEBUG_CHANNEL(psdrv);
 
 struct tagTYPE1 {
-    DWORD glyph_sent_size;
-    BOOL *glyph_sent;
     DWORD emsize;
 };
 
@@ -62,7 +60,7 @@ TYPE1 *T1_download_header(PSDRV_PDEVICE *physDev, char *ps_name, RECT *bbox, UIN
 
     char dict[] = /* name, emsquare, fontbbox */
       "25 dict begin\n"
-      " /FontName /%s def\n"
+      " /FontName /%s_wine_0000 def\n"
       " /Encoding 256 array 0 1 255{1 index exch /.notdef put} for def\n"
       " /PaintType 0 def\n"
       " /FontMatrix [1 %d div 0 0 1 %d div 0 0] def\n"
@@ -87,11 +85,6 @@ TYPE1 *T1_download_header(PSDRV_PDEVICE *physDev, char *ps_name, RECT *bbox, UIN
     t1 = HeapAlloc(GetProcessHeap(), 0, sizeof(*t1));
     t1->emsize = emsize;
 
-    t1->glyph_sent_size = GLYPH_SENT_INC;
-    t1->glyph_sent = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
-			       t1->glyph_sent_size *
-			       sizeof(*(t1->glyph_sent)));
-
     buf = HeapAlloc(GetProcessHeap(), 0, sizeof(dict) + strlen(ps_name) +
 		    100);
 
@@ -194,7 +187,7 @@ BOOL T1_download_glyph(PSDRV_PDEVICE *physDev, DOWNLOAD *pdl, DWORD index,
     RECT rc;
 
     static const char glyph_def_begin[] =
-      "/%s findfont dup\n"
+      "/%s_wine_0000 findfont dup\n"
       "/Private get begin\n"
       "/CharStrings get begin\n"
       "/%s %d RD\n";
@@ -206,15 +199,10 @@ BOOL T1_download_glyph(PSDRV_PDEVICE *physDev, DOWNLOAD *pdl, DWORD index,
     assert(pdl->type == Type1);
     t1 = pdl->typeinfo.Type1;
 
-    if(index < t1->glyph_sent_size) {
-        if(t1->glyph_sent[index])
-	    return TRUE;
-    } else {
-        t1->glyph_sent_size = (index / GLYPH_SENT_INC + 1) * GLYPH_SENT_INC;
-	t1->glyph_sent = HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
-				      t1->glyph_sent,
-				      t1->glyph_sent_size * sizeof(*(t1->glyph_sent)));
-    }
+    if(index >= pdl->glyph_sent_size)
+        return FALSE;
+    if(pdl->glyph_sent[index])
+	return TRUE;
 
     GetObjectW(GetCurrentObject(physDev->hdc, OBJ_FONT), sizeof(lf), &lf);
     rc.left = rc.right = rc.bottom = 0;
@@ -295,7 +283,7 @@ BOOL T1_download_glyph(PSDRV_PDEVICE *physDev, DOWNLOAD *pdl, DWORD index,
     PSDRV_WriteSpool(physDev, buf, strlen(buf));
     str_free(charstring);
 
-    t1->glyph_sent[index] = TRUE;
+    pdl->glyph_sent[index] = 1;
     HeapFree(GetProcessHeap(), 0, glyph_buf);
     HeapFree(GetProcessHeap(), 0, buf);
     return TRUE;
@@ -303,7 +291,6 @@ BOOL T1_download_glyph(PSDRV_PDEVICE *physDev, DOWNLOAD *pdl, DWORD index,
 
 void T1_free(TYPE1 *t1)
 {
-    HeapFree(GetProcessHeap(), 0, t1->glyph_sent);
     HeapFree(GetProcessHeap(), 0, t1);
     return;
 }
diff --git a/dlls/wineps.drv/type42.c b/dlls/wineps.drv/type42.c
index 172072e..a6c7f8a 100644
--- a/dlls/wineps.drv/type42.c
+++ b/dlls/wineps.drv/type42.c
@@ -74,8 +74,6 @@ struct tagTYPE42 {
     int glyf_tab, loca_tab, head_tab; /* indices of glyf, loca and head tables */
     int hmtx_tab, maxp_tab;
     int num_of_written_tables;
-    DWORD glyph_sent_size;
-    BOOL *glyph_sent;
     DWORD emsize;
     DWORD *glyf_blocks;
 };
@@ -143,7 +141,7 @@ TYPE42 *T42_download_header(PSDRV_PDEVICE *physDev, char *ps_name,
     TYPE42 *t42;
     static const char start[] = /* name, fontbbox */
             "25 dict begin\n"
-	    " /FontName /%s def\n"
+	    " /FontName /%s_wine_0000 def\n"
 	    " /Encoding 256 array 0 1 255{1 index exch /.notdef put} for\n"
 	    " def\n"
 	    " /PaintType 0 def\n"
@@ -193,11 +191,6 @@ TYPE42 *T42_download_header(PSDRV_PDEVICE *physDev, char *ps_name,
 	return NULL;
     }
 
-    t42->glyph_sent_size = GLYPH_SENT_INC;
-    t42->glyph_sent = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
-				t42->glyph_sent_size *
-				sizeof(*(t42->glyph_sent)));
-
     buf = HeapAlloc(GetProcessHeap(), 0, sizeof(start) + strlen(ps_name) +
 		    100);
 
@@ -287,7 +280,7 @@ BOOL T42_download_glyph(PSDRV_PDEVICE *physDev, DOWNLOAD *pdl, DWORD index,
     TYPE42 *t42;
 
     const char glyph_def[] = 
-      "/%s findfont exch 1 index\n"
+      "/%s_wine_0000 findfont exch 1 index\n"
       "havetype42gdir\n"
       "{/GlyphDirectory get begin %d exch def end}\n"
       "{/sfnts get 4 index get 3 index 2 index putinterval pop}\n"
@@ -302,15 +295,10 @@ BOOL T42_download_glyph(PSDRV_PDEVICE *physDev, DOWNLOAD *pdl, DWORD index,
     assert(pdl->type == Type42);
     t42 = pdl->typeinfo.Type42;
 
-    if(index < t42->glyph_sent_size) {
-        if(t42->glyph_sent[index])
-	    return TRUE;
-    } else {
-        t42->glyph_sent_size = (index / GLYPH_SENT_INC + 1) * GLYPH_SENT_INC;
-	t42->glyph_sent = HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
-				      t42->glyph_sent,
-				      t42->glyph_sent_size * sizeof(*(t42->glyph_sent)));
-    }
+    if(index >= pdl->glyph_sent_size)
+        return FALSE;
+    if(pdl->glyph_sent[index])
+        return TRUE;
 
     if(!get_glyf_pos(t42, index, &start, &end)) return FALSE;
     TRACE("start = %x end = %x\n", start, end);
@@ -364,7 +352,7 @@ BOOL T42_download_glyph(PSDRV_PDEVICE *physDev, DOWNLOAD *pdl, DWORD index,
     sprintf(buf, glyph_def, pdl->ps_name, index, glyph_name, index);
     PSDRV_WriteSpool(physDev, buf, strlen(buf));
 
-    t42->glyph_sent[index] = TRUE;
+    pdl->glyph_sent[index] = 1;
     HeapFree(GetProcessHeap(), 0, buf);
     return TRUE;
 }
@@ -374,7 +362,6 @@ void T42_free(TYPE42 *t42)
     OTTable *table;
     for(table = t42->tables; table->MS_tag; table++)
         HeapFree(GetProcessHeap(), 0, table->data);
-    HeapFree(GetProcessHeap(), 0, t42->glyph_sent);
     HeapFree(GetProcessHeap(), 0, t42->glyf_blocks);
     HeapFree(GetProcessHeap(), 0, t42);
     return;
-- 
1.5.6.5




More information about the wine-devel mailing list