/*
 *	PostScript driver Type42 font functions
 *
 *	Copyright 2002  Huw D M Davies for CodeWeavers
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <assert.h>
#include "winspool.h"
#include "psdrv.h"
#include "wine/debug.h"
#include "winerror.h"
#include "config.h"
#include "wine/port.h"

WINE_DEFAULT_DEBUG_CHANNEL(psdrv);


#define GET_BE_WORD(ptr)  MAKEWORD( ((BYTE *)(ptr))[1], ((BYTE *)(ptr))[0] )
#define GET_BE_DWORD(ptr) ((DWORD)MAKELONG( GET_BE_WORD(&((WORD *)(ptr))[1]), \
                                            GET_BE_WORD(&((WORD *)(ptr))[0]) ))

#define MS_MAKE_TAG( _x1, _x2, _x3, _x4 ) \
          ( ( (DWORD)_x4 << 24 ) |     \
            ( (DWORD)_x3 << 16 ) |     \
            ( (DWORD)_x2 <<  8 ) |     \
              (DWORD)_x1         )

typedef struct {
  DWORD MS_tag;
  DWORD len, check;
  BYTE *data;
  BOOL write;
} OTTable;

const OTTable tables_templ[] = {
      { MS_MAKE_TAG('c','v','t',' '), 0, 0, NULL, TRUE },
      { MS_MAKE_TAG('f','p','g','m'), 0, 0, NULL, TRUE },
      { MS_MAKE_TAG('g','d','i','r'), 0, 0, NULL, TRUE },
      { MS_MAKE_TAG('g','l','y','f'), 0, 0, NULL, FALSE },
      { MS_MAKE_TAG('h','e','a','d'), 0, 0, NULL, TRUE },
      { MS_MAKE_TAG('h','h','e','a'), 0, 0, NULL, TRUE },
      { MS_MAKE_TAG('h','m','t','x'), 0, 0, NULL, FALSE },
      { MS_MAKE_TAG('l','o','c','a'), 0, 0, NULL, FALSE },
      { MS_MAKE_TAG('m','a','x','p'), 0, 0, NULL, TRUE },
      { MS_MAKE_TAG('p','r','e','p'), 0, 0, NULL, TRUE },
      { 0, 0, 0, NULL, 0 }
};

struct tagTYPE42 {
    OTTable tables[sizeof(tables_templ)/sizeof(tables_templ[0])];
    int glyf_tab, loca_tab, head_tab; /* indices of glyf, loca and head tables */
    int hmtx_tab;
    DWORD glyph_sent_size;
    BOOL *glyph_sent;
    DWORD emsize;
};

#define GLYPH_SENT_INC 128

#define FLIP_ORDER(x) \
 ( ( ((x) & 0xff) << 24) | \
   ( ((x) & 0xff00) << 8) | \
   ( ((x) & 0xff0000) >> 8) | \
   ( ((x) & 0xff000000) >> 24) )


/* Some flags for composite glyphs.  See glyf table in OT spec */
#define ARG_1_AND_2_ARE_WORDS    (1L << 0)
#define WE_HAVE_A_SCALE          (1L << 3)
#define MORE_COMPONENTS          (1L << 5)
#define WE_HAVE_AN_X_AND_Y_SCALE (1L << 6)
#define WE_HAVE_A_TWO_BY_TWO     (1L << 7)

static BOOL LoadTable(HDC hdc, OTTable *table)
{
    int i;

    if(table->MS_tag == MS_MAKE_TAG('g','d','i','r')) return TRUE;
    table->len = GetFontData(hdc, table->MS_tag, 0, NULL, 0);
    table->data = HeapAlloc(GetProcessHeap(), 0, (table->len + 3) & ~3 );
    memset(table->data + ((table->len - 1) & ~3), 0, sizeof(DWORD));
    GetFontData(hdc, table->MS_tag, 0, table->data, table->len);
    table->check = 0;
    for(i = 0; i < (table->len + 3) / 4; i++)
        table->check += FLIP_ORDER(*((DWORD*)(table->data) + i));
    return TRUE;
}


TYPE42 *T42_download_header(PSDRV_PDEVICE *physDev, LPOUTLINETEXTMETRICA potm,
			    char *ps_name)
{
    DWORD i, j, tablepos;
    WORD num_of_tables = sizeof(tables_templ) / sizeof(tables_templ[0]) - 1;
    WORD num_of_write_tables = 0;
    char *buf;
    TYPE42 *t42;
    char start[] = /* name, fontbbox */
            "25 dict begin\n"
	    " /FontName /%s def\n"
	    " /Encoding 256 array 0 1 255{1 index exch /.notdef put} for\n"
	    " def\n"
	    " /PaintType 0 def\n"
	    " /FontMatrix [1 0 0 1 0 0] def\n"
	    " /FontBBox [%f %f %f %f] def\n"
	    " /FontType 42 def\n"
	    " /CharStrings 256 dict begin\n"
	    "  /.notdef 0 def\n"
            " currentdict end def\n"
	    " /GlyphDirectory 256 dict def\n"
            " /Metrics 256 dict def\n"
	    " /sfnts [\n";
    char TT_offset_table[] = "<00010000%04x%04x%04x%04x\n";
    char TT_table_dir_entry[] = "%08lx%08lx%08lx%08lx\n";
    char end[] = "] def\n"
      "currentdict end dup /FontName get exch definefont pop\n";


    t42 = HeapAlloc(GetProcessHeap(), 0, sizeof(*t42));
    memcpy(t42->tables, tables_templ, sizeof(tables_templ));
    t42->loca_tab = t42->glyf_tab = t42->head_tab = t42->hmtx_tab = -1;
    t42->glyph_sent_size = GLYPH_SENT_INC;
    t42->glyph_sent = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
				t42->glyph_sent_size *
				sizeof(*(t42->glyph_sent)));
    t42->emsize = potm->otmEMSquare;

    for(i = 0; i < num_of_tables; i++) {
        LoadTable(physDev->hdc, t42->tables + i);
	if(t42->tables[i].write) num_of_write_tables++;
	if(t42->tables[i].MS_tag == MS_MAKE_TAG('l','o','c','a'))
	    t42->loca_tab = i;
	else if(t42->tables[i].MS_tag == MS_MAKE_TAG('g','l','y','f'))
	    t42->glyf_tab = i;
	else if(t42->tables[i].MS_tag == MS_MAKE_TAG('h','e','a','d'))
	    t42->head_tab = i;
	else if(t42->tables[i].MS_tag == MS_MAKE_TAG('h','m','t','x'))
	    t42->hmtx_tab = i;
    }

    buf = HeapAlloc(GetProcessHeap(), 0, sizeof(start) + strlen(ps_name) +
		    100);

    sprintf(buf, start, ps_name,
	    (float)potm->otmrcFontBox.left / potm->otmEMSquare,
	    (float)potm->otmrcFontBox.bottom / potm->otmEMSquare,
	    (float)potm->otmrcFontBox.right / potm->otmEMSquare,
	    (float)potm->otmrcFontBox.top / potm->otmEMSquare);

    PSDRV_WriteSpool(physDev, buf, strlen(buf));

    sprintf(buf, TT_offset_table, num_of_write_tables,
	    num_of_write_tables, num_of_write_tables, num_of_write_tables);

    PSDRV_WriteSpool(physDev, buf, strlen(buf));

    tablepos = 12 + num_of_write_tables * 16;
    for(i = 0; i < num_of_tables; i++) {
        if(!t42->tables[i].write) continue;
        sprintf(buf, TT_table_dir_entry, FLIP_ORDER(t42->tables[i].MS_tag),
		t42->tables[i].check, t42->tables[i].len ? tablepos : 0,
		t42->tables[i].len);
	PSDRV_WriteSpool(physDev, buf, strlen(buf));
	tablepos += ((t42->tables[i].len + 3) & ~3);
    }
    PSDRV_WriteSpool(physDev, ">\n", 2);

    for(i = 0; i < num_of_tables; i++) {
        if(t42->tables[i].len == 0 || !t42->tables[i].write) continue;
	PSDRV_WriteSpool(physDev, "<", 1);
	for(j = 0; j < ((t42->tables[i].len + 3) & ~3); j++) {
	    sprintf(buf, "%02x", t42->tables[i].data[j]);
	    PSDRV_WriteSpool(physDev, buf, strlen(buf));
	    if(j % 16 == 15) PSDRV_WriteSpool(physDev, "\n", 1);
	}
	PSDRV_WriteSpool(physDev, ">\n", 2);
    }

    PSDRV_WriteSpool(physDev, end, sizeof(end) - 1);
    HeapFree(GetProcessHeap(), 0, buf);
    return t42;
}




BOOL T42_download_glyph(PSDRV_PDEVICE *physDev, DOWNLOAD *pdl, DWORD index,
			char *glyph_name)
{
    DWORD start, end, i;
    char *buf;
    TYPE42 *t42;
    WORD loca_format;
    WORD awidth;
    short lsb;
    char glyph_def[] =
      "/%s findfont exch 1 index /GlyphDirectory get\n"
      "begin\n"
      " %d exch def\n"
      "end\n"
      "dup /CharStrings get\n"
      "begin\n"
      " /%s %d def\n"
      "end\n"
      "/Metrics get\n"
      "begin\n"
      " /%s [%f %f] def\n"
      "end\n";


    TRACE("%ld %s\n", index, glyph_name);
    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)));
    }

    buf = HeapAlloc(GetProcessHeap(), 0, sizeof(glyph_def) +
		    strlen(pdl->ps_name) + 100);

    loca_format = GET_BE_WORD(t42->tables[t42->head_tab].data + 50);
    TRACE("loca_format = %d\n", loca_format);
    switch(loca_format) {
    case 0:
        start = GET_BE_WORD(((WORD*)t42->tables[t42->loca_tab].data) + index);
	start <<= 1;
	end = GET_BE_WORD(((WORD*)t42->tables[t42->loca_tab].data) + index + 1);
	end <<= 1;
	break;
    case 1:
        start = GET_BE_DWORD(((DWORD*)t42->tables[t42->loca_tab].data) + index);
	end = GET_BE_DWORD(((DWORD*)t42->tables[t42->loca_tab].data) + index + 1);
	break;
    default:
        ERR("Unknown loca_format %d\n", loca_format);
	return FALSE;
    }
    TRACE("start = %lx end = %lx\n", start, end);

    awidth = GET_BE_WORD(t42->tables[t42->hmtx_tab].data + index * 4);
    lsb = GET_BE_WORD(t42->tables[t42->hmtx_tab].data + index * 4 + 2);

    if(GET_BE_WORD(t42->tables[t42->glyf_tab].data + start) == 0xffff) {
      /* Composite glyph */
        char *sg_start = t42->tables[t42->glyf_tab].data + start + 10;
	DWORD sg_flags, sg_index;
	char sg_name[MAX_G_NAME + 1];

	do {
	    sg_flags = GET_BE_WORD(sg_start);
	    sg_index = GET_BE_WORD(sg_start + 2);

	    TRACE("Sending subglyph %04lx for glyph %04lx\n", sg_index, index);
	    get_glyph_name(physDev->hdc, sg_index, sg_name);
	    T42_download_glyph(physDev, pdl, sg_index, sg_name);
	    sg_start += 4;
	    if(sg_flags & ARG_1_AND_2_ARE_WORDS)
	        sg_start += 4;
	    else
	        sg_start += 2;
	    if(sg_flags & WE_HAVE_A_SCALE)
	        sg_start += 2;
	    else if(sg_flags & WE_HAVE_AN_X_AND_Y_SCALE)
	        sg_start += 4;
	    else if(sg_flags & WE_HAVE_A_TWO_BY_TWO)
	        sg_start += 8;
	} while(sg_flags & MORE_COMPONENTS);
    }

    sprintf(buf, "%%%%glyph %04lx\n", index);
    PSDRV_WriteSpool(physDev, buf, strlen(buf));
    PSDRV_WriteSpool(physDev, "<", 1);
    for(i = start; i < end; i++) {
        sprintf(buf, "%02x", *(t42->tables[t42->glyf_tab].data + i));
	PSDRV_WriteSpool(physDev, buf, strlen(buf));
	if((i - start) % 16 == 15)
	    PSDRV_WriteSpool(physDev, "\n", 1);
    }
    PSDRV_WriteSpool(physDev, ">\n", 2);
    sprintf(buf, glyph_def, pdl->ps_name, index, glyph_name, index,
	    glyph_name, (float)lsb / t42->emsize, (float)awidth / t42->emsize);
    PSDRV_WriteSpool(physDev, buf, strlen(buf));

    t42->glyph_sent[index] = TRUE;
    HeapFree(GetProcessHeap(), 0, buf);
    return TRUE;
}

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);
    return;
}
