1
0
Fork 0
mirror of synced 2025-03-07 03:53:26 +01:00
wine/objects/text.c
Alexandre Julliard cdd0923710 Release 0.6
Tue Jan  4 13:01:33 1994  David Metcalfe <david@prism.demon.co.uk>

        * [window/caret.c]
        Modified code to use system timer.

Jan 9, 94 martin2@trgcorp.solucorp.qc.ca (Martin Ayotte)

	* [windows/win.c]
	Windows create if required new XLIB MenuBar & CaptionBar.

	* [windows/defwnd.c]
	WM_CALCSIZE Move & Resize caption, menubar & scrollbars.
	(I'm not sure it's the good place for it, but it work...)

	* [loader/resource.c]
	optimize in FindResourceByNumber, make lseek() if next type ...

	* [controls/scroll.c]
	scrollbar buttons are now using system resources bitmaps.

	* [controls/caption.c] - new file ...
	captionbar showing title, close button with SysMenu,
	and other buttons using system resources bitmaps.

	* [controls/menu.c]
	New functions: SetMenuItemBitmaps() with 'glues',
	Make new version of LoadMenu() & ParseMenu(),
	( put #define USE_POPUPMENU ).
	Implementation of MenuBar functions.
	
	* [sysres.dll]
	New bitmaps for system such OBM_CLOSE, OBM_MINIMIZE, OBM_UPARROWI.
	New SYSMENU menu, it don't work yet ! :-((

Tue Jan 11 05:27:45 1994  julliard@di.epfl.ch (Alexandre Julliard

	* [memory/atom.c]
	Fixed a bug that could cause atoms to be case-sensitive.

	* [misc/rect.c]
	Bug fix in SubtractRect().

	* [objects/clipping.c]
	Bug fix when setting the clip mask to an empty region.

	* [windows/dce.c]
	Bug fix in ReleaseDC().

	* [windows/dialog.c]
	Call AdjustWindowRectEx() before creating the dialog window.
	Added support for DS_MODALFRAME style.

	* [windows/event.c]
	Cleaned up event handling and removed old Xt stuff.
	Moved double-click handling to windows/message.c

	* [windows/focus.c]
	Bug fix: only set the X focus when the window is viewable.

	* [windows/graphics.c]
	Rewritten DrawReliefRect() to use brush instead of pen, and
	to use the system colors.

	* [windows/message.c]
	Implemented WM_NCHITTEST message sending, and non-client
	mouse messages.
	Cleaned up double-click handling, and removed the Xt code.

	* [windows/nonclient.c]  (New file)
	Implemented AdjustWindowRect().
	Implemented WM_NCCALCSIZE, WM_NCHITTEST and WM_NCPAINT handling.

	* [windows/painting.c]
	Added sending of the WM_NCPAINT message in BeginPaint().

	* [windows/sysmetrics.c] [include/sysmetrics.h]  (New files)
	Implemented system metrics.

	* [windows/win.c]
	Bug fix in setting the parent and owner in CreateWindow().
	Removed the Xt code.

	* [windows/winpos.c]
	Added sending of the WM_NCPAINT message in SetWindowPos().
	Removed the Xt code.
1994-01-12 11:12:51 +00:00

384 lines
9.1 KiB
C

/*
* text functions
*
* Copyright 1993 Alexandre Julliard
*/
static char Copyright[] = "Copyright Alexandre Julliard, 1993";
#include <X11/Xatom.h>
#include "gdi.h"
#define TAB 9
#define LF 10
#define CR 13
#define SPACE 32
#define PREFIX 38
static int tabstop = 8;
static int tabwidth;
static int spacewidth;
static int prefix_offset;
static char *TEXT_NextLine(HDC hdc, char *str, int *count, char *dest,
int *len, int width, WORD format)
{
/* Return next line of text from a string.
*
* hdc - handle to DC.
* str - string to parse into lines.
* count - length of str.
* dest - destination in which to return line.
* len - length of resultant line in dest in chars.
* width - maximum width of line in pixels.
* format - format type passed to DrawText.
*
* Returns pointer to next char in str after end of the line
* or NULL if end of str reached.
*/
int i = 0, j = 0, k;
int plen = 0;
int numspaces;
SIZE size;
int lasttab = 0;
int wb_i = 0, wb_j = 0, wb_count;
while (*count)
{
switch (str[i])
{
case CR:
case LF:
if (!(format & DT_SINGLELINE))
{
i++;
if (str[i] == CR || str[i] == LF)
i++;
*len = j;
return (&str[i]);
}
dest[j++] = str[i++];
if (!(format & DT_NOCLIP) || !(format & DT_NOPREFIX))
{
if (!GetTextExtentPoint(hdc, &dest[j-1], 1, &size))
return NULL;
plen += size.cx;
}
break;
case PREFIX:
if (!(format & DT_NOPREFIX))
{
prefix_offset = j + 1;
i++;
}
else
{
dest[j++] = str[i++];
if (!(format & DT_NOCLIP))
{
if (!GetTextExtentPoint(hdc, &dest[j-1], 1, &size))
return NULL;
plen += size.cx;
}
}
break;
case TAB:
if (format & DT_EXPANDTABS)
{
wb_i = ++i;
wb_j = j;
wb_count = *count;
if (!GetTextExtentPoint(hdc, &dest[lasttab], j - lasttab,
&size))
return NULL;
numspaces = (tabwidth - size.cx) / spacewidth;
for (k = 0; k < numspaces; k++)
dest[j++] = SPACE;
plen += tabwidth - size.cx;
lasttab = wb_j + numspaces;
}
else
{
dest[j++] = str[i++];
if (!(format & DT_NOCLIP) || !(format & DT_NOPREFIX))
{
if (!GetTextExtentPoint(hdc, &dest[j-1], 1, &size))
return NULL;
plen += size.cx;
}
}
break;
case SPACE:
dest[j++] = str[i++];
if (!(format & DT_NOCLIP) || !(format & DT_NOPREFIX))
{
wb_i = i;
wb_j = j - 1;
wb_count = *count;
if (!GetTextExtentPoint(hdc, &dest[j-1], 1, &size))
return NULL;
plen += size.cx;
}
break;
default:
dest[j++] = str[i++];
if (!(format & DT_NOCLIP) || !(format & DT_NOPREFIX))
{
if (!GetTextExtentPoint(hdc, &dest[j-1], 1, &size))
return NULL;
plen += size.cx;
}
}
(*count)--;
if (!(format & DT_NOCLIP) || (format & DT_WORDBREAK))
{
if (plen > width)
{
if (format & DT_WORDBREAK)
{
*len = wb_j;
*count = wb_count;
return (&str[wb_i]);
}
else
{
*len = j;
return (&str[i]);
}
}
}
}
*len = j;
return NULL;
}
/***********************************************************************
* DrawText (USER.85)
*/
int DrawText( HDC hdc, LPSTR str, int count, LPRECT rect, WORD flags )
{
SIZE size;
char *strPtr;
static char line[1024];
int len, lh, prefix_x, prefix_len;
TEXTMETRIC tm;
int x = rect->left, y = rect->top;
int width = rect->right - rect->left;
if (count == -1) count = strlen(str);
strPtr = str;
GetTextMetrics(hdc, &tm);
if (flags & DT_EXTERNALLEADING)
lh = tm.tmHeight + tm.tmExternalLeading;
else
lh = tm.tmHeight;
if (flags & DT_TABSTOP)
tabstop = flags >> 8;
if (flags & DT_EXPANDTABS)
{
GetTextExtentPoint(hdc, " ", 1, &size);
spacewidth = size.cx;
GetTextExtentPoint(hdc, "o", 1, &size);
tabwidth = size.cx * tabstop;
}
do
{
prefix_offset = -1;
strPtr = TEXT_NextLine(hdc, strPtr, &count, line, &len, width, flags);
if (prefix_offset != -1)
{
GetTextExtentPoint(hdc, line, prefix_offset - 1, &size);
prefix_x = size.cx;
GetTextExtentPoint(hdc, line + prefix_offset, 1, &size);
prefix_len = size.cx;
}
if (!GetTextExtentPoint(hdc, line, len, &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_SINGLELINE)
{
if (flags & DT_VCENTER) y = rect->top +
(rect->bottom - rect->top) / 2 - size.cy / 2;
else if (flags & DT_BOTTOM) y = rect->bottom - size.cy;
}
if (!(flags & DT_CALCRECT))
if (!TextOut(hdc, x, y, line, len)) return 0;
if (prefix_offset != -1)
{
MoveTo(hdc, x + prefix_x, y + size.cy);
LineTo(hdc, x + prefix_x + prefix_len, y + size.cy);
}
if (strPtr)
{
y += lh;
if (!(flags & DT_NOCLIP))
{
if (y > rect->bottom - lh)
break;
}
}
}
while (strPtr);
if (flags & DT_CALCRECT) rect->bottom = y;
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,
dc->w.DCOrgX + x, dc->w.DCOrgY + y, str, count );
else
XDrawImageString( XT_display, dc->u.x.drawable, dc->u.x.gc,
dc->w.DCOrgX + x, dc->w.DCOrgY + 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,
dc->w.DCOrgX + xchar, dc->w.DCOrgY + y, p, 1 );
else
{
XDrawImageString( XT_display, dc->u.x.drawable, dc->u.x.gc,
dc->w.DCOrgX + xchar, dc->w.DCOrgY + y, p, 1 );
XSetForeground( XT_display, dc->u.x.gc, dc->w.backgroundPixel);
XFillRectangle( XT_display, dc->u.x.drawable, dc->u.x.gc,
dc->w.DCOrgX + xchar + charStr->width,
dc->w.DCOrgY + 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,
dc->w.DCOrgX + x, dc->w.DCOrgY + y + linePos,
dc->w.DCOrgX + x + info.width, dc->w.DCOrgY + 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,
dc->w.DCOrgX + x, dc->w.DCOrgY + y - lineAscent,
dc->w.DCOrgX + x + info.width, dc->w.DCOrgY + y - lineAscent );
}
return TRUE;
}