Text Alignment, how is it handled ?

Ulrich Czekalla ulrich at codeweavers.com
Thu Feb 10 11:58:05 CST 2005


Hi George,

I haven't heard back from you so I assume you haven't implemented anything
yet. Here is my quick attempt at adding support for ES_RIGHT and ES_CENTER.

Modifying the edit control made me realize how much room there is to
improve the overall edit control implementation. Of course, my patch makes
no attempt to rewrite any of it ;-)

/Ulrich


On Tue, Feb 08, 2005 at 12:53:56PM -0500, Ulrich Czekalla wrote:
> Actually I just started to look at this as well. I expect to have a patch
> in the next day or so. If you already have something let me know and I'll
> stop working on it.
> 
> Thanks,
> 
> /Ulrich
> 
> On Tue, Feb 08, 2005 at 09:26:30AM +0100, George Ginden wrote:
> > Dimitrie O. Paun ha scritto:
> > 
> > >Currently, our edit box (dlls/user/edit.c) does not support
> > >right-aligned fields. It is a known limitation. If you want
> > >you can try to implement it, and submit a patch.
> > > 
> > >
> > OK, I'm into it. But wait, I'm pretty new to the Wine codebase...
> > Do you think it is a hard implementation or an easy one ?
> > If the alignment thing is still not implement... Well there must be a 
> > reason ...
> > Do I miss somthing ?
> > 
> > Regards.
> > 
> > 
> 
-------------- next part --------------
Index: dlls/user/edit.c
===================================================================
RCS file: /home/wine/wine/dlls/user/edit.c,v
retrieving revision 1.14
diff -u -p -r1.14 edit.c
--- dlls/user/edit.c	19 Jan 2005 20:53:38 -0000	1.14
+++ dlls/user/edit.c	10 Feb 2005 17:49:00 -0000
@@ -1274,7 +1274,10 @@ static void EDIT_BuildLineDefs_ML(EDITST
 		rc.top = es->format_rect.top + nstart_line * es->line_height -
 			(es->y_offset * es->line_height); /* Adjust for vertical scrollbar */
 		rc.bottom = rc.top + es->line_height;
-		rc.left = es->format_rect.left + (INT)LOWORD(GetTabbedTextExtentW(dc,
+		if ((es->style & ES_CENTER) || (es->style & ES_RIGHT))
+			rc.left = es->format_rect.left;
+		else
+		    rc.left = es->format_rect.left + (INT)LOWORD(GetTabbedTextExtentW(dc,
 					es->text + nstart_index, istart - nstart_index,
 					es->tabs_count, es->tabs)) - es->x_offset; /* Adjust for horz scroll */
 		rc.right = es->format_rect.right;
@@ -1312,7 +1315,27 @@ static void EDIT_BuildLineDefs_ML(EDITST
  */
 static void EDIT_CalcLineWidth_SL(EDITSTATE *es)
 {
-    es->text_width = (short)LOWORD(EDIT_EM_PosFromChar(es, strlenW(es->text), FALSE));
+	SIZE size;
+	LPWSTR text;
+	HDC dc;
+	HFONT old_font = 0;
+
+	text = EDIT_GetPasswordPointer_SL(es);
+
+	dc = GetDC(es->hwndSelf);
+	if (es->font)
+		old_font = SelectObject(dc, es->font);
+
+	GetTextExtentPoint32W(dc, text, strlenW(text), &size);
+
+	if (es->font)
+		SelectObject(dc, old_font);
+	ReleaseDC(es->hwndSelf, dc);
+
+	if (es->style & ES_PASSWORD)
+		HeapFree(GetProcessHeap(), 0, text);
+
+	es->text_width = size.cx;
 }
 
 /*********************************************************************
@@ -1412,6 +1435,10 @@ static INT EDIT_CharFromPos(EDITSTATE *e
 			line--;
 		}
 		x += es->x_offset - es->format_rect.left;
+		if (es->style & ES_RIGHT)
+			x -= (es->format_rect.right - es->format_rect.left) - line_def->width;
+		else if (es->style & ES_CENTER)
+			x -= ((es->format_rect.right - es->format_rect.left) - line_def->width) / 2;
 		if (x >= line_def->width) {
 			if (after_wrap)
 				*after_wrap = (line_def->ending == END_WRAP);
@@ -1441,11 +1468,22 @@ static INT EDIT_CharFromPos(EDITSTATE *e
 	} else {
 		LPWSTR text;
 		SIZE size;
+		INT indent;
 		if (after_wrap)
 			*after_wrap = FALSE;
 		x -= es->format_rect.left;
 		if (!x)
 			return es->x_offset;
+
+		if (!es->x_offset)
+		{
+			indent = (es->format_rect.right - es->format_rect.left) - es->text_width;
+			if (es->style & ES_RIGHT)
+				x -= indent;
+			else if (es->style & ES_CENTER)
+				x -= indent / 2;
+		}
+
 		text = EDIT_GetPasswordPointer_SL(es);
 		dc = GetDC(es->hwndSelf);
 		if (es->font)
@@ -2884,9 +2922,13 @@ static LRESULT EDIT_EM_PosFromChar(EDITS
 	INT li;
 	INT x;
 	INT y = 0;
+	INT w;
+	INT lw = 0;
+	INT ll = 0;
 	HDC dc;
 	HFONT old_font = 0;
 	SIZE size;
+	LINEDEF *line_def;
 
 	index = min(index, len);
 	dc = GetDC(es->hwndSelf);
@@ -2898,7 +2940,7 @@ static LRESULT EDIT_EM_PosFromChar(EDITS
 		li = EDIT_EM_LineIndex(es, l);
 		if (after_wrap && (li == index) && l) {
 			INT l2 = l - 1;
-			LINEDEF *line_def = es->first_line_def;
+			line_def = es->first_line_def;
 			while (l2) {
 				line_def = line_def->next;
 				l2--;
@@ -2909,8 +2951,32 @@ static LRESULT EDIT_EM_PosFromChar(EDITS
 				li = EDIT_EM_LineIndex(es, l);
 			}
 		}
-		x = LOWORD(GetTabbedTextExtentW(dc, es->text + li, index - li,
+
+		line_def = es->first_line_def;
+		while (line_def->index != li)
+			line_def = line_def->next;
+
+		ll = line_def->net_length;
+		lw = line_def->width;
+
+		w = es->format_rect.right - es->format_rect.left;
+		if (es->style & ES_RIGHT)
+		{
+			x = LOWORD(GetTabbedTextExtentW(dc, es->text + li + (index - li), ll - (index - li),
+				es->tabs_count, es->tabs)) - es->x_offset;
+			x = w - x;
+		}
+		else if (es->style & ES_CENTER)
+		{
+			x = LOWORD(GetTabbedTextExtentW(dc, es->text + li, index - li,
+				es->tabs_count, es->tabs)) - es->x_offset;
+			x += (w - lw) / 2;
+		}
+		else /* if (es->style & ES_LEFT) */
+		{
+		    x = LOWORD(GetTabbedTextExtentW(dc, es->text + li, index - li,
 				es->tabs_count, es->tabs)) - es->x_offset;
+		}
 	} else {
 		LPWSTR text = EDIT_GetPasswordPointer_SL(es);
 		if (index < es->x_offset) {
@@ -2921,6 +2987,18 @@ static LRESULT EDIT_EM_PosFromChar(EDITS
 			GetTextExtentPoint32W(dc, text + es->x_offset,
 					index - es->x_offset, &size);
 			 x = size.cx;
+
+			if (!es->x_offset)
+			{
+				w = es->format_rect.right - es->format_rect.left;
+				if (w > es->text_width)
+				{
+					if (es->style & ES_RIGHT)
+						x += w - es->text_width;
+					else if (es->style & ES_CENTER)
+						x += (w - es->text_width) / 2;
+				}
+			}
 		}
 		y = 0;
 		if (es->style & ES_PASSWORD)
@@ -3054,6 +3132,20 @@ static void EDIT_EM_ReplaceSel(EDITSTATE
 	else
 	    EDIT_CalcLineWidth_SL(es);
 
+	/* If text has been deleted and we're right or center aligned then scroll rightward */
+	if (es->style & (ES_RIGHT | ES_CENTER))
+	{
+		INT delta = strl - abs(es->selection_end - es->selection_start);
+
+		if (delta < 0 && es->x_offset)
+		{
+			if (abs(delta) > es->x_offset)
+				es->x_offset = 0;
+			else
+				es->x_offset += delta;
+		}
+	}
+
 	EDIT_EM_SetSel(es, s, s, FALSE);
 	es->flags |= EF_MODIFIED;
 	if (send_update) es->flags |= EF_UPDATE;
@@ -4434,8 +4526,11 @@ static LRESULT EDIT_WM_NCCreate(HWND hwn
 		es->style |= ES_AUTOVSCROLL;
 	} else {
 		es->buffer_limit = BUFLIMIT_SINGLE;
-		es->style &= ~ES_CENTER;
-		es->style &= ~ES_RIGHT;
+		if ((es->style & ES_CENTER) || (es->style & ES_RIGHT)) 
+		{
+			if (es->style & ES_RIGHT)
+				es->style &= ~ES_CENTER;
+		}
 		es->style &= ~WS_HSCROLL;
 		es->style &= ~WS_VSCROLL;
 		if (es->style & ES_PASSWORD)


More information about the wine-devel mailing list