diff --git a/dlls/riched20/caret.c b/dlls/riched20/caret.c index 6a939608422..98a638e28a7 100644 --- a/dlls/riched20/caret.c +++ b/dlls/riched20/caret.c @@ -300,12 +300,6 @@ void ME_InsertTextFromCursor(ME_TextEditor *editor, int nCursor, assert(style); editor->bCaretAtEnd = FALSE; - /* - if (!style) - style = ME_GetInsertStyle(editor, nCursor); - else - ME_AddRefStyle(style); - */ ME_AddRefStyle(style); /* FIXME really HERE ? */ @@ -800,8 +794,6 @@ BOOL ME_CancelSelection(ME_TextEditor *editor, int dir) editor->pCursors[1] = editor->pCursors[0]; else editor->pCursors[0] = editor->pCursors[1]; - /* FIXME optimize */ - ME_MarkAllForWrapping(editor); ME_Repaint(editor); return TRUE; } @@ -809,14 +801,6 @@ BOOL ME_CancelSelection(ME_TextEditor *editor, int dir) void ME_RepaintSelection(ME_TextEditor *editor, ME_Cursor *pTempCursor) { ME_Cursor old_anchor = editor->pCursors[1]; - BOOL bRedraw = FALSE; - bRedraw = memcmp(&editor->pCursors[0], &editor->pCursors[1], sizeof(ME_Cursor)); - - if (bRedraw) - { - /* FIXME optimize */ - ME_MarkAllForWrapping(editor); - } if (GetKeyState(VK_SHIFT)>=0) /* cancelling selection */ { @@ -915,6 +899,7 @@ BOOL ME_ArrowKey(ME_TextEditor *editor, int nVKey, int nCtrl) } if (ME_ArrowLeft(editor, p)) { editor->bCaretAtEnd = FALSE; /* FIXME or maybe not */ + ME_ClearTempStyle(editor); ME_MoveCaret(editor); ME_DeleteTextAtCursor(editor, nCursor, 1); ME_UpdateRepaint(editor); @@ -928,10 +913,12 @@ BOOL ME_ArrowKey(ME_TextEditor *editor, int nVKey, int nCtrl) if (ME_IsSelection(editor)) { ME_DeleteSelection(editor); + ME_ClearTempStyle(editor); ME_UpdateRepaint(editor); return TRUE; } ME_DeleteTextAtCursor(editor, nCursor, 1); + ME_ClearTempStyle(editor); ME_UpdateRepaint(editor); return TRUE; } diff --git a/dlls/riched20/editor.c b/dlls/riched20/editor.c index 2ab2952e3cf..2b945dc762c 100644 --- a/dlls/riched20/editor.c +++ b/dlls/riched20/editor.c @@ -277,7 +277,7 @@ static LRESULT ME_StreamInText(ME_TextEditor *editor, DWORD dwFormat, EDITSTREAM void ME_RTFCharAttrHook(RTF_Info *info) { - CHARFORMAT2A fmt; + CHARFORMAT2W fmt; fmt.cbSize = sizeof(fmt); fmt.dwMask = 0; @@ -334,8 +334,8 @@ void ME_RTFCharAttrHook(RTF_Info *info) RTFFont *f = RTFGetFont(info, info->rtfParam); if (f) { - strncpy(fmt.szFaceName, f->rtfFName, sizeof(fmt.szFaceName)-1); - fmt.szFaceName[sizeof(fmt.szFaceName)-1] = '\0'; + MultiByteToWideChar(CP_ACP, 0, f->rtfFName, -1, fmt.szFaceName, sizeof(fmt.szFaceName)/sizeof(WCHAR)); + fmt.szFaceName[sizeof(fmt.szFaceName)/sizeof(WCHAR)-1] = '\0'; fmt.dwMask = CFM_FACE; } } @@ -347,8 +347,12 @@ void ME_RTFCharAttrHook(RTF_Info *info) break; } if (fmt.dwMask) { + ME_Style *style2; RTFFlushOutputBuffer(info); - SendMessageW(info->hwndEdit, EM_SETCHARFORMAT, SCF_SELECTION, (LPARAM)&fmt); + /* FIXME too slow ? how come ? */ + style2 = ME_ApplyStyle(info->style, &fmt); + ME_ReleaseStyle(info->style); + info->style = style2; } } @@ -380,7 +384,8 @@ void ME_RTFParAttrHook(RTF_Info *info) } if (fmt.dwMask) { RTFFlushOutputBuffer(info); - SendMessageW(info->hwndEdit, EM_SETPARAFORMAT, 0, (LPARAM)&fmt); + /* FIXME too slow ? how come ?*/ + ME_SetSelectionParaFormat(info->editor, &fmt); } } @@ -393,17 +398,21 @@ void ME_RTFReadHook(RTF_Info *info) { case rtfBeginGroup: if (info->formatStackTop < maxCharFormatStack) { info->formatStack[info->formatStackTop].cbSize = sizeof(info->formatStack[0]); - SendMessageW(info->hwndEdit, EM_GETCHARFORMAT, 1, (LPARAM)&info->formatStack[info->formatStackTop]); + memcpy(&info->formatStack[info->formatStackTop], &info->style->fmt, sizeof(CHARFORMAT2W)); } info->formatStackTop++; break; case rtfEndGroup: + { + ME_Style *s; RTFFlushOutputBuffer(info); info->formatStackTop--; - if (info->formatStackTop < maxCharFormatStack) { - SendMessageW(info->hwndEdit, EM_SETCHARFORMAT, SCF_SELECTION, (LPARAM)&info->formatStack[info->formatStackTop]); - } + /* FIXME too slow ? how come ? */ + s = ME_ApplyStyle(info->style, &info->formatStack[info->formatStackTop]); + ME_ReleaseStyle(info->style); + info->style = s; break; + } } break; case rtfControl: @@ -426,8 +435,10 @@ static LRESULT ME_StreamIn(ME_TextEditor *editor, DWORD format, EDITSTREAM *stre ME_Style *style; int from, to, to2, nUndoMode; ME_UndoItem *pUI; + int nEventMask = editor->nEventMask; TRACE("%p %p\n", stream, editor->hWnd); + editor->nEventMask = 0; ME_GetSelection(editor, &from, &to); if (format & SFF_SELECTION) { @@ -442,6 +453,7 @@ static LRESULT ME_StreamIn(ME_TextEditor *editor, DWORD format, EDITSTREAM *stre ME_InternalDeleteText(editor, 0, ME_GetTextLength(editor)); from = to = 0; ME_ClearTempStyle(editor); + /* FIXME restore default paragraph formatting ! */ } nUndoMode = editor->nUndoMode; @@ -452,6 +464,8 @@ static LRESULT ME_StreamIn(ME_TextEditor *editor, DWORD format, EDITSTREAM *stre RTFSetEditStream(&parser, stream); parser.rtfFormat = format&(SF_TEXT|SF_RTF); parser.hwndEdit = editor->hWnd; + parser.editor = editor; + parser.style = style; WriterInit(&parser); RTFInit(&parser); RTFSetReadHook(&parser, ME_RTFReadHook); @@ -460,6 +474,8 @@ static LRESULT ME_StreamIn(ME_TextEditor *editor, DWORD format, EDITSTREAM *stre /* do the parsing */ RTFRead(&parser); RTFFlushOutputBuffer(&parser); + + style = parser.style; } else if (format & SF_TEXT) ME_StreamInText(editor, format, stream, style); @@ -483,7 +499,15 @@ static LRESULT ME_StreamIn(ME_TextEditor *editor, DWORD format, EDITSTREAM *stre pUI->nLen = to-from; } ME_CommitUndo(editor); - ME_ReleaseStyle(style); + ME_ReleaseStyle(style); + editor->nEventMask = nEventMask; + ME_UpdateRepaint(editor); + if (!(format & SFF_SELECTION)) { + ME_ClearTempStyle(editor); + ME_EnsureVisible(editor, editor->pCursors[0].pRun); + } + ME_MoveCaret(editor); + ME_SendSelChange(editor); return 0; } @@ -817,6 +841,7 @@ LRESULT WINAPI RichEditANSIWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lP case EM_SETCHARFORMAT: { CHARFORMAT2W buf, *p; + BOOL bRepaint = TRUE; p = ME_ToCF2W(&buf, (CHARFORMAT2W *)lParam); if (!wParam) ME_SetDefaultCharFormat(editor, p); @@ -824,10 +849,15 @@ LRESULT WINAPI RichEditANSIWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lP FIXME("word selection not supported\n"); else if (wParam == SCF_ALL) ME_SetCharFormat(editor, 0, ME_GetTextLength(editor), p); - else + else { + int from, to; + ME_GetSelection(editor, &from, &to); + bRepaint = (from != to); ME_SetSelectionCharFormat(editor, p); + } ME_CommitUndo(editor); - ME_UpdateRepaint(editor); + if (bRepaint) + ME_UpdateRepaint(editor); return 0; } case EM_GETCHARFORMAT: @@ -843,6 +873,7 @@ LRESULT WINAPI RichEditANSIWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lP } case EM_SETPARAFORMAT: ME_SetSelectionParaFormat(editor, (PARAFORMAT2 *)lParam); + ME_UpdateRepaint(editor); ME_CommitUndo(editor); return 0; case EM_GETPARAFORMAT: diff --git a/dlls/riched20/editor.h b/dlls/riched20/editor.h index ff0c19884c2..0a2b8ae1e59 100644 --- a/dlls/riched20/editor.h +++ b/dlls/riched20/editor.h @@ -85,6 +85,10 @@ void ME_EndToUnicode(HWND hWnd, LPVOID psz); LPSTR ME_ToAnsi(HWND hWnd, LPVOID psz); void ME_EndToAnsi(HWND hWnd, LPVOID psz); +static inline int ME_IsWSpace(WCHAR ch) +{ + return ch > '\0' && ch <= ' '; +} /* note: those two really return the first matching offset (starting from EOS)+1 * in other words, an offset of the first trailing white/black */ diff --git a/dlls/riched20/paint.c b/dlls/riched20/paint.c index 90b8d9d36c6..21c7a799069 100644 --- a/dlls/riched20/paint.c +++ b/dlls/riched20/paint.c @@ -146,8 +146,8 @@ void ME_Repaint(ME_TextEditor *editor) ME_DisplayItem *pRun = NULL; int nOffset = -1; HDC hDC; - int nCharOfs = ME_CharOfsFromRunOfs(editor, pCursor->pRun, pCursor->nOffset); + ME_RunOfsFromCharOfs(editor, nCharOfs, &pRun, &nOffset); assert(pRun == pCursor->pRun); assert(nOffset == pCursor->nOffset); @@ -244,6 +244,9 @@ void ME_DrawRun(ME_Context *c, int x, int y, ME_DisplayItem *rundi, ME_Paragraph ME_Run *run = &rundi->member.run; int runofs = run->nCharOfs+para->nCharOfs; + /* you can always comment it out if you need visible paragraph marks */ + if (run->nFlags & MERF_ENDPARA) + return; if (run->nFlags & MERF_GRAPHICS) { int blfrom, blto; ME_GetSelection(c->editor, &blfrom, &blto); diff --git a/dlls/riched20/para.c b/dlls/riched20/para.c index ecd8e49e58b..48ba176760c 100644 --- a/dlls/riched20/para.c +++ b/dlls/riched20/para.c @@ -310,7 +310,6 @@ void ME_SetSelectionParaFormat(ME_TextEditor *editor, PARAFORMAT2 *pFmt) break; para = para->member.para.next_para; } while(1); - ME_Repaint(editor); } void ME_GetParaFormat(ME_TextEditor *editor, ME_DisplayItem *para, PARAFORMAT2 *pFmt) diff --git a/dlls/riched20/reader.c b/dlls/riched20/reader.c index f17850a332a..40d4517c017 100644 --- a/dlls/riched20/reader.c +++ b/dlls/riched20/reader.c @@ -42,12 +42,13 @@ #include #include -#include "rtf.h" - #include "windef.h" #include "winbase.h" #include "wine/debug.h" +#include "editor.h" +#include "rtf.h" + WINE_DEFAULT_DEBUG_CHANNEL(richedit); extern HANDLE me_heap; @@ -68,6 +69,7 @@ static int Hash (char*); static void CharSetInit (RTF_Info *); static void ReadCharSetMaps (RTF_Info *); +static void RTFOutputUnicodeString( RTF_Info *info, WCHAR *str, int len ); /* @@ -2452,6 +2454,7 @@ static RTFKey rtfKey[] = { rtfSpecialChar, rtfNoWidthNonJoiner, "zwnj", 0 }, /* is this valid? */ { rtfSpecialChar, rtfCurHeadPict, "chpict", 0 }, + { rtfSpecialChar, rtfUnicode, "u", 0 }, /* * Character formatting attributes @@ -3698,7 +3701,6 @@ Destination (RTF_Info *info) RTFSkipGroup (info); } - /* * The reason these use the rtfSC_xxx thingies instead of just writing * out ' ', '-', '"', etc., is so that the mapping for these characters @@ -3721,6 +3723,22 @@ void SpecialChar (RTF_Info *info) else RTFRouteToken(info); /* "\*" is ignored with known destinations */ break; + case rtfUnicode: + { + WCHAR buf[2]; + buf[0] = info->rtfParam; + buf[1] = 0; + RTFFlushOutputBuffer(info); + RTFOutputUnicodeString(info, buf, 1); + + RTFGetToken(info); + if (info->rtfClass != rtfText && info->rtfMajor != '?') + { + ERR("The character behind \\u is not a question mark, but (%d,%d,%d)\n", + info->rtfClass, info->rtfMajor, info->rtfMinor); + } + break; + } case rtfPage: case rtfSect: case rtfRow: @@ -3801,10 +3819,32 @@ void PutLitChar (RTF_Info *info, int c) info->OutputBuffer[info->dwOutputCount++] = c; } +void RTFOutputANSIStringOrig( RTF_Info *info, char *str, int len ) +{ + assert(str[len] == '\0'); + if (len) { + SendMessageA( info->hwndEdit, EM_REPLACESEL, FALSE, (LPARAM) str); + } +} + void RTFOutputANSIString( RTF_Info *info, char *str, int len ) { assert(str[len] == '\0'); - if (len) SendMessageA( info->hwndEdit, EM_REPLACESEL, FALSE, (LPARAM) str); + if (len) { + WCHAR *buf = ALLOC_N_OBJ(WCHAR, len); + + len = MultiByteToWideChar(CP_ACP, 0, str, len, buf, len); + ME_InsertTextFromCursor( info->editor, 0, buf, len, info->style ); + FREE_OBJ(buf); + } +} + +void RTFOutputUnicodeString( RTF_Info *info, WCHAR *str, int len ) +{ + assert(str[len] == '\0'); + if (len) { + ME_InsertTextFromCursor( info->editor, 0, str, len, info->style ); + } } void RTFFlushOutputBuffer( RTF_Info *info ) diff --git a/dlls/riched20/richole.c b/dlls/riched20/richole.c index 1c9e4509a75..21e50cb4a23 100644 --- a/dlls/riched20/richole.c +++ b/dlls/riched20/richole.c @@ -64,6 +64,7 @@ IRichEditOle_fnQueryInterface(IRichEditOle *me, REFIID riid, LPVOID *ppvObj) *ppvObj = (LPVOID) This; return S_OK; } + FIXME("%p: unhandled interface %s\n", This, debugstr_guid(riid) ); return E_NOINTERFACE; } @@ -215,7 +216,7 @@ static HRESULT WINAPI IRichEditOle_fnSetHostNames(IRichEditOle *me, LPCSTR lpstrContainerApp, LPCSTR lpstrContainerObj) { IRichEditOleImpl *This = (IRichEditOleImpl *)me; - FIXME("stub %p\n",This); + FIXME("stub %p %s %s\n",This, lpstrContainerApp, lpstrContainerObj); return E_NOTIMPL; } diff --git a/dlls/riched20/rtf.h b/dlls/riched20/rtf.h index f869273629e..ede410eedca 100644 --- a/dlls/riched20/rtf.h +++ b/dlls/riched20/rtf.h @@ -625,6 +625,7 @@ # define rtfNoWidthNonJoiner 56 /* new in 1.10 */ # define rtfCurHeadPict 57 /* valid? */ /*# define rtfCurAnnot 58*/ /* apparently not used */ +# define rtfUnicode 58 /* no better category*/ # define rtfStyleAttr 7 # define rtfAdditive 0 /* new in 1.10 */ @@ -1452,6 +1453,9 @@ struct _RTF_Info { /* edit window to output to */ HWND hwndEdit; + + ME_TextEditor *editor; + ME_Style *style; /* * These arrays are used to map RTF input character values onto the standard diff --git a/dlls/riched20/run.c b/dlls/riched20/run.c index a34f0c2a7f8..0bc2a8e171d 100644 --- a/dlls/riched20/run.c +++ b/dlls/riched20/run.c @@ -321,11 +321,6 @@ ME_DisplayItem *ME_InsertRun(ME_TextEditor *editor, int nCharOfs, ME_DisplayItem return pDI; } -static inline int ME_IsWSpace(WCHAR ch) -{ - return ch <= ' '; -} - void ME_UpdateRunFlags(ME_TextEditor *editor, ME_Run *run) { assert(run->nCharOfs != -1); diff --git a/dlls/riched20/string.c b/dlls/riched20/string.c index c18fa1d5501..42ba34c858f 100644 --- a/dlls/riched20/string.c +++ b/dlls/riched20/string.c @@ -112,7 +112,7 @@ int ME_IsWhitespaces(ME_String *s) { /* FIXME multibyte */ WCHAR *pos = s->szData; - while(*pos++ == ' ') + while(ME_IsWSpace(*pos++)) ; pos--; if (*pos) @@ -126,12 +126,12 @@ int ME_IsSplitable(ME_String *s) /* FIXME multibyte */ WCHAR *pos = s->szData; WCHAR ch; - while(*pos++ == L' ') + while(ME_IsWSpace(*pos++)) ; pos--; while((ch = *pos++) != 0) { - if (ch == L' ') + if (ME_IsWSpace(*pos++)) return 1; } return 0; diff --git a/dlls/riched20/wrap.c b/dlls/riched20/wrap.c index 683b659130f..5f48e172488 100644 --- a/dlls/riched20/wrap.c +++ b/dlls/riched20/wrap.c @@ -274,10 +274,6 @@ ME_DisplayItem *ME_WrapHandleRun(ME_WrapContext *wc, ME_DisplayItem *p) wc->bOverflown = FALSE; pp = ME_SplitRun(wc->context, p, black); p->member.run.nFlags |= MERF_SKIPPED; -/* - run->pt = wc->pt; - wc->pt.x += run->nWidth; - */ ME_InsertRowStart(wc, pp); return pp; }