Text Alignment, how is it handled ?

Ulrich Czekalla ulrich.czekalla at utoronto.ca
Thu Feb 10 13:29:39 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 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)
-------------- 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-patches mailing list