This patch is experimental but people had some interest in testing it and I would love some more testing.

What is currently known not to be working:
 * Tabs
 * Font Fallback
 * Complex composed glyphs are not breaking or highlighting properly.

Testing is appreceated. Send me crashes or incorrect behavior.

It should work with both native and builtin usp10.

The patch will be cleaned and broken up before being send it this is just for testing.

thanks!

-aric

---
dlls/user32/edit.c | 495 +++++++++++++++++++++++++++-------------------------
 1 files changed, 256 insertions(+), 239 deletions(-)


diff --git a/dlls/user32/edit.c b/dlls/user32/edit.c
index da57b97..49b71be 100644
--- a/dlls/user32/edit.c
+++ b/dlls/user32/edit.c
@@ -98,6 +98,7 @@ typedef struct tagLINEDEF {
 	LINE_END ending;
 	INT width;			/* width of the line in pixels */
 	INT index; 			/* line index into the buffer */
+	SCRIPT_STRING_ANALYSIS ssa; /* Uniscribe Data */
 	struct tagLINEDEF *next;
 } LINEDEF;
 
@@ -158,6 +159,7 @@ typedef struct
 	 * Uniscribe Data
 	 */
 	SCRIPT_LOGATTR *logAttr;
+	SCRIPT_STRING_ANALYSIS ssa; /* Uniscribe Data for single line controls */
 } EDITSTATE;
 
 
@@ -175,6 +177,10 @@ typedef struct
 	} while(0)
 
 static const WCHAR empty_stringW[] = {0};
+static SCRIPT_STRING_ANALYSIS EDIT_UpdateUniscribeData(EDITSTATE *es, HDC dc, int line);
+static SCRIPT_STRING_ANALYSIS EDIT_UpdateUniscribeData_linedef(EDITSTATE *es, HDC dc, LINEDEF *line_def);
+static INT EDIT_EM_LineIndex(const EDITSTATE *es, INT line);
+static LRESULT EDIT_EM_PosFromChar(EDITSTATE *es, INT index, BOOL after_wrap);
 
 /*********************************************************************
  *
@@ -259,7 +265,6 @@ static inline UINT get_text_length(EDITSTATE *es)
     return es->text_length;
 }
 
-
 /*********************************************************************
  *
  *	EDIT_WordBreakProc
@@ -365,6 +370,30 @@ static INT EDIT_CallWordBreakProc(EDITSTATE *es, INT start, INT index, INT count
 	return ret;
 }
 
+static inline void EDIT_InvalidateUniscribeData_linedef(LINEDEF *line_def)
+{
+	if (line_def->ssa)
+	{
+		ScriptStringFree(&line_def->ssa);
+		line_def->ssa = NULL;
+	}
+}
+
+static inline void EDIT_InvalidateUniscribeData(EDITSTATE *es)
+{
+	LINEDEF *line_def = es->first_line_def;
+	while (line_def)
+	{
+		EDIT_InvalidateUniscribeData_linedef(line_def);
+		line_def = line_def->next;
+	}
+	if (es->ssa)
+	{
+		ScriptStringFree(&es->ssa);
+		es->ssa = NULL;
+	}
+}
+
 /*********************************************************************
  *
  *	EDIT_BuildLineDefs_ML
@@ -392,6 +421,7 @@ static void EDIT_BuildLineDefs_ML(EDITSTATE *es, INT istart, INT iend, INT delta
 		return;
 
 	dc = GetDC(es->hwndSelf);
+
 	if (es->font)
 		old_font = SelectObject(dc, es->font);
 
@@ -439,7 +469,7 @@ static void EDIT_BuildLineDefs_ML(EDITSTATE *es, INT istart, INT iend, INT delta
 			{
 				/* The buffer has been expanded, create a new line and
 				   insert it into the link list */
-				LINEDEF *new_line = HeapAlloc(GetProcessHeap(), 0, sizeof(LINEDEF));
+				LINEDEF *new_line = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(LINEDEF));
 				new_line->next = previous_line->next;
 				previous_line->next = new_line;
 				current_line = new_line;
@@ -489,34 +519,68 @@ static void EDIT_BuildLineDefs_ML(EDITSTATE *es, INT istart, INT iend, INT delta
 			current_line->net_length = cp - current_position;
 		}
 
-		/* Calculate line width */
-		current_line->width = (INT)LOWORD(GetTabbedTextExtentW(dc,
-					current_position, current_line->net_length,
-					es->tabs_count, es->tabs));
+		if (current_line->net_length)
+		{
+			const SIZE *sz;
+			EDIT_InvalidateUniscribeData_linedef(current_line);
+			EDIT_UpdateUniscribeData_linedef(es, dc, current_line);
+			sz = ScriptString_pSize(current_line->ssa);
+			/* Calculate line width */
+			current_line->width = sz->cx;
+		}
+		else current_line->width = 0;
 
 		/* FIXME: check here for lines that are too wide even in AUTOHSCROLL (> 32767 ???) */
+
+/* Line breaks just look back from then end and find the next break and tries that. */
+
 		if (!(es->style & ES_AUTOHSCROLL)) {
 		   if (current_line->width > fw) {
-			INT next = 0;
+
 			INT prev;
+			int w;
+			const SIZE *sz;
+
+ERR("ARIC Start!\n");
+			prev = current_line->net_length - 1;
+			w = current_line->net_length;
 			do {
-				prev = next;
-				next = EDIT_CallWordBreakProc(es, current_position - es->text,
-						prev + 1, current_line->net_length, WB_RIGHT);
-				current_line->width = (INT)LOWORD(GetTabbedTextExtentW(dc,
-							current_position, next, es->tabs_count, es->tabs));
-			} while (current_line->width <= fw);
-			if (!prev) { /* Didn't find a line break so force a break */
-				next = 0;
+				prev = EDIT_CallWordBreakProc(es, current_position - es->text,
+						prev-1, current_line->net_length, WB_LEFT);
+				current_line->net_length = prev;
+				EDIT_InvalidateUniscribeData_linedef(current_line);
+				EDIT_UpdateUniscribeData_linedef(es, dc, current_line);
+				sz = ScriptString_pSize(current_line->ssa);
+				if (sz)
+					current_line->width = sz->cx;
+				else
+					prev = 0;
+			} while (prev && current_line->width > fw);
+			current_line->net_length = w;
+
+ERR("ARIC choose %i\n",prev);
+			if (prev == 0) { /* Didn't find a line break so force a break */
+				INT *piDx;
+				const INT *count;
+
+				EDIT_InvalidateUniscribeData_linedef(current_line);
+				EDIT_UpdateUniscribeData_linedef(es, dc, current_line);
+
+				count = ScriptString_pcOutChars(current_line->ssa);
+				piDx = HeapAlloc(GetProcessHeap(),0,sizeof(INT) * (*count));
+				ScriptStringGetLogicalWidths(current_line->ssa,piDx);
+
+				prev = current_line->net_length-1;
 				do {
-					prev = next;
-					next++;
-					current_line->width = (INT)LOWORD(GetTabbedTextExtentW(dc,
-								current_position, next, es->tabs_count, es->tabs));
-				} while (current_line->width <= fw);
-				if (!prev)
+ERR("ARIC shrink %i is %i result %i\n",prev, piDx[prev], current_line->width - piDx[prev]);
+					current_line->width -= piDx[prev];
+					prev--;
+				} while ( prev > 0 && current_line->width > fw);
+				if (prev==0)
 					prev = 1;
+				HeapFree(GetProcessHeap(),0,piDx);
 			}
+ERR("ARIC choose-2 %i\n",prev);
 
 			/* If the first line we are calculating, wrapped before istart, we must
 			 * adjust istart in order for this to be reflected in the update region. */
@@ -536,8 +600,14 @@ static void EDIT_BuildLineDefs_ML(EDITSTATE *es, INT istart, INT iend, INT delta
 
 			current_line->net_length = prev;
 			current_line->ending = END_WRAP;
-			current_line->width = (INT)LOWORD(GetTabbedTextExtentW(dc, current_position,
-					current_line->net_length, es->tabs_count, es->tabs));
+
+			if (current_line->net_length > 0)
+			{
+				EDIT_UpdateUniscribeData_linedef(es, dc, current_line);
+				sz = ScriptString_pSize(current_line->ssa);
+				current_line->width = sz->cx;
+			}
+			else current_line->width = 0;
 		    }
 		    else if (current_line == start_line &&
                              current_line->index != nstart_index &&
@@ -584,6 +654,7 @@ static void EDIT_BuildLineDefs_ML(EDITSTATE *es, INT istart, INT iend, INT delta
 		while (current_line)
 		{
 			pnext = current_line->next;
+			EDIT_InvalidateUniscribeData_linedef(current_line);
 			HeapFree(GetProcessHeap(), 0, current_line);
 			current_line = pnext;
 			es->line_count--;
@@ -613,9 +684,7 @@ static void EDIT_BuildLineDefs_ML(EDITSTATE *es, INT istart, INT iend, INT delta
 		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.left = LOWORD(EDIT_EM_PosFromChar(es, nstart_index, FALSE));
 		rc.right = es->format_rect.right;
 		SetRectRgn(hrgn, rc.left, rc.top, rc.right, rc.bottom);
 
@@ -647,23 +716,82 @@ static void EDIT_BuildLineDefs_ML(EDITSTATE *es, INT istart, INT iend, INT delta
 
 /*********************************************************************
  *
- *	EDIT_GetPasswordPointer_SL
- *
- *	note: caller should free the (optionally) allocated buffer
- *
+ * EDIT_UpdateUniscribeData
  */
-static LPWSTR EDIT_GetPasswordPointer_SL(EDITSTATE *es)
+static SCRIPT_STRING_ANALYSIS EDIT_UpdateUniscribeData_linedef(EDITSTATE *es, HDC dc, LINEDEF *line_def)
 {
-	if (es->style & ES_PASSWORD) {
-		INT len = get_text_length(es);
-		LPWSTR text = HeapAlloc(GetProcessHeap(), 0, (len + 1) * sizeof(WCHAR));
-		text[len] = '\0';
-		while(len) text[--len] = es->password_char;
-		return text;
-	} else
-		return es->text;
+	if (!line_def)
+		return NULL;
+
+	if (line_def->net_length && !line_def->ssa)
+	{
+		int index = line_def->index;
+		HFONT old_font = NULL;
+		HDC udc = dc;
+		SCRIPT_TABDEF tabdef;
+
+		if (!udc)
+			udc = GetDC(es->hwndSelf);
+		if (es->font)
+			old_font = SelectObject(udc, es->font);
+
+		tabdef.cTabStops = es->tabs_count;
+		tabdef.iScale = 0;
+		tabdef.pTabStops = es->tabs;
+		tabdef.iTabOrigin = 0;
+
+		ScriptStringAnalyse(udc, &es->text[index], line_def->net_length, (1.5*line_def->net_length+16), -1, SSA_LINK|SSA_FALLBACK|SSA_GLYPHS|SSA_TAB, -1, NULL, NULL, NULL, &tabdef, NULL, &line_def->ssa);
+
+		if (es->font)
+			SelectObject(udc, old_font);
+		if (udc != dc)
+			ReleaseDC(es->hwndSelf, udc);
+	}
+
+	return line_def->ssa;
 }
 
+static SCRIPT_STRING_ANALYSIS EDIT_UpdateUniscribeData(EDITSTATE *es, HDC dc, INT line)
+{
+	LINEDEF *line_def;
+
+	if (!(es->style & ES_MULTILINE))
+	{
+		if (!es->ssa)
+		{
+			INT length = get_text_length(es);
+			HFONT old_font = NULL;
+			HDC udc = dc;
+
+			if (!udc)
+				udc = GetDC(es->hwndSelf);
+			if (es->font)
+				old_font = SelectObject(udc, es->font);
+
+			if (es->style & ES_PASSWORD)
+				ScriptStringAnalyse(udc, &es->password_char, length, (1.5*length+16), -1, SSA_LINK|SSA_FALLBACK|SSA_GLYPHS|SSA_PASSWORD, -1, NULL, NULL, NULL, NULL, NULL, &es->ssa);
+			else
+				ScriptStringAnalyse(udc, es->text, length, (1.5*length+16), -1, SSA_LINK|SSA_FALLBACK|SSA_GLYPHS, -1, NULL, NULL, NULL, NULL, NULL, &es->ssa);
+
+			if (es->font)
+				SelectObject(udc, old_font);
+			if (udc != dc)
+				ReleaseDC(es->hwndSelf, udc);
+		}
+		return es->ssa;
+	}
+	else
+	{
+		line_def = es->first_line_def;
+		while (line_def && line)
+		{
+			line_def = line_def->next;
+			line--;
+		}
+
+		return EDIT_UpdateUniscribeData_linedef(es,dc,line_def);
+	}
+}
 
 /*********************************************************************
  *
@@ -672,27 +800,14 @@ static LPWSTR EDIT_GetPasswordPointer_SL(EDITSTATE *es)
  */
 static void EDIT_CalcLineWidth_SL(EDITSTATE *es)
 {
-	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);
+	const SIZE *size;
 
-	es->text_width = size.cx;
+	EDIT_UpdateUniscribeData(es, NULL, 0);
+	size = ScriptString_pSize(es->ssa);
+	if (size)
+		es->text_width = size->cx;
+	else
+		es->text_width = 0;
 }
 
 /*********************************************************************
@@ -708,20 +823,19 @@ static void EDIT_CalcLineWidth_SL(EDITSTATE *es)
 static INT EDIT_CharFromPos(EDITSTATE *es, INT x, INT y, LPBOOL after_wrap)
 {
 	INT index;
-	HDC dc;
-	HFONT old_font = 0;
-	INT x_high = 0, x_low = 0;
 
 	if (es->style & ES_MULTILINE) {
+		int trailing;
 		INT line = (y - es->format_rect.top) / es->line_height + es->y_offset;
 		INT line_index = 0;
 		LINEDEF *line_def = es->first_line_def;
-		INT low, high;
+		EDIT_UpdateUniscribeData(es, NULL, line);
 		while ((line > 0) && line_def->next) {
 			line_index += line_def->length;
 			line_def = line_def->next;
 			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;
@@ -737,34 +851,16 @@ static INT EDIT_CharFromPos(EDITSTATE *es, INT x, INT y, LPBOOL after_wrap)
 				*after_wrap = FALSE;
 			return line_index;
 		}
-		dc = GetDC(es->hwndSelf);
-		if (es->font)
-			old_font = SelectObject(dc, es->font);
-                    low = line_index;
-                    high = line_index + line_def->net_length + 1;
-                    while (low < high - 1)
-                    {
-                        INT mid = (low + high) / 2;
-                        INT x_now = LOWORD(GetTabbedTextExtentW(dc, es->text + line_index, mid - line_index, es->tabs_count, es->tabs));
-                        if (x_now > x) {
-                            high = mid;
-                            x_high = x_now;
-                        } else {
-                            low = mid;
-                            x_low = x_now;
-                        }
-                    }
-                    if (abs(x_high - x) + 1 <= abs(x_low - x))
-                        index = high;
-                    else
-                        index = low;
 
+	ScriptStringXtoCP(line_def->ssa, x , &index, &trailing);
+	if (trailing) index++;
+	index += line_index;
 		if (after_wrap)
 			*after_wrap = ((index == line_index + line_def->net_length) &&
 							(line_def->ending == END_WRAP));
 	} else {
-		LPWSTR text;
-		SIZE size;
+		INT xoff = 0;
+		INT trailing;
 		if (after_wrap)
 			*after_wrap = FALSE;
 		x -= es->format_rect.left;
@@ -780,60 +876,39 @@ static INT EDIT_CharFromPos(EDITSTATE *es, INT x, INT y, LPBOOL after_wrap)
 				x -= indent / 2;
 		}
 
-		text = EDIT_GetPasswordPointer_SL(es);
-		dc = GetDC(es->hwndSelf);
-		if (es->font)
-			old_font = SelectObject(dc, es->font);
+		EDIT_UpdateUniscribeData(es, NULL, 0);
+		if (es->x_offset)
+			ScriptStringCPtoX(es->ssa, es->x_offset, FALSE, &xoff);
 		if (x < 0)
                 {
-                    INT low = 0;
-                    INT high = es->x_offset;
-                    while (low < high - 1)
-                    {
-                        INT mid = (low + high) / 2;
-                        GetTextExtentPoint32W( dc, text + mid,
-                                               es->x_offset - mid, &size );
-                        if (size.cx > -x) {
-                            low = mid;
-                            x_low = size.cx;
-                        } else {
-                            high = mid;
-                            x_high = size.cx;
-                        }
-                    }
-                    if (abs(x_high + x) <= abs(x_low + x) + 1)
-                        index = high;
-                    else
-                        index = low;
+			if (x + xoff > 0)
+			{
+				ScriptStringXtoCP(es->ssa, x+xoff, &index, &trailing);
+				if (trailing) index++;
+			}
+			else
+				index = 0;
 		}
                 else
                 {
-                    INT low = es->x_offset;
-                    INT high = get_text_length(es) + 1;
-                    while (low < high - 1)
-                    {
-                        INT mid = (low + high) / 2;
-                        GetTextExtentPoint32W( dc, text + es->x_offset,
-                                               mid - es->x_offset, &size );
-                        if (size.cx > x) {
-                               high = mid;
-                               x_high = size.cx;
-                        } else {
-                               low = mid;
-                               x_low = size.cx;
-                       }
-                    }
-                   if (abs(x_high - x) <= abs(x_low - x) + 1)
-                       index = high;
-                   else
-                       index = low;
+			if (x)
+			{
+				const SIZE *size;
+				size = ScriptString_pSize(es->ssa);
+				if (!size)
+					index = 0;
+				else if (x > size->cx)
+					index = get_text_length(es);
+				else
+				{
+					ScriptStringXtoCP(es->ssa, x+xoff, &index, &trailing);
+					if (trailing) index++;
+				}
+			}
+			else
+				index = es->x_offset;
 		}
-		if (es->style & ES_PASSWORD)
-			HeapFree(GetProcessHeap(), 0, text);
 	}
-	if (es->font)
-		SelectObject(dc, old_font);
-	ReleaseDC(es->hwndSelf, dc);
 	return index;
 }
 
@@ -963,22 +1038,19 @@ static LRESULT EDIT_EM_PosFromChar(EDITSTATE *es, INT index, BOOL after_wrap)
 	INT len = get_text_length(es);
 	INT l;
 	INT li;
-	INT x;
+	INT x = 0;
 	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);
-	if (es->font)
-		old_font = SelectObject(dc, es->font);
+
 	if (es->style & ES_MULTILINE) {
 		l = EDIT_EM_LineFromChar(es, index);
+		EDIT_UpdateUniscribeData(es, NULL, l);
+
 		y = (l - es->y_offset) * es->line_height;
 		li = EDIT_EM_LineIndex(es, l);
 		if (after_wrap && (li == index) && l) {
@@ -1002,35 +1074,45 @@ static LRESULT EDIT_EM_PosFromChar(EDITSTATE *es, INT index, BOOL after_wrap)
 		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;
+    ScriptStringCPtoX(line_def->ssa, ll - ((index - 1) - li) , TRUE, &x);
+    x = x - 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;
+    ScriptStringCPtoX(line_def->ssa, (index - 1) - li, TRUE, &x);
+    x -= es->x_offset;
 			x += (w - lw) / 2;
 		}
 		else /* ES_LEFT */
 		{
-		    x = LOWORD(GetTabbedTextExtentW(dc, es->text + li, index - li,
-				es->tabs_count, es->tabs)) - es->x_offset;
+    ScriptStringCPtoX(line_def->ssa, (index - 1) - li, TRUE, &x);
+    x -= es->x_offset;
 		}
 	} else {
-		LPWSTR text = EDIT_GetPasswordPointer_SL(es);
-		if (index < es->x_offset) {
-			GetTextExtentPoint32W(dc, text + index,
-					es->x_offset - index, &size);
-			x = -size.cx;
-		} else {
-			GetTextExtentPoint32W(dc, text + es->x_offset,
-					index - es->x_offset, &size);
-			 x = size.cx;
+		INT xoff = 0;
+		INT xi = 0;
+		EDIT_UpdateUniscribeData(es, NULL, 0);
+		if (es->x_offset)
+			ScriptStringCPtoX(es->ssa, es->x_offset, FALSE, &xoff);
+		if (index)
+        {
+			if (index >= get_text_length(es))
+			{
+				const SIZE *size;
+				size = ScriptString_pSize(es->ssa);
+				xi = size->cx;
+			}
+			else
+				ScriptStringCPtoX(es->ssa, index, FALSE, &xi);
+        }
+		x = xi - xoff;
 
+		if (index >= es->x_offset) {
 			if (!es->x_offset && (es->style & (ES_RIGHT | ES_CENTER)))
 			{
 				w = es->format_rect.right - es->format_rect.left;
@@ -1044,14 +1126,10 @@ static LRESULT EDIT_EM_PosFromChar(EDITSTATE *es, INT index, BOOL after_wrap)
 			}
 		}
 		y = 0;
-		if (es->style & ES_PASSWORD)
-			HeapFree(GetProcessHeap(), 0, text);
 	}
 	x += es->format_rect.left;
 	y += es->format_rect.top;
-	if (es->font)
-		SelectObject(dc, old_font);
-	ReleaseDC(es->hwndSelf, dc);
+
 	return MAKELONG((INT16)x, (INT16)y);
 }
 
@@ -1067,14 +1145,18 @@ static LRESULT EDIT_EM_PosFromChar(EDITSTATE *es, INT index, BOOL after_wrap)
 static void EDIT_GetLineRect(EDITSTATE *es, INT line, INT scol, INT ecol, LPRECT rc)
 {
 	INT line_index =  EDIT_EM_LineIndex(es, line);
+	INT pt1, pt2;
 
 	if (es->style & ES_MULTILINE)
 		rc->top = es->format_rect.top + (line - es->y_offset) * es->line_height;
 	else
 		rc->top = es->format_rect.top;
 	rc->bottom = rc->top + es->line_height;
-	rc->left = (scol == 0) ? es->format_rect.left : (short)LOWORD(EDIT_EM_PosFromChar(es, line_index + scol, TRUE));
-	rc->right = (ecol == -1) ? es->format_rect.right : (short)LOWORD(EDIT_EM_PosFromChar(es, line_index + ecol, TRUE));
+
+	pt1 = (scol == 0) ? es->format_rect.left : (short)LOWORD(EDIT_EM_PosFromChar(es, line_index + scol, TRUE));
+	pt2 = (ecol == -1) ? es->format_rect.right : (short)LOWORD(EDIT_EM_PosFromChar(es, line_index + ecol, TRUE));
+	rc->right = max(pt1,pt2);
+	rc->left = min(pt1, pt2);
 }
 
 
@@ -1087,6 +1169,7 @@ static inline void text_buffer_changed(EDITSTATE *es)
         HeapFree(GetProcessHeap(),0,es->logAttr);
         es->logAttr = NULL;
     }
+    EDIT_InvalidateUniscribeData(es);
 }
 
 /*********************************************************************
@@ -1291,6 +1374,7 @@ static void EDIT_UpdateText(EDITSTATE *es, const RECT *rc, BOOL bErase)
         es->flags &= ~EF_UPDATE;
         EDIT_NOTIFY_PARENT(es, EN_UPDATE);
     }
+    EDIT_InvalidateUniscribeData(es);
     InvalidateRect(es->hwndSelf, rc, bErase);
 }
 
@@ -1987,76 +2071,6 @@ static void EDIT_MoveWordForward(EDITSTATE *es, BOOL extend)
 	EDIT_EM_ScrollCaret(es);
 }
 
-
-/*********************************************************************
- *
- *	EDIT_PaintText
- *
- */
-static INT EDIT_PaintText(EDITSTATE *es, HDC dc, INT x, INT y, INT line, INT col, INT count, BOOL rev)
-{
-	COLORREF BkColor;
-	COLORREF TextColor;
-	LOGFONTW underline_font;
-	HFONT hUnderline = 0;
-	HFONT old_font = 0;
-	INT ret;
-	INT li;
-	INT BkMode;
-	SIZE size;
-
-	if (!count)
-		return 0;
-	BkMode = GetBkMode(dc);
-	BkColor = GetBkColor(dc);
-	TextColor = GetTextColor(dc);
-	if (rev) {
-	        if (es->composition_len == 0)
-	        {
-			SetBkColor(dc, GetSysColor(COLOR_HIGHLIGHT));
-			SetTextColor(dc, GetSysColor(COLOR_HIGHLIGHTTEXT));
-			SetBkMode( dc, OPAQUE);
-	        }
-		else
-		{
-			HFONT current = GetCurrentObject(dc,OBJ_FONT);
-			GetObjectW(current,sizeof(LOGFONTW),&underline_font);
-			underline_font.lfUnderline = TRUE;
-	            	hUnderline = CreateFontIndirectW(&underline_font);
-			old_font = SelectObject(dc,hUnderline);
-	        }
-	}
-	li = EDIT_EM_LineIndex(es, line);
-	if (es->style & ES_MULTILINE) {
-		ret = (INT)LOWORD(TabbedTextOutW(dc, x, y, es->text + li + col, count,
-					es->tabs_count, es->tabs, es->format_rect.left - es->x_offset));
-	} else {
-		LPWSTR text = EDIT_GetPasswordPointer_SL(es);
-		TextOutW(dc, x, y, text + li + col, count);
-		GetTextExtentPoint32W(dc, text + li + col, count, &size);
-		ret = size.cx;
-		if (es->style & ES_PASSWORD)
-			HeapFree(GetProcessHeap(), 0, text);
-	}
-	if (rev) {
-		if (es->composition_len == 0)
-		{
-			SetBkColor(dc, BkColor);
-			SetTextColor(dc, TextColor);
-			SetBkMode( dc, BkMode);
-		}
-		else
-		{
-			if (old_font)
-				SelectObject(dc,old_font);
-			if (hUnderline)
-				DeleteObject(hUnderline);
-	        }
-	}
-	return ret;
-}
-
-
 /*********************************************************************
  *
  *	EDIT_PaintLine
@@ -2071,6 +2085,7 @@ static void EDIT_PaintLine(EDITSTATE *es, HDC dc, INT line, BOOL rev)
 	INT x;
 	INT y;
 	LRESULT pos;
+	SCRIPT_STRING_ANALYSIS ssa;
 
 	if (es->style & ES_MULTILINE) {
 		INT vlc = get_vertical_line_count(es);
@@ -2082,6 +2097,8 @@ static void EDIT_PaintLine(EDITSTATE *es, HDC dc, INT line, BOOL rev)
 
 	TRACE("line=%d\n", line);
 
+	ssa = EDIT_UpdateUniscribeData(es, dc, line);
+
 	pos = EDIT_EM_PosFromChar(es, EDIT_EM_LineIndex(es, line), FALSE);
 	x = (short)LOWORD(pos);
 	y = (short)HIWORD(pos);
@@ -2091,13 +2108,8 @@ static void EDIT_PaintLine(EDITSTATE *es, HDC dc, INT line, BOOL rev)
 	e = max(es->selection_start, es->selection_end);
 	s = min(li + ll, max(li, s));
 	e = min(li + ll, max(li, e));
-	if (rev && (s != e) &&
-			((es->flags & EF_FOCUSED) || (es->style & ES_NOHIDESEL))) {
-		x += EDIT_PaintText(es, dc, x, y, line, 0, s - li, FALSE);
-		x += EDIT_PaintText(es, dc, x, y, line, s - li, e - s, TRUE);
-		x += EDIT_PaintText(es, dc, x, y, line, e - li, li + ll - e, FALSE);
-	} else
-		x += EDIT_PaintText(es, dc, x, y, line, 0, ll, FALSE);
+
+	ScriptStringOut(ssa, x, y, 0, &es->format_rect, s - li, e - li, FALSE);
 }
 
 
@@ -2765,6 +2777,7 @@ static void EDIT_EM_SetPasswordChar(EDITSTATE *es, WCHAR c)
             SetWindowLongW( es->hwndSelf, GWL_STYLE, style & ~ES_PASSWORD );
             es->style &= ~ES_PASSWORD;
 	}
+	EDIT_InvalidateUniscribeData(es);
 	EDIT_UpdateText(es, NULL, TRUE);
 }
 
@@ -2786,6 +2799,7 @@ static BOOL EDIT_EM_SetTabStops(EDITSTATE *es, INT count, const INT *tabs)
 		es->tabs = HeapAlloc(GetProcessHeap(), 0, count * sizeof(INT));
 		memcpy(es->tabs, tabs, count * sizeof(INT));
 	}
+	EDIT_InvalidateUniscribeData(es);
 	return TRUE;
 }
 
@@ -3537,6 +3551,7 @@ static void EDIT_WM_Paint(EDITSTATE *es, HDC hdc)
 	if (es->font)
 		old_font = SelectObject(dc, es->font);
 
+	EDIT_InvalidateUniscribeData(es);
 	if (!es->bEnableState)
 		SetTextColor(dc, GetSysColor(COLOR_GRAYTEXT));
 	GetClipBox(dc, &rcRgn);
@@ -3605,6 +3620,7 @@ static void EDIT_WM_SetFont(EDITSTATE *es, HFONT font, BOOL redraw)
 	RECT clientRect;
 
 	es->font = font;
+	EDIT_InvalidateUniscribeData(es);
 	dc = GetDC(es->hwndSelf);
 	if (font)
 		old_font = SelectObject(dc, font);
@@ -4316,6 +4332,7 @@ static LRESULT EDIT_WM_NCCreate(HWND hwnd, LPCREATESTRUCTW lpcs, BOOL unicode)
 
 cleanup:
 	SetWindowLongPtrW(es->hwndSelf, 0, 0);
+	EDIT_InvalidateUniscribeData(es);
 	HeapFree(GetProcessHeap(), 0, es->first_line_def);
 	HeapFree(GetProcessHeap(), 0, es->undo_text);
 	if (es->hloc32W) LocalFree(es->hloc32W);



Reply via email to