/*
 * X11 graphics driver text functions
 *
 * Copyright 1993,1994 Alexandre Julliard
 */

#include "config.h"

#ifndef X_DISPLAY_MISSING

#include <X11/Xatom.h>
#include "ts_xlib.h"

#include <stdlib.h>
#include "windef.h"
#include <math.h>
#include "dc.h"
#include "gdi.h"
#include "heap.h"
#include "x11font.h"
#include "debugtools.h"

DEFAULT_DEBUG_CHANNEL(text)

#define SWAP_INT(a,b)  { int t = a; a = b; b = t; }
#define IROUND(x) (int)((x)>0? (x)+0.5 : (x) - 0.5)

/***********************************************************************
 *           X11DRV_ExtTextOut
 */
BOOL
X11DRV_ExtTextOut( DC *dc, INT x, INT y, UINT flags,
                   const RECT *lprect, LPCSTR str, UINT count,
                   const INT *lpDx )
{
    int 	        i;
    fontObject*		pfo;
    INT	 	width, ascent, descent, xwidth, ywidth;
    XFontStruct*	font;
    RECT 		rect;
    char		dfBreakChar, lfUnderline, lfStrikeOut;
    BOOL		rotated = FALSE;
    X11DRV_PDEVICE      *physDev = (X11DRV_PDEVICE *)dc->physDev;

    if (!X11DRV_SetupGCForText( dc )) return TRUE;

    pfo = XFONT_GetFontObject( physDev->font );
    font = pfo->fs;
     
    if (pfo->lf.lfEscapement && pfo->lpX11Trans)
        rotated = TRUE;
    dfBreakChar = (char)pfo->fi->df.dfBreakChar;
    lfUnderline = (pfo->fo_flags & FO_SYNTH_UNDERLINE) ? 1 : 0;
    lfStrikeOut = (pfo->fo_flags & FO_SYNTH_STRIKEOUT) ? 1 : 0;

    TRACE("hdc=%04x df=%04x %d,%d %s, %d  flags=%d lpDx=%p\n",
	  dc->hSelf, (UINT16)(physDev->font), x, y,
	  debugstr_an (str, count), count, flags, lpDx);

    /* some strings sent here end in a newline for whatever reason.  I have no
       clue what the right treatment should be in general, but ignoring
       terminating newlines seems ok.  MW, April 1998.  */
    if (count > 0 && str[count - 1] == '\n') count--;

    if (lprect != NULL) TRACE("\trect=(%d,%d - %d,%d)\n",
                                     lprect->left, lprect->top,
                                     lprect->right, lprect->bottom );
      /* Setup coordinates */

    if (dc->w.textAlign & TA_UPDATECP)
    {
	x = dc->w.CursPosX;
	y = dc->w.CursPosY;
    }

    if (flags & (ETO_OPAQUE | ETO_CLIPPED))  /* there's a rectangle */
    {
        if (!lprect)  /* not always */
        {
            SIZE sz;
            if (flags & ETO_CLIPPED)  /* Can't clip with no rectangle */
	      return FALSE;
	    if (!X11DRV_GetTextExtentPoint( dc, str, count, &sz ))
	      return FALSE;
	    rect.left   = XLPTODP( dc, x );
	    rect.right  = XLPTODP( dc, x+sz.cx );
	    rect.top    = YLPTODP( dc, y );
	    rect.bottom = YLPTODP( dc, y+sz.cy );
	}
	else
	{
	    rect.left   = XLPTODP( dc, lprect->left );
	    rect.right  = XLPTODP( dc, lprect->right );
	    rect.top    = YLPTODP( dc, lprect->top );
	    rect.bottom = YLPTODP( dc, lprect->bottom );
	}
	if (rect.right < rect.left) SWAP_INT( rect.left, rect.right );
	if (rect.bottom < rect.top) SWAP_INT( rect.top, rect.bottom );
    }

    x = XLPTODP( dc, x );
    y = YLPTODP( dc, y );

    TRACE("\treal coord: x=%i, y=%i, rect=(%d,%d - %d,%d)\n",
			  x, y, rect.left, rect.top, rect.right, rect.bottom);

      /* Draw the rectangle */

    if (flags & ETO_OPAQUE)
    {
        TSXSetForeground( display, physDev->gc, physDev->backgroundPixel );
        TSXFillRectangle( display, physDev->drawable, physDev->gc,
                        dc->w.DCOrgX + rect.left, dc->w.DCOrgY + rect.top,
                        rect.right-rect.left, rect.bottom-rect.top );
    }
    if (!count) return TRUE;  /* Nothing more to do */

      /* Compute text starting position */

    if (lpDx) /* have explicit character cell x offsets in logical coordinates */
    {
	int extra = dc->wndExtX / 2;
        for (i = width = 0; i < count; i++) width += lpDx[i];
	width = (width * dc->vportExtX + extra ) / dc->wndExtX;
    }
    else
    {
        SIZE sz;
        if (!X11DRV_GetTextExtentPoint( dc, str, count, &sz ))
	    return FALSE;
	width = XLSTODS(dc, sz.cx);
    }
    ascent = pfo->lpX11Trans ? pfo->lpX11Trans->ascent : font->ascent;
    descent = pfo->lpX11Trans ? pfo->lpX11Trans->descent : font->descent;
    xwidth = pfo->lpX11Trans ? width * pfo->lpX11Trans->a /
      pfo->lpX11Trans->pixelsize : width;
    ywidth = pfo->lpX11Trans ? width * pfo->lpX11Trans->b /
      pfo->lpX11Trans->pixelsize : 0;

    switch( dc->w.textAlign & (TA_LEFT | TA_RIGHT | TA_CENTER) )
    {
      case TA_LEFT:
	  if (dc->w.textAlign & TA_UPDATECP) {
	      dc->w.CursPosX = XDPTOLP( dc, x + xwidth );
	      dc->w.CursPosY = YDPTOLP( dc, y - ywidth );
	  }
	  break;
      case TA_RIGHT:
	  x -= xwidth;
	  y += ywidth;
	  if (dc->w.textAlign & TA_UPDATECP) {
	      dc->w.CursPosX = XDPTOLP( dc, x );
	      dc->w.CursPosY = YDPTOLP( dc, y );
	  }
	  break;
      case TA_CENTER:
	  x -= xwidth / 2;
	  y += ywidth / 2;
	  break;
    }

    switch( dc->w.textAlign & (TA_TOP | TA_BOTTOM | TA_BASELINE) )
    {
      case TA_TOP:
	  x -= pfo->lpX11Trans ? ascent * pfo->lpX11Trans->c /
	    pfo->lpX11Trans->pixelsize : 0;
	  y += pfo->lpX11Trans ? ascent * pfo->lpX11Trans->d /
	    pfo->lpX11Trans->pixelsize : ascent;
	  break;
      case TA_BOTTOM:
	  x += pfo->lpX11Trans ? descent * pfo->lpX11Trans->c /
	    pfo->lpX11Trans->pixelsize : 0;
	  y -= pfo->lpX11Trans ? descent * pfo->lpX11Trans->d /
	    pfo->lpX11Trans->pixelsize : descent;
	  break;
      case TA_BASELINE:
	  break;
    }

      /* Set the clip region */

    if (flags & ETO_CLIPPED)
    {
        SaveVisRgn16( dc->hSelf );
        CLIPPING_IntersectVisRect( dc, rect.left, rect.top, rect.right,
                                   rect.bottom, FALSE );
    }

      /* Draw the text background if necessary */

    if (dc->w.backgroundMode != TRANSPARENT)
    {
          /* If rectangle is opaque and clipped, do nothing */
        if (!(flags & ETO_CLIPPED) || !(flags & ETO_OPAQUE))
        {
              /* Only draw if rectangle is not opaque or if some */
              /* text is outside the rectangle */
            if (!(flags & ETO_OPAQUE) ||
                (x < rect.left) ||
                (x + width >= rect.right) ||
                (y - ascent < rect.top) ||
                (y + descent >= rect.bottom))
            {
                TSXSetForeground( display, physDev->gc,
				  physDev->backgroundPixel );
                TSXFillRectangle( display, physDev->drawable, physDev->gc,
                                dc->w.DCOrgX + x,
                                dc->w.DCOrgY + y - ascent,
                                width,
                                ascent + descent );
            }
        }
    }
    
    /* Draw the text (count > 0 verified) */

    TSXSetForeground( display, physDev->gc, physDev->textPixel );
    if(!rotated)
    {
      if (!dc->w.charExtra && !dc->w.breakExtra && !lpDx)
      {
        TSXDrawString( display, physDev->drawable, physDev->gc, 
                     dc->w.DCOrgX + x, dc->w.DCOrgY + y, str, count );
      }
      else  /* Now the fun begins... */
      {
        XTextItem *items, *pitem;
	int delta;

	/* allocate max items */

        pitem = items = HEAP_xalloc( GetProcessHeap(), 0,
                                     count * sizeof(XTextItem) );
        delta = i = 0;
	if( lpDx ) /* explicit character widths */
	{
	    int extra = dc->wndExtX / 2;

	    while (i < count)
	    {
		/* initialize text item with accumulated delta */

		pitem->chars  = (char *)str + i;
		pitem->delta  = delta;
		pitem->nchars = 0;
		pitem->font   = None;
		delta = 0;

		/* add characters  to the same XTextItem until new delta
		 * becomes  non-zero */

		do
		{
		    delta += (lpDx[i] * dc->vportExtX + extra) / dc->wndExtX
					    - TSXTextWidth( font, str + i, 1);
		    pitem->nchars++;
		} while ((++i < count) && !delta);
		pitem++;
	   }
	}
	else /* charExtra or breakExtra */
	{
            while (i < count)
            {
		pitem->chars  = (char *)str + i;
		pitem->delta  = delta;
		pitem->nchars = 0;
		pitem->font   = None;
		delta = 0;

		do
                {
                    delta += dc->w.charExtra;
                    if (str[i] == (char)dfBreakChar) delta += dc->w.breakExtra;
		    pitem->nchars++;
                } while ((++i < count) && !delta);
		pitem++;
            } 
        }

        TSXDrawText( display, physDev->drawable, physDev->gc,
                   dc->w.DCOrgX + x, dc->w.DCOrgY + y, items, pitem - items );
        HeapFree( GetProcessHeap(), 0, items );
      }
    }
    else /* rotated */
    {  
      /* have to render character by character. */
      double offset = 0.0;
      int i;

      for (i=0; i<count; i++)
      {
	int char_metric_offset = (unsigned char) str[i] 
	  - font->min_char_or_byte2;
	int x_i = IROUND((double) (dc->w.DCOrgX + x) + offset *
			 pfo->lpX11Trans->a / pfo->lpX11Trans->pixelsize );
	int y_i = IROUND((double) (dc->w.DCOrgY + y) - offset *
			 pfo->lpX11Trans->b / pfo->lpX11Trans->pixelsize );

	TSXDrawString( display, physDev->drawable, physDev->gc,
		       x_i, y_i, &str[i], 1);
	if (lpDx)
	  offset += XLSTODS(dc, lpDx[i]);
	else
	{
	  offset += (double) (font->per_char ?
			      font->per_char[char_metric_offset].attributes:
			      font->min_bounds.attributes)
	                  * pfo->lpX11Trans->pixelsize / 1000.0;
	  offset += dc->w.charExtra;
	  if (str[i] == (char)dfBreakChar)
	    offset += dc->w.breakExtra;
	}
      }
    }

      /* Draw underline and strike-out if needed */

    if (lfUnderline)
    {
	long linePos, lineWidth;       

	if (!TSXGetFontProperty( font, XA_UNDERLINE_POSITION, &linePos ))
	    linePos = descent - 1;
	if (!TSXGetFontProperty( font, XA_UNDERLINE_THICKNESS, &lineWidth ))
	    lineWidth = 0;
	else if (lineWidth == 1) lineWidth = 0;
	TSXSetLineAttributes( display, physDev->gc, lineWidth,
			      LineSolid, CapRound, JoinBevel ); 
        TSXDrawLine( display, physDev->drawable, physDev->gc,
		     dc->w.DCOrgX + x, dc->w.DCOrgY + y + linePos,
		     dc->w.DCOrgX + x + width, dc->w.DCOrgY + y + linePos );
    }
    if (lfStrikeOut)
    {
	long lineAscent, lineDescent;
	if (!TSXGetFontProperty( font, XA_STRIKEOUT_ASCENT, &lineAscent ))
	    lineAscent = ascent / 2;
	if (!TSXGetFontProperty( font, XA_STRIKEOUT_DESCENT, &lineDescent ))
	    lineDescent = -lineAscent * 2 / 3;
	TSXSetLineAttributes( display, physDev->gc, lineAscent + lineDescent,
			    LineSolid, CapRound, JoinBevel ); 
	TSXDrawLine( display, physDev->drawable, physDev->gc,
		   dc->w.DCOrgX + x, dc->w.DCOrgY + y - lineAscent,
		   dc->w.DCOrgX + x + width, dc->w.DCOrgY + y - lineAscent );
    }

    if (flags & ETO_CLIPPED) 
        RestoreVisRgn16( dc->hSelf );

    return TRUE;
}

#endif /* !defined(X_DISPLAY_MISSING) */
