57#define BUFLIMIT_INITIAL 30000
59#define ROUND_TO_GROW(size) (((size) + (GROWLENGTH - 1)) & ~(GROWLENGTH - 1))
60#define HSCROLL_FRACTION 3
65#define EF_MODIFIED 0x0001
66#define EF_FOCUSED 0x0002
67#define EF_UPDATE 0x0004
68#define EF_VSCROLL_TRACK 0x0008
69#define EF_HSCROLL_TRACK 0x0010
70#define EF_AFTER_WRAP 0x0080
72#define EF_USE_SOFTBRK 0x0100
73#define EF_DIALOGMODE 0x0200
75#define ID_CB_LISTBOX 1000
138 BOOL cue_banner_draw_focused;
154 int composition_start;
164#define SWAP_UINT32(x,y) do { UINT temp = (UINT)(x); (x) = (UINT)(y); (y) = temp; } while(0)
165#define ORDER_UINT(x,y) do { if ((UINT)(y) < (UINT)(x)) SWAP_UINT32((x),(y)); } while(0)
170 TRACE(
"notification %d sent to %p.\n",
code,
es->hwndParent);
184 return (
es->undo_insert_count ||
lstrlenW(
es->undo_text));
195 es->undo_insert_count = 0;
196 *
es->undo_text =
'\0';
219 if(
es->text_length == (
UINT)-1)
221 return es->text_length;
275 ERR(
"unknown action code, please report !\n");
299 if (
es->word_break_proc)
322 line_def = line_def->
next;
360 WARN(
"ScriptStringAnalyse failed (%x)\n",
hr);
370 return line_def->
ssa;
391 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);
393 ScriptStringAnalyse(udc,
es->text,
length, (1.5*
length+16), -1,
SSA_LINK|
SSA_FALLBACK|
SSA_GLYPHS, -1,
NULL,
NULL,
NULL,
NULL,
NULL, &
es->ssa);
404 line_def =
es->first_line_def;
405 while (line_def &&
line)
407 line_def = line_def->
next;
417 INT vlc = (
es->format_rect.bottom -
es->format_rect.top) /
es->line_height;
437 INT line_index = 0, nstart_line, nstart_index;
438 INT line_count =
es->line_count;
443 if (istart == iend && delta == 0)
446 previous_line =
NULL;
447 current_line =
es->first_line_def;
452 if (istart < current_line->
index + current_line->
length ||
456 previous_line = current_line;
457 current_line = current_line->
next;
459 }
while (current_line);
463 FIXME(
" modification occurred outside buffer\n");
468 nstart_line = line_index;
469 nstart_index = current_line->
index;
476 current_line = previous_line;
478 start_line = current_line;
480 fw =
es->format_rect.right -
es->format_rect.left;
481 current_position =
es->text + current_line->
index;
484 if (current_line != start_line)
486 if (!current_line || current_line->
index + delta > current_position -
es->text)
490 LINEDEF *new_line = heap_alloc_zero(
sizeof(*new_line));
491 new_line->
next = previous_line->
next;
492 previous_line->
next = new_line;
493 current_line = new_line;
496 else if (current_line->
index + delta < current_position - es->
text)
499 previous_line->
next = current_line->
next;
501 current_line = previous_line->
next;
507 if (current_position -
es->text > iend)
513 current_line->
index = current_position -
es->text;
517 cp = current_position;
519 if (*
cp ==
'\n')
break;
520 if ((*
cp ==
'\r') && (*(
cp + 1) ==
'\n'))
529 }
else if ((
cp > current_position) && (*(
cp - 1) ==
'\r')) {
532 }
else if (*
cp ==
'\n') {
545 if (current_line->
ssa)
553 else current_line->
width = 0;
560 if (current_line->
width > fw && fw >
es->char_width) {
570 if (
d > 1.2f)
d -= 0.2f;
579 if (current_line->
ssa)
587 }
while (prev && current_line->
width > fw);
597 if (current_line->
ssa)
605 current_line->
width -= piDx[prev];
607 }
while ( prev > 0 && current_line->
width > fw);
613 prev = (fw /
es->char_width);
618 if (current_line->
index == nstart_index && istart > current_line->
index + prev)
619 istart = current_line->
index + prev;
622 else if (current_line == start_line &&
623 current_line->
index != nstart_index && orig_net_length < prev)
627 nstart_line = line_index;
628 nstart_index = current_line->
index;
629 istart = current_line->
index + orig_net_length;
638 if (current_line->
ssa)
644 current_line->
width = 0;
646 else current_line->
width = 0;
648 else if (current_line == start_line &&
649 current_line->
index != nstart_index &&
654 nstart_line = line_index;
655 nstart_index = current_line->
index;
656 istart = current_line->
index + orig_net_length;
662 switch (current_line->
ending) {
677 es->text_width =
max(
es->text_width, current_line->
width);
678 current_position += current_line->
length;
679 previous_line = current_line;
682 if ((line_index < es->y_offset) || (line_index >
es->y_offset + vlc))
685 current_line = current_line->
next;
697 pnext = current_line->
next;
700 current_line = pnext;
708 current_line->
index += delta;
709 current_line = current_line->
next;
722 rc.
top =
es->format_rect.top + nstart_line *
es->line_height -
723 (
es->y_offset *
es->line_height);
726 rc.
left =
es->format_rect.left;
733 rc.
right =
es->format_rect.right;
737 rc.
left =
es->format_rect.left;
738 rc.
right =
es->format_rect.right;
743 if (line_count < es->line_count)
745 else if (line_count >
es->line_count)
746 rc.
bottom = line_count *
es->line_height;
748 rc.
bottom = line_index *
es->line_height;
750 rc.
bottom -= (
es->y_offset *
es->line_height);
769 es->text_width =
size->cx;
791 INT line = (
y -
es->format_rect.top) /
es->line_height +
es->y_offset;
795 while ((
line > 0) && line_def->next) {
796 line_index += line_def->length;
797 line_def = line_def->next;
801 x +=
es->x_offset -
es->format_rect.left;
803 x -= (
es->format_rect.right -
es->format_rect.left) - line_def->width;
805 x -= ((
es->format_rect.right -
es->format_rect.left) - line_def->width) / 2;
806 if (
x >= line_def->width) {
808 *after_wrap = (line_def->ending ==
END_WRAP);
809 return line_index + line_def->net_length;
811 if (x <= 0 || !line_def->
ssa) {
818 if (trailing)
index++;
821 *after_wrap = ((
index == line_index + line_def->net_length) &&
828 x -=
es->format_rect.left;
834 INT indent = (
es->format_rect.right -
es->format_rect.left) -
es->text_width;
859 if (
x + xoff > 0 || !
es->ssa)
862 if (trailing)
index++;
876 else if (
x >
size->cx)
881 if (trailing)
index++;
904 *
x =
min(
max(*
x,
es->format_rect.left),
es->format_rect.right - 1);
905 *
y =
min(
max(*
y,
es->format_rect.top),
es->format_rect.bottom - 1);
922 return es->line_count - 1;
927 line_def =
es->first_line_def;
931 line_def = line_def->
next;
950 if (
line >=
es->line_count)
954 line_def =
es->first_line_def;
958 line_index += line_def->
length;
959 line_def = line_def->
next;
964 line_index += line_def->
length;
965 line_def = line_def->
next;
999 line_def =
es->first_line_def;
1001 while ((
index >= 0) && line_def->
next) {
1002 line_def = line_def->
next;
1030 y = (
l -
es->y_offset) *
es->line_height;
1032 if (after_wrap && (
li ==
index) &&
l) {
1034 line_def =
es->first_line_def;
1036 line_def = line_def->
next;
1041 y -=
es->line_height;
1046 line_def =
es->first_line_def;
1048 line_def = line_def->
next;
1050 lw = line_def->
width;
1051 w =
es->format_rect.right -
es->format_rect.left;
1063 x = (lw > 0 ?
es->x_offset :
x -
es->x_offset);
1091 xoff +=
es->char_width * leftover;
1122 w =
es->format_rect.right -
es->format_rect.left;
1123 if (
w >
es->text_width)
1126 x +=
w -
es->text_width;
1128 x += (
w -
es->text_width) / 2;
1134 x +=
es->format_rect.left;
1135 y +=
es->format_rect.top;
1157 rc->
top =
es->format_rect.top + (
line -
es->y_offset) *
es->line_height;
1161 line_def =
es->first_line_def;
1164 while ((
index >= 0) && line_def->
next) {
1165 line_index += line_def->
length;
1166 line_def = line_def->
next;
1171 line_index += line_def->
length;
1172 line_def = line_def->
next;
1181 rc->
top =
es->format_rect.top;
1191 pt3+=
es->format_rect.left;
1201 es->text_length = (
UINT)-1;
1236 WARN(
"edit hwnd %p already destroyed\n",
es->hwndSelf);
1240 if (!
es->lock_count)
1242 ERR(
"lock_count == 0 ... please report\n");
1248 ERR(
"es->text == 0 ... please report\n");
1252 if (force || (
es->lock_count == 1))
1261 ERR(
"no buffer ... please report\n");
1284 TRACE(
"trying to ReAlloc to %d+1 characters\n",
size);
1292 TRACE(
"Old 32 bit handle %p, new handle %p\n",
es->hloc32W, hNew32W);
1293 es->hloc32W = hNew32W;
1300 if (
es->buffer_size <
size) {
1301 WARN(
"FAILED ! We now have %d+1\n",
es->buffer_size);
1305 TRACE(
"We now have %d+1\n",
es->buffer_size);
1322 if (size <= es->undo_buffer_size)
1325 TRACE(
"trying to ReAlloc to %d+1\n",
size);
1329 es->undo_buffer_size = alloc_size/
sizeof(
WCHAR) - 1;
1334 WARN(
"FAILED ! We now have %d+1\n",
es->undo_buffer_size);
1348 es->flags &= ~EF_UPDATE;
1363 es->flags &= ~EF_UPDATE;
1408 if ((el < es->y_offset) || (sl >
es->y_offset + vlc))
1413 if (sl < es->y_offset) {
1417 if (el >
es->y_offset + vlc) {
1418 el =
es->y_offset + vlc;
1434 for (
l = sl + 1 ;
l < el ;
l++) {
1492 UINT old_start =
es->selection_start;
1493 UINT old_end =
es->selection_end;
1496 if (
start == old_start &&
end == old_end)
1501 end =
es->selection_end;
1507 es->selection_end =
end;
1511 es->flags &= ~EF_AFTER_WRAP;
1529 if (
end != old_start)
1539 if (old_start >
end )
1569 si.
nMax =
es->line_count - 1;
1570 si.
nPage = (
es->format_rect.bottom -
es->format_rect.top) /
es->line_height;
1572 TRACE(
"SB_VERT, nMin=%d, nMax=%d, nPage=%d, nPos=%d\n",
1583 si.
nMax =
es->text_width - 1;
1584 si.
nPage =
es->format_rect.right -
es->format_rect.left;
1586 TRACE(
"SB_HORZ, nMin=%d, nMax=%d, nPage=%d, nPos=%d\n",
1605 INT x_offset_in_pixels;
1606 INT lines_per_page = (
es->format_rect.bottom -
es->format_rect.top) /
1611 x_offset_in_pixels =
es->x_offset;
1619 if (-
dx > x_offset_in_pixels)
1620 dx = -x_offset_in_pixels;
1621 if (
dx >
es->text_width - x_offset_in_pixels)
1622 dx =
es->text_width - x_offset_in_pixels;
1623 nyoff =
max(0,
es->y_offset +
dy);
1624 if (nyoff >=
es->line_count - lines_per_page)
1625 nyoff =
max(0,
es->line_count - lines_per_page);
1626 dy = (
es->y_offset - nyoff) *
es->line_height;
1631 es->y_offset = nyoff;
1635 es->x_offset +=
dx /
es->char_width;
1663 dx *=
es->char_width;
1688 if (
es->y_offset <
es->line_count - 1)
1693 dy = -(
es->format_rect.bottom -
es->format_rect.top) /
es->line_height;
1696 if (
es->y_offset <
es->line_count - 1)
1697 dy = (
es->format_rect.bottom -
es->format_rect.top) /
es->line_height;
1705 if(
es->y_offset +
dy >
es->line_count - vlc)
1706 dy =
max(
es->line_count - vlc, 0) -
es->y_offset;
1768 EDIT_ImmSetCompositionWindow(
es,
pt);
1787 INT cw =
es->char_width;
1795 if (
l >=
es->y_offset + vlc)
1796 dy =
l - vlc + 1 -
es->y_offset;
1797 if (l < es->y_offset)
1798 dy =
l -
es->y_offset;
1799 ww =
es->format_rect.right -
es->format_rect.left;
1800 if (x < es->format_rect.left)
1802 if (
x >
es->format_rect.right)
1804 if (
dy ||
dx || (
es->y_offset && (
es->line_count -
es->y_offset < vlc)))
1807 if(
es->x_offset +
dx + ww >
es->text_width)
1808 dx =
es->text_width - ww -
es->x_offset;
1809 if(
dx ||
dy || (
es->y_offset && (
es->line_count -
es->y_offset < vlc)))
1818 format_width =
es->format_rect.right -
es->format_rect.left;
1819 if (x < es->format_rect.left) {
1824 }
while ((
x < goal) &&
es->x_offset);
1827 }
else if (
x >
es->format_rect.right) {
1835 }
while ((
x > goal) && (x_last >
es->format_rect.right));
1852 INT e =
es->selection_end;
1857 (
es->text[
e - 1] ==
'\r') && (
es->text[
e] ==
'\n')) {
1859 if (
e && (
es->text[
e - 1] ==
'\r'))
1879 INT s =
es->selection_start;
1880 INT e =
es->selection_end;
1922 INT e =
es->selection_end;
1927 if (
es->text[
e] ==
'\n')
1929 else if ((
es->text[
e] ==
'\r') && (
es->text[
e + 1] ==
'\n'))
1971 INT s =
es->selection_start;
1972 INT e =
es->selection_end;
1979 y + (
es->format_rect.bottom -
es->format_rect.top),
1999 INT s =
es->selection_start;
2000 INT e =
es->selection_end;
2007 y - (
es->format_rect.bottom -
es->format_rect.top),
2027 INT s =
es->selection_start;
2028 INT e =
es->selection_end;
2049 INT s =
es->selection_start;
2050 INT e =
es->selection_end;
2080 INT s =
es->selection_start;
2081 INT e =
es->selection_end;
2113 HFONT hUnderline = 0;
2129 if (
es->composition_len == 0)
2148 es->tabs_count,
es->tabs,
es->format_rect.left -
es->x_offset));
2158 if (
es->composition_len == 0)
2196 if ((line < es->y_offset) || (
line >
es->y_offset + vlc) || (
line >=
es->line_count))
2210 int line_idx =
line;
2217 while (line_def && line_idx)
2219 line_def = line_def->
next;
2222 w =
es->format_rect.right -
es->format_rect.left;
2223 lw = line_def->
width;
2230 x +=
es->format_rect.left;
2237 s =
min(
es->selection_start,
es->selection_end);
2238 e =
max(
es->selection_start,
es->selection_end);
2245 else if (
rev && (
s !=
e) &&
2253 if (
es->cue_banner_text &&
es->text_length == 0 && (!(
es->flags &
EF_FOCUSED) ||
es->cue_banner_draw_focused))
2273 es->format_rect.right =
max(
es->format_rect.right,
es->format_rect.left +
es->char_width);
2276 INT fw, vlc, max_x_offset, max_y_offset;
2279 es->format_rect.bottom =
es->format_rect.top + vlc *
es->line_height;
2282 fw =
es->format_rect.right -
es->format_rect.left;
2283 max_x_offset =
es->text_width - fw;
2284 if(max_x_offset < 0) max_x_offset = 0;
2285 if(
es->x_offset > max_x_offset)
2286 es->x_offset = max_x_offset;
2289 max_y_offset =
es->line_count - vlc;
2290 if(max_y_offset < 0) max_y_offset = 0;
2291 if(
es->y_offset > max_y_offset)
2292 es->y_offset = max_y_offset;
2299 es->format_rect.bottom =
es->format_rect.top +
es->line_height;
2303 es->format_rect.bottom =
min(
es->format_rect.bottom, ClientRect.
bottom);
2329 es->format_rect.left++;
2330 es->format_rect.right--;
2332 if (
es->format_rect.bottom -
es->format_rect.top
2333 >=
es->line_height + 2)
2335 es->format_rect.top++;
2336 es->format_rect.bottom--;
2343 if (
es->format_rect.bottom -
es->format_rect.top >=
es->line_height + 2 * bh)
2347 es->format_rect.left +=
es->left_margin;
2348 es->format_rect.right -=
es->right_margin;
2394 es->flags &= ~EF_USE_SOFTBRK;
2397 FIXME(
"soft break enabled, not implemented\n");
2422 es->hlocapp =
es->hloc32W;
2436 INT line_len, dst_len;
2442 if (
line >=
es->line_count)
2453 if (dst_len <= line_len)
2494 BOOL send_update,
BOOL honor_limit)
2507 TRACE(
"%s, can_undo %d, send_update %d\n",
2508 debugstr_wn(lpsz_replace, strl), can_undo, send_update);
2510 s =
es->selection_start;
2511 e =
es->selection_end;
2514 if ((
s ==
e) && !strl)
2519 size = tl - (
e -
s) + strl;
2525 if ((honor_limit) && (
size >
es->buffer_limit))
2529 if (
es->buffer_limit < (tl - (
e-
s)))
2532 strl =
min(strl,
es->buffer_limit - (tl - (
e-
s)));
2540 TRACE(
"deleting stuff.\n");
2554 for (
p =
es->text + tl ;
p >=
es->text +
s ;
p--)
2556 for (
i = 0 ,
p =
es->text +
s ;
i < strl ;
i++)
2557 p[
i] = lpsz_replace[
i];
2566 INT st =
min(
es->selection_start,
es->selection_end);
2571 strl -
abs(
es->selection_end -
es->selection_start),
hrgn);
2577 for (
i = 0 ,
p =
es->text ;
i <
e -
s ;
i++)
2581 abs(
es->selection_end -
es->selection_start) - strl,
hrgn);
2589 INT fw =
es->format_rect.right -
es->format_rect.left;
2594 while ((
es->text_width > fw) &&
s + strl >=
s) {
2597 es->text_length = -1;
2609 if (!
es->undo_insert_count && (*
es->undo_text && (
s ==
es->undo_position))) {
2613 (
es->undo_text + utl)[
e -
s] = 0;
2614 }
else if (!
es->undo_insert_count && (*
es->undo_text && (
e ==
es->undo_position))) {
2617 for (
p =
es->undo_text + utl ;
p >=
es->undo_text ;
p--)
2619 for (
i = 0 ,
p =
es->undo_text ;
i <
e -
s ;
i++)
2621 es->undo_position =
s;
2626 es->undo_text[
e -
s] = 0;
2627 es->undo_position =
s;
2630 es->undo_insert_count = 0;
2636 if ((
s ==
es->undo_position) ||
2637 ((
es->undo_insert_count) &&
2638 (
s ==
es->undo_position +
es->undo_insert_count)))
2643 es->undo_insert_count += strl;
2646 es->undo_position =
s;
2647 es->undo_insert_count = strl;
2649 *
es->undo_text =
'\0';
2662 INT delta = strl -
abs(
es->selection_end -
es->selection_start);
2664 if (delta < 0 && es->x_offset)
2666 if (
abs(delta) >
es->x_offset)
2669 es->x_offset += delta;
2692 es->flags &= ~EF_UPDATE;
2725 es->x_offset =
es->y_offset = 0;
2726 es->selection_start =
es->selection_end = 0;
2728 es->flags &= ~EF_MODIFIED;
2729 es->flags &= ~EF_UPDATE;
2758 case 932:
case 936:
case 949:
case 950:
case 1361:
2762 (
fs.fsCsb[0] & FS_DBCS_MASK));
2769 if (side_bearing < 0)
2770 margin =
min(-side_bearing,
width/2);
2799 INT default_left_margin = 0;
2800 INT default_right_margin = 0;
2820 default_left_margin =
width / 2;
2821 default_right_margin =
width / 2;
2826 if (rc_width < default_left_margin + default_right_margin +
width * 2) {
2827 default_left_margin =
es->left_margin;
2828 default_right_margin =
es->right_margin;
2836 es->format_rect.left -=
es->left_margin;
2840 es->left_margin = default_left_margin;
2841 es->format_rect.left +=
es->left_margin;
2845 es->format_rect.right +=
es->right_margin;
2849 es->right_margin = default_right_margin;
2850 es->format_rect.right -=
es->right_margin;
2858 TRACE(
"left=%d, right=%d\n",
es->left_margin,
es->right_margin);
2874 if (
es->password_char ==
c)
2878 es->password_char =
c;
2884 es->style &= ~ES_PASSWORD;
2920 if (
es->word_break_proc == wbp)
2923 es->word_break_proc = wbp;
2953 TRACE(
"before UNDO:insertion length = %d, deletion buffer = %s\n",
2965 TRACE(
"after UNDO:insertion length = %d, deletion buffer = %s\n",
3027 INT s =
min(
es->selection_start,
es->selection_end);
3028 INT e =
max(
es->selection_start,
es->selection_end);
3086 if (
es->bCaptureState)
3107 static const WCHAR cr_lfW[] = {
'\r',
'\n'};
3115 static const WCHAR tabW[] = {
'\t'};
3123 if (
es->selection_start !=
es->selection_end)
3190 ERR(
"unknown menu item, please report\n");
3239 if (
pt.x == -1 &&
pt.y == -1)
3284 HWND hLBox =
es->hwndListBox;
3296 TRACE(
"[%p]: handling msg %x (%x)\n",
es->hwndSelf,
msg,
key);
3403 if (
es->selection_start !=
es->selection_end) {
3481 HWND hwndSelf =
es->hwndSelf;
3483 es->flags &= ~EF_FOCUSED;
3489 es->wheelDeltaRemainder = 0;
3509 INT e =
es->selection_end;
3514 es->bCaptureState =
TRUE;
3524 es->region_posx =
es->region_posy = 0;
3540 es->bCaptureState =
TRUE;
3546 es->region_posx =
es->region_posy = 0;
3563 if (
es->bCaptureState) {
3607 es->region_posx = (prex <
x) ? -1 : ((prex >
x) ? 1 : 0);
3608 es->region_posy = (prey <
y) ? -1 : ((prey >
y) ? 1 : 0);
3676 es->format_rect.top,
3677 es->format_rect.right,
3678 es->format_rect.bottom);
3686 if (!
es->bEnableState)
3691 for (
i =
es->y_offset ;
i <=
min(
es->y_offset + vlc,
es->y_offset +
es->line_count - 1) ;
i++) {
3714 HRGN cliprgn = region;
3737 r.right - cxEdge,
r.bottom - cyEdge);
3738 if (region != (HRGN)1)
3763 if (cliprgn != region)
3844 es->line_height =
tm.tmHeight;
3845 es->char_width =
tm.tmAveCharWidth;