/*
 *	PostScript driver font functions
 *
 *	Copyright 1998  Huw D M Davies
 *
 */
#include <string.h>
#include <stdlib.h> 	    /* for bsearch() */
#include "winspool.h"
#include "psdrv.h"
#include "debugtools.h"
#include "winerror.h"

DEFAULT_DEBUG_CHANNEL(psdrv);

/***********************************************************************
 *           is_stock_font
 */
inline static BOOL is_stock_font( HFONT font )
{
    int i;
    for (i = OEM_FIXED_FONT; i <= DEFAULT_GUI_FONT; i++)
    {
        if (i != DEFAULT_PALETTE && font == GetStockObject(i)) return TRUE;
    }
    return FALSE;
}


/*******************************************************************************
 *  ScaleFont
 *
 *  Scale font to requested lfHeight
 *
 */
inline static float round(float f)
{
    return (f > 0) ? (f + 0.5) : (f - 0.5);
}

static VOID ScaleFont(const AFM *afm, LONG lfHeight, PSFONT *font,
    	TEXTMETRICW *tm)
{
    const WINMETRICS	*wm = &(afm->WinMetrics);
    USHORT  	    	usUnitsPerEm, usWinAscent, usWinDescent;
    SHORT   	    	sAscender, sDescender, sLineGap, sTypoAscender;
    SHORT    	    	sTypoDescender, sTypoLineGap, sAvgCharWidth;
    
    TRACE("'%s' %li\n", afm->FontName, lfHeight);
		
    if (lfHeight < 0)   	    	    	    	/* match em height */
    {
        font->scale = - ((float)lfHeight / (float)(wm->usUnitsPerEm));
    }
    else    	    	    	    	    	    	/* match cell height */
    {
    	font->scale = (float)lfHeight /
	    	(float)(wm->usWinAscent + wm->usWinDescent);
    }
    
    font->size = (INT)round(font->scale * (float)wm->usUnitsPerEm);
    font->set = FALSE;
    
    usUnitsPerEm = (USHORT)round((float)(wm->usUnitsPerEm) * font->scale);
    sAscender = (SHORT)round((float)(wm->sAscender) * font->scale);
    sDescender = (SHORT)round((float)(wm->sDescender) * font->scale);
    sLineGap = (SHORT)round((float)(wm->sLineGap) * font->scale);
    sTypoAscender = (SHORT)round((float)(wm->sTypoAscender) * font->scale);
    sTypoDescender = (SHORT)round((float)(wm->sTypoDescender) * font->scale);
    sTypoLineGap = (SHORT)round((float)(wm->sTypoLineGap) * font->scale);
    usWinAscent = (USHORT)round((float)(wm->usWinAscent) * font->scale);
    usWinDescent = (USHORT)round((float)(wm->usWinDescent) * font->scale);
    sAvgCharWidth = (SHORT)round((float)(wm->sAvgCharWidth) * font->scale);
    
    tm->tmAscent = (LONG)usWinAscent;
    tm->tmDescent = (LONG)usWinDescent;
    tm->tmHeight = tm->tmAscent + tm->tmDescent;
    
    tm->tmInternalLeading = tm->tmHeight - (LONG)usUnitsPerEm;
    if (tm->tmInternalLeading < 0)
        tm->tmInternalLeading = 0;
	
    tm->tmExternalLeading =
    	    (LONG)(sAscender - sDescender + sLineGap) - tm->tmHeight;
    if (tm->tmExternalLeading < 0)
    	tm->tmExternalLeading = 0;
    
    tm->tmAveCharWidth = (LONG)sAvgCharWidth;
	
    tm->tmWeight = afm->Weight;
    tm->tmItalic = (afm->ItalicAngle != 0.0);
    tm->tmUnderlined = 0;
    tm->tmStruckOut = 0;
    tm->tmFirstChar = (WCHAR)(afm->Metrics[0].UV);
    tm->tmLastChar = (WCHAR)(afm->Metrics[afm->NumofMetrics - 1].UV);
    tm->tmDefaultChar = 0x001f;     	/* Win2K does this - FIXME? */
    tm->tmBreakChar = tm->tmFirstChar;	    	/* should be 'space' */
    
    tm->tmPitchAndFamily = TMPF_DEVICE | TMPF_VECTOR;
    if (!afm->IsFixedPitch)
    	tm->tmPitchAndFamily |= TMPF_FIXED_PITCH;   /* yes, it's backwards */
    if (wm->usUnitsPerEm != 1000)
    	tm->tmPitchAndFamily |= TMPF_TRUETYPE;
    
    tm->tmCharSet = ANSI_CHARSET;   	/* FIXME */
    tm->tmOverhang = 0;
    
    /*
     *	This is kludgy.  font->scale is used in several places in the driver
     *	to adjust PostScript-style metrics.  Since these metrics have been
     *	"normalized" to an em-square size of 1000, font->scale needs to be
     *	similarly adjusted..
     */
     
    font->scale *= (float)wm->usUnitsPerEm / 1000.0;
     
    tm->tmMaxCharWidth = (LONG)round(
    	    (afm->FontBBox.urx - afm->FontBBox.llx) * font->scale);
    
    TRACE("Selected PS font '%s' size %d weight %ld.\n", afm->FontName,
    	    font->size, tm->tmWeight );
    TRACE("H = %ld As = %ld Des = %ld IL = %ld EL = %ld\n", tm->tmHeight,
    	    tm->tmAscent, tm->tmDescent, tm->tmInternalLeading,
    	    tm->tmExternalLeading);
}

/***********************************************************************
 *           PSDRV_FONT_SelectObject
 */
HFONT PSDRV_FONT_SelectObject( DC * dc, HFONT hfont )
{
    LOGFONTW lf;
    PSDRV_PDEVICE *physDev = (PSDRV_PDEVICE *)dc->physDev;
    BOOL bd = FALSE, it = FALSE;
    AFMLISTENTRY *afmle;
    FONTFAMILY *family;
    char FaceName[LF_FACESIZE];

    if (!GetObjectW( hfont, sizeof(lf), &lf )) return 0;

    TRACE("FaceName = %s Height = %ld Italic = %d Weight = %ld\n",
	  debugstr_w(lf.lfFaceName), lf.lfHeight, lf.lfItalic,
	  lf.lfWeight);

    if(lf.lfItalic)
        it = TRUE;
    if(lf.lfWeight > 550)
        bd = TRUE;
    WideCharToMultiByte(CP_ACP, 0, lf.lfFaceName, -1,
			FaceName, sizeof(FaceName), NULL, NULL);
    
    if(FaceName[0] == '\0') {
        switch(lf.lfPitchAndFamily & 0xf0) {
	case FF_DONTCARE:
	    break;
	case FF_ROMAN:
	case FF_SCRIPT:
	    strcpy(FaceName, "Times");
	    break;
	case FF_SWISS:
	    strcpy(FaceName, "Helvetica");
	    break;
	case FF_MODERN:
	    strcpy(FaceName, "Courier");
	    break;
	case FF_DECORATIVE:
	    strcpy(FaceName, "Symbol");
	    break;
	}
    }

    if(FaceName[0] == '\0') {
        switch(lf.lfPitchAndFamily & 0x0f) {
	case VARIABLE_PITCH:
	    strcpy(FaceName, "Times");
	    break;
	default:
	    strcpy(FaceName, "Courier");
	    break;
	}
    }

    if (physDev->pi->FontSubTableSize != 0)
    {
	DWORD i;

	for (i = 0; i < physDev->pi->FontSubTableSize; ++i)
	{
	    if (!strcasecmp (FaceName,
		    physDev->pi->FontSubTable[i].pValueName))
	    {
		TRACE ("substituting facename '%s' for '%s'\n",
			(LPSTR) physDev->pi->FontSubTable[i].pData, FaceName);
		if (strlen ((LPSTR) physDev->pi->FontSubTable[i].pData) <
			LF_FACESIZE)
		    strcpy (FaceName,
			    (LPSTR) physDev->pi->FontSubTable[i].pData);
		else
		    WARN ("Facename '%s' is too long; ignoring substitution\n",
			    (LPSTR) physDev->pi->FontSubTable[i].pData);
		break;
	    }
	}
    }

    TRACE("Trying to find facename '%s'\n", FaceName);

    /* Look for a matching font family */
    for(family = physDev->pi->Fonts; family; family = family->next) {
        if(!strcasecmp(FaceName, family->FamilyName))
	    break;
    }
    if(!family) {
	/* Fallback for Window's font families to common PostScript families */
	if(!strcmp(FaceName, "Arial"))
	    strcpy(FaceName, "Helvetica");
	else if(!strcmp(FaceName, "System"))
	    strcpy(FaceName, "Helvetica");
	else if(!strcmp(FaceName, "Times New Roman"))
	    strcpy(FaceName, "Times");
	else if(!strcmp(FaceName, "Courier New"))
	    strcpy(FaceName, "Courier");

	for(family = physDev->pi->Fonts; family; family = family->next) {
	    if(!strcmp(FaceName, family->FamilyName))
		break;
	}
    }
    /* If all else fails, use the first font defined for the printer */
    if(!family)
        family = physDev->pi->Fonts;

    TRACE("Got family '%s'\n", family->FamilyName);

    for(afmle = family->afmlist; afmle; afmle = afmle->next) {
        if( (bd == (afmle->afm->Weight == FW_BOLD)) && 
	    (it == (afmle->afm->ItalicAngle != 0.0)) )
	        break;
    }
    if(!afmle)
        afmle = family->afmlist; /* not ideal */
	
    TRACE("Got font '%s'\n", afmle->afm->FontName);
    
    physDev->font.afm = afmle->afm;
    /* stock fonts ignore the mapping mode */
    if (!is_stock_font( hfont )) lf.lfHeight = INTERNAL_YWSTODS(dc, lf.lfHeight);
    ScaleFont(physDev->font.afm, lf.lfHeight,
    	    &(physDev->font), &(physDev->font.tm));
    
    physDev->font.escapement = lf.lfEscapement;
    
    /* Does anyone know if these are supposed to be reversed like this? */
    
    physDev->font.tm.tmDigitizedAspectX = physDev->logPixelsY;
    physDev->font.tm.tmDigitizedAspectY = physDev->logPixelsX;
    
    return TRUE; /* We'll use a device font for now */
}

/***********************************************************************
 *           PSDRV_GetTextMetrics
 */
BOOL PSDRV_GetTextMetrics(DC *dc, TEXTMETRICW *metrics)
{
    PSDRV_PDEVICE *physDev = (PSDRV_PDEVICE *)dc->physDev;

    memcpy(metrics, &(physDev->font.tm), sizeof(physDev->font.tm));
    return TRUE;
}

/******************************************************************************
 *  	PSDRV_UVMetrics
 *
 *  Find the AFMMETRICS for a given UV.  Returns first glyph in the font
 *  (space?) if the font does not have a glyph for the given UV.
 */
static int MetricsByUV(const void *a, const void *b)
{
    return (int)(((const AFMMETRICS *)a)->UV - ((const AFMMETRICS *)b)->UV);
}
 
const AFMMETRICS *PSDRV_UVMetrics(LONG UV, const AFM *afm)
{
    AFMMETRICS	    	key;
    const AFMMETRICS	*needle;
    
    /*
     *	Ugly work-around for symbol fonts.  Wine is sending characters which
     *	belong in the Unicode private use range (U+F020 - U+F0FF) as ASCII
     *	characters (U+0020 - U+00FF).
     */
    
    if ((afm->Metrics->UV & 0xff00) == 0xf000 && UV < 0x100)
    	UV |= 0xf000;
    
    key.UV = UV;
    
    needle = bsearch(&key, afm->Metrics, afm->NumofMetrics, sizeof(AFMMETRICS),
	    MetricsByUV);

    if (needle == NULL)
    {
    	WARN("No glyph for U+%.4lX in %s\n", UV, afm->FontName);
    	needle = afm->Metrics;
    }
	
    return needle;
}

/***********************************************************************
 *           PSDRV_GetTextExtentPoint
 */
BOOL PSDRV_GetTextExtentPoint(DC *dc, LPCWSTR str, INT count, LPSIZE size)
{
    PSDRV_PDEVICE   *physDev = (PSDRV_PDEVICE *)dc->physDev;
    int     	    i;
    float   	    width = 0.0;
    
    TRACE("%s %i\n", debugstr_wn(str, count), count);
    
    for (i = 0; i < count && str[i] != '\0'; ++i)
	width += PSDRV_UVMetrics(str[i], physDev->font.afm)->WX;
	
    width *= physDev->font.scale;
    
    size->cx = GDI_ROUND((FLOAT)width * dc->xformVport2World.eM11);
    size->cy = GDI_ROUND((FLOAT)physDev->font.tm.tmHeight *
    	    dc->xformVport2World.eM22);
	    
    TRACE("cx=%li cy=%li\n", size->cx, size->cy);
	    
    return TRUE;
}

/***********************************************************************
 *           PSDRV_GetCharWidth
 */
BOOL PSDRV_GetCharWidth(DC *dc, UINT firstChar, UINT lastChar, LPINT buffer)
{
    PSDRV_PDEVICE   *physDev = (PSDRV_PDEVICE *)dc->physDev;
    UINT    	    i;
    
    TRACE("U+%.4X U+%.4X\n", firstChar, lastChar);
    
    if (lastChar > 0xffff || firstChar > lastChar)
    {
    	SetLastError(ERROR_INVALID_PARAMETER);
    	return FALSE;
    }
	
    for (i = firstChar; i <= lastChar; ++i)
    {
    	*buffer = GDI_ROUND(PSDRV_UVMetrics(i, physDev->font.afm)->WX
	    	* physDev->font.scale);
	TRACE("U+%.4X: %i\n", i, *buffer);
	++buffer;
    }
	
    return TRUE;
}
    
/***********************************************************************
 *           PSDRV_SetFont
 */
BOOL PSDRV_SetFont( DC *dc )
{
    PSDRV_PDEVICE *physDev = (PSDRV_PDEVICE *)dc->physDev;

    PSDRV_WriteSetColor(dc, &physDev->font.color);
    if(physDev->font.set) return TRUE;

    PSDRV_WriteSetFont(dc);
    physDev->font.set = TRUE;
    return TRUE;
}


/***********************************************************************
 *           PSDRV_GetFontMetric
 */
static UINT PSDRV_GetFontMetric(HDC hdc, const AFM *afm,
    	NEWTEXTMETRICEXW *ntmx, ENUMLOGFONTEXW *elfx)
{
    /* ntmx->ntmTm is NEWTEXTMETRICW; compatible w/ TEXTMETRICW per Win32 doc */

    TEXTMETRICW     *tm = (TEXTMETRICW *)&(ntmx->ntmTm);
    LOGFONTW	    *lf = &(elfx->elfLogFont);
    PSFONT  	    font;
    
    memset(ntmx, 0, sizeof(*ntmx));
    memset(elfx, 0, sizeof(*elfx));
    
    ScaleFont(afm, -(LONG)(afm->WinMetrics.usUnitsPerEm), &font, tm);
    
    lf->lfHeight = tm->tmHeight;
    lf->lfWidth = tm->tmAveCharWidth;
    lf->lfWeight = tm->tmWeight;
    lf->lfItalic = tm->tmItalic;
    lf->lfCharSet = tm->tmCharSet;
    
    lf->lfPitchAndFamily = (afm->IsFixedPitch) ? FIXED_PITCH : VARIABLE_PITCH;
    
    MultiByteToWideChar(CP_ACP, 0, afm->FamilyName, -1, lf->lfFaceName,
    	    LF_FACESIZE);
	    
    return DEVICE_FONTTYPE;
}

/***********************************************************************
 *           PSDRV_EnumDeviceFonts
 */
BOOL PSDRV_EnumDeviceFonts( HDC hdc, LPLOGFONTW plf, 
			    DEVICEFONTENUMPROC proc, LPARAM lp )
{
    ENUMLOGFONTEXW	lf;
    NEWTEXTMETRICEXW	tm;
    BOOL	  	b, bRet = 0;
    AFMLISTENTRY	*afmle;
    FONTFAMILY		*family;
    PSDRV_PDEVICE	*physDev;
    char                FaceName[LF_FACESIZE];
    DC *dc = DC_GetDCPtr( hdc );
    if (!dc) return FALSE;

    physDev = (PSDRV_PDEVICE *)dc->physDev;
    /* FIXME!! should reevaluate dc->physDev after every callback */
    GDI_ReleaseObj( hdc );

    if( plf->lfFaceName[0] ) {
        WideCharToMultiByte(CP_ACP, 0, plf->lfFaceName, -1,
			  FaceName, sizeof(FaceName), NULL, NULL);
        TRACE("lfFaceName = '%s'\n", FaceName);
        for(family = physDev->pi->Fonts; family; family = family->next) {
            if(!strncmp(FaceName, family->FamilyName, 
			strlen(family->FamilyName)))
	        break;
	}
	if(family) {
	    for(afmle = family->afmlist; afmle; afmle = afmle->next) {
	        TRACE("Got '%s'\n", afmle->afm->FontName);
		if( (b = (*proc)( &lf, &tm, 
			PSDRV_GetFontMetric( hdc, afmle->afm, &tm, &lf ),
				  lp )) )
		     bRet = b;
		else break;
	    }
	}
    } else {

        TRACE("lfFaceName = NULL\n");
        for(family = physDev->pi->Fonts; family; family = family->next) {
	    afmle = family->afmlist;
	    TRACE("Got '%s'\n", afmle->afm->FontName);
	    if( (b = (*proc)( &lf, &tm, 
		   PSDRV_GetFontMetric( hdc, afmle->afm, &tm, &lf ), 
			      lp )) )
	        bRet = b;
	    else break;
	}
    }
    return bRet;
}
