/*
 *	PostScript driver text functions
 *
 *	Copyright 1998  Huw D M Davies
 *
 * 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 <stdarg.h>
#include <stdlib.h>
#include <math.h>

#include "windef.h"
#include "winbase.h"
#include "wingdi.h"
#include "psdrv.h"
#include "winspool.h"
#include "wine/debug.h"

WINE_DEFAULT_DEBUG_CHANNEL(psdrv);

static BOOL PSDRV_Text(PSDRV_PDEVICE *physDev, INT x, INT y, UINT flags,
		       LPCWSTR str, UINT count,
		       BOOL bDrawBackground, const INT *lpDx);

/***********************************************************************
 *           PSDRV_ExtTextOut
 */
BOOL PSDRV_ExtTextOut( PSDRV_PDEVICE *physDev, INT x, INT y, UINT flags,
		       const RECT *lprect, LPCWSTR str, UINT count,
		       const INT *lpDx, INT breakExtra )
{
    BOOL bResult = TRUE;
    BOOL bClipped = FALSE;
    BOOL bOpaque = FALSE;
    RECT rect;

    TRACE("(x=%d, y=%d, flags=0x%08x, str=%s, count=%d, lpDx=%p)\n", x, y,
	  flags, debugstr_wn(str, count), count, lpDx);

    /* write font if not already written */
    PSDRV_SetFont(physDev);

    PSDRV_SetClip(physDev);

    /* set clipping and/or draw background */
    if ((flags & (ETO_CLIPPED | ETO_OPAQUE)) && (lprect != NULL))
    {
        rect = *lprect;
        LPtoDP( physDev->hdc, (POINT *)&rect, 2 );
	PSDRV_WriteGSave(physDev);
	PSDRV_WriteRectangle(physDev, rect.left, rect.top, rect.right - rect.left,
			     rect.bottom - rect.top);

	if (flags & ETO_OPAQUE)
	{
	    bOpaque = TRUE;
	    PSDRV_WriteGSave(physDev);
	    PSDRV_WriteSetColor(physDev, &physDev->bkColor);
	    PSDRV_WriteFill(physDev);
	    PSDRV_WriteGRestore(physDev);
	}

	if (flags & ETO_CLIPPED)
	{
	    bClipped = TRUE;
	    PSDRV_WriteClip(physDev);
	}

	bResult = PSDRV_Text(physDev, x, y, flags, str, count, !(bClipped && bOpaque), lpDx);
	PSDRV_WriteGRestore(physDev);
    }
    else
    {
	bResult = PSDRV_Text(physDev, x, y, flags, str, count, TRUE, lpDx);
    }

    PSDRV_ResetClip(physDev);
    return bResult;
}

/***********************************************************************
 *           PSDRV_Text
 */
static BOOL PSDRV_Text(PSDRV_PDEVICE *physDev, INT x, INT y, UINT flags, LPCWSTR str,
		       UINT count, BOOL bDrawBackground, const INT *lpDx)
{
    SIZE sz;
    TEXTMETRICW tm;
    POINT pt;
    INT ascent, descent;
    WORD *glyphs = NULL;
    UINT align = GetTextAlign( physDev->hdc );
    INT char_extra;
    INT *deltas = NULL;
    double cosEsc, sinEsc;
    LOGFONTW lf;

    if (!count)
	return TRUE;

    GetObjectW(GetCurrentObject(physDev->hdc, OBJ_FONT), sizeof(lf), &lf);
    if(lf.lfEscapement != 0) {
        cosEsc = cos(lf.lfEscapement * M_PI / 1800);
        sinEsc = sin(lf.lfEscapement * M_PI / 1800);
    } else {
        cosEsc = 1;
        sinEsc = 0;
    }

    if(physDev->font.fontloc == Download) {
        if(flags & ETO_GLYPH_INDEX)
	    glyphs = (LPWORD)str;
	else {
	    glyphs = HeapAlloc(GetProcessHeap(), 0, count * sizeof(WORD));
	    GetGlyphIndicesW(physDev->hdc, str, count, glyphs, 0);
	}
    }

    pt.x = x;
    pt.y = y;
    if(align & TA_UPDATECP) GetCurrentPositionEx( physDev->hdc, &pt );
    LPtoDP(physDev->hdc, &pt, 1);
    x = pt.x;
    y = pt.y;

    if(physDev->font.fontloc == Download)
        GetTextExtentPointI(physDev->hdc, glyphs, count, &sz);
    else
        GetTextExtentPoint32W(physDev->hdc, str, count, &sz);

    if((char_extra = GetTextCharacterExtra(physDev->hdc)) != 0) {
        INT i;
	SIZE tmpsz;

        deltas = HeapAlloc(GetProcessHeap(), 0, count * sizeof(INT));
	for(i = 0; i < count; i++) {
	    if(lpDx)
	        deltas[i] = lpDx[i] + char_extra;
	    else {
	        if(physDev->font.fontloc == Download)
		    GetTextExtentPointI(physDev->hdc, glyphs + i, 1, &tmpsz);
		else
		    GetTextExtentPoint32W(physDev->hdc, str + i, 1, &tmpsz);
	        deltas[i] = tmpsz.cx;
	    }
	}
    } else if(lpDx)
        deltas = (INT*)lpDx;

    if(deltas) {
        SIZE tmpsz;
	INT i;
	/* Get the width of the last char and add on all the offsets */
	if(physDev->font.fontloc == Download)
	    GetTextExtentPointI(physDev->hdc, glyphs + count - 1, 1, &tmpsz);
	else
	    GetTextExtentPoint32W(physDev->hdc, str + count - 1, 1, &tmpsz);
	for(i = 0; i < count-1; i++)
	    tmpsz.cx += deltas[i];
	sz.cx = tmpsz.cx; /* sz.cy remains untouched */
    }

    sz.cx = PSDRV_XWStoDS(physDev, sz.cx);
    sz.cy = PSDRV_YWStoDS(physDev, sz.cy);

    GetTextMetricsW(physDev->hdc, &tm);
    ascent = abs(PSDRV_YWStoDS(physDev, tm.tmAscent));
    descent = abs(PSDRV_YWStoDS(physDev, tm.tmDescent));

    TRACE("textAlign = %x\n", align);
    switch(align & (TA_LEFT | TA_CENTER | TA_RIGHT) ) {
    case TA_LEFT:
        if(align & TA_UPDATECP)
        {
            POINT pt;
            pt.x = x + sz.cx * cosEsc;
            pt.y = y - sz.cx * sinEsc;
            DPtoLP( physDev->hdc, &pt, 1 );
            MoveToEx( physDev->hdc, pt.x, pt.y, NULL );
	}
	break;

    case TA_CENTER:
        x -= sz.cx * cosEsc / 2;
        y += sz.cx * sinEsc / 2;
	break;

    case TA_RIGHT:
        x -= sz.cx * cosEsc;
        y += sz.cx * sinEsc;
	if(align & TA_UPDATECP)
        {
            POINT pt;
            pt.x = x;
            pt.y = y;
            DPtoLP( physDev->hdc, &pt, 1 );
            MoveToEx( physDev->hdc, pt.x, pt.y, NULL );
	}
	break;
    }

    switch(align & (TA_TOP | TA_BASELINE | TA_BOTTOM) ) {
    case TA_TOP:
        y += ascent * cosEsc;
        x += ascent * sinEsc;
	break;

    case TA_BASELINE:
	break;

    case TA_BOTTOM:
        y -= descent * cosEsc;
        x -= descent * sinEsc;
	break;
    }

    if ((GetBkMode( physDev->hdc ) != TRANSPARENT) && bDrawBackground)
    {
	PSDRV_WriteGSave(physDev);
	PSDRV_WriteNewPath(physDev);
	PSDRV_WriteRectangle(physDev, x, y - ascent, sz.cx,
			     ascent + descent);
	PSDRV_WriteSetColor(physDev, &physDev->bkColor);
	PSDRV_WriteFill(physDev);
	PSDRV_WriteGRestore(physDev);
    }

    PSDRV_WriteMoveTo(physDev, x, y);

    if(!deltas) {
        if(physDev->font.fontloc == Download)
	    PSDRV_WriteDownloadGlyphShow(physDev, glyphs, count);
	else
	    PSDRV_WriteBuiltinGlyphShow(physDev, str, count);
    }
    else {
        INT i;
	float dx = 0.0, dy = 0.0;
	float cos_theta = cos(physDev->font.escapement * M_PI / 1800.0);
	float sin_theta = sin(physDev->font.escapement * M_PI / 1800.0);
        for(i = 0; i < count-1; i++) {
	    TRACE("lpDx[%d] = %d\n", i, deltas[i]);
	    if(physDev->font.fontloc == Download)
	        PSDRV_WriteDownloadGlyphShow(physDev, glyphs + i, 1);
	    else
	        PSDRV_WriteBuiltinGlyphShow(physDev, str + i, 1);
	    dx += deltas[i] * cos_theta;
	    dy -= deltas[i] * sin_theta;
	    PSDRV_WriteMoveTo(physDev, x + PSDRV_XWStoDS(physDev, dx),
			      y + PSDRV_YWStoDS(physDev, dy));
	}
	if(physDev->font.fontloc == Download)
	    PSDRV_WriteDownloadGlyphShow(physDev, glyphs + i, 1);
	else
	    PSDRV_WriteBuiltinGlyphShow(physDev, str + i, 1);
	if(deltas != lpDx)
	    HeapFree(GetProcessHeap(), 0, deltas);
    }

    /*
     * Underline and strikeout attributes.
     */
    if ((tm.tmUnderlined) || (tm.tmStruckOut)) {

        /* Get the thickness and the position for the underline attribute */
        /* We'll use the same thickness for the strikeout attribute       */

        INT escapement =  physDev->font.escapement;

        /* Do the underline */

        if (tm.tmUnderlined) {
            PSDRV_WriteNewPath(physDev); /* will be closed by WriteRectangle */
            if (escapement != 0)  /* rotated text */
            {
                PSDRV_WriteGSave(physDev);  /* save the graphics state */
                PSDRV_WriteMoveTo(physDev, x, y); /* move to the start */

                /* temporarily rotate the coord system */
                PSDRV_WriteRotate(physDev, -escapement/10);

                /* draw the underline relative to the starting point */
                PSDRV_WriteRRectangle(physDev, 0, -physDev->font.underlinePosition,
				      sz.cx, physDev->font.underlineThickness);
            }
            else
                PSDRV_WriteRectangle(physDev, x, y - physDev->font.underlinePosition,
				     sz.cx, physDev->font.underlineThickness);

            PSDRV_WriteFill(physDev);

            if (escapement != 0)  /* rotated text */
                PSDRV_WriteGRestore(physDev);  /* restore the graphics state */
        }

        /* Do the strikeout */

        if (tm.tmStruckOut) {
            PSDRV_WriteNewPath(physDev); /* will be closed by WriteRectangle */
            if (escapement != 0)  /* rotated text */
            {
                PSDRV_WriteGSave(physDev);  /* save the graphics state */
                PSDRV_WriteMoveTo(physDev, x, y); /* move to the start */

                /* temporarily rotate the coord system */
                PSDRV_WriteRotate(physDev, -escapement/10);

                /* draw the line relative to the starting point */
                PSDRV_WriteRRectangle(physDev, 0, -physDev->font.strikeoutPosition,
				      sz.cx, physDev->font.strikeoutThickness);
            }
            else
                PSDRV_WriteRectangle(physDev, x, y - physDev->font.strikeoutPosition,
				     sz.cx, physDev->font.strikeoutThickness);

            PSDRV_WriteFill(physDev);

            if (escapement != 0)  /* rotated text */
                PSDRV_WriteGRestore(physDev);  /* restore the graphics state */
        }
    }

    if(glyphs && glyphs != str) HeapFree(GetProcessHeap(), 0, glyphs);
    return TRUE;
}
