Although the text must be empty for the mode to change to plain text
mode, there still may be a non-default style for the temporary insert
style and style for the end of text run.
ME_SplitRun is only called by wrapping code. In all but one call the
returned second half of the split run will be returned, get passed back
to ME_WrapHandleRun, then ME_CalcRunExtent will be called at the start of
ME_WrapHandleRun through ME_WrapSizeRun.
There are unsupported flags documented on MSDN which would cause problems
for the equality checks used in EM_SETCHARFORMAT. Also, to handle a
combined set of flags they must be checked for in the right order.
The first paragraph was being handled just by ME_StreamOutParaProps,
but subsequent paragraphs would check if the paragraph was starting or
ending a table. So I moved the code to check for tables into
ME_StreamOutParaProps.
This is a regression caused by commit
54b53b6018 which change the code to use
if statements instead of a switch, so the break statement should have
been changed to a continue statement.
ME_InsertTextFromCursor could previously follow the ME_CommitUndo call
leaving uncommitted changes which would cause improper grouping of commits,
or an assertion failure.
The call to ME_SendSelChange cannot be done in ME_CommitUndo like it was
before, because it must be done after wrapping. Native richedit controls
send EN_CHANGE first, which is sent in ME_UpdateRepaint, so
ME_SendSelChange must be before this notification in ME_UpdateRepaint.
Revert commit 049cf5aca0
richedit: Avoid notifying parent window in improper state.
The commit was meant to fix a problem caused by ME_SendSelChange being
called in ME_SendSelChange, but moving the calls to ME_CommitUndo caused
a regression. So this patch reverts the previous commit, and my
following patch will instead fix the bug by moving the call to
ME_SendSelChange out of ME_CommitUndo.
ME_CommitUndo and ME_CommitCoalescingUndo call ME_SendSelChange, which
may notify the parent window that the selection has changed, therefore
should generally be called after wrapping the text. Otherwise, the parent
window may send a message to the editor and cause an assertion failure.
The border widths documented by msdn are in points which are 72 dpi, which
is not equivalent to pixels (normally 96 dpi). I pre-converted all the
border widths to 96 dpi resolution since this avoids needed to store
fractions, and often avoids the need for convertion to the displays
resolution.
The existing tests were not properly testing the return value for the case
where all the text fits in the page rect, so this patch adds a couple of
simple tests for this case.
The parent window for the richedit control on creation is the one that
receives notify messages, even after the parent has been changed using
SetParent.
Using the ITextHost interface allows this notification to be received
for windowless richedit controls. Windowed richedit conrols have an
ITextHost implementation that will fill in hwndFrom and idFrom, but
these should probably be initialized to 0 for windowless richedit
controls.
For some reason the code previously mixed up a selection cursor with the
result cursor. The problem seemed to have corrected itself before as a
result of conversion between offsets and cursors, but my recent changes
made this bug more severe.
The function was used in one place, and was simply a wrapper around a
call to ME_InsertRunAtCursor, so I removed it to avoids it use in other
parts of the code.
Previously the function was only used to move a single character in
either direction, so I made the function more general so that it could
be used in more places.
The test that succeeded from this change was as a result of allowing the
end of the character format change be specified using NULL as the rest
of the text. Before, the end paragraph run at the end of the text was
not being set for this case, when all the text was supposed to have its
character format changed.
Plenty of places in the code find following or preceding runs, then
afterwards find the paragraph from the run. This is inefficient because
the same linked list is used for both runs and paragraphs, so changes in
paragraphs can be detected while returning the next or previous run.
The code was previously getting the same text in the loop from the
editor, and it was converting each of the prefixes to compare against
for each URL candidate.
Before a single length was used for the number of characters to retrieve
from the text, and to keep track of the size of the buffer. These are
not equivalent, since there is a possible end of line conversion.
Previously the only convenient way to get the start and end of the
selection was through offsets, which eventually need to get converted
back into items in the linked list storing the text. The new function
will help with eliminating these inefficiencies.
This function will make it easier to work with ME_Cursor objects, which
should be used in a lot of places instead of character offsets (which
often require seeking through the linked lists to perform operations
with).
Since the table row start is inserted after the rest of the table is
inserted, the cursor is saved, and temporarily moved to the start of the
row to insert the table row start paragraph. Unfortunately the
paragraph in saved cursor becomes invalid during this insertion and
needs to be updated, so this code introduced a regression once
paragraphs started to be stored in cursors.
Style objects are referenced counted in richedit controls, so I tried to
make sure styles were released properly. This can be checked using with
the all_refs global reference count to see if everything is cleaned up.
Previously inserting the object didn't result in the text being wrapped,
which would cause an assertion error when this is checked for during
repainting the text. It is also important to invalidate the affected
areas of text, update the scrollbar, and end the creation of undo
transactions for this insertion.
The application AutoGK was getting the length of the text with
WM_GETTEXTLENGTH to allocate an appropriate buffer size, but then
claimed the buffer was twice the size when sending WM_GETTEXTEX. This
caused the memcpy call to overflow the actual buffer since the count
is based on the size of the buffer alone, regardless of the amount of
text retrieved.
ME_GetTextEx directly handles EM_GETTEXTEX, and previously a NULL buffer
would be dereferenced, and a 0 buffer length would cause nCount an
underflow in the nCount value which would allow a buffer overflow to
occur.
The application Blitzin2 was sending WM_VSCROLL messages to the
richedit control directly, when normally this message is supposed to
be a notification sent after the scrollinfo is set. Native richedit
controls always use the 16-bit value passed to this message to set the
scroll position for SB_THUMBPOSITION, rather than trying to find a
32-bit value through GetScrollInfo like I had previously done.
The missing return was to prevent automatic vertically scrolling when
style for it is not set, but is set for the horizontal scrollbar. I
initially missed this by testing with no autoscrolling on either
scrollbar.
Rich text files have groupings of text, where styles are pushed onto
the stack when encountering a start of the group, then popped at the
end of the group. This was being handled improperly before, because a
single styleChanged flag was being stored to keep track of whether the
style needed to be restored at the end of a group. This fails to work
properly since the single flag isn't keeping track of all the levels
of the stack, so some styles are not restored properly.
When a colour table entry is empty, then the default colour is used.
For an incomplete colour table entry 0 is used for the missing colours.
Previously the -1 value used internally for missing colours was being
converted into white, where it should be using the default colour that
is normally black.
This bug could be seen by loading the following rich text into wordpad:
{\rtf{\colortbl;;}\cf1 text}
Previously after initial window creation of a richedit control with the
ES_DISABLENOSCROLL window style flag the scrollbar would be shown but
not disabled. This patch fixes this issue by explicitly disabling and
showing the scrollbar.
When the richedit control is created without the ES_AUTOHSCROLL or the
ES_AUTOVSCROLL, then scrolling isn't done automatically when moving the
cursor with the arrow keys, drag selecting with the mouse, or even from
using the EM_SCROLLCARET (based on testing using a modified version of
wordpad).
WM_SETTEXT seems to check for {\rtf or {\urtf to determine if it is an
ascii RTF string, even if it is a unicode message. So I removed the
check to see if it is a unicode message, and added a check for {\urtf.
This was partially handled by ungetting the end group token (i.e. '}')
so that it was read again at the proper place. Unfortunately there is a
read hook that maintains a stackTop variable, which is decremented when
receiving this end group token. Therefore stackTop would get
decremented twice, and the rich text file would end prematurely.
This is fixed by incrementing the stackTop variable to compensate for it
being decremented twice.
Wine was not doing bounds checks for EM_GETTEXTRANGE, which was causing
a crash in Bug 17822. The added tests would cause a crash without the
added bounds checks in the richedit code.
The bounds checks I put in HandleMessage, since ME_GetTextRange is also
called for ME_GETSELTEXT which should not have bounds checks, since it
uses the selection range.
When the ME_GETTEXTRANGE message returns 0, no text is copied, not even
the NULL terminating charter. This differs from EM_GETSELTEXT which
will copy the NULL terminating character when no text is selected. This
behaviour is consistent with native richedit controls.
Images that are inserted into richedit controls store a space for the
text, since that is the character returned when getting the plain text
from the control.
When calculating the width of a line, the space character is skipped,
but images should not be skipped. This can be seen by inserting an
image into wordpad on a line by it's own, then centering the line. The
image will start from the center rather than being centered in the
control.
EM_SETCHARFORMAT can be used to make text links. Automatic URL
detection being enable would cause these links to be removed if the text
is not a URL, so this must be prevented.
Previously checks were made for AutoURLDetect_bEnable before calling
ME_UpdateSelectionLinkAttribute, or ME_UpdateLinkAttribute. This is
more error prone than checking for this within the function, so one call
was missing this check.
ME_SetCursor also didn't respect this behaviour, since it wouldn't set
the cursor to the hand when hovering over a link without automatic URL
detection disabled.