blob: 97ff35b5b3fcac1f1de1d9b01daf414a1bef1e74 [file] [log] [blame]
/*
* text functions
*
* Copyright 1993 Alexandre Julliard
*/
static char Copyright[] = "Copyright Alexandre Julliard, 1993";
#include <X11/Intrinsic.h>
#include <X11/StringDefs.h>
#include <X11/Core.h>
#include <X11/Shell.h>
#include <X11/Xatom.h>
#include "message.h"
#include "callback.h"
#include "win.h"
#include "gdi.h"
/***********************************************************************
* DrawText (USER.85)
*/
int DrawText( HDC hdc, LPSTR str, int count, LPRECT rect, WORD flags )
{
SIZE size;
int x = rect->left, y = rect->top;
if (count == -1) count = strlen(str);
if (!GetTextExtentPoint( hdc, str, count, &size )) return 0;
if (flags & DT_CENTER) x = (rect->left + rect->right - size.cx) / 2;
else if (flags & DT_RIGHT) x = rect->right - size.cx;
if (flags & DT_VCENTER) y = (rect->top + rect->bottom - size.cy) / 2;
else if (flags & DT_BOTTOM) y = rect->bottom - size.cy;
if (!TextOut( hdc, x, y, str, count )) return 0;
return 1;
}
/***********************************************************************
* TextOut (GDI.33)
*/
BOOL TextOut( HDC hdc, short x, short y, LPSTR str, short count )
{
int dir, ascent, descent, i;
XCharStruct info;
XFontStruct *font;
DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
if (!dc) return FALSE;
if (!DC_SetupGCForText( dc )) return TRUE;
font = dc->u.x.font.fstruct;
if (dc->w.textAlign & TA_UPDATECP)
{
x = dc->w.CursPosX;
y = dc->w.CursPosY;
}
#ifdef DEBUG_TEXT
printf( "TextOut: %d,%d '%s'\n", x, y, str );
#endif
x = XLPTODP( dc, x );
y = YLPTODP( dc, y );
XTextExtents( font, str, count, &dir, &ascent, &descent, &info );
info.width += count*dc->w.charExtra + dc->w.breakExtra*dc->w.breakCount;
/* Compute starting position */
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 + info.width );
break;
case TA_RIGHT:
x -= info.width;
if (dc->w.textAlign & TA_UPDATECP) dc->w.CursPosX = XDPTOLP( dc, x );
break;
case TA_CENTER:
x -= info.width / 2;
break;
}
switch( dc->w.textAlign & (TA_TOP | TA_BOTTOM | TA_BASELINE) )
{
case TA_TOP:
y += font->ascent;
break;
case TA_BOTTOM:
y -= font->descent;
break;
case TA_BASELINE:
break;
}
/* Draw text */
if (!dc->w.charExtra && !dc->w.breakExtra)
{
if (dc->w.backgroundMode == TRANSPARENT)
XDrawString( XT_display, dc->u.x.drawable, dc->u.x.gc,
x, y, str, count );
else
XDrawImageString( XT_display, dc->u.x.drawable, dc->u.x.gc,
x, y, str, count );
}
else
{
char * p = str;
int xchar = x;
for (i = 0; i < count; i++, p++)
{
XCharStruct * charStr;
unsigned char ch = *p;
int extraWidth;
if ((ch < font->min_char_or_byte2)||(ch > font->max_char_or_byte2))
ch = font->default_char;
if (!font->per_char) charStr = &font->min_bounds;
else charStr = font->per_char + ch - font->min_char_or_byte2;
extraWidth = dc->w.charExtra;
if (ch == dc->u.x.font.metrics.tmBreakChar)
extraWidth += dc->w.breakExtra;
if (dc->w.backgroundMode == TRANSPARENT)
XDrawString( XT_display, dc->u.x.drawable, dc->u.x.gc,
xchar, y, p, 1 );
else
{
XDrawImageString( XT_display, dc->u.x.drawable, dc->u.x.gc,
xchar, y, p, 1 );
XSetForeground( XT_display, dc->u.x.gc, dc->w.backgroundPixel);
XFillRectangle( XT_display, dc->u.x.drawable, dc->u.x.gc,
xchar + charStr->width, y - font->ascent,
extraWidth, font->ascent + font->descent );
XSetForeground( XT_display, dc->u.x.gc, dc->w.textPixel );
}
xchar += charStr->width + extraWidth;
}
}
/* Draw underline and strike-out if needed */
if (dc->u.x.font.metrics.tmUnderlined)
{
long linePos, lineWidth;
if (!XGetFontProperty( font, XA_UNDERLINE_POSITION, &linePos ))
linePos = font->descent-1;
if (!XGetFontProperty( font, XA_UNDERLINE_THICKNESS, &lineWidth ))
lineWidth = 0;
else if (lineWidth == 1) lineWidth = 0;
XSetLineAttributes( XT_display, dc->u.x.gc, lineWidth,
LineSolid, CapRound, JoinBevel );
XDrawLine( XT_display, dc->u.x.drawable, dc->u.x.gc,
x, y + linePos, x + info.width, y + linePos );
}
if (dc->u.x.font.metrics.tmStruckOut)
{
long lineAscent, lineDescent;
if (!XGetFontProperty( font, XA_STRIKEOUT_ASCENT, &lineAscent ))
lineAscent = font->ascent / 3;
if (!XGetFontProperty( font, XA_STRIKEOUT_DESCENT, &lineDescent ))
lineDescent = -lineAscent;
XSetLineAttributes( XT_display, dc->u.x.gc, lineAscent + lineDescent,
LineSolid, CapRound, JoinBevel );
XDrawLine( XT_display, dc->u.x.drawable, dc->u.x.gc,
x, y - lineAscent, x + info.width, y - lineAscent );
}
return TRUE;
}