From c70c88c57eed7721352ef092b75beb8ed4cdc3e5 Mon Sep 17 00:00:00 2001
From: "Erich E. Hoover" <erich.e.hoover@wine-staging.com>
Date: Wed, 2 Sep 2015 17:21:15 -0600
Subject: wineps.drv: Add support for PostScript Format 1 glyph names.

---
 dlls/wineps.drv/download.c | 315 ++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 313 insertions(+), 2 deletions(-)

diff --git a/dlls/wineps.drv/download.c b/dlls/wineps.drv/download.c
index e5b57f7..baebefd 100644
--- a/dlls/wineps.drv/download.c
+++ b/dlls/wineps.drv/download.c
@@ -30,6 +30,8 @@
 #include "winnls.h"
 
 #include "psdrv.h"
+#include "data/agl.h"
+
 #include "wine/debug.h"
 
 WINE_DEFAULT_DEBUG_CHANNEL(psdrv);
@@ -359,11 +361,320 @@ BOOL PSDRV_WriteSetDownloadFont(PHYSDEV dev, BOOL vertical)
     return TRUE;
 }
 
+void get_standard_glyph_name(WORD index, char *name)
+{
+    /* These PostScript Format 1 glyph names are stored by glyph index, do not reorder them. */
+    const char *glyph_table[] = {
+        ".notdef",
+        ".null",
+        "nonmarkingreturn",
+        GN_space->sz,
+        GN_exclam->sz,
+        GN_quotedbl->sz,
+        GN_numbersign->sz,
+        GN_dollar->sz,
+        GN_percent->sz,
+        GN_ampersand->sz,
+        GN_quotesingle->sz,
+        GN_parenleft->sz,
+        GN_parenright->sz,
+        GN_asterisk->sz,
+        GN_plus->sz,
+        GN_comma->sz,
+        GN_hyphen->sz,
+        GN_period->sz,
+        GN_slash->sz,
+        GN_zero->sz,
+        GN_one->sz,
+        GN_two->sz,
+        GN_three->sz,
+        GN_four->sz,
+        GN_five->sz,
+        GN_six->sz,
+        GN_seven->sz,
+        GN_eight->sz,
+        GN_nine->sz,
+        GN_colon->sz,
+        GN_semicolon->sz,
+        GN_less->sz,
+        GN_equal->sz,
+        GN_greater->sz,
+        GN_question->sz,
+        GN_at->sz,
+        GN_A->sz,
+        GN_B->sz,
+        GN_C->sz,
+        GN_D->sz,
+        GN_E->sz,
+        GN_F->sz,
+        GN_G->sz,
+        GN_H->sz,
+        GN_I->sz,
+        GN_J->sz,
+        GN_K->sz,
+        GN_L->sz,
+        GN_M->sz,
+        GN_N->sz,
+        GN_O->sz,
+        GN_P->sz,
+        GN_Q->sz,
+        GN_R->sz,
+        GN_S->sz,
+        GN_T->sz,
+        GN_U->sz,
+        GN_V->sz,
+        GN_W->sz,
+        GN_X->sz,
+        GN_Y->sz,
+        GN_Z->sz,
+        GN_bracketleft->sz,
+        GN_backslash->sz,
+        GN_bracketright->sz,
+        GN_asciicircum->sz,
+        GN_underscore->sz,
+        GN_grave->sz,
+        GN_a->sz,
+        GN_b->sz,
+        GN_c->sz,
+        GN_d->sz,
+        GN_e->sz,
+        GN_f->sz,
+        GN_g->sz,
+        GN_h->sz,
+        GN_i->sz,
+        GN_j->sz,
+        GN_k->sz,
+        GN_l->sz,
+        GN_m->sz,
+        GN_n->sz,
+        GN_o->sz,
+        GN_p->sz,
+        GN_q->sz,
+        GN_r->sz,
+        GN_s->sz,
+        GN_t->sz,
+        GN_u->sz,
+        GN_v->sz,
+        GN_w->sz,
+        GN_x->sz,
+        GN_y->sz,
+        GN_z->sz,
+        GN_braceleft->sz,
+        GN_bar->sz,
+        GN_braceright->sz,
+        GN_asciitilde->sz,
+        GN_Adieresis->sz,
+        GN_Aring->sz,
+        GN_Ccedilla->sz,
+        GN_Eacute->sz,
+        GN_Ntilde->sz,
+        GN_Odieresis->sz,
+        GN_Udieresis->sz,
+        GN_aacute->sz,
+        GN_agrave->sz,
+        GN_acircumflex->sz,
+        GN_adieresis->sz,
+        GN_atilde->sz,
+        GN_aring->sz,
+        GN_ccedilla->sz,
+        GN_eacute->sz,
+        GN_egrave->sz,
+        GN_ecircumflex->sz,
+        GN_edieresis->sz,
+        GN_iacute->sz,
+        GN_igrave->sz,
+        GN_icircumflex->sz,
+        GN_idieresis->sz,
+        GN_ntilde->sz,
+        GN_oacute->sz,
+        GN_ograve->sz,
+        GN_ocircumflex->sz,
+        GN_odieresis->sz,
+        GN_otilde->sz,
+        GN_uacute->sz,
+        GN_ugrave->sz,
+        GN_ucircumflex->sz,
+        GN_udieresis->sz,
+        GN_dagger->sz,
+        GN_degree->sz,
+        GN_cent->sz,
+        GN_sterling->sz,
+        GN_section->sz,
+        GN_bullet->sz,
+        GN_paragraph->sz,
+        GN_germandbls->sz,
+        GN_registered->sz,
+        GN_copyright->sz,
+        GN_trademark->sz,
+        GN_acute->sz,
+        GN_dieresis->sz,
+        GN_notequal->sz,
+        GN_AE->sz,
+        GN_Oslash->sz,
+        GN_infinity->sz,
+        GN_plusminus->sz,
+        GN_lessequal->sz,
+        GN_greaterequal->sz,
+        GN_yen->sz,
+        GN_mu->sz,
+        GN_partialdiff->sz,
+        GN_summation->sz,
+        GN_product->sz,
+        GN_pi->sz,
+        GN_integral->sz,
+        GN_ordfeminine->sz,
+        GN_ordmasculine->sz,
+        GN_Omega->sz,
+        GN_ae->sz,
+        GN_oslash->sz,
+        GN_questiondown->sz,
+        GN_exclamdown->sz,
+        GN_logicalnot->sz,
+        GN_radical->sz,
+        GN_florin->sz,
+        GN_approxequal->sz,
+        GN_Delta->sz,
+        GN_guillemotleft->sz,
+        GN_guillemotright->sz,
+        GN_ellipsis->sz,
+        "nonbreakingspace",
+        GN_Agrave->sz,
+        GN_Atilde->sz,
+        GN_Otilde->sz,
+        GN_OE->sz,
+        GN_oe->sz,
+        GN_endash->sz,
+        GN_emdash->sz,
+        GN_quotedblleft->sz,
+        GN_quotedblright->sz,
+        GN_quoteleft->sz,
+        GN_quoteright->sz,
+        GN_divide->sz,
+        GN_lozenge->sz,
+        GN_ydieresis->sz,
+        GN_Ydieresis->sz,
+        GN_fraction->sz,
+        GN_currency->sz,
+        GN_guilsinglleft->sz,
+        GN_guilsinglright->sz,
+        GN_fi->sz,
+        GN_fl->sz,
+        GN_daggerdbl->sz,
+        GN_periodcentered->sz,
+        GN_quotesinglbase->sz,
+        GN_quotedblbase->sz,
+        GN_perthousand->sz,
+        GN_Acircumflex->sz,
+        GN_Ecircumflex->sz,
+        GN_Aacute->sz,
+        GN_Edieresis->sz,
+        GN_Egrave->sz,
+        GN_Iacute->sz,
+        GN_Icircumflex->sz,
+        GN_Idieresis->sz,
+        GN_Igrave->sz,
+        GN_Oacute->sz,
+        GN_Ocircumflex->sz,
+        GN_apple->sz,
+        GN_Ograve->sz,
+        GN_Uacute->sz,
+        GN_Ucircumflex->sz,
+        GN_Ugrave->sz,
+        GN_dotlessi->sz,
+        GN_circumflex->sz,
+        GN_tilde->sz,
+        GN_macron->sz,
+        GN_breve->sz,
+        GN_dotaccent->sz,
+        GN_ring->sz,
+        GN_cedilla->sz,
+        GN_hungarumlaut->sz,
+        GN_ogonek->sz,
+        GN_caron->sz,
+        GN_Lslash->sz,
+        GN_lslash->sz,
+        GN_Scaron->sz,
+        GN_scaron->sz,
+        GN_Zcaron->sz,
+        GN_zcaron->sz,
+        GN_brokenbar->sz,
+        GN_Eth->sz,
+        GN_eth->sz,
+        GN_Yacute->sz,
+        GN_yacute->sz,
+        GN_Thorn->sz,
+        GN_thorn->sz,
+        GN_minus->sz,
+        GN_multiply->sz,
+        GN_onesuperior->sz,
+        GN_twosuperior->sz,
+        GN_threesuperior->sz,
+        GN_onehalf->sz,
+        GN_onequarter->sz,
+        GN_threequarters->sz,
+        GN_franc->sz,
+        GN_Gbreve->sz,
+        GN_gbreve->sz,
+        GN_Idotaccent->sz,
+        GN_Scedilla->sz,
+        GN_scedilla->sz,
+        GN_Cacute->sz,
+        GN_cacute->sz,
+        GN_Ccaron->sz,
+        GN_ccaron->sz,
+        GN_dcroat->sz
+    };
+    strcpy(name, glyph_table[index]);
+}
+
 void get_glyph_name(HDC hdc, WORD index, char *name)
 {
-  /* FIXME */
+    struct
+    {
+        DWORD format;
+        DWORD italicAngle;
+        SHORT underlinePosition;
+        SHORT underlineThickness;
+        DWORD isFixedPitch;
+        DWORD minMemType42;
+        DWORD maxMemType42;
+        DWORD minMemType1;
+        DWORD maxMemType1;
+    } *post_header;
+    BYTE *post = NULL;
+    DWORD size;
+
+    /* set a fallback name that is just 'g<index>' */
     sprintf(name, "g%04x", index);
-    return;
+
+    /* attempt to obtain the glyph name from the 'post' table */
+    size = GetFontData(hdc, MS_MAKE_TAG('p','o','s','t'), 0, NULL, 0);
+    if(size == 0 || size == GDI_ERROR)
+        goto cleanup;
+    post = HeapAlloc(GetProcessHeap(), 0, size);
+    if(!post)
+        goto cleanup;
+    size = GetFontData(hdc, MS_MAKE_TAG('p','o','s','t'), 0, post, size);
+    if(size == 0 || size == GDI_ERROR)
+        goto cleanup;
+    post_header = (typeof(post_header))(post);
+    /* note: only interested in the format for obtaining glyph names */
+    post_header->format = GET_BE_DWORD(&post_header->format);
+
+    /* now that we know the format of the 'post' table we can get the glyph name */
+    if(post_header->format == MAKELONG(0, 1))
+    {
+        if(index < 258)
+            get_standard_glyph_name(index, name);
+        else
+            WARN("Font uses PostScript Format 1, but non-standard glyph (%d) requested.\n", index);
+    }
+    else
+        FIXME("PostScript Format %d.%d glyph names are currently unsupported.\n",
+              HIWORD(post_header->format), LOWORD(post_header->format));
+
+cleanup:
+    HeapFree(GetProcessHeap(), 0, post);
 }
 
 /****************************************************************************
-- 
1.9.1

