55#include "wine/unicode.h"
61#define BUFLIMIT_INITIAL 30000
63#define ROUND_TO_GROW(size) (((size) + (GROWLENGTH - 1)) & ~(GROWLENGTH - 1))
64#define HSCROLL_FRACTION 3
69#define EF_MODIFIED 0x0001
70#define EF_FOCUSED 0x0002
71#define EF_UPDATE 0x0004
72#define EF_VSCROLL_TRACK 0x0008
73#define EF_HSCROLL_TRACK 0x0010
74#define EF_AFTER_WRAP 0x0080
76#define EF_USE_SOFTBRK 0x0100
77#define EF_DIALOGMODE 0x0200
79#define ID_CB_LISTBOX 1000
140 INT wheelDeltaRemainder;
155 int composition_start;
165#define SWAP_UINT32(x,y) do { UINT temp = (UINT)(x); (x) = (UINT)(y); (y) = temp; } while(0)
166#define ORDER_UINT(x,y) do { if ((UINT)(y) < (UINT)(x)) SWAP_UINT32((x),(y)); } while(0)
171 TRACE(
"notification %d sent to %p.\n",
code,
es->hwndParent);
185 return (
es->undo_insert_count ||
strlenW(
es->undo_text));
196 es->undo_insert_count = 0;
197 *
es->undo_text =
'\0';
220 if(
es->text_length == (
UINT)-1)
222 return es->text_length;
276 ERR(
"unknown action code, please report !\n");
300 if (
es->word_break_proc)
323 line_def = line_def->
next;
361 WARN(
"ScriptStringAnalyse failed (%x)\n",
hr);
371 return line_def->
ssa;
392 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);
394 ScriptStringAnalyse(udc,
es->text,
length, (1.5*
length+16), -1,
SSA_LINK|
SSA_FALLBACK|
SSA_GLYPHS, -1,
NULL,
NULL,
NULL,
NULL,
NULL, &
es->ssa);
405 line_def =
es->first_line_def;
406 while (line_def &&
line)
408 line_def = line_def->
next;
418 INT vlc = (
es->format_rect.bottom -
es->format_rect.top) /
es->line_height;
438 INT line_index = 0, nstart_line, nstart_index;
439 INT line_count =
es->line_count;
444 if (istart == iend && delta == 0)
447 previous_line =
NULL;
448 current_line =
es->first_line_def;
453 if (istart < current_line->
index + current_line->
length ||
457 previous_line = current_line;
458 current_line = current_line->
next;
460 }
while (current_line);
464 FIXME(
" modification occurred outside buffer\n");
469 nstart_line = line_index;
470 nstart_index = current_line->
index;
477 current_line = previous_line;
479 start_line = current_line;
481 fw =
es->format_rect.right -
es->format_rect.left;
482 current_position =
es->text + current_line->
index;
485 if (current_line != start_line)
487 if (!current_line || current_line->
index + delta > current_position -
es->text)
491 LINEDEF *new_line = heap_alloc_zero(
sizeof(*new_line));
492 new_line->
next = previous_line->
next;
493 previous_line->
next = new_line;
494 current_line = new_line;
497 else if (current_line->
index + delta < current_position - es->
text)
500 previous_line->
next = current_line->
next;
502 current_line = previous_line->
next;
508 if (current_position -
es->text > iend)
514 current_line->
index = current_position -
es->text;
518 cp = current_position;
520 if (*
cp ==
'\n')
break;
521 if ((*
cp ==
'\r') && (*(
cp + 1) ==
'\n'))
530 }
else if ((
cp > current_position) && (*(
cp - 1) ==
'\r')) {
533 }
else if (*
cp ==
'\n') {
546 if (current_line->
ssa)
554 else current_line->
width = 0;
561 if (current_line->
width > fw && fw >
es->char_width) {
571 if (
d > 1.2f)
d -= 0.2f;
580 if (current_line->
ssa)
588 }
while (prev && current_line->
width > fw);
598 if (current_line->
ssa)
606 current_line->
width -= piDx[prev];
608 }
while ( prev > 0 && current_line->
width > fw);
614 prev = (fw /
es->char_width);
619 if (current_line->
index == nstart_index && istart > current_line->
index + prev)
620 istart = current_line->
index + prev;
623 else if (current_line == start_line &&
624 current_line->
index != nstart_index && orig_net_length < prev)
628 nstart_line = line_index;
629 nstart_index = current_line->
index;
630 istart = current_line->
index + orig_net_length;
639 if (current_line->
ssa)
645 current_line->
width = 0;
647 else current_line->
width = 0;
649 else if (current_line == start_line &&
650 current_line->
index != nstart_index &&
655 nstart_line = line_index;
656 nstart_index = current_line->
index;
657 istart = current_line->
index + orig_net_length;
663 switch (current_line->
ending) {
678 es->text_width =
max(
es->text_width, current_line->
width);
679 current_position += current_line->
length;
680 previous_line = current_line;
683 if ((line_index < es->y_offset) || (line_index >
es->y_offset + vlc))
686 current_line = current_line->
next;
698 pnext = current_line->
next;
701 current_line = pnext;
709 current_line->
index += delta;
710 current_line = current_line->
next;
723 rc.
top =
es->format_rect.top + nstart_line *
es->line_height -
724 (
es->y_offset *
es->line_height);
727 rc.
left =
es->format_rect.left;
734 rc.
right =
es->format_rect.right;
738 rc.
left =
es->format_rect.left;
739 rc.
right =
es->format_rect.right;
744 if (line_count < es->line_count)
746 else if (line_count >
es->line_count)
747 rc.
bottom = line_count *
es->line_height;
749 rc.
bottom = line_index *
es->line_height;
751 rc.
bottom -= (
es->y_offset *
es->line_height);
770 es->text_width =
size->cx;
792 INT line = (
y -
es->format_rect.top) /
es->line_height +
es->y_offset;
796 while ((
line > 0) && line_def->next) {
797 line_index += line_def->length;
798 line_def = line_def->next;
802 x +=
es->x_offset -
es->format_rect.left;
804 x -= (
es->format_rect.right -
es->format_rect.left) - line_def->width;
806 x -= ((
es->format_rect.right -
es->format_rect.left) - line_def->width) / 2;
807 if (
x >= line_def->width) {
809 *after_wrap = (line_def->ending ==
END_WRAP);
810 return line_index + line_def->net_length;
812 if (x <= 0 || !line_def->
ssa) {
819 if (trailing)
index++;
822 *after_wrap = ((
index == line_index + line_def->net_length) &&
829 x -=
es->format_rect.left;
835 INT indent = (
es->format_rect.right -
es->format_rect.left) -
es->text_width;
860 if (
x + xoff > 0 || !
es->ssa)
863 if (trailing)
index++;
877 else if (
x >
size->cx)
882 if (trailing)
index++;
905 *
x =
min(
max(*
x,
es->format_rect.left),
es->format_rect.right - 1);
906 *
y =
min(
max(*
y,
es->format_rect.top),
es->format_rect.bottom - 1);
923 return es->line_count - 1;
928 line_def =
es->first_line_def;
932 line_def = line_def->
next;
951 if (
line >=
es->line_count)
955 line_def =
es->first_line_def;
959 line_index += line_def->
length;
960 line_def = line_def->
next;
965 line_index += line_def->
length;
966 line_def = line_def->
next;
1000 line_def =
es->first_line_def;
1002 while ((
index >= 0) && line_def->
next) {
1003 line_def = line_def->
next;
1031 y = (
l -
es->y_offset) *
es->line_height;
1033 if (after_wrap && (
li ==
index) &&
l) {
1035 line_def =
es->first_line_def;
1037 line_def = line_def->
next;
1042 y -=
es->line_height;
1047 line_def =
es->first_line_def;
1049 line_def = line_def->
next;
1051 lw = line_def->
width;
1052 w =
es->format_rect.right -
es->format_rect.left;
1060 x = (lw > 0 ?
es->x_offset :
x -
es->x_offset);
1088 xoff +=
es->char_width * leftover;
1119 w =
es->format_rect.right -
es->format_rect.left;
1120 if (
w >
es->text_width)
1123 x +=
w -
es->text_width;
1125 x += (
w -
es->text_width) / 2;
1131 x +=
es->format_rect.left;
1132 y +=
es->format_rect.top;
1154 rc->
top =
es->format_rect.top + (
line -
es->y_offset) *
es->line_height;
1158 line_def =
es->first_line_def;
1161 while ((
index >= 0) && line_def->
next) {
1162 line_index += line_def->
length;
1163 line_def = line_def->
next;
1168 line_index += line_def->
length;
1169 line_def = line_def->
next;
1178 rc->
top =
es->format_rect.top;
1188 pt3+=
es->format_rect.left;
1198 es->text_length = (
UINT)-1;
1233 WARN(
"edit hwnd %p already destroyed\n",
es->hwndSelf);
1237 if (!
es->lock_count)
1239 ERR(
"lock_count == 0 ... please report\n");
1245 ERR(
"es->text == 0 ... please report\n");
1249 if (force || (
es->lock_count == 1))
1258 ERR(
"no buffer ... please report\n");
1281 TRACE(
"trying to ReAlloc to %d+1 characters\n",
size);
1289 TRACE(
"Old 32 bit handle %p, new handle %p\n",
es->hloc32W, hNew32W);
1290 es->hloc32W = hNew32W;
1297 if (
es->buffer_size <
size) {
1298 WARN(
"FAILED ! We now have %d+1\n",
es->buffer_size);
1302 TRACE(
"We now have %d+1\n",
es->buffer_size);
1319 if (size <= es->undo_buffer_size)
1322 TRACE(
"trying to ReAlloc to %d+1\n",
size);
1326 es->undo_buffer_size = alloc_size/
sizeof(
WCHAR) - 1;
1331 WARN(
"FAILED ! We now have %d+1\n",
es->undo_buffer_size);
1345 es->flags &= ~EF_UPDATE;
1360 es->flags &= ~EF_UPDATE;
1405 if ((el < es->y_offset) || (sl >
es->y_offset + vlc))
1410 if (sl < es->y_offset) {
1414 if (el >
es->y_offset + vlc) {
1415 el =
es->y_offset + vlc;
1431 for (
l = sl + 1 ;
l < el ;
l++) {
1489 UINT old_start =
es->selection_start;
1490 UINT old_end =
es->selection_end;
1493 if (
start == old_start &&
end == old_end)
1498 end =
es->selection_end;
1504 es->selection_end =
end;
1508 es->flags &= ~EF_AFTER_WRAP;
1526 if (
end != old_start)
1536 if (old_start >
end )
1566 si.
nMax =
es->line_count - 1;
1567 si.
nPage = (
es->format_rect.bottom -
es->format_rect.top) /
es->line_height;
1569 TRACE(
"SB_VERT, nMin=%d, nMax=%d, nPage=%d, nPos=%d\n",
1580 si.
nMax =
es->text_width - 1;
1581 si.
nPage =
es->format_rect.right -
es->format_rect.left;
1583 TRACE(
"SB_HORZ, nMin=%d, nMax=%d, nPage=%d, nPos=%d\n",
1602 INT x_offset_in_pixels;
1603 INT lines_per_page = (
es->format_rect.bottom -
es->format_rect.top) /
1608 x_offset_in_pixels =
es->x_offset;
1616 if (-
dx > x_offset_in_pixels)
1617 dx = -x_offset_in_pixels;
1618 if (
dx >
es->text_width - x_offset_in_pixels)
1619 dx =
es->text_width - x_offset_in_pixels;
1620 nyoff =
max(0,
es->y_offset +
dy);
1621 if (nyoff >=
es->line_count - lines_per_page)
1622 nyoff =
max(0,
es->line_count - lines_per_page);
1623 dy = (
es->y_offset - nyoff) *
es->line_height;
1628 es->y_offset = nyoff;
1632 es->x_offset +=
dx /
es->char_width;
1660 dx *=
es->char_width;
1685 if (
es->y_offset <
es->line_count - 1)
1690 dy = -(
es->format_rect.bottom -
es->format_rect.top) /
es->line_height;
1693 if (
es->y_offset <
es->line_count - 1)
1694 dy = (
es->format_rect.bottom -
es->format_rect.top) /
es->line_height;
1702 if(
es->y_offset +
dy >
es->line_count - vlc)
1703 dy =
max(
es->line_count - vlc, 0) -
es->y_offset;
1760 EDIT_ImmSetCompositionWindow(
es,
pt);
1779 INT cw =
es->char_width;
1787 if (
l >=
es->y_offset + vlc)
1788 dy =
l - vlc + 1 -
es->y_offset;
1789 if (l < es->y_offset)
1790 dy =
l -
es->y_offset;
1791 ww =
es->format_rect.right -
es->format_rect.left;
1792 if (x < es->format_rect.left)
1794 if (
x >
es->format_rect.right)
1796 if (
dy ||
dx || (
es->y_offset && (
es->line_count -
es->y_offset < vlc)))
1799 if(
es->x_offset +
dx + ww >
es->text_width)
1800 dx =
es->text_width - ww -
es->x_offset;
1801 if(
dx ||
dy || (
es->y_offset && (
es->line_count -
es->y_offset < vlc)))
1810 format_width =
es->format_rect.right -
es->format_rect.left;
1811 if (x < es->format_rect.left) {
1816 }
while ((
x < goal) &&
es->x_offset);
1819 }
else if (
x >
es->format_rect.right) {
1827 }
while ((
x > goal) && (x_last >
es->format_rect.right));
1845 INT e =
es->selection_end;
1850 (
es->text[
e - 1] ==
'\r') && (
es->text[
e] ==
'\n')) {
1852 if (
e && (
es->text[
e - 1] ==
'\r'))
1872 INT s =
es->selection_start;
1873 INT e =
es->selection_end;
1915 INT e =
es->selection_end;
1920 if (
es->text[
e] ==
'\n')
1922 else if ((
es->text[
e] ==
'\r') && (
es->text[
e + 1] ==
'\n'))
1964 INT s =
es->selection_start;
1965 INT e =
es->selection_end;
1972 y + (
es->format_rect.bottom -
es->format_rect.top),
1992 INT s =
es->selection_start;
1993 INT e =
es->selection_end;
2000 y - (
es->format_rect.bottom -
es->format_rect.top),
2020 INT s =
es->selection_start;
2021 INT e =
es->selection_end;
2042 INT s =
es->selection_start;
2043 INT e =
es->selection_end;
2073 INT s =
es->selection_start;
2074 INT e =
es->selection_end;
2106 HFONT hUnderline = 0;
2122 if (
es->composition_len == 0)
2141 es->tabs_count,
es->tabs,
es->format_rect.left -
es->x_offset));
2151 if (
es->composition_len == 0)
2189 if ((line < es->y_offset) || (
line >
es->y_offset + vlc) || (
line >=
es->line_count))
2203 int line_idx =
line;
2210 while (line_def && line_idx)
2212 line_def = line_def->
next;
2215 w =
es->format_rect.right -
es->format_rect.left;
2216 lw = line_def->
width;
2223 x +=
es->format_rect.left;
2230 s =
min(
es->selection_start,
es->selection_end);
2231 e =
max(
es->selection_start,
es->selection_end);
2238 else if (
rev && (
s !=
e) &&
2260 es->format_rect.right =
max(
es->format_rect.right,
es->format_rect.left +
es->char_width);
2263 INT fw, vlc, max_x_offset, max_y_offset;
2266 es->format_rect.bottom =
es->format_rect.top + vlc *
es->line_height;
2269 fw =
es->format_rect.right -
es->format_rect.left;
2270 max_x_offset =
es->text_width - fw;
2271 if(max_x_offset < 0) max_x_offset = 0;
2272 if(
es->x_offset > max_x_offset)
2273 es->x_offset = max_x_offset;
2276 max_y_offset =
es->line_count - vlc;
2277 if(max_y_offset < 0) max_y_offset = 0;
2278 if(
es->y_offset > max_y_offset)
2279 es->y_offset = max_y_offset;
2286 es->format_rect.bottom =
es->format_rect.top +
es->line_height;
2290 es->format_rect.bottom =
min(
es->format_rect.bottom, ClientRect.
bottom);
2316 es->format_rect.left++;
2317 es->format_rect.right--;
2319 if (
es->format_rect.bottom -
es->format_rect.top
2320 >=
es->line_height + 2)
2322 es->format_rect.top++;
2323 es->format_rect.bottom--;
2330 if (
es->format_rect.bottom -
es->format_rect.top >=
es->line_height + 2 * bh)
2334 es->format_rect.left +=
es->left_margin;
2335 es->format_rect.right -=
es->right_margin;
2381 es->flags &= ~EF_USE_SOFTBRK;
2384 FIXME(
"soft break enabled, not implemented\n");
2409 es->hlocapp =
es->hloc32W;
2423 INT line_len, dst_len;
2429 if (
line >=
es->line_count)
2440 if (dst_len <= line_len)
2481 BOOL send_update,
BOOL honor_limit)
2494 TRACE(
"%s, can_undo %d, send_update %d\n",
2495 debugstr_wn(lpsz_replace, strl), can_undo, send_update);
2497 s =
es->selection_start;
2498 e =
es->selection_end;
2501 if ((
s ==
e) && !strl)
2506 size = tl - (
e -
s) + strl;
2512 if ((honor_limit) && (
size >
es->buffer_limit))
2516 if (
es->buffer_limit < (tl - (
e-
s)))
2519 strl =
min(strl,
es->buffer_limit - (tl - (
e-
s)));
2527 TRACE(
"deleting stuff.\n");
2541 for (
p =
es->text + tl ;
p >=
es->text +
s ;
p--)
2543 for (
i = 0 ,
p =
es->text +
s ;
i < strl ;
i++)
2544 p[
i] = lpsz_replace[
i];
2553 INT st =
min(
es->selection_start,
es->selection_end);
2558 strl -
abs(
es->selection_end -
es->selection_start),
hrgn);
2564 for (
i = 0 ,
p =
es->text ;
i <
e -
s ;
i++)
2568 abs(
es->selection_end -
es->selection_start) - strl,
hrgn);
2576 INT fw =
es->format_rect.right -
es->format_rect.left;
2581 while ((
es->text_width > fw) &&
s + strl >=
s) {
2584 es->text_length = -1;
2596 if (!
es->undo_insert_count && (*
es->undo_text && (
s ==
es->undo_position))) {
2600 (
es->undo_text + utl)[
e -
s] = 0;
2601 }
else if (!
es->undo_insert_count && (*
es->undo_text && (
e ==
es->undo_position))) {
2604 for (
p =
es->undo_text + utl ;
p >=
es->undo_text ;
p--)
2606 for (
i = 0 ,
p =
es->undo_text ;
i <
e -
s ;
i++)
2608 es->undo_position =
s;
2613 es->undo_text[
e -
s] = 0;
2614 es->undo_position =
s;
2617 es->undo_insert_count = 0;
2623 if ((
s ==
es->undo_position) ||
2624 ((
es->undo_insert_count) &&
2625 (
s ==
es->undo_position +
es->undo_insert_count)))
2630 es->undo_insert_count += strl;
2633 es->undo_position =
s;
2634 es->undo_insert_count = strl;
2636 *
es->undo_text =
'\0';
2649 INT delta = strl -
abs(
es->selection_end -
es->selection_start);
2651 if (delta < 0 && es->x_offset)
2653 if (
abs(delta) >
es->x_offset)
2656 es->x_offset += delta;
2679 es->flags &= ~EF_UPDATE;
2712 es->x_offset =
es->y_offset = 0;
2713 es->selection_start =
es->selection_end = 0;
2715 es->flags &= ~EF_MODIFIED;
2716 es->flags &= ~EF_UPDATE;
2772 INT default_left_margin = 0;
2773 INT default_right_margin = 0;
2785 default_left_margin =
width / 2;
2786 default_right_margin =
width / 2;
2791 default_left_margin =
es->left_margin;
2792 default_right_margin =
es->right_margin;
2796 default_left_margin =
width / 2;
2797 default_right_margin =
width / 2;
2805 es->format_rect.left -=
es->left_margin;
2809 es->left_margin = default_left_margin;
2810 es->format_rect.left +=
es->left_margin;
2814 es->format_rect.right +=
es->right_margin;
2818 es->right_margin = default_right_margin;
2819 es->format_rect.right -=
es->right_margin;
2827 TRACE(
"left=%d, right=%d\n",
es->left_margin,
es->right_margin);
2843 if (
es->password_char ==
c)
2847 es->password_char =
c;
2853 es->style &= ~ES_PASSWORD;
2889 if (
es->word_break_proc == wbp)
2892 es->word_break_proc = wbp;
2922 TRACE(
"before UNDO:insertion length = %d, deletion buffer = %s\n",
2934 TRACE(
"after UNDO:insertion length = %d, deletion buffer = %s\n",
2996 INT s =
min(
es->selection_start,
es->selection_end);
2997 INT e =
max(
es->selection_start,
es->selection_end);
3071 static const WCHAR cr_lfW[] = {
'\r',
'\n'};
3079 static const WCHAR tabW[] = {
'\t'};
3087 if (
es->selection_start !=
es->selection_end)
3154 ERR(
"unknown menu item, please report\n");
3203 if (
pt.x == -1 &&
pt.y == -1)
3248 HWND hLBox =
es->hwndListBox;
3260 TRACE(
"[%p]: handling msg %x (%x)\n",
es->hwndSelf,
msg,
key);
3367 if (
es->selection_start !=
es->selection_end) {
3378 }
else if (control) {
3450 HWND hwndSelf =
es->hwndSelf;
3452 es->flags &= ~EF_FOCUSED;
3458 es->wheelDeltaRemainder = 0;
3478 INT e =
es->selection_end;
3483 es->bCaptureState =
TRUE;
3493 es->region_posx =
es->region_posy = 0;
3509 es->bCaptureState =
TRUE;
3515 es->region_posx =
es->region_posy = 0;
3532 if (
es->bCaptureState) {
3576 es->region_posx = (prex <
x) ? -1 : ((prex >
x) ? 1 : 0);
3577 es->region_posy = (prey <
y) ? -1 : ((prey >
y) ? 1 : 0);
3645 es->format_rect.top,
3646 es->format_rect.right,
3647 es->format_rect.bottom);
3655 if (!
es->bEnableState)
3660 for (
i =
es->y_offset ;
i <=
min(
es->y_offset + vlc,
es->y_offset +
es->line_count - 1) ;
i++) {
3683 HRGN cliprgn = region;
3706 r.right - cxEdge,
r.bottom - cyEdge);
3707 if (region != (HRGN)1)
3787 es->line_height =
tm.tmHeight;
3788 es->char_width =
tm.tmAveCharWidth;
3848 ERR(
"SetSel may generate UPDATE message whose handler may reset "
3863 es->flags &= ~EF_MODIFIED;