mirror of
https://github.com/reactos/reactos.git
synced 2024-12-31 19:42:51 +00:00
Sync riched20 to Wine 1.0-rc1
Samuel Serapión got some apps like 7-Zip and PowerISO installed with the new version. svn path=/trunk/; revision=33419
This commit is contained in:
parent
620f89d44b
commit
32a2579694
13 changed files with 417 additions and 168 deletions
|
@ -57,7 +57,9 @@ int ME_GetTextLengthEx(ME_TextEditor *editor, const GETTEXTLENGTHEX *how)
|
|||
|
||||
length = ME_GetTextLength(editor);
|
||||
|
||||
if ((GetWindowLongW(editor->hWnd, GWL_STYLE) & ES_MULTILINE) && (how->flags & GTL_USECRLF))
|
||||
if ((GetWindowLongW(editor->hWnd, GWL_STYLE) & ES_MULTILINE)
|
||||
&& (how->flags & GTL_USECRLF)
|
||||
&& !editor->bEmulateVersion10) /* Ignore GTL_USECRLF flag in 1.0 emulation */
|
||||
length += editor->nParagraphs - 1;
|
||||
|
||||
if (how->flags & GTL_NUMBYTES)
|
||||
|
@ -270,6 +272,8 @@ void ME_InternalDeleteText(ME_TextEditor *editor, int nOfs,
|
|||
ME_CursorFromCharOfs(editor, nOfs, &c);
|
||||
run = &c.pRun->member.run;
|
||||
if (run->nFlags & MERF_ENDPARA) {
|
||||
int eollen = run->nCR + run->nLF;
|
||||
|
||||
if (!ME_FindItemFwd(c.pRun, diParagraph))
|
||||
{
|
||||
return;
|
||||
|
@ -277,9 +281,7 @@ void ME_InternalDeleteText(ME_TextEditor *editor, int nOfs,
|
|||
ME_JoinParagraphs(editor, ME_GetParagraph(c.pRun));
|
||||
/* ME_SkipAndPropagateCharOffset(p->pRun, shift); */
|
||||
ME_CheckCharOffsets(editor);
|
||||
nChars--;
|
||||
if (editor->bEmulateVersion10 && nChars)
|
||||
nChars--;
|
||||
nChars -= (eollen < nChars) ? eollen : nChars;
|
||||
continue;
|
||||
}
|
||||
else
|
||||
|
@ -522,6 +524,8 @@ void ME_InsertTextFromCursor(ME_TextEditor *editor, int nCursor,
|
|||
if (pos-str < len) { /* handle EOLs */
|
||||
ME_DisplayItem *tp, *end_run;
|
||||
ME_Style *tmp_style;
|
||||
int numCR, numLF;
|
||||
|
||||
if (pos!=str)
|
||||
ME_InternalInsertTextFromCursor(editor, nCursor, str, pos-str, style, 0);
|
||||
p = &editor->pCursors[nCursor];
|
||||
|
@ -531,16 +535,48 @@ void ME_InsertTextFromCursor(ME_TextEditor *editor, int nCursor,
|
|||
}
|
||||
tmp_style = ME_GetInsertStyle(editor, nCursor);
|
||||
/* ME_SplitParagraph increases style refcount */
|
||||
tp = ME_SplitParagraph(editor, p->pRun, p->pRun->member.run.style);
|
||||
|
||||
/* Encode and fill number of CR and LF according to emulation mode */
|
||||
if (editor->bEmulateVersion10) {
|
||||
const WCHAR * tpos;
|
||||
|
||||
/* We have to find out how many consecutive \r are there, and if there
|
||||
is a \n terminating the run of \r's. */
|
||||
numCR = 0; numLF = 0;
|
||||
tpos = pos;
|
||||
while (tpos-str < len && *tpos == '\r') {
|
||||
tpos++;
|
||||
numCR++;
|
||||
}
|
||||
if (tpos-str >= len) {
|
||||
/* Reached end of text without finding anything but '\r' */
|
||||
if (tpos != pos) {
|
||||
pos++;
|
||||
}
|
||||
numCR = 1; numLF = 0;
|
||||
} else if (*tpos == '\n') {
|
||||
/* The entire run of \r's plus the one \n is one single line break */
|
||||
pos = tpos + 1;
|
||||
numLF = 1;
|
||||
} else {
|
||||
/* Found some other content past the run of \r's */
|
||||
pos++;
|
||||
numCR = 1; numLF = 0;
|
||||
}
|
||||
} else {
|
||||
if(pos-str < len && *pos =='\r')
|
||||
pos++;
|
||||
if(pos-str < len && *pos =='\n')
|
||||
pos++;
|
||||
numCR = 1; numLF = 0;
|
||||
}
|
||||
tp = ME_SplitParagraph(editor, p->pRun, p->pRun->member.run.style, numCR, numLF);
|
||||
p->pRun = ME_FindItemFwd(tp, diRun);
|
||||
end_run = ME_FindItemBack(tp, diRun);
|
||||
ME_ReleaseStyle(end_run->member.run.style);
|
||||
end_run->member.run.style = tmp_style;
|
||||
p->nOffset = 0;
|
||||
if(pos-str < len && *pos =='\r')
|
||||
pos++;
|
||||
if(pos-str < len && *pos =='\n')
|
||||
pos++;
|
||||
|
||||
if(pos-str <= len) {
|
||||
len -= pos - str;
|
||||
str = pos;
|
||||
|
@ -1294,7 +1330,15 @@ void ME_SendSelChange(ME_TextEditor *editor)
|
|||
sc.seltyp |= SEL_TEXT;
|
||||
if (sc.chrg.cpMin < sc.chrg.cpMax+1) /* wth were RICHEDIT authors thinking ? */
|
||||
sc.seltyp |= SEL_MULTICHAR;
|
||||
SendMessageW(GetParent(editor->hWnd), WM_NOTIFY, sc.nmhdr.idFrom, (LPARAM)&sc);
|
||||
TRACE("cpMin=%d cpMax=%d seltyp=%d (%s %s)\n",
|
||||
sc.chrg.cpMin, sc.chrg.cpMax, sc.seltyp,
|
||||
(sc.seltyp & SEL_TEXT) ? "SEL_TEXT" : "",
|
||||
(sc.seltyp & SEL_MULTICHAR) ? "SEL_MULTICHAR" : "");
|
||||
if (sc.chrg.cpMin != editor->notified_cr.cpMin || sc.chrg.cpMax != editor->notified_cr.cpMax)
|
||||
{
|
||||
editor->notified_cr = sc.chrg;
|
||||
SendMessageW(GetParent(editor->hWnd), WM_NOTIFY, sc.nmhdr.idFrom, (LPARAM)&sc);
|
||||
}
|
||||
}
|
||||
|
||||
BOOL
|
||||
|
|
|
@ -115,7 +115,7 @@
|
|||
+ EM_SETSCROLLPOS 3.0
|
||||
- EM_SETTABSTOPS 3.0
|
||||
- EM_SETTARGETDEVICE (partial)
|
||||
+ EM_SETTEXTEX 3.0 (no rich text insertion handling, proper style?)
|
||||
+ EM_SETTEXTEX 3.0 (proper style?)
|
||||
- EM_SETTEXTMODE 2.0
|
||||
- EM_SETTYPOGRAPHYOPTIONS 3.0
|
||||
+ EM_SETUNDOLIMIT 2.0
|
||||
|
@ -620,31 +620,31 @@ static void ME_RTFParAttrHook(RTF_Info *info)
|
|||
case rtfBorderSingle:
|
||||
ME_GetSelectionParaFormat(info->editor, &fmt);
|
||||
/* we assume that borders have been created before (RTF spec) */
|
||||
fmt.wBorders &= ~0x70;
|
||||
fmt.wBorders &= ~0x700;
|
||||
fmt.wBorders |= 1 << 8;
|
||||
break;
|
||||
case rtfBorderThick:
|
||||
ME_GetSelectionParaFormat(info->editor, &fmt);
|
||||
/* we assume that borders have been created before (RTF spec) */
|
||||
fmt.wBorders &= ~0x70;
|
||||
fmt.wBorders &= ~0x700;
|
||||
fmt.wBorders |= 2 << 8;
|
||||
break;
|
||||
case rtfBorderShadow:
|
||||
ME_GetSelectionParaFormat(info->editor, &fmt);
|
||||
/* we assume that borders have been created before (RTF spec) */
|
||||
fmt.wBorders &= ~0x70;
|
||||
fmt.wBorders &= ~0x700;
|
||||
fmt.wBorders |= 10 << 8;
|
||||
break;
|
||||
case rtfBorderDouble:
|
||||
ME_GetSelectionParaFormat(info->editor, &fmt);
|
||||
/* we assume that borders have been created before (RTF spec) */
|
||||
fmt.wBorders &= ~0x70;
|
||||
fmt.wBorders &= ~0x700;
|
||||
fmt.wBorders |= 7 << 8;
|
||||
break;
|
||||
case rtfBorderDot:
|
||||
ME_GetSelectionParaFormat(info->editor, &fmt);
|
||||
/* we assume that borders have been created before (RTF spec) */
|
||||
fmt.wBorders &= ~0x70;
|
||||
fmt.wBorders &= ~0x700;
|
||||
fmt.wBorders |= 11 << 8;
|
||||
break;
|
||||
case rtfBorderWidth:
|
||||
|
@ -1022,13 +1022,14 @@ ME_StreamInFill(ME_InStream *stream)
|
|||
stream->dwUsed = 0;
|
||||
}
|
||||
|
||||
static LRESULT ME_StreamIn(ME_TextEditor *editor, DWORD format, EDITSTREAM *stream)
|
||||
static LRESULT ME_StreamIn(ME_TextEditor *editor, DWORD format, EDITSTREAM *stream, BOOL stripLastCR)
|
||||
{
|
||||
RTF_Info parser;
|
||||
ME_Style *style;
|
||||
int from, to, to2, nUndoMode;
|
||||
int nEventMask = editor->nEventMask;
|
||||
ME_InStream inStream;
|
||||
BOOL invalidRTF = FALSE;
|
||||
|
||||
TRACE("stream==%p hWnd==%p format==0x%X\n", stream, editor->hWnd, format);
|
||||
editor->nEventMask = 0;
|
||||
|
@ -1068,15 +1069,16 @@ static LRESULT ME_StreamIn(ME_TextEditor *editor, DWORD format, EDITSTREAM *stre
|
|||
ME_StreamInFill(&inStream);
|
||||
if (!inStream.editstream->dwError)
|
||||
{
|
||||
if (strncmp(inStream.buffer, "{\\rtf", 5) && strncmp(inStream.buffer, "{\\urtf", 6))
|
||||
if ((!editor->bEmulateVersion10 && strncmp(inStream.buffer, "{\\rtf", 5) && strncmp(inStream.buffer, "{\\urtf", 6))
|
||||
|| (editor->bEmulateVersion10 && *inStream.buffer != '{'))
|
||||
{
|
||||
format &= ~SF_RTF;
|
||||
format |= SF_TEXT;
|
||||
invalidRTF = TRUE;
|
||||
inStream.editstream->dwError = -16;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!inStream.editstream->dwError)
|
||||
if (!invalidRTF && !inStream.editstream->dwError)
|
||||
{
|
||||
if (format & SF_RTF) {
|
||||
/* setup the RTF parser */
|
||||
|
@ -1100,6 +1102,24 @@ static LRESULT ME_StreamIn(ME_TextEditor *editor, DWORD format, EDITSTREAM *stre
|
|||
if (parser.lpRichEditOle)
|
||||
IRichEditOle_Release(parser.lpRichEditOle);
|
||||
|
||||
/* Remove last line break, as mandated by tests. This is not affected by
|
||||
CR/LF counters, since RTF streaming presents only \para tokens, which
|
||||
are converted according to the standard rules: \r for 2.0, \r\n for 1.0
|
||||
*/
|
||||
if (stripLastCR) {
|
||||
int newfrom, newto;
|
||||
ME_GetSelection(editor, &newfrom, &newto);
|
||||
if (newto > to + (editor->bEmulateVersion10 ? 1 : 0)) {
|
||||
WCHAR lastchar[3] = {'\0', '\0'};
|
||||
int linebreakSize = editor->bEmulateVersion10 ? 2 : 1;
|
||||
|
||||
ME_GetTextW(editor, lastchar, newto - linebreakSize, linebreakSize, 0);
|
||||
if (lastchar[0] == '\r' && (lastchar[1] == '\n' || lastchar[1] == '\0')) {
|
||||
ME_InternalDeleteText(editor, newto - linebreakSize, linebreakSize);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
style = parser.style;
|
||||
}
|
||||
else if (format & SF_TEXT)
|
||||
|
@ -1124,10 +1144,7 @@ static LRESULT ME_StreamIn(ME_TextEditor *editor, DWORD format, EDITSTREAM *stre
|
|||
|
||||
ME_ReleaseStyle(style);
|
||||
editor->nEventMask = nEventMask;
|
||||
if (editor->bRedraw)
|
||||
{
|
||||
ME_UpdateRepaint(editor);
|
||||
}
|
||||
ME_UpdateRepaint(editor);
|
||||
if (!(format & SFF_SELECTION)) {
|
||||
ME_ClearTempStyle(editor);
|
||||
}
|
||||
|
@ -1169,7 +1186,7 @@ ME_StreamInRTFString(ME_TextEditor *editor, BOOL selection, char *string)
|
|||
data.pos = 0;
|
||||
es.dwCookie = (DWORD)&data;
|
||||
es.pfnCallback = ME_ReadFromRTFString;
|
||||
ME_StreamIn(editor, SF_RTF | (selection ? SFF_SELECTION : 0), &es);
|
||||
ME_StreamIn(editor, SF_RTF | (selection ? SFF_SELECTION : 0), &es, FALSE);
|
||||
}
|
||||
|
||||
|
||||
|
@ -1177,6 +1194,7 @@ ME_DisplayItem *
|
|||
ME_FindItemAtOffset(ME_TextEditor *editor, ME_DIType nItemType, int nOffset, int *nItemOffset)
|
||||
{
|
||||
ME_DisplayItem *item = ME_FindItemFwd(editor->pBuffer->pFirst, diParagraph);
|
||||
int runLength;
|
||||
|
||||
while (item && item->member.para.next_para->member.para.nCharOfs <= nOffset)
|
||||
item = ME_FindItemFwd(item, diParagraph);
|
||||
|
@ -1193,9 +1211,27 @@ ME_FindItemAtOffset(ME_TextEditor *editor, ME_DIType nItemType, int nOffset, int
|
|||
|
||||
do {
|
||||
item = ME_FindItemFwd(item, diRun);
|
||||
} while (item && (item->member.run.nCharOfs + ME_StrLen(item->member.run.strText) <= nOffset));
|
||||
runLength = ME_StrLen(item->member.run.strText);
|
||||
if (item->member.run.nFlags & MERF_ENDPARA)
|
||||
runLength = item->member.run.nCR + item->member.run.nLF;
|
||||
} while (item && (item->member.run.nCharOfs + runLength <= nOffset));
|
||||
if (item) {
|
||||
nOffset -= item->member.run.nCharOfs;
|
||||
|
||||
/* Special case: nOffset may not point exactly at the division between the
|
||||
\r and the \n in 1.0 emulation. If such a case happens, it is sent
|
||||
into the next run, if one exists
|
||||
*/
|
||||
if ( item->member.run.nFlags & MERF_ENDPARA
|
||||
&& nOffset == item->member.run.nCR
|
||||
&& item->member.run.nLF > 0) {
|
||||
ME_DisplayItem *nextItem;
|
||||
nextItem = ME_FindItemFwd(item, diRun);
|
||||
if (nextItem) {
|
||||
nOffset = 0;
|
||||
item = nextItem;
|
||||
}
|
||||
}
|
||||
if (nItemOffset)
|
||||
*nItemOffset = nOffset;
|
||||
}
|
||||
|
@ -1227,12 +1263,29 @@ ME_FindText(ME_TextEditor *editor, DWORD flags, const CHARRANGE *chrg, const WCH
|
|||
else
|
||||
nMax = chrg->cpMax > nTextLen ? nTextLen : chrg->cpMax;
|
||||
|
||||
/* In 1.0 emulation, if cpMax reaches end of text, add the FR_DOWN flag */
|
||||
if (editor->bEmulateVersion10 && nMax == nTextLen)
|
||||
{
|
||||
flags |= FR_DOWN;
|
||||
}
|
||||
|
||||
/* In 1.0 emulation, cpMin must always be no greater than cpMax */
|
||||
if (editor->bEmulateVersion10 && nMax < nMin)
|
||||
{
|
||||
if (chrgText)
|
||||
{
|
||||
chrgText->cpMin = -1;
|
||||
chrgText->cpMax = -1;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* when searching up, if cpMin < cpMax, then instead of searching
|
||||
* on [cpMin,cpMax], we search on [0,cpMin], otherwise, search on
|
||||
* [cpMax, cpMin]. The exception is when cpMax is -1, in which
|
||||
* case, it is always bigger than cpMin.
|
||||
*/
|
||||
if (!(flags & FR_DOWN))
|
||||
if (!editor->bEmulateVersion10 && !(flags & FR_DOWN))
|
||||
{
|
||||
int nSwap = nMax;
|
||||
|
||||
|
@ -1630,6 +1683,8 @@ ME_TextEditor *ME_MakeEditor(HWND hWnd) {
|
|||
else
|
||||
ed->cPasswordMask = 0;
|
||||
|
||||
ed->notified_cr.cpMin = ed->notified_cr.cpMax = 0;
|
||||
|
||||
return ed;
|
||||
}
|
||||
|
||||
|
@ -1922,7 +1977,7 @@ static LRESULT RichEditWndProc_common(HWND hWnd, UINT msg, WPARAM wParam,
|
|||
/* Messages specific to Richedit controls */
|
||||
|
||||
case EM_STREAMIN:
|
||||
return ME_StreamIn(editor, wParam, (EDITSTREAM*)lParam);
|
||||
return ME_StreamIn(editor, wParam, (EDITSTREAM*)lParam, TRUE);
|
||||
case EM_STREAMOUT:
|
||||
return ME_StreamOut(editor, wParam, (EDITSTREAM *)lParam);
|
||||
case WM_GETDLGCODE:
|
||||
|
@ -2117,17 +2172,20 @@ static LRESULT RichEditWndProc_common(HWND hWnd, UINT msg, WPARAM wParam,
|
|||
wszText = lParam ? ME_ToUnicode(pStruct->codepage == 1200, (void *)lParam) : NULL;
|
||||
len = wszText ? lstrlenW(wszText) : 0;
|
||||
|
||||
/* FIXME: this should support RTF strings too, according to MSDN */
|
||||
if (pStruct->flags & ST_SELECTION) {
|
||||
ME_GetSelection(editor, &from, &to);
|
||||
style = ME_GetSelectionInsertStyle(editor);
|
||||
ME_InternalDeleteText(editor, from, to - from);
|
||||
ME_InsertTextFromCursor(editor, 0, wszText, len, style);
|
||||
if (pStruct->codepage != 1200 && lParam && !strncmp((char *)lParam, "{\\rtf", 5))
|
||||
ME_StreamInRTFString(editor, 0, (char *)lParam);
|
||||
else ME_InsertTextFromCursor(editor, 0, wszText, len, style);
|
||||
ME_ReleaseStyle(style);
|
||||
}
|
||||
else {
|
||||
ME_InternalDeleteText(editor, 0, ME_GetTextLength(editor));
|
||||
ME_InsertTextFromCursor(editor, 0, wszText, len, editor->pBuffer->pDefaultStyle);
|
||||
if (pStruct->codepage != 1200 && lParam && !strncmp((char *)lParam, "{\\rtf", 5))
|
||||
ME_StreamInRTFString(editor, 0, (char *)lParam);
|
||||
else ME_InsertTextFromCursor(editor, 0, wszText, len, editor->pBuffer->pDefaultStyle);
|
||||
len = 1;
|
||||
}
|
||||
ME_CommitUndo(editor);
|
||||
|
@ -2166,7 +2224,7 @@ static LRESULT RichEditWndProc_common(HWND hWnd, UINT msg, WPARAM wParam,
|
|||
return lColor;
|
||||
}
|
||||
case EM_GETMODIFY:
|
||||
return editor->nModifyStep == 0 ? 0 : 1;
|
||||
return editor->nModifyStep == 0 ? 0 : -1;
|
||||
case EM_SETMODIFY:
|
||||
{
|
||||
if (wParam)
|
||||
|
@ -2209,8 +2267,10 @@ static LRESULT RichEditWndProc_common(HWND hWnd, UINT msg, WPARAM wParam,
|
|||
} else if (wParam == SCF_ALL) {
|
||||
if (editor->mode & TM_PLAINTEXT)
|
||||
ME_SetDefaultCharFormat(editor, p);
|
||||
else
|
||||
else {
|
||||
ME_SetCharFormat(editor, 0, ME_GetTextLength(editor), p);
|
||||
editor->nModifyStep = 1;
|
||||
}
|
||||
} else if (editor->mode & TM_PLAINTEXT) {
|
||||
return 0;
|
||||
} else {
|
||||
|
@ -2218,8 +2278,8 @@ static LRESULT RichEditWndProc_common(HWND hWnd, UINT msg, WPARAM wParam,
|
|||
ME_GetSelection(editor, &from, &to);
|
||||
bRepaint = (from != to);
|
||||
ME_SetSelectionCharFormat(editor, p);
|
||||
if (from != to) editor->nModifyStep = 1;
|
||||
}
|
||||
editor->nModifyStep = 1;
|
||||
ME_CommitUndo(editor);
|
||||
if (bRepaint)
|
||||
ME_RewrapRepaint(editor);
|
||||
|
@ -2394,10 +2454,10 @@ static LRESULT RichEditWndProc_common(HWND hWnd, UINT msg, WPARAM wParam,
|
|||
}
|
||||
else
|
||||
TRACE("WM_SETTEXT - NULL\n");
|
||||
ME_CommitUndo(editor);
|
||||
ME_EmptyUndoStack(editor);
|
||||
ME_SetSelection(editor, 0, 0);
|
||||
editor->nModifyStep = 0;
|
||||
ME_CommitUndo(editor);
|
||||
ME_EmptyUndoStack(editor);
|
||||
ME_UpdateRepaint(editor);
|
||||
return 1;
|
||||
}
|
||||
|
@ -2431,7 +2491,7 @@ static LRESULT RichEditWndProc_common(HWND hWnd, UINT msg, WPARAM wParam,
|
|||
gds.nLength = 0;
|
||||
es.dwCookie = (DWORD)&gds;
|
||||
es.pfnCallback = dwFormat == SF_RTF ? ME_ReadFromHGLOBALRTF : ME_ReadFromHGLOBALUnicode;
|
||||
ME_StreamIn(editor, dwFormat|SFF_SELECTION, &es);
|
||||
ME_StreamIn(editor, dwFormat|SFF_SELECTION, &es, FALSE);
|
||||
|
||||
CloseClipboard();
|
||||
return 0;
|
||||
|
@ -2467,6 +2527,7 @@ static LRESULT RichEditWndProc_common(HWND hWnd, UINT msg, WPARAM wParam,
|
|||
{
|
||||
GETTEXTLENGTHEX how;
|
||||
|
||||
/* CR/LF conversion required in 2.0 mode, verbatim in 1.0 mode */
|
||||
how.flags = GTL_CLOSE | (editor->bEmulateVersion10 ? 0 : GTL_USECRLF) | GTL_NUMCHARS;
|
||||
how.codepage = unicode ? 1200 : CP_ACP;
|
||||
return ME_GetTextLengthEx(editor, &how);
|
||||
|
@ -2532,7 +2593,10 @@ static LRESULT RichEditWndProc_common(HWND hWnd, UINT msg, WPARAM wParam,
|
|||
else
|
||||
{
|
||||
/* potentially each char may be a CR, why calculate the exact value with O(N) when
|
||||
we can just take a bigger buffer? :) */
|
||||
we can just take a bigger buffer? :)
|
||||
The above assumption still holds with CR/LF counters, since CR->CRLF expansion
|
||||
occurs only in richedit 2.0 mode, in which line breaks have only one CR
|
||||
*/
|
||||
int crlfmul = (ex->flags & GT_USECRLF) ? 2 : 1;
|
||||
LPWSTR buffer;
|
||||
DWORD buflen = ex->cb;
|
||||
|
@ -2574,12 +2638,12 @@ static LRESULT RichEditWndProc_common(HWND hWnd, UINT msg, WPARAM wParam,
|
|||
rng->chrg.cpMin, rng->chrg.cpMax, unicode,
|
||||
editor->bEmulateVersion10, ME_GetTextLength(editor));
|
||||
if (unicode)
|
||||
return ME_GetTextW(editor, rng->lpstrText, rng->chrg.cpMin, rng->chrg.cpMax-rng->chrg.cpMin, editor->bEmulateVersion10);
|
||||
return ME_GetTextW(editor, rng->lpstrText, rng->chrg.cpMin, rng->chrg.cpMax-rng->chrg.cpMin, 0);
|
||||
else
|
||||
{
|
||||
int nLen = rng->chrg.cpMax-rng->chrg.cpMin;
|
||||
WCHAR *p = ALLOC_N_OBJ(WCHAR, nLen+1);
|
||||
int nChars = ME_GetTextW(editor, p, rng->chrg.cpMin, nLen, editor->bEmulateVersion10);
|
||||
int nChars = ME_GetTextW(editor, p, rng->chrg.cpMin, nLen, 0);
|
||||
/* FIXME this is a potential security hole (buffer overrun)
|
||||
if you know more about wchar->mbyte conversion please explain
|
||||
*/
|
||||
|
@ -2592,11 +2656,9 @@ static LRESULT RichEditWndProc_common(HWND hWnd, UINT msg, WPARAM wParam,
|
|||
{
|
||||
ME_DisplayItem *run;
|
||||
const unsigned int nMaxChars = *(WORD *) lParam;
|
||||
unsigned int nEndChars, nCharsLeft = nMaxChars;
|
||||
unsigned int nCharsLeft = nMaxChars;
|
||||
char *dest = (char *) lParam;
|
||||
/* rich text editor 1.0 uses \r\n for line end, 2.0 uses just \r;
|
||||
we need to know how if we have the extra \n or not */
|
||||
int nLF = editor->bEmulateVersion10;
|
||||
BOOL wroteNull = FALSE;
|
||||
|
||||
TRACE("EM_GETLINE: row=%d, nMaxChars=%d (%s)\n", (int) wParam, nMaxChars,
|
||||
unicode ? "Unicode" : "Ansi");
|
||||
|
@ -2624,36 +2686,68 @@ static LRESULT RichEditWndProc_common(HWND hWnd, UINT msg, WPARAM wParam,
|
|||
nCharsLeft -= nCopy;
|
||||
}
|
||||
|
||||
/* append \r\0 (or \r\n\0 in 1.0), space allowing */
|
||||
nEndChars = min(nCharsLeft, 2 + nLF);
|
||||
nCharsLeft -= nEndChars;
|
||||
if (unicode)
|
||||
/* append line termination, space allowing */
|
||||
if (nCharsLeft > 0)
|
||||
{
|
||||
const WCHAR src[] = {'\r', '\0'};
|
||||
const WCHAR src10[] = {'\r', '\n', '\0'};
|
||||
lstrcpynW((LPWSTR) dest, nLF ? src10 : src, nEndChars);
|
||||
if (run && (run->member.run.nFlags & MERF_ENDPARA))
|
||||
{
|
||||
unsigned int i;
|
||||
/* Write as many \r as encoded in end-of-paragraph, space allowing */
|
||||
for (i = 0; i < run->member.run.nCR && nCharsLeft > 0; i++, nCharsLeft--)
|
||||
{
|
||||
*((WCHAR *)dest) = '\r';
|
||||
dest += unicode ? sizeof(WCHAR) : 1;
|
||||
}
|
||||
/* Write as many \n as encoded in end-of-paragraph, space allowing */
|
||||
for (i = 0; i < run->member.run.nLF && nCharsLeft > 0; i++, nCharsLeft--)
|
||||
{
|
||||
*((WCHAR *)dest) = '\n';
|
||||
dest += unicode ? sizeof(WCHAR) : 1;
|
||||
}
|
||||
}
|
||||
if (nCharsLeft > 0)
|
||||
{
|
||||
if (unicode)
|
||||
*((WCHAR *)dest) = '\0';
|
||||
else
|
||||
*dest = '\0';
|
||||
nCharsLeft--;
|
||||
wroteNull = TRUE;
|
||||
}
|
||||
}
|
||||
else
|
||||
lstrcpynA(dest, nLF ? "\r\n" : "\r", nEndChars);
|
||||
|
||||
TRACE("EM_GETLINE: got %u bytes\n", nMaxChars - nCharsLeft);
|
||||
|
||||
if (nEndChars == 2 + nLF)
|
||||
return nMaxChars - nCharsLeft - 1; /* don't count \0 */
|
||||
else
|
||||
return nMaxChars - nCharsLeft;
|
||||
TRACE("EM_GETLINE: got %u characters\n", nMaxChars - nCharsLeft);
|
||||
return nMaxChars - nCharsLeft - (wroteNull ? 1 : 0);
|
||||
}
|
||||
case EM_GETLINECOUNT:
|
||||
{
|
||||
ME_DisplayItem *item = editor->pBuffer->pFirst->next;
|
||||
int nRows = 0;
|
||||
|
||||
ME_DisplayItem *prev_para = NULL, *last_para = NULL;
|
||||
|
||||
while (item != editor->pBuffer->pLast)
|
||||
{
|
||||
assert(item->type == diParagraph);
|
||||
prev_para = ME_FindItemBack(item, diRun);
|
||||
if (prev_para) {
|
||||
assert(prev_para->member.run.nFlags & MERF_ENDPARA);
|
||||
}
|
||||
nRows += item->member.para.nRows;
|
||||
item = item->member.para.next_para;
|
||||
}
|
||||
last_para = ME_FindItemBack(item, diRun);
|
||||
assert(last_para);
|
||||
assert(last_para->member.run.nFlags & MERF_ENDPARA);
|
||||
if (editor->bEmulateVersion10 && prev_para && last_para->member.run.nCharOfs == 0
|
||||
&& prev_para->member.run.nCR == 1 && prev_para->member.run.nLF == 0)
|
||||
{
|
||||
/* In 1.0 emulation, the last solitary \r at the very end of the text
|
||||
(if one exists) is NOT a line break.
|
||||
FIXME: this is an ugly hack. This should have a more regular model. */
|
||||
nRows--;
|
||||
}
|
||||
|
||||
TRACE("EM_GETLINECOUNT: nRows==%d\n", nRows);
|
||||
return max(1, nRows);
|
||||
}
|
||||
|
@ -2707,8 +2801,17 @@ static LRESULT RichEditWndProc_common(HWND hWnd, UINT msg, WPARAM wParam,
|
|||
if (item_end->type == diStartRow)
|
||||
nNextLineOfs = ME_CharOfsFromRunOfs(editor, ME_FindItemFwd(item_end, diRun), 0);
|
||||
else
|
||||
nNextLineOfs = ME_FindItemFwd(item, diParagraphOrEnd)->member.para.nCharOfs
|
||||
- (editor->bEmulateVersion10?2:1);
|
||||
{
|
||||
ME_DisplayItem *endPara;
|
||||
|
||||
nNextLineOfs = ME_FindItemFwd(item, diParagraphOrEnd)->member.para.nCharOfs;
|
||||
endPara = ME_FindItemFwd(item, diParagraphOrEnd);
|
||||
endPara = ME_FindItemBack(endPara, diRun);
|
||||
assert(endPara);
|
||||
assert(endPara->type == diRun);
|
||||
assert(endPara->member.run.nFlags & MERF_ENDPARA);
|
||||
nNextLineOfs -= endPara->member.run.nCR + endPara->member.run.nLF;
|
||||
}
|
||||
nChars = nNextLineOfs - nThisLineOfs;
|
||||
TRACE("EM_LINELENGTH(%ld)==%d\n",wParam, nChars);
|
||||
return nChars;
|
||||
|
@ -3207,7 +3310,12 @@ static LRESULT RichEditWndProc_common(HWND hWnd, UINT msg, WPARAM wParam,
|
|||
case EM_SETTARGETDEVICE:
|
||||
if (wParam == 0)
|
||||
{
|
||||
editor->bWordWrap = (lParam == 0);
|
||||
BOOL new = (lParam == 0);
|
||||
if (editor->bWordWrap != new)
|
||||
{
|
||||
editor->bWordWrap = new;
|
||||
ME_RewrapRepaint(editor);
|
||||
}
|
||||
}
|
||||
else FIXME("Unsupported yet non NULL device in EM_SETTARGETDEVICE\n");
|
||||
break;
|
||||
|
@ -3257,6 +3365,9 @@ LRESULT WINAPI RichEdit10ANSIWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM
|
|||
|
||||
editor->bEmulateVersion10 = TRUE;
|
||||
editor->pBuffer->pLast->member.para.nCharOfs = 2;
|
||||
assert(editor->pBuffer->pLast->prev->type == diRun);
|
||||
assert(editor->pBuffer->pLast->prev->member.run.nFlags & MERF_ENDPARA);
|
||||
editor->pBuffer->pLast->prev->member.run.nLF = 1;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
@ -3327,6 +3438,9 @@ int ME_GetTextW(ME_TextEditor *editor, WCHAR *buffer, int nStart, int nChars, in
|
|||
return 0;
|
||||
}
|
||||
|
||||
/* bCRLF flag is only honored in 2.0 and up. 1.0 must always return text verbatim */
|
||||
if (editor->bEmulateVersion10) bCRLF = 0;
|
||||
|
||||
if (nStart)
|
||||
{
|
||||
int nLen = ME_StrLen(item->member.run.strText) - nStart;
|
||||
|
@ -3345,6 +3459,8 @@ int ME_GetTextW(ME_TextEditor *editor, WCHAR *buffer, int nStart, int nChars, in
|
|||
while(nChars && item)
|
||||
{
|
||||
int nLen = ME_StrLen(item->member.run.strText);
|
||||
if (item->member.run.nFlags & MERF_ENDPARA)
|
||||
nLen = item->member.run.nCR + item->member.run.nLF;
|
||||
if (nLen > nChars)
|
||||
nLen = nChars;
|
||||
|
||||
|
@ -3357,16 +3473,30 @@ int ME_GetTextW(ME_TextEditor *editor, WCHAR *buffer, int nStart, int nChars, in
|
|||
nLen = 0;
|
||||
nChars = 0;
|
||||
} else {
|
||||
*buffer = '\r';
|
||||
if (bCRLF)
|
||||
{
|
||||
*(++buffer) = '\n';
|
||||
/* richedit 2.0 case - actual line-break is \r but should report \r\n */
|
||||
assert(nLen == 1);
|
||||
*buffer++ = '\r';
|
||||
*buffer = '\n'; /* Later updated by nLen==1 at the end of the loop */
|
||||
nWritten++;
|
||||
}
|
||||
assert(nLen == 1);
|
||||
/* our end paragraph consists of 2 characters now */
|
||||
if (editor->bEmulateVersion10)
|
||||
nChars--;
|
||||
else
|
||||
{
|
||||
int i, j;
|
||||
|
||||
/* richedit 2.0 verbatim has only \r. richedit 1.0 should honor encodings */
|
||||
i = 0;
|
||||
while (nChars - i > 0 && i < item->member.run.nCR)
|
||||
{
|
||||
buffer[i] = '\r'; i++;
|
||||
}
|
||||
j = 0;
|
||||
while (nChars - i - j > 0 && j < item->member.run.nLF)
|
||||
{
|
||||
buffer[i+j] = '\n'; j++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -3522,7 +3652,6 @@ int ME_AutoURLDetect(ME_TextEditor *editor, WCHAR curChar)
|
|||
int car_pos = 0;
|
||||
int text_pos=-1;
|
||||
int URLmin, URLmax = 0;
|
||||
CHARRANGE url;
|
||||
FINDTEXTA ft;
|
||||
CHARFORMAT2W cur_format;
|
||||
CHARFORMAT2W default_format;
|
||||
|
@ -3576,8 +3705,6 @@ int ME_AutoURLDetect(ME_TextEditor *editor, WCHAR curChar)
|
|||
}
|
||||
if (text_pos != -1)
|
||||
{
|
||||
url.cpMin=text_pos;
|
||||
url.cpMax=car_pos-1;
|
||||
ME_SetCharFormat(editor, text_pos, (URLmax-text_pos), &link);
|
||||
ME_RewrapRepaint(editor);
|
||||
break;
|
||||
|
|
|
@ -189,9 +189,6 @@ void ME_InsertTextFromCursor(ME_TextEditor *editor, int nCursor,
|
|||
void ME_InsertEndRowFromCursor(ME_TextEditor *editor, int nCursor);
|
||||
BOOL ME_ArrowKey(ME_TextEditor *ed, int nVKey, BOOL extend, BOOL ctrl);
|
||||
|
||||
void ME_InitContext(ME_Context *c, ME_TextEditor *editor, HDC hDC);
|
||||
void ME_DestroyContext(ME_Context *c, HWND release);
|
||||
ME_Style *GetInsertStyle(ME_TextEditor *editor, int nCursor);
|
||||
void ME_MustBeWrapped(ME_Context *c, ME_DisplayItem *para);
|
||||
void ME_GetCursorCoordinates(ME_TextEditor *editor, ME_Cursor *pCursor,
|
||||
int *x, int *y, int *height);
|
||||
|
@ -209,6 +206,10 @@ int ME_GetTextLengthEx(ME_TextEditor *editor, const GETTEXTLENGTHEX *how);
|
|||
ME_Style *ME_GetSelectionInsertStyle(ME_TextEditor *editor);
|
||||
BOOL ME_UpdateSelection(ME_TextEditor *editor, const ME_Cursor *pTempCursor);
|
||||
|
||||
/* context.c */
|
||||
void ME_InitContext(ME_Context *c, ME_TextEditor *editor, HDC hDC);
|
||||
void ME_DestroyContext(ME_Context *c, HWND release);
|
||||
|
||||
/* wrap.c */
|
||||
BOOL ME_WrapMarkedParagraphs(ME_TextEditor *editor);
|
||||
void ME_InvalidateMarkedParagraphs(ME_TextEditor *editor);
|
||||
|
@ -220,7 +221,7 @@ int ME_twips2pointsY(ME_Context *c, int y);
|
|||
ME_DisplayItem *ME_GetParagraph(ME_DisplayItem *run);
|
||||
void ME_GetSelectionParas(ME_TextEditor *editor, ME_DisplayItem **para, ME_DisplayItem **para_end);
|
||||
void ME_MakeFirstParagraph(ME_TextEditor *editor);
|
||||
ME_DisplayItem *ME_SplitParagraph(ME_TextEditor *editor, ME_DisplayItem *rp, ME_Style *style);
|
||||
ME_DisplayItem *ME_SplitParagraph(ME_TextEditor *editor, ME_DisplayItem *rp, ME_Style *style, int numCR, int numLF);
|
||||
ME_DisplayItem *ME_JoinParagraphs(ME_TextEditor *editor, ME_DisplayItem *tp);
|
||||
void ME_DumpParaStyle(ME_Paragraph *s);
|
||||
void ME_DumpParaStyleToBuf(const PARAFORMAT2 *pFmt, char buf[2048]);
|
||||
|
@ -272,11 +273,6 @@ ME_TextEditor *ME_MakeEditor(HWND hWnd);
|
|||
void ME_DestroyEditor(ME_TextEditor *editor);
|
||||
void ME_SendOldNotify(ME_TextEditor *editor, int nCode);
|
||||
void ME_LinkNotify(ME_TextEditor *editor, UINT msg, WPARAM wParam, LPARAM lParam);
|
||||
ME_UndoItem *ME_AddUndoItem(ME_TextEditor *editor, ME_DIType type, const ME_DisplayItem *pdi);
|
||||
void ME_CommitUndo(ME_TextEditor *editor);
|
||||
void ME_Undo(ME_TextEditor *editor);
|
||||
void ME_Redo(ME_TextEditor *editor);
|
||||
void ME_EmptyUndoStack(ME_TextEditor *editor);
|
||||
int ME_GetTextW(ME_TextEditor *editor, WCHAR *buffer, int nStart, int nChars, BOOL bCRLF);
|
||||
ME_DisplayItem *ME_FindItemAtOffset(ME_TextEditor *editor, ME_DIType nItemType, int nOffset, int *nItemOffset);
|
||||
void ME_StreamInFill(ME_InStream *stream);
|
||||
|
@ -284,6 +280,13 @@ int ME_AutoURLDetect(ME_TextEditor *editor, WCHAR curChar);
|
|||
extern int me_debug;
|
||||
extern void DoWrap(ME_TextEditor *editor);
|
||||
|
||||
/* undo.c */
|
||||
ME_UndoItem *ME_AddUndoItem(ME_TextEditor *editor, ME_DIType type, const ME_DisplayItem *pdi);
|
||||
void ME_CommitUndo(ME_TextEditor *editor);
|
||||
void ME_Undo(ME_TextEditor *editor);
|
||||
void ME_Redo(ME_TextEditor *editor);
|
||||
void ME_EmptyUndoStack(ME_TextEditor *editor);
|
||||
|
||||
/* writer.c */
|
||||
LRESULT ME_StreamOutRange(ME_TextEditor *editor, DWORD dwFormat, int nStart, int nTo, EDITSTREAM *stream);
|
||||
LRESULT ME_StreamOut(ME_TextEditor *editor, DWORD dwFormat, EDITSTREAM *stream);
|
||||
|
|
|
@ -148,6 +148,7 @@ typedef struct tagME_Run
|
|||
POINT pt; /* relative to para's position */
|
||||
struct tagME_TableCell *pCell; /* for MERF_CELL: points to respective cell in ME_Paragraph */
|
||||
REOBJECT *ole_obj; /* FIXME: should be a union with strText (at least) */
|
||||
int nCR; int nLF; /* for MERF_ENDPARA: number of \r and \n characters encoded by run */
|
||||
} ME_Run;
|
||||
|
||||
typedef struct tagME_Document {
|
||||
|
@ -217,6 +218,7 @@ typedef struct tagME_UndoItem
|
|||
{
|
||||
ME_DisplayItem di;
|
||||
int nStart, nLen;
|
||||
int nCR, nLF; /* used by diUndoSplitParagraph */
|
||||
} ME_UndoItem;
|
||||
|
||||
typedef struct tagME_TextBuffer
|
||||
|
@ -329,6 +331,9 @@ typedef struct tagME_TextEditor
|
|||
/*for IME */
|
||||
int imeStartIndex;
|
||||
DWORD selofs, linesel, sely;
|
||||
|
||||
/* Track previous notified selection */
|
||||
CHARRANGE notified_cr;
|
||||
} ME_TextEditor;
|
||||
|
||||
typedef struct tagME_Context
|
||||
|
|
|
@ -200,6 +200,8 @@ void ME_DumpDocument(ME_TextBuffer *buffer)
|
|||
case diRun:
|
||||
TRACE(" - Run(\"%s\", %d)\n", debugstr_w(pItem->member.run.strText->szData),
|
||||
pItem->member.run.nCharOfs);
|
||||
if (pItem->member.run.nFlags & MERF_ENDPARA)
|
||||
TRACE(" - Paragraph end: %d CR, %d LF\n", pItem->member.run.nCR, pItem->member.run.nLF);
|
||||
break;
|
||||
case diTextEnd:
|
||||
TRACE("End(ofs=%d)\n", pItem->member.para.nCharOfs);
|
||||
|
|
|
@ -43,8 +43,7 @@ void ME_PaintContent(ME_TextEditor *editor, HDC hDC, BOOL bOnlyNew, const RECT *
|
|||
{
|
||||
BOOL bPaint = (rcUpdate == NULL);
|
||||
if (rcUpdate)
|
||||
bPaint = c.pt.y<rcUpdate->bottom &&
|
||||
c.pt.y+item->member.para.nHeight>rcUpdate->top;
|
||||
bPaint = c.pt.y<rcUpdate->bottom && ye>rcUpdate->top;
|
||||
if (bPaint)
|
||||
{
|
||||
ME_DrawParagraph(&c, item);
|
||||
|
@ -85,8 +84,6 @@ void ME_PaintContent(ME_TextEditor *editor, HDC hDC, BOOL bOnlyNew, const RECT *
|
|||
rc.bottom = ye;
|
||||
FillRect(hDC, &rc, c.editor->hbrBackground);
|
||||
}
|
||||
if (ys == c.pt.y) /* don't overwrite the top bar */
|
||||
ys++;
|
||||
}
|
||||
if (editor->nTotalLength != editor->nLastTotalLength)
|
||||
ME_SendRequestResize(editor, FALSE);
|
||||
|
@ -109,9 +106,11 @@ void ME_UpdateRepaint(ME_TextEditor *editor)
|
|||
{
|
||||
/* Should be called whenever the contents of the control have changed */
|
||||
ME_Cursor *pCursor;
|
||||
BOOL wrappedParagraphs;
|
||||
|
||||
wrappedParagraphs = ME_WrapMarkedParagraphs(editor);
|
||||
if (!editor->bRedraw) return;
|
||||
if (ME_WrapMarkedParagraphs(editor))
|
||||
if (wrappedParagraphs)
|
||||
ME_UpdateScrollBar(editor);
|
||||
|
||||
/* Ensure that the cursor is visible */
|
||||
|
@ -371,47 +370,51 @@ int ME_GetParaLineSpace(ME_Context* c, ME_Paragraph* para)
|
|||
return sp * c->editor->nZoomNumerator / c->editor->nZoomDenominator;
|
||||
}
|
||||
|
||||
static int ME_DrawParaDecoration(ME_Context* c, ME_Paragraph* para, int y)
|
||||
static void ME_DrawParaDecoration(ME_Context* c, ME_Paragraph* para, int y, RECT* bounds)
|
||||
{
|
||||
int idx, border_width;
|
||||
int ybefore, yafter;
|
||||
int idx, border_width, top_border, bottom_border;
|
||||
RECT rc;
|
||||
|
||||
if (!(para->pFmt->dwMask & (PFM_BORDER | PFM_SPACEBEFORE | PFM_SPACEAFTER))) return 0;
|
||||
SetRectEmpty(bounds);
|
||||
if (!(para->pFmt->dwMask & (PFM_BORDER | PFM_SPACEBEFORE | PFM_SPACEAFTER))) return;
|
||||
|
||||
border_width = top_border = bottom_border = 0;
|
||||
idx = (para->pFmt->wBorders >> 8) & 0xF;
|
||||
if ((para->pFmt->dwMask & PFM_BORDER) && idx != 0 && (para->pFmt->wBorders & 0xF))
|
||||
{
|
||||
if (para->pFmt->wBorders & 0x00B0)
|
||||
FIXME("Unsupported border flags %x\n", para->pFmt->wBorders);
|
||||
border_width = ME_GetParaBorderWidth(c->editor, para->pFmt->wBorders);
|
||||
if (para->pFmt->wBorders & 4) top_border = border_width;
|
||||
if (para->pFmt->wBorders & 8) bottom_border = border_width;
|
||||
}
|
||||
|
||||
if (para->pFmt->dwMask & PFM_SPACEBEFORE)
|
||||
{
|
||||
rc.left = c->rcView.left;
|
||||
rc.right = c->rcView.right;
|
||||
rc.top = y;
|
||||
ybefore = ME_twips2pointsY(c, para->pFmt->dySpaceBefore);
|
||||
rc.bottom = y + ybefore;
|
||||
bounds->top = ME_twips2pointsY(c, para->pFmt->dySpaceBefore);
|
||||
rc.bottom = y + bounds->top + top_border;
|
||||
FillRect(c->hDC, &rc, c->editor->hbrBackground);
|
||||
}
|
||||
else ybefore = 0;
|
||||
|
||||
if (para->pFmt->dwMask & PFM_SPACEAFTER)
|
||||
{
|
||||
rc.left = c->rcView.left;
|
||||
rc.right = c->rcView.right;
|
||||
rc.bottom = y + para->nHeight;
|
||||
yafter = ME_twips2pointsY(c, para->pFmt->dySpaceAfter);
|
||||
rc.top = rc.bottom - yafter;
|
||||
bounds->bottom = ME_twips2pointsY(c, para->pFmt->dySpaceAfter);
|
||||
rc.top = rc.bottom - bounds->bottom - bottom_border;
|
||||
FillRect(c->hDC, &rc, c->editor->hbrBackground);
|
||||
}
|
||||
else yafter = 0;
|
||||
|
||||
border_width = 0;
|
||||
idx = (para->pFmt->wBorders >> 8) & 0xF;
|
||||
if ((para->pFmt->dwMask & PFM_BORDER) && idx != 0 && (para->pFmt->wBorders & 0xF)) {
|
||||
int pen_width;
|
||||
COLORREF pencr;
|
||||
HPEN pen = NULL, oldpen = NULL;
|
||||
POINT pt;
|
||||
|
||||
if (para->pFmt->wBorders & 0x00B0)
|
||||
FIXME("Unsupported border flags %x\n", para->pFmt->wBorders);
|
||||
border_width = ME_GetParaBorderWidth(c->editor, para->pFmt->wBorders);
|
||||
|
||||
if (para->pFmt->wBorders & 64) /* autocolor */
|
||||
pencr = GetSysColor(COLOR_WINDOWTEXT);
|
||||
else
|
||||
|
@ -423,50 +426,66 @@ static int ME_DrawParaDecoration(ME_Context* c, ME_Paragraph* para, int y)
|
|||
MoveToEx(c->hDC, 0, 0, &pt);
|
||||
|
||||
/* before & after spaces are not included in border */
|
||||
|
||||
/* helper to draw the double lines in case of corner */
|
||||
#define DD(x) ((para->pFmt->wBorders & (x)) ? (pen_width + 1) : 0)
|
||||
|
||||
if (para->pFmt->wBorders & 1)
|
||||
{
|
||||
MoveToEx(c->hDC, c->rcView.left, y + ybefore, NULL);
|
||||
LineTo(c->hDC, c->rcView.left, y + para->nHeight - yafter);
|
||||
MoveToEx(c->hDC, c->rcView.left, y + bounds->top, NULL);
|
||||
LineTo(c->hDC, c->rcView.left, y + para->nHeight - bounds->bottom);
|
||||
if (border_details[idx].dble) {
|
||||
MoveToEx(c->hDC, c->rcView.left + pen_width + 1, y + ybefore + pen_width + 1, NULL);
|
||||
LineTo(c->hDC, c->rcView.left + pen_width + 1, y + para->nHeight - yafter - pen_width - 1);
|
||||
rc.left = c->rcView.left + 1;
|
||||
rc.right = rc.left + border_width;
|
||||
rc.top = y + bounds->top;
|
||||
rc.bottom = y + para->nHeight - bounds->bottom;
|
||||
FillRect(c->hDC, &rc, c->editor->hbrBackground);
|
||||
MoveToEx(c->hDC, c->rcView.left + pen_width + 1, y + bounds->top + DD(4), NULL);
|
||||
LineTo(c->hDC, c->rcView.left + pen_width + 1, y + para->nHeight - bounds->bottom - DD(8));
|
||||
}
|
||||
bounds->left += border_width;
|
||||
}
|
||||
if (para->pFmt->wBorders & 2)
|
||||
{
|
||||
MoveToEx(c->hDC, c->rcView.right, y + ybefore, NULL);
|
||||
LineTo(c->hDC, c->rcView.right, y + para->nHeight - yafter);
|
||||
MoveToEx(c->hDC, c->rcView.right - 1, y + bounds->top, NULL);
|
||||
LineTo(c->hDC, c->rcView.right - 1, y + para->nHeight - bounds->bottom);
|
||||
if (border_details[idx].dble) {
|
||||
MoveToEx(c->hDC, c->rcView.right - pen_width - 1, y + ybefore + pen_width + 1, NULL);
|
||||
LineTo(c->hDC, c->rcView.right - pen_width - 1, y + para->nHeight - yafter - pen_width - 1);
|
||||
rc.left = c->rcView.right - pen_width - 1;
|
||||
rc.right = c->rcView.right - 1;
|
||||
rc.top = y + bounds->top;
|
||||
rc.bottom = y + para->nHeight - bounds->bottom;
|
||||
FillRect(c->hDC, &rc, c->editor->hbrBackground);
|
||||
MoveToEx(c->hDC, c->rcView.right - 1 - pen_width - 1, y + bounds->top + DD(4), NULL);
|
||||
LineTo(c->hDC, c->rcView.right - 1 - pen_width - 1, y + para->nHeight - bounds->bottom - DD(8));
|
||||
}
|
||||
bounds->right += border_width;
|
||||
}
|
||||
if (para->pFmt->wBorders & 4)
|
||||
{
|
||||
MoveToEx(c->hDC, c->rcView.left, y + ybefore, NULL);
|
||||
LineTo(c->hDC, c->rcView.right, y + ybefore);
|
||||
MoveToEx(c->hDC, c->rcView.left, y + bounds->top, NULL);
|
||||
LineTo(c->hDC, c->rcView.right, y + bounds->top);
|
||||
if (border_details[idx].dble) {
|
||||
MoveToEx(c->hDC, c->rcView.left + pen_width + 1, y + ybefore + pen_width + 1, NULL);
|
||||
LineTo(c->hDC, c->rcView.right - pen_width - 1, y + ybefore + pen_width + 1);
|
||||
MoveToEx(c->hDC, c->rcView.left + DD(1), y + bounds->top + pen_width + 1, NULL);
|
||||
LineTo(c->hDC, c->rcView.right - DD(2), y + bounds->top + pen_width + 1);
|
||||
}
|
||||
bounds->top += border_width;
|
||||
}
|
||||
if (para->pFmt->wBorders & 8)
|
||||
{
|
||||
MoveToEx(c->hDC, c->rcView.left, y + para->nHeight - yafter - 1, NULL);
|
||||
LineTo(c->hDC, c->rcView.right, y + para->nHeight - yafter - 1);
|
||||
MoveToEx(c->hDC, c->rcView.left, y + para->nHeight - bounds->bottom - 1, NULL);
|
||||
LineTo(c->hDC, c->rcView.right, y + para->nHeight - bounds->bottom - 1);
|
||||
if (border_details[idx].dble) {
|
||||
MoveToEx(c->hDC, c->rcView.left + pen_width + 1, y + para->nHeight - yafter - 1 - pen_width - 1, NULL);
|
||||
LineTo(c->hDC, c->rcView.right - pen_width - 1, y + para->nHeight - yafter - 1 - pen_width - 1);
|
||||
MoveToEx(c->hDC, c->rcView.left + DD(1), y + para->nHeight - bounds->bottom - 1 - pen_width - 1, NULL);
|
||||
LineTo(c->hDC, c->rcView.right - DD(2), y + para->nHeight - bounds->bottom - 1 - pen_width - 1);
|
||||
}
|
||||
bounds->bottom += border_width;
|
||||
}
|
||||
#undef DD
|
||||
|
||||
MoveToEx(c->hDC, pt.x, pt.y, NULL);
|
||||
SelectObject(c->hDC, oldpen);
|
||||
DeleteObject(pen);
|
||||
}
|
||||
return ybefore +
|
||||
((para->pFmt->dwMask & PFM_BORDER) && (para->pFmt->wBorders & 4) ?
|
||||
border_width : 0);
|
||||
}
|
||||
|
||||
void ME_DrawParagraph(ME_Context *c, ME_DisplayItem *paragraph) {
|
||||
|
@ -474,12 +493,11 @@ void ME_DrawParagraph(ME_Context *c, ME_DisplayItem *paragraph) {
|
|||
ME_DisplayItem *p;
|
||||
ME_Run *run;
|
||||
ME_Paragraph *para = NULL;
|
||||
RECT rc, rcPara;
|
||||
RECT rc, rcPara, bounds;
|
||||
int y = c->pt.y;
|
||||
int height = 0, baseline = 0, no=0, pno = 0;
|
||||
int xs = 0, xe = 0;
|
||||
BOOL visible = FALSE;
|
||||
int nMargWidth = 0;
|
||||
|
||||
c->pt.x = c->rcView.left;
|
||||
rcPara.left = c->rcView.left;
|
||||
|
@ -489,12 +507,11 @@ void ME_DrawParagraph(ME_Context *c, ME_DisplayItem *paragraph) {
|
|||
case diParagraph:
|
||||
para = &p->member.para;
|
||||
assert(para);
|
||||
nMargWidth = ME_twips2pointsX(c, para->pFmt->dxStartIndent);
|
||||
if (pno != 0)
|
||||
nMargWidth += ME_twips2pointsX(c, para->pFmt->dxOffset);
|
||||
xs = c->rcView.left+nMargWidth;
|
||||
pno = 0;
|
||||
xs = c->rcView.left + ME_twips2pointsX(c, para->pFmt->dxStartIndent);
|
||||
xe = c->rcView.right - ME_twips2pointsX(c, para->pFmt->dxRightIndent);
|
||||
y += ME_DrawParaDecoration(c, para, y);
|
||||
ME_DrawParaDecoration(c, para, y, &bounds);
|
||||
y += bounds.top;
|
||||
break;
|
||||
case diStartRow:
|
||||
y += height;
|
||||
|
@ -503,16 +520,16 @@ void ME_DrawParagraph(ME_Context *c, ME_DisplayItem *paragraph) {
|
|||
visible = RectVisible(c->hDC, &rcPara);
|
||||
if (visible) {
|
||||
/* left margin */
|
||||
rc.left = c->rcView.left;
|
||||
rc.right = c->rcView.left+nMargWidth;
|
||||
rc.left = c->rcView.left + bounds.left;
|
||||
rc.right = xs;
|
||||
rc.top = y;
|
||||
rc.bottom = y+p->member.row.nHeight;
|
||||
FillRect(c->hDC, &rc, c->editor->hbrBackground);
|
||||
/* right margin */
|
||||
rc.left = xe;
|
||||
rc.right = c->rcView.right;
|
||||
rc.right = c->rcView.right - bounds.right;
|
||||
FillRect(c->hDC, &rc, c->editor->hbrBackground);
|
||||
rc.left = c->rcView.left+nMargWidth;
|
||||
rc.left = xs;
|
||||
rc.right = xe;
|
||||
FillRect(c->hDC, &rc, c->editor->hbrBackground);
|
||||
}
|
||||
|
@ -528,7 +545,8 @@ void ME_DrawParagraph(ME_Context *c, ME_DisplayItem *paragraph) {
|
|||
|
||||
height = p->member.row.nHeight;
|
||||
baseline = p->member.row.nBaseline;
|
||||
pno++;
|
||||
if (!pno++)
|
||||
xe += ME_twips2pointsX(c, para->pFmt->dxOffset);
|
||||
break;
|
||||
case diRun:
|
||||
assert(para);
|
||||
|
@ -595,7 +613,7 @@ void ME_Scroll(ME_TextEditor *editor, int value, int type)
|
|||
switch (type)
|
||||
{
|
||||
case 1:
|
||||
/*Scroll absolutly*/
|
||||
/*Scroll absolutely*/
|
||||
si.nPos = value;
|
||||
break;
|
||||
case 2:
|
||||
|
@ -628,7 +646,7 @@ void ME_Scroll(ME_TextEditor *editor, int value, int type)
|
|||
|
||||
void ME_UpdateScrollBar(ME_TextEditor *editor)
|
||||
{
|
||||
/* Note that this is the only funciton that should ever call SetScrolLInfo
|
||||
/* Note that this is the only function that should ever call SetScrolLInfo
|
||||
* with SIF_PAGE or SIF_RANGE. SetScrollPos and SetScrollRange should never
|
||||
* be used at all. */
|
||||
|
||||
|
|
|
@ -73,6 +73,8 @@ void ME_MakeFirstParagraph(ME_TextEditor *editor)
|
|||
|
||||
run = ME_MakeRun(style, ME_MakeString(wszParagraphSign), MERF_ENDPARA);
|
||||
run->member.run.nCharOfs = 0;
|
||||
run->member.run.nCR = 1;
|
||||
run->member.run.nLF = (editor->bEmulateVersion10) ? 1 : 0;
|
||||
|
||||
ME_InsertBefore(text->pLast, para);
|
||||
ME_InsertBefore(text->pLast, run);
|
||||
|
@ -110,7 +112,7 @@ void ME_MarkForPainting(ME_TextEditor *editor, ME_DisplayItem *first, const ME_D
|
|||
}
|
||||
|
||||
/* split paragraph at the beginning of the run */
|
||||
ME_DisplayItem *ME_SplitParagraph(ME_TextEditor *editor, ME_DisplayItem *run, ME_Style *style)
|
||||
ME_DisplayItem *ME_SplitParagraph(ME_TextEditor *editor, ME_DisplayItem *run, ME_Style *style, int numCR, int numLF)
|
||||
{
|
||||
ME_DisplayItem *next_para = NULL;
|
||||
ME_DisplayItem *run_para = NULL;
|
||||
|
@ -119,10 +121,12 @@ ME_DisplayItem *ME_SplitParagraph(ME_TextEditor *editor, ME_DisplayItem *run, ME
|
|||
ME_UndoItem *undo = NULL;
|
||||
int ofs;
|
||||
ME_DisplayItem *pp;
|
||||
int end_len = (editor->bEmulateVersion10 ? 2 : 1);
|
||||
int end_len = numCR + numLF;
|
||||
|
||||
assert(run->type == diRun);
|
||||
|
||||
end_run->member.run.nCR = numCR;
|
||||
end_run->member.run.nLF = numLF;
|
||||
run_para = ME_GetParagraph(run);
|
||||
assert(run_para->member.para.pFmt->cbSize == sizeof(PARAFORMAT2));
|
||||
|
||||
|
@ -204,7 +208,7 @@ ME_DisplayItem *ME_JoinParagraphs(ME_TextEditor *editor, ME_DisplayItem *tp)
|
|||
ME_DisplayItem *pNext, *pFirstRunInNext, *pRun, *pTmp;
|
||||
int i, shift;
|
||||
ME_UndoItem *undo = NULL;
|
||||
int end_len = (editor->bEmulateVersion10 ? 2 : 1);
|
||||
int end_len;
|
||||
|
||||
assert(tp->type == diParagraph);
|
||||
assert(tp->member.para.next_para);
|
||||
|
@ -212,6 +216,15 @@ ME_DisplayItem *ME_JoinParagraphs(ME_TextEditor *editor, ME_DisplayItem *tp)
|
|||
|
||||
pNext = tp->member.para.next_para;
|
||||
|
||||
/* Need to locate end-of-paragraph run here, in order to know end_len */
|
||||
pRun = ME_FindItemBack(pNext, diRunOrParagraph);
|
||||
|
||||
assert(pRun);
|
||||
assert(pRun->type == diRun);
|
||||
assert(pRun->member.run.nFlags & MERF_ENDPARA);
|
||||
|
||||
end_len = pRun->member.run.nCR + pRun->member.run.nLF;
|
||||
|
||||
{
|
||||
/* null char format operation to store the original char format for the ENDPARA run */
|
||||
CHARFORMAT2W fmt;
|
||||
|
@ -222,18 +235,16 @@ ME_DisplayItem *ME_JoinParagraphs(ME_TextEditor *editor, ME_DisplayItem *tp)
|
|||
if (undo)
|
||||
{
|
||||
undo->nStart = pNext->member.para.nCharOfs - end_len;
|
||||
undo->nCR = pRun->member.run.nCR;
|
||||
undo->nLF = pRun->member.run.nLF;
|
||||
assert(pNext->member.para.pFmt->cbSize == sizeof(PARAFORMAT2));
|
||||
*undo->di.member.para.pFmt = *pNext->member.para.pFmt;
|
||||
}
|
||||
|
||||
shift = pNext->member.para.nCharOfs - tp->member.para.nCharOfs - end_len;
|
||||
|
||||
pRun = ME_FindItemBack(pNext, diRunOrParagraph);
|
||||
pFirstRunInNext = ME_FindItemFwd(pNext, diRunOrParagraph);
|
||||
|
||||
assert(pRun);
|
||||
assert(pRun->type == diRun);
|
||||
assert(pRun->member.run.nFlags & MERF_ENDPARA);
|
||||
|
||||
assert(pFirstRunInNext->type == diRun);
|
||||
|
||||
/* if some cursor points at end of paragraph, make it point to the first
|
||||
|
|
|
@ -2605,7 +2605,8 @@ static void SpecialChar (RTF_Info *info)
|
|||
case rtfSect:
|
||||
case rtfRow:
|
||||
case rtfPar:
|
||||
RTFPutUnicodeChar (info, '\n');
|
||||
RTFPutUnicodeChar (info, '\r');
|
||||
if (info->editor->bEmulateVersion10) RTFPutUnicodeChar (info, '\n');
|
||||
break;
|
||||
case rtfNoBrkSpace:
|
||||
RTFPutUnicodeChar (info, 0x00A0);
|
||||
|
|
|
@ -127,8 +127,10 @@ void ME_CheckCharOffsets(ME_TextEditor *editor)
|
|||
p->member.run.nFlags,
|
||||
p->member.run.style->fmt.dwMask & p->member.run.style->fmt.dwEffects);
|
||||
assert(ofs == p->member.run.nCharOfs);
|
||||
if (p->member.run.nFlags & MERF_ENDPARA)
|
||||
ofs += (editor->bEmulateVersion10 ? 2 : 1);
|
||||
if (p->member.run.nFlags & MERF_ENDPARA) {
|
||||
assert(p->member.run.nCR + p->member.run.nLF > 0);
|
||||
ofs += p->member.run.nCR + p->member.run.nLF;
|
||||
}
|
||||
else
|
||||
ofs += ME_StrLen(p->member.run.strText);
|
||||
break;
|
||||
|
@ -209,10 +211,12 @@ void ME_RunOfsFromCharOfs(ME_TextEditor *editor, int nCharOfs, ME_DisplayItem **
|
|||
}
|
||||
*ppRun = pNext;
|
||||
}
|
||||
/* the handling of bEmulateVersion10 may be a source of many bugs, I'm afraid */
|
||||
eollen = (editor->bEmulateVersion10 ? 2 : 1);
|
||||
/* Recover proper character length of this line break */
|
||||
eollen = (*ppRun)->member.run.nCR + (*ppRun)->member.run.nLF;
|
||||
if (nCharOfs >= nParaOfs + (*ppRun)->member.run.nCharOfs &&
|
||||
nCharOfs < nParaOfs + (*ppRun)->member.run.nCharOfs + eollen) {
|
||||
/* FIXME: Might cause problems when actually requiring an offset in the
|
||||
middle of a run that is considered a single line break */
|
||||
*pOfs = 0;
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -327,10 +327,9 @@ ME_LogFontFromStyle(ME_Context* c, LOGFONTW *lf, const ME_Style *s)
|
|||
|
||||
void ME_CharFormatFromLogFont(HDC hDC, const LOGFONTW *lf, CHARFORMAT2W *fmt)
|
||||
{
|
||||
int rx, ry;
|
||||
int ry;
|
||||
|
||||
ME_InitCharFormat2W(fmt);
|
||||
rx = GetDeviceCaps(hDC, LOGPIXELSX);
|
||||
ry = GetDeviceCaps(hDC, LOGPIXELSY);
|
||||
lstrcpyW(fmt->szFaceName, lf->lfFaceName);
|
||||
fmt->dwEffects = 0;
|
||||
|
@ -341,7 +340,7 @@ void ME_CharFormatFromLogFont(HDC hDC, const LOGFONTW *lf, CHARFORMAT2W *fmt)
|
|||
if (lf->lfItalic) fmt->dwEffects |= CFM_ITALIC;
|
||||
if (lf->lfUnderline) fmt->dwEffects |= CFM_UNDERLINE;
|
||||
/* notice that if a logfont was created with underline due to CFM_LINK, this
|
||||
would add an erronious CFM_UNDERLINE. This isn't currently ever a problem */
|
||||
would add an erroneous CFM_UNDERLINE. This isn't currently ever a problem. */
|
||||
if (lf->lfStrikeOut) fmt->dwEffects |= CFM_STRIKEOUT;
|
||||
fmt->bPitchAndFamily = lf->lfPitchAndFamily;
|
||||
fmt->bCharSet = lf->lfCharSet;
|
||||
|
|
|
@ -56,6 +56,7 @@ ME_UndoItem *ME_AddUndoItem(ME_TextEditor *editor, ME_DIType type, const ME_Disp
|
|||
else
|
||||
{
|
||||
ME_DisplayItem *pItem = (ME_DisplayItem *)ALLOC_OBJ(ME_UndoItem);
|
||||
((ME_UndoItem *)pItem)->nCR = ((ME_UndoItem *)pItem)->nLF = -1;
|
||||
switch(type)
|
||||
{
|
||||
case diUndoEndTransaction:
|
||||
|
@ -225,7 +226,10 @@ static void ME_PlayUndoItem(ME_TextEditor *editor, ME_DisplayItem *pItem)
|
|||
ME_CursorFromCharOfs(editor, pUItem->nStart, &tmp);
|
||||
if (tmp.nOffset)
|
||||
tmp.pRun = ME_SplitRunSimple(editor, tmp.pRun, tmp.nOffset);
|
||||
new_para = ME_SplitParagraph(editor, tmp.pRun, tmp.pRun->member.run.style);
|
||||
assert(pUItem->nCR >= 0);
|
||||
assert(pUItem->nLF >= 0);
|
||||
new_para = ME_SplitParagraph(editor, tmp.pRun, tmp.pRun->member.run.style,
|
||||
pUItem->nCR, pUItem->nLF);
|
||||
assert(pItem->member.para.pFmt->cbSize == sizeof(PARAFORMAT2));
|
||||
*new_para->member.para.pFmt = *pItem->member.para.pFmt;
|
||||
break;
|
||||
|
@ -247,7 +251,7 @@ void ME_Undo(ME_TextEditor *editor) {
|
|||
if (!editor->pUndoStack)
|
||||
return;
|
||||
|
||||
/* watch out for uncommited transactions ! */
|
||||
/* watch out for uncommitted transactions ! */
|
||||
assert(editor->pUndoStack->type == diUndoEndTransaction);
|
||||
|
||||
editor->nUndoMode = umAddToRedo;
|
||||
|
@ -280,7 +284,7 @@ void ME_Redo(ME_TextEditor *editor) {
|
|||
if (!editor->pRedoStack)
|
||||
return;
|
||||
|
||||
/* watch out for uncommited transactions ! */
|
||||
/* watch out for uncommitted transactions ! */
|
||||
assert(editor->pRedoStack->type == diUndoEndTransaction);
|
||||
|
||||
editor->nUndoMode = umAddBackToUndo;
|
||||
|
|
|
@ -470,11 +470,9 @@ BOOL ME_WrapMarkedParagraphs(ME_TextEditor *editor) {
|
|||
ME_DisplayItem *item;
|
||||
ME_Context c;
|
||||
BOOL bModified = FALSE;
|
||||
int yStart = -1, yEnd = -1;
|
||||
int yStart = -1;
|
||||
|
||||
ME_InitContext(&c, editor, GetDC(editor->hWnd));
|
||||
c.pt.x = 0;
|
||||
c.pt.y = 0;
|
||||
editor->nHeight = 0;
|
||||
item = editor->pBuffer->pFirst->next;
|
||||
while(item != editor->pBuffer->pLast) {
|
||||
|
@ -499,8 +497,6 @@ BOOL ME_WrapMarkedParagraphs(ME_TextEditor *editor) {
|
|||
bModified = bModified | bRedraw;
|
||||
|
||||
c.pt.y += item->member.para.nHeight;
|
||||
if (bRedraw)
|
||||
yEnd = c.pt.y;
|
||||
item = item->member.para.next_para;
|
||||
}
|
||||
editor->sizeWindow.cx = c.rcView.right-c.rcView.left;
|
||||
|
@ -510,6 +506,14 @@ BOOL ME_WrapMarkedParagraphs(ME_TextEditor *editor) {
|
|||
|
||||
ME_DestroyContext(&c, editor->hWnd);
|
||||
|
||||
/* Each paragraph may contain multiple rows, which should be scrollable, even
|
||||
if the containing paragraph has nYPos == 0 */
|
||||
item = editor->pBuffer->pFirst;
|
||||
while ((item = ME_FindItemFwd(item, diStartRow)) != NULL) {
|
||||
assert(item->type == diStartRow);
|
||||
editor->nHeight = max(editor->nHeight, item->member.row.nYPos);
|
||||
}
|
||||
|
||||
if (bModified || editor->nTotalLength < editor->nLastTotalLength)
|
||||
ME_InvalidateMarkedParagraphs(editor);
|
||||
return bModified;
|
||||
|
|
|
@ -711,9 +711,9 @@ ME_StreamOutRTF(ME_TextEditor *editor, ME_OutStream *pStream, int nStart, int nC
|
|||
if (!ME_StreamOutPrint(pStream, "\r\n\\par"))
|
||||
return FALSE;
|
||||
}
|
||||
nChars--;
|
||||
if (editor->bEmulateVersion10 && nChars)
|
||||
nChars--;
|
||||
/* Skip as many characters as required by current line break */
|
||||
nChars -= (p->member.run.nCR <= nChars) ? p->member.run.nCR : nChars;
|
||||
nChars -= (p->member.run.nLF <= nChars) ? p->member.run.nLF : nChars;
|
||||
} else if (p->member.run.nFlags & MERF_ENDROW) {
|
||||
if (!ME_StreamOutPrint(pStream, "\\line \r\n"))
|
||||
return FALSE;
|
||||
|
@ -775,10 +775,39 @@ ME_StreamOutText(ME_TextEditor *editor, ME_OutStream *pStream, int nStart, int n
|
|||
if (item->member.run.nFlags & MERF_ENDPARA) {
|
||||
static const WCHAR szEOL[2] = { '\r', '\n' };
|
||||
|
||||
if (dwFormat & SF_UNICODE)
|
||||
success = ME_StreamOutMove(pStream, (const char *)szEOL, sizeof(szEOL));
|
||||
else
|
||||
success = ME_StreamOutMove(pStream, "\r\n", 2);
|
||||
if (!editor->bEmulateVersion10) {
|
||||
/* richedit 2.0 - all line breaks are \r\n */
|
||||
if (dwFormat & SF_UNICODE)
|
||||
success = ME_StreamOutMove(pStream, (const char *)szEOL, sizeof(szEOL));
|
||||
else
|
||||
success = ME_StreamOutMove(pStream, "\r\n", 2);
|
||||
assert(nLen == 1);
|
||||
} else {
|
||||
int i; int tnLen;
|
||||
|
||||
/* richedit 1.0 - need to honor actual \r and \n amounts */
|
||||
nLen = item->member.run.nCR + item->member.run.nLF;
|
||||
if (nLen > nChars)
|
||||
nLen = nChars;
|
||||
tnLen = nLen;
|
||||
|
||||
i = 0;
|
||||
while (tnLen > 0 && i < item->member.run.nCR) {
|
||||
if (dwFormat & SF_UNICODE)
|
||||
success = ME_StreamOutMove(pStream, (const char *)(&szEOL[0]), sizeof(WCHAR));
|
||||
else
|
||||
success = ME_StreamOutMove(pStream, "\r", 1);
|
||||
tnLen--; i++;
|
||||
}
|
||||
i = 0;
|
||||
while (tnLen > 0 && i < item->member.run.nLF) {
|
||||
if (dwFormat & SF_UNICODE)
|
||||
success = ME_StreamOutMove(pStream, (const char *)(&szEOL[1]), sizeof(WCHAR));
|
||||
else
|
||||
success = ME_StreamOutMove(pStream, "\n", 1);
|
||||
tnLen--; i++;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (dwFormat & SF_UNICODE)
|
||||
success = ME_StreamOutMove(pStream, (const char *)(item->member.run.strText->szData + nStart),
|
||||
|
@ -800,8 +829,6 @@ ME_StreamOutText(ME_TextEditor *editor, ME_OutStream *pStream, int nStart, int n
|
|||
}
|
||||
|
||||
nChars -= nLen;
|
||||
if (editor->bEmulateVersion10 && nChars && item->member.run.nFlags & MERF_ENDPARA)
|
||||
nChars--;
|
||||
nStart = 0;
|
||||
item = ME_FindItemFwd(item, diRun);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue