/*
 *	PostScript driver Type1 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
 */

#include "config.h"
#include "wine/port.h"

#include <string.h>
#include <stdlib.h>
#include <stdarg.h>
#include <stdio.h>
#include <assert.h>

#include "windef.h"
#include "winbase.h"
#include "wingdi.h"
#include "winternl.h"

#include "psdrv.h"
#include "wine/debug.h"

WINE_DEFAULT_DEBUG_CHANNEL(psdrv);

struct tagTYPE1 {
    DWORD glyph_sent_size;
    BOOL *glyph_sent;
    DWORD emsize;
};

#define GLYPH_SENT_INC 128

/* Type 1 font commands */
enum t1_cmds {
    rlineto = 5,
    rrcurveto = 8,
    closepath = 9,
    hsbw = 13,
    endchar = 14,
    rmoveto = 21
};


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

#ifdef WORDS_BIGENDIAN
static inline WORD  get_be_word(const void *p)  { return *(const WORD*)p; }
static inline DWORD get_be_dword(const void *p) { return *(const DWORD*)p; }
#else
static inline WORD  get_be_word(const void *p)  { return RtlUshortByteSwap(*(const WORD*)p); }
static inline DWORD get_be_dword(const void *p) { return RtlUlongByteSwap(*(const DWORD*)p); }
#endif

TYPE1 *T1_download_header(PHYSDEV dev, char *ps_name, RECT *bbox, UINT emsize)
{
    char *buf;
    TYPE1 *t1;

    static const char dict[] = /* name, emsquare, fontbbox */
      "25 dict begin\n"
      " /FontName /%s 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"
      " /FontBBox [%d %d %d %d] def\n"
      " /FontType 1 def\n"
      " /Private 7 dict begin\n"
      "  /RD {string currentfile exch readhexstring pop} def\n"
      "  /ND {def} def\n"
      "  /NP {put} def\n"
      "  /MinFeature {16 16} def\n"
      "  /BlueValues [] def\n"
      "  /password 5839 def\n"
      "  /lenIV -1 def\n"
      " currentdict end def\n"
      " currentdict dup /Private get begin\n"
      "  /CharStrings 256 dict begin\n"
      "   /.notdef 4 RD 8b8b0d0e ND\n"
      "  currentdict end put\n"
      " end\n"
      "currentdict end dup /FontName get exch definefont pop\n";

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

    sprintf(buf, dict, ps_name, t1->emsize, t1->emsize,
	    bbox->left, bbox->bottom, bbox->right, bbox->top);

    PSDRV_WriteSpool(dev, buf, strlen(buf));

    HeapFree(GetProcessHeap(), 0, buf);
    return t1;
}


typedef struct {
  BYTE *str;
  int len, max_len;
} STR;

static STR *str_init(int sz)
{
  STR *str = HeapAlloc(GetProcessHeap(), 0, sizeof(*str));
  str->max_len = sz;
  str->str = HeapAlloc(GetProcessHeap(), 0, str->max_len);
  str->len = 0;
  return str;
}

static void str_free(STR *str)
{
  HeapFree(GetProcessHeap(), 0, str->str);
  HeapFree(GetProcessHeap(), 0, str);
}

static void str_add_byte(STR *str, BYTE b)
{
    if(str->len == str->max_len) {
        str->max_len *= 2;
	str->str = HeapReAlloc(GetProcessHeap(), 0, str->str, str->max_len);
    }
    str->str[str->len++] = b;
}

static void str_add_num(STR *str, int num)
{
    if(num <= 107 && num >= -107)
        str_add_byte(str, num + 139);
    else if(num >= 108 && num <= 1131) {
        str_add_byte(str, ((num - 108) >> 8) + 247);
	str_add_byte(str, (num - 108) & 0xff);
    } else if(num <= -108 && num >= -1131) {
        num = -num;
	str_add_byte(str, ((num - 108) >> 8) + 251);
	str_add_byte(str, (num - 108) & 0xff);
    } else {
        str_add_byte(str, 0xff);
	str_add_byte(str, (num >> 24) & 0xff);
	str_add_byte(str, (num >> 16) & 0xff);
	str_add_byte(str, (num >> 8) & 0xff);
	str_add_byte(str, (num & 0xff));
    }
}

static void str_add_point(STR *str, POINT pt, POINT *curpos)
{
    str_add_num(str, pt.x - curpos->x);
    str_add_num(str, pt.y - curpos->y);
    *curpos = pt;
}

static void str_add_cmd(STR *str, enum t1_cmds cmd)
{
    str_add_byte(str, (BYTE)cmd);
}

static int str_get_bytes(STR *str, BYTE **b)
{
  *b = str->str;
  return str->len;
}

static BOOL get_hmetrics(HDC hdc, DWORD index, short *lsb, WORD *advance)
{
    BYTE hhea[36];
    WORD num_of_long;
    BYTE buf[4];

    *lsb = 0;
    *advance = 0;

    GetFontData(hdc, MS_MAKE_TAG('h','h','e','a'), 0, hhea, sizeof(hhea));
    num_of_long = get_be_word(hhea + 34);

    if(index < num_of_long)
    {
        if(GetFontData(hdc, MS_MAKE_TAG('h','m','t','x'), index * 4, buf, 4) != 4) return FALSE;
        *advance = get_be_word(buf);
        *lsb = (signed short)get_be_word(buf + 2);
    }
    else
    {
        if(GetFontData(hdc, MS_MAKE_TAG('h','m','t','x'), (num_of_long - 1) * 4, buf, 2) != 2) return FALSE;
        *advance = get_be_word(buf);
        if(GetFontData(hdc, MS_MAKE_TAG('h','m','t','x'), num_of_long * 4 + (index - num_of_long) * 2, buf, 2) != 2) return FALSE;
        *lsb = (signed short)get_be_word(buf);
    }

    return TRUE;
}

static BOOL get_glyf_pos(HDC hdc, DWORD index, DWORD *start, DWORD *end)
{
    DWORD len;
    BYTE *head, *loca;
    WORD loca_format;
    BOOL ret = FALSE;

    *start = *end = 0;

    len = GetFontData(hdc, MS_MAKE_TAG('h','e','a','d'), 0, NULL, 0);
    if (len == GDI_ERROR) return FALSE;
    head = HeapAlloc(GetProcessHeap(), 0, len);
    GetFontData(hdc, MS_MAKE_TAG('h','e','a','d'), 0, head, len);
    loca_format = get_be_word(head + 50);

    len = GetFontData(hdc, MS_MAKE_TAG('l','o','c','a'), 0, NULL, 0);
    if (len == GDI_ERROR)
    {
        len = GetFontData(hdc, MS_MAKE_TAG('C','F','F',' '), 0, NULL, 0);
        if (len != GDI_ERROR) FIXME( "CFF tables not supported yet\n" );
        else ERR( "loca table not found\n" );
        HeapFree(GetProcessHeap(), 0, head);
        return FALSE;
    }
    loca = HeapAlloc(GetProcessHeap(), 0, len);
    GetFontData(hdc, MS_MAKE_TAG('l','o','c','a'), 0, loca, len);

    switch(loca_format) {
    case 0:
        *start = get_be_word(((WORD*)loca) + index);
        *start <<= 1;
        *end = get_be_word(((WORD*)loca) + index + 1);
        *end <<= 1;
        ret = TRUE;
        break;
    case 1:
        *start = get_be_dword(((DWORD*)loca) + index);
        *end = get_be_dword(((DWORD*)loca) + index + 1);
        ret = TRUE;
        break;
    default:
        ERR("Unknown loca_format %d\n", loca_format);
    }

    HeapFree(GetProcessHeap(), 0, loca);
    HeapFree(GetProcessHeap(), 0, head);
    return ret;
}


static BYTE *get_glyph_data(HDC hdc, DWORD index)
{
    DWORD start, end, len;
    BYTE *data;

    if(!get_glyf_pos(hdc, index, &start, &end))
        return NULL;

    len = end - start;
    if(!len) return NULL;

    data = HeapAlloc(GetProcessHeap(), 0, len);
    if(!data) return NULL;

    if(GetFontData(hdc, MS_MAKE_TAG('g','l','y','f'), start, data, len) != len)
    {
        HeapFree(GetProcessHeap(), 0, data);
        return NULL;
    }
    return data;
}

typedef struct
{
    WORD num_conts;
    WORD *end_pts; /* size_is(num_conts) */
    BYTE *flags;   /* size_is(end_pts[num_conts - 1] + 1) */
    POINT *pts;    /* size_is(end_pts[num_conts - 1] + 1) */
    short lsb;
    WORD advance;
} glyph_outline;

static inline WORD pts_in_outline(glyph_outline *outline)
{
    WORD num_pts = 0;

    if(outline->num_conts)
        num_pts = outline->end_pts[outline->num_conts - 1] + 1;

    return num_pts;
}

static BOOL append_glyph_outline(HDC hdc, DWORD index, glyph_outline *outline);

static BOOL append_simple_glyph(BYTE *data, glyph_outline *outline)
{
    USHORT num_pts, start_pt = 0, ins_len;
    WORD *end_pts;
    int num_conts, start_cont, i;
    BYTE *ptr;
    int x, y;

    start_cont = outline->num_conts;
    start_pt = pts_in_outline(outline);

    num_conts = get_be_word(data);

    end_pts = (WORD*)(data + 10);
    num_pts = get_be_word(end_pts + num_conts - 1) + 1;

    ins_len = get_be_word(end_pts + num_conts);

    ptr = (BYTE*)(end_pts + num_conts) + 2 + ins_len;

    if(outline->num_conts)
    {
        outline->end_pts = HeapReAlloc(GetProcessHeap(), 0, outline->end_pts, (start_cont + num_conts) * sizeof(*outline->end_pts));
        outline->flags   = HeapReAlloc(GetProcessHeap(), 0, outline->flags, start_pt + num_pts);
        outline->pts     = HeapReAlloc(GetProcessHeap(), 0, outline->pts,  (start_pt + num_pts) * sizeof(*outline->pts));
    }
    else
    {
        outline->end_pts = HeapAlloc(GetProcessHeap(), 0, num_conts * sizeof(*outline->end_pts));
        outline->flags   = HeapAlloc(GetProcessHeap(), 0, num_pts);
        outline->pts     = HeapAlloc(GetProcessHeap(), 0, num_pts * sizeof(*outline->pts));
    }

    outline->num_conts += num_conts;

    for(i = 0; i < num_conts; i++)
        outline->end_pts[start_cont + i] = start_pt + get_be_word(end_pts + i);

    for(i = 0; i < num_pts; i++)
    {
        outline->flags[start_pt + i] = *ptr;
        if(*ptr & 8)
        {
            BYTE count = *++ptr;
            while(count)
            {
                i++;
                outline->flags[start_pt + i] = *(ptr - 1);
                count--;
            }
        }
        ptr++;
    }

    x = 0;

    for(i = 0; i < num_pts; i++)
    {
        INT delta;

        delta = 0;
        if(outline->flags[start_pt + i] & 2)
        {
            delta = *ptr++;
            if((outline->flags[start_pt + i] & 0x10) == 0)
                delta = -delta;
        }
        else if((outline->flags[start_pt + i] & 0x10) == 0)
        {
            delta = (signed short)get_be_word(ptr);
            ptr += 2;
        }
        x += delta;
        outline->pts[start_pt + i].x = x;
    }

    y = 0;
    for(i = 0; i < num_pts; i++)
    {
        INT delta;

        delta = 0;
        if(outline->flags[start_pt + i] & 4)
        {
            delta = *ptr++;
            if((outline->flags[start_pt + i] & 0x20) == 0)
                delta = -delta;
        }
        else if((outline->flags[start_pt + i] & 0x20) == 0)
        {
            delta = (signed short)get_be_word(ptr);
            ptr += 2;
        }
        y += delta;
        outline->pts[start_pt + i].y = y;
    }
    return TRUE;
}

/* Some flags for composite glyphs.  See glyf table in OT spec */
#define ARG_1_AND_2_ARE_WORDS    (1L << 0)
#define ARGS_ARE_XY_VALUES       (1L << 1)
#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)
#define USE_MY_METRICS           (1L << 9)

static BOOL append_complex_glyph(HDC hdc, const BYTE *data, glyph_outline *outline)
{
    const BYTE *ptr = data;
    WORD flags, index;
    short arg1, arg2;
    FLOAT scale_xx = 1, scale_xy = 0, scale_yx = 0, scale_yy = 1;
    WORD start_pt, end_pt;

    ptr += 10;
    do
    {
        flags = get_be_word(ptr);
        ptr += 2;
        index = get_be_word(ptr);
        ptr += 2;
        if(flags & ARG_1_AND_2_ARE_WORDS)
        {
            arg1 = (short)get_be_word(ptr);
            ptr += 2;
            arg2 = (short)get_be_word(ptr);
            ptr += 2;
        }
        else
        {
            arg1 = *(const char*)ptr++;
            arg2 = *(const char*)ptr++;
        }
        if(flags & WE_HAVE_A_SCALE)
        {
            scale_xx = scale_yy = (FLOAT)(short)get_be_word(ptr) / 0x4000;
            ptr += 2;
        }
        else if(flags & WE_HAVE_AN_X_AND_Y_SCALE)
        {
            scale_xx = (FLOAT)(short)get_be_word(ptr) / 0x4000;
            ptr += 2;
            scale_yy = (FLOAT)(short)get_be_word(ptr) / 0x4000;
            ptr += 2;
        }
        else if(flags & WE_HAVE_A_TWO_BY_TWO)
        {
            scale_xx = (FLOAT)(short)get_be_word(ptr) / 0x4000;
            ptr += 2;
            scale_xy = (FLOAT)(short)get_be_word(ptr) / 0x4000;
            ptr += 2;
            scale_yx = (FLOAT)(short)get_be_word(ptr) / 0x4000;
            ptr += 2;
            scale_yy = (FLOAT)(short)get_be_word(ptr) / 0x4000;
            ptr += 2;
        }

        start_pt = pts_in_outline(outline);
        append_glyph_outline(hdc, index, outline);
        end_pt = pts_in_outline(outline);

        if (flags & (WE_HAVE_A_SCALE | WE_HAVE_AN_X_AND_Y_SCALE | WE_HAVE_A_TWO_BY_TWO))
        {
            WORD i;
            TRACE("transform %f,%f,%f,%f of glyph %x\n", scale_xx, scale_xy, scale_yx, scale_yy, index);
            for (i = start_pt; i < end_pt; i++)
            {
                LONG x = outline->pts[i].x, y = outline->pts[i].y;
                outline->pts[i].x = x * scale_xx + y * scale_yx;
                outline->pts[i].y = x * scale_xy + y * scale_yy;
            }
        }

        if((flags & ARGS_ARE_XY_VALUES) == 0)
        {
            WORD orig_pt = arg1, new_pt = arg2;
            new_pt += start_pt;

            if(orig_pt >= start_pt || new_pt >= end_pt) return FALSE;

            arg1 = outline->pts[orig_pt].x - outline->pts[new_pt].x;
            arg2 = outline->pts[orig_pt].y - outline->pts[new_pt].y;
        }
        while(start_pt < end_pt)
        {
            outline->pts[start_pt].x += arg1;
            outline->pts[start_pt].y += arg2;
            start_pt++;
        }

        if(flags & USE_MY_METRICS)
            get_hmetrics(hdc, index, &outline->lsb, &outline->advance);

    } while(flags & MORE_COMPONENTS);
    return TRUE;
}

static BOOL append_glyph_outline(HDC hdc, DWORD index, glyph_outline *outline)
{
    BYTE *glyph_data;
    SHORT num_conts;

    glyph_data = get_glyph_data(hdc, index);
    if(!glyph_data) return TRUE;

    num_conts = get_be_word(glyph_data);

    if(num_conts == -1)
        append_complex_glyph(hdc, glyph_data, outline);
    else if(num_conts > 0)
        append_simple_glyph(glyph_data, outline);

    HeapFree(GetProcessHeap(), 0, glyph_data);
    return TRUE;
}

static inline BOOL on_point(const glyph_outline *outline, WORD pt)
{
    return outline->flags[pt] & 1;
}

BOOL T1_download_glyph(PHYSDEV dev, DOWNLOAD *pdl, DWORD index, char *glyph_name)
{
    DWORD len;
    WORD cur_pt, cont;
    char *buf;
    TYPE1 *t1;
    STR *charstring;
    BYTE *bytes;
    POINT curpos;
    glyph_outline outline;

    static const char glyph_def_begin[] =
      "/%s findfont dup\n"
      "/Private get begin\n"
      "/CharStrings get begin\n"
      "/%s %d RD\n";
    static const char glyph_def_end[] =
      "ND\n"
      "end end\n";

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

    outline.num_conts = 0;
    outline.flags = NULL;
    outline.end_pts = NULL;
    outline.pts = NULL;
    get_hmetrics(dev->hdc, index, &outline.lsb, &outline.advance);

    if(!append_glyph_outline(dev->hdc, index, &outline)) return FALSE;

    charstring = str_init(100);
    curpos.x = outline.lsb;
    curpos.y = 0;

    str_add_num(charstring, curpos.x);
    str_add_num(charstring, outline.advance);
    str_add_cmd(charstring, hsbw);

    for(cur_pt = 0, cont = 0; cont < outline.num_conts; cont++)
    {
        POINT start_pos = outline.pts[cur_pt++];
        WORD end_pt = outline.end_pts[cont];
        POINT curve_pts[3] = {{0,0},{0,0},{0,0}};

	str_add_point(charstring, start_pos, &curpos);
	str_add_cmd(charstring, rmoveto);

        for(; cur_pt <= end_pt; cur_pt++)
        {
            if(on_point(&outline, cur_pt))
            {
                str_add_point(charstring, outline.pts[cur_pt], &curpos);
                str_add_cmd(charstring, rlineto);
            }
            else
            {
                BOOL added_next = FALSE;

                /* temporarily store the start pt in curve_pts[0] */
                if(on_point(&outline, cur_pt - 1))
                    curve_pts[0] = outline.pts[cur_pt - 1];
                else /* last pt was off curve too, so the previous curve's
                        end pt was constructed */
                    curve_pts[0] = curve_pts[2];

                if(cur_pt != end_pt)
                {
                    if(on_point(&outline, cur_pt + 1))
                    {
                        curve_pts[2] = outline.pts[cur_pt + 1];
                        added_next = TRUE;
                    }
                    else /* next pt is off curve too, so construct the end pt from the
                            average of the two */
                    {
                        curve_pts[2].x = (outline.pts[cur_pt].x + outline.pts[cur_pt + 1].x + 1) / 2;
                        curve_pts[2].y = (outline.pts[cur_pt].y + outline.pts[cur_pt + 1].y + 1) / 2;
                    }
                }
                else /* last pt of the contour is off curve, so the end pt is the
                        start pt of the contour */
                    curve_pts[2] = start_pos;

                curve_pts[0].x = (curve_pts[0].x + 2 * outline.pts[cur_pt].x + 1) / 3;
                curve_pts[0].y = (curve_pts[0].y + 2 * outline.pts[cur_pt].y + 1) / 3;

                curve_pts[1].x = (curve_pts[2].x + 2 * outline.pts[cur_pt].x + 1) / 3;
                curve_pts[1].y = (curve_pts[2].y + 2 * outline.pts[cur_pt].y + 1) / 3;

                str_add_point(charstring, curve_pts[0], &curpos);
                str_add_point(charstring, curve_pts[1], &curpos);
                str_add_point(charstring, curve_pts[2], &curpos);
                str_add_cmd(charstring, rrcurveto);
                if(added_next) cur_pt++;
            }
        }
        str_add_cmd(charstring, closepath);
    }
    str_add_cmd(charstring, endchar);

    HeapFree(GetProcessHeap(), 0, outline.pts);
    HeapFree(GetProcessHeap(), 0, outline.end_pts);
    HeapFree(GetProcessHeap(), 0, outline.flags);

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

    sprintf(buf, "%%%%glyph %04x\n", index);
    PSDRV_WriteSpool(dev, buf, strlen(buf));

    len = str_get_bytes(charstring, &bytes);
    sprintf(buf, glyph_def_begin, pdl->ps_name, glyph_name, len);
    PSDRV_WriteSpool(dev, buf, strlen(buf));
    PSDRV_WriteBytes(dev, bytes, len);
    sprintf(buf, glyph_def_end);
    PSDRV_WriteSpool(dev, buf, strlen(buf));
    str_free(charstring);

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

void T1_free(TYPE1 *t1)
{
    HeapFree(GetProcessHeap(), 0, t1->glyph_sent);
    HeapFree(GetProcessHeap(), 0, t1);
    return;
}
