https://git.reactos.org/?p=reactos.git;a=commitdiff;h=601646e3b0cf5750e01d31...
commit 601646e3b0cf5750e01d31023c46decca7e84fa6 Author: Doug Lyons douglyons@douglyons.com AuthorDate: Wed Feb 19 22:02:06 2025 -0600 Commit: GitHub noreply@github.com CommitDate: Wed Feb 19 22:02:06 2025 -0600
[RICHED20] Sync to Wine-6.10 (#7713)
* Restore cherry picked commit limiting tab stops in para.c * Add 'remove_definitions(-D_CRT_NON_CONFORMING_SWPRINTFS)' to CMakeFiles.txt. Restore para.c to standard conforming 'swprintf'.
CORE-6727 --- dll/win32/riched20/CMakeLists.txt | 1 + dll/win32/riched20/caret.c | 1071 +++++++---------- dll/win32/riched20/clipboard.c | 7 +- dll/win32/riched20/editor.c | 2358 +++++++++++-------------------------- dll/win32/riched20/editor.h | 215 +++- dll/win32/riched20/editstr.h | 70 +- dll/win32/riched20/list.c | 45 - dll/win32/riched20/paint.c | 649 +++++----- dll/win32/riched20/para.c | 698 ++++++----- dll/win32/riched20/reader.c | 2 +- dll/win32/riched20/riched20.h | 185 +++ dll/win32/riched20/richole.c | 1472 +++++++++++------------ dll/win32/riched20/row.c | 169 ++- dll/win32/riched20/rtf.h | 4 +- dll/win32/riched20/run.c | 565 ++++----- dll/win32/riched20/style.c | 48 +- dll/win32/riched20/table.c | 694 +++++------ dll/win32/riched20/txthost.c | 1537 +++++++++++++++++++----- dll/win32/riched20/txtsrv.c | 719 +++++++---- dll/win32/riched20/undo.c | 64 +- dll/win32/riched20/wrap.c | 934 +++++++-------- dll/win32/riched20/writer.c | 290 ++--- media/doc/WINESYNC.txt | 2 +- 23 files changed, 5920 insertions(+), 5879 deletions(-)
diff --git a/dll/win32/riched20/CMakeLists.txt b/dll/win32/riched20/CMakeLists.txt index b61a49dfa06..5f22d91ca54 100644 --- a/dll/win32/riched20/CMakeLists.txt +++ b/dll/win32/riched20/CMakeLists.txt @@ -1,4 +1,5 @@
+remove_definitions(-D_CRT_NON_CONFORMING_SWPRINTFS) add_definitions(-D__WINESRC__ -D__ROS_LONG64__) include_directories(${REACTOS_SOURCE_DIR}/sdk/include/reactos/wine) spec2def(riched20.dll riched20.spec ADD_IMPORTLIB) diff --git a/dll/win32/riched20/caret.c b/dll/win32/riched20/caret.c index 96a95872c2d..4785650bb78 100644 --- a/dll/win32/riched20/caret.c +++ b/dll/win32/riched20/caret.c @@ -26,16 +26,16 @@ WINE_DEFAULT_DEBUG_CHANNEL(richedit);
void ME_SetCursorToStart(ME_TextEditor *editor, ME_Cursor *cursor) { - cursor->pPara = editor->pBuffer->pFirst->member.para.next_para; - cursor->pRun = ME_FindItemFwd(cursor->pPara, diRun); + cursor->para = editor_first_para( editor ); + cursor->run = para_first_run( cursor->para ); cursor->nOffset = 0; }
static void ME_SetCursorToEnd(ME_TextEditor *editor, ME_Cursor *cursor, BOOL final_eop) { - cursor->pPara = editor->pBuffer->pLast->member.para.prev_para; - cursor->pRun = ME_FindItemBack(editor->pBuffer->pLast, diRun); - cursor->nOffset = final_eop ? cursor->pRun->member.run.len : 0; + cursor->para = para_prev( editor_end_para( editor ) ); + cursor->run = para_end_run( cursor->para ); + cursor->nOffset = final_eop ? cursor->run->len : 0; }
@@ -99,7 +99,7 @@ int ME_GetTextLengthEx(ME_TextEditor *editor, const GETTEXTLENGTHEX *how)
length = ME_GetTextLength(editor);
- if ((editor->styleFlags & ES_MULTILINE) + if ((editor->props & TXTBIT_MULTILINE) && (how->flags & GTL_USECRLF) && !editor->bEmulateVersion10) /* Ignore GTL_USECRLF flag in 1.0 emulation */ length += editor->nParagraphs - 1; @@ -201,16 +201,16 @@ int set_selection_cursors(ME_TextEditor *editor, int from, int to) return len; }
- ME_CursorFromCharOfs(editor, from, &editor->pCursors[1]); + cursor_from_char_ofs( editor, from, &editor->pCursors[1] ); editor->pCursors[0] = editor->pCursors[1]; ME_MoveCursorChars(editor, &editor->pCursors[0], to - from, FALSE); /* Selection is not allowed in the middle of an end paragraph run. */ - if (editor->pCursors[1].pRun->member.run.nFlags & MERF_ENDPARA) + if (editor->pCursors[1].run->nFlags & MERF_ENDPARA) editor->pCursors[1].nOffset = 0; - if (editor->pCursors[0].pRun->member.run.nFlags & MERF_ENDPARA) + if (editor->pCursors[0].run->nFlags & MERF_ENDPARA) { if (to > len) - editor->pCursors[0].nOffset = editor->pCursors[0].pRun->member.run.len; + editor->pCursors[0].nOffset = editor->pCursors[0].run->len; else editor->pCursors[0].nOffset = 0; } @@ -218,54 +218,33 @@ int set_selection_cursors(ME_TextEditor *editor, int from, int to) }
-void ME_GetCursorCoordinates(ME_TextEditor *editor, ME_Cursor *pCursor, - int *x, int *y, int *height) +void cursor_coords( ME_TextEditor *editor, ME_Cursor *cursor, + int *x, int *y, int *height ) { - ME_DisplayItem *row; - ME_DisplayItem *run = pCursor->pRun; - ME_DisplayItem *para = pCursor->pPara; - ME_DisplayItem *pSizeRun = run; + ME_Row *row; + ME_Run *run = cursor->run; + ME_Paragraph *para = cursor->para; + ME_Run *size_run = run, *prev; ME_Context c; int run_x; + HDC hdc = ITextHost_TxGetDC( editor->texthost );
- assert(height && x && y); - assert(~para->member.para.nFlags & MEPF_REWRAP); - assert(run && run->type == diRun); - assert(para && para->type == diParagraph); + assert(~para->nFlags & MEPF_REWRAP);
- row = ME_FindItemBack(run, diStartRowOrParagraph); - assert(row && row->type == diStartRow); + row = row_from_cursor( cursor );
- ME_InitContext(&c, editor, ITextHost_TxGetDC(editor->texthost)); + ME_InitContext( &c, editor, hdc );
- if (!pCursor->nOffset) - { - ME_DisplayItem *prev = ME_FindItemBack(run, diRunOrParagraph); - assert(prev); - if (prev->type == diRun) - pSizeRun = prev; - } - if (editor->bCaretAtEnd && !pCursor->nOffset && - run == ME_FindItemFwd(row, diRun)) - { - ME_DisplayItem *tmp = ME_FindItemBack(row, diRunOrParagraph); - assert(tmp); - if (tmp->type == diRun) - { - row = ME_FindItemBack(tmp, diStartRow); - pSizeRun = run = tmp; - assert(run); - assert(run->type == diRun); - } - } - run_x = ME_PointFromCharContext( &c, &run->member.run, pCursor->nOffset, TRUE ); + if (!cursor->nOffset && (prev = run_prev( run ))) size_run = prev;
- *height = pSizeRun->member.run.nAscent + pSizeRun->member.run.nDescent; - *x = c.rcView.left + run->member.run.pt.x + run_x - editor->horz_si.nPos; - *y = c.rcView.top + para->member.para.pt.y + row->member.row.nBaseline - + run->member.run.pt.y - pSizeRun->member.run.nAscent - - editor->vert_si.nPos; + run_x = ME_PointFromCharContext( &c, run, cursor->nOffset, TRUE ); + + *height = size_run->nAscent + size_run->nDescent; + *x = c.rcView.left + run->pt.x + run_x - editor->horz_si.nPos; + *y = c.rcView.top + para->pt.y + row->nBaseline + + run->pt.y - size_run->nAscent - editor->vert_si.nPos; ME_DestroyContext(&c); + ITextHost_TxReleaseDC( editor->texthost, hdc ); return; }
@@ -273,7 +252,7 @@ void create_caret(ME_TextEditor *editor) { int x, y, height;
- ME_GetCursorCoordinates(editor, &editor->pCursors[0], &x, &y, &height); + cursor_coords( editor, &editor->pCursors[0], &x, &y, &height ); ITextHost_TxCreateCaret(editor->texthost, NULL, 0, height); editor->caret_height = height; editor->caret_hidden = TRUE; @@ -302,7 +281,7 @@ void update_caret(ME_TextEditor *editor) if (!editor->bHaveFocus) return; if (!ME_IsSelection(editor)) { - ME_GetCursorCoordinates(editor, &editor->pCursors[0], &x, &y, &height); + cursor_coords( editor, &editor->pCursors[0], &x, &y, &height ); if (height != editor->caret_height) create_caret(editor); x = min(x, editor->rcFormat.right-1); ITextHost_TxSetCaretPos(editor->texthost, x, y); @@ -364,60 +343,57 @@ BOOL ME_InternalDeleteText(ME_TextEditor *editor, ME_Cursor *start, int nOfs = ME_GetCursorOfs(start), text_len = ME_GetTextLength( editor ); int shift = 0; int totalChars = nChars; - ME_DisplayItem *start_para; + ME_Paragraph *start_para; BOOL delete_all = FALSE;
/* Prevent deletion past last end of paragraph run. */ nChars = min(nChars, text_len - nOfs); if (nChars == text_len) delete_all = TRUE; - start_para = c.pPara; + start_para = c.para;
if (!bForce) { - ME_ProtectPartialTableDeletion(editor, &c, &nChars); - if (nChars == 0) - return FALSE; + table_protect_partial_deletion( editor, &c, &nChars ); + if (nChars == 0) return FALSE; }
- while(nChars > 0) + while (nChars > 0) { ME_Run *run; - ME_CursorFromCharOfs(editor, nOfs+nChars, &c); - if (!c.nOffset && - nOfs+nChars == (c.pRun->member.run.nCharOfs - + c.pPara->member.para.nCharOfs)) + cursor_from_char_ofs( editor, nOfs + nChars, &c ); + if (!c.nOffset) { /* We aren't deleting anything in this run, so we will go back to the * last run we are deleting text in. */ - ME_PrevRun(&c.pPara, &c.pRun, TRUE); - c.nOffset = c.pRun->member.run.len; + c.run = run_prev_all_paras( c.run ); + c.para = c.run->para; + c.nOffset = c.run->len; } - run = &c.pRun->member.run; - if (run->nFlags & MERF_ENDPARA) { - int eollen = c.pRun->member.run.len; + run = c.run; + if (run->nFlags & MERF_ENDPARA) + { + int eollen = c.run->len; BOOL keepFirstParaFormat;
- if (!ME_FindItemFwd(c.pRun, diParagraph)) - { - return TRUE; - } + if (!para_next( para_next( c.para ) )) return TRUE; + keepFirstParaFormat = (totalChars == nChars && nChars <= eollen && run->nCharOfs); if (!editor->bEmulateVersion10) /* v4.1 */ { - ME_DisplayItem *next_para = ME_FindItemFwd(c.pRun, diParagraphOrEnd); - ME_DisplayItem *this_para = next_para->member.para.prev_para; + ME_Paragraph *this_para = run->para; + ME_Paragraph *next_para = para_next( this_para );
/* The end of paragraph before a table row is only deleted if there * is nothing else on the line before it. */ - if (this_para == start_para && - next_para->member.para.nFlags & MEPF_ROWSTART) + if (this_para == start_para && next_para->nFlags & MEPF_ROWSTART) { /* If the paragraph will be empty, then it should be deleted, however * it still might have text right now which would inherit the * MEPF_STARTROW property if we joined it right now. * Instead we will delete it after the preceding text is deleted. */ - if (nOfs > this_para->member.para.nCharOfs) { + if (nOfs > this_para->nCharOfs) + { /* Skip this end of line. */ nChars -= (eollen < nChars) ? eollen : nChars; continue; @@ -425,7 +401,7 @@ BOOL ME_InternalDeleteText(ME_TextEditor *editor, ME_Cursor *start, keepFirstParaFormat = TRUE; } } - ME_JoinParagraphs(editor, c.pPara, keepFirstParaFormat); + para_join( editor, c.para, keepFirstParaFormat ); /* ME_SkipAndPropagateCharOffset(p->pRun, shift); */ ME_CheckCharOffsets(editor); nChars -= (eollen < nChars) ? eollen : nChars; @@ -439,7 +415,7 @@ BOOL ME_InternalDeleteText(ME_TextEditor *editor, ME_Cursor *start,
c.nOffset -= nCharsToDelete;
- mark_para_rewrap(editor, ME_FindItemBack(c.pRun, diParagraph)); + para_mark_rewrap( editor, c.run->para );
cursor = c; /* nChars is the number of characters that should be deleted from the @@ -464,7 +440,7 @@ BOOL ME_InternalDeleteText(ME_TextEditor *editor, ME_Cursor *start, for (i=-1; i<editor->nCursors; i++) { ME_Cursor *pThisCur = editor->pCursors + i; if (i == -1) pThisCur = &c; - if (pThisCur->pRun == cursor.pRun) { + if (pThisCur->run == cursor.run) { if (pThisCur->nOffset > cursor.nOffset) { if (pThisCur->nOffset-cursor.nOffset < nCharsToDelete) pThisCur->nOffset = cursor.nOffset; @@ -475,8 +451,8 @@ BOOL ME_InternalDeleteText(ME_TextEditor *editor, ME_Cursor *start, } if (pThisCur->nOffset == run->len) { - pThisCur->pRun = ME_FindItemFwd(pThisCur->pRun, diRunOrParagraphOrEnd); - assert(pThisCur->pRun->type == diRun); + pThisCur->run = run_next( pThisCur->run ); + assert( pThisCur->run ); pThisCur->nOffset = 0; } } @@ -484,26 +460,21 @@ BOOL ME_InternalDeleteText(ME_TextEditor *editor, ME_Cursor *start,
/* c = updated data now */
- if (c.pRun == cursor.pRun) - ME_SkipAndPropagateCharOffset(c.pRun, shift); - else - ME_PropagateCharOffset(c.pRun, shift); + if (c.run == cursor.run) c.run->nCharOfs -= shift; + editor_propagate_char_ofs( NULL, c.run, shift );
- if (!cursor.pRun->member.run.len) + if (!cursor.run->len) { TRACE("Removing empty run\n"); - ME_Remove(cursor.pRun); - ME_DestroyDisplayItem(cursor.pRun); + ME_Remove( run_get_di( cursor.run )); + ME_DestroyDisplayItem( run_get_di( cursor.run )); }
shift = 0; - /* - ME_CheckCharOffsets(editor); - */ continue; } } - if (delete_all) ME_SetDefaultParaFormat( editor, &start_para->member.para.fmt ); + if (delete_all) editor_set_default_para_fmt( editor, &start_para->fmt ); return TRUE; }
@@ -516,20 +487,6 @@ BOOL ME_DeleteTextAtCursor(ME_TextEditor *editor, int nCursor, int nChars) nChars, FALSE); }
-static ME_DisplayItem * -ME_InternalInsertTextFromCursor(ME_TextEditor *editor, int nCursor, - const WCHAR *str, int len, ME_Style *style, - int flags) -{ - ME_Cursor *p = &editor->pCursors[nCursor]; - - editor->bCaretAtEnd = FALSE; - - assert(p->pRun->type == diRun); - - return ME_InsertRunAtCursor(editor, p, style, str, len, flags); -} - static struct re_object* create_re_object(const REOBJECT *reo) { struct re_object *reobj = heap_alloc(sizeof(*reobj)); @@ -545,66 +502,65 @@ static struct re_object* create_re_object(const REOBJECT *reo)
void ME_InsertOLEFromCursor(ME_TextEditor *editor, const REOBJECT* reo, int nCursor) { - ME_Style *pStyle = ME_GetInsertStyle(editor, nCursor); - ME_DisplayItem *di; - WCHAR space = ' '; - ME_DisplayItem *di_prev = NULL; - struct re_object *reobj_prev = NULL; - + ME_Run *run, *prev; + const WCHAR space = ' '; + struct re_object *reobj_prev = NULL; + ME_Cursor *cursor = editor->pCursors + nCursor; + ME_Style *style = style_get_insert_style( editor, cursor ); + /* FIXME no no no */ if (ME_IsSelection(editor)) ME_DeleteSelection(editor);
- di = ME_InternalInsertTextFromCursor(editor, nCursor, &space, 1, pStyle, - MERF_GRAPHICS); - di->member.run.reobj = create_re_object(reo); + run = run_insert( editor, cursor, style, &space, 1, MERF_GRAPHICS ); + + run->reobj = create_re_object( reo );
- di_prev = di; - while (ME_PrevRun(NULL, &di_prev, TRUE)) + prev = run; + while ((prev = run_prev_all_paras( prev ))) { - if (di_prev->member.run.reobj) + if (prev->reobj) { - reobj_prev = di_prev->member.run.reobj; + reobj_prev = prev->reobj; break; } } if (reobj_prev) - list_add_after(&reobj_prev->entry, &di->member.run.reobj->entry); + list_add_after(&reobj_prev->entry, &run->reobj->entry); else - list_add_head(&editor->reobj_list, &di->member.run.reobj->entry); + list_add_head(&editor->reobj_list, &run->reobj->entry);
- ME_ReleaseStyle(pStyle); + ME_ReleaseStyle( style ); }
void ME_InsertEndRowFromCursor(ME_TextEditor *editor, int nCursor) { - ME_Style *pStyle = ME_GetInsertStyle(editor, nCursor); - WCHAR space = ' '; + const WCHAR space = ' '; + ME_Cursor *cursor = editor->pCursors + nCursor; + ME_Style *style = style_get_insert_style( editor, cursor );
/* FIXME no no no */ if (ME_IsSelection(editor)) ME_DeleteSelection(editor);
- ME_InternalInsertTextFromCursor(editor, nCursor, &space, 1, pStyle, - MERF_ENDROW); - ME_ReleaseStyle(pStyle); + run_insert( editor, cursor, style, &space, 1, MERF_ENDROW ); + + ME_ReleaseStyle( style ); }
void ME_InsertTextFromCursor(ME_TextEditor *editor, int nCursor, - const WCHAR *str, int len, ME_Style *style) + const WCHAR *str, int len, ME_Style *style) { const WCHAR *pos; - ME_Cursor *p = NULL; + ME_Cursor *cursor = editor->pCursors + nCursor; int oldLen;
/* FIXME really HERE ? */ if (ME_IsSelection(editor)) ME_DeleteSelection(editor);
- /* FIXME: is this too slow? */ - /* Didn't affect performance for WM_SETTEXT (around 50sec/30K) */ oldLen = ME_GetTextLength(editor);
/* text operations set modified state */ @@ -612,34 +568,35 @@ void ME_InsertTextFromCursor(ME_TextEditor *editor, int nCursor,
assert(style);
- assert(nCursor>=0 && nCursor<editor->nCursors); - if (len == -1) - len = lstrlenW(str); + if (len == -1) len = lstrlenW( str );
/* grow the text limit to fit our text */ - if(editor->nTextLimit < oldLen +len) - editor->nTextLimit = oldLen + len; + if (editor->nTextLimit < oldLen + len) editor->nTextLimit = oldLen + len;
pos = str;
while (len) { /* FIXME this sucks - no respect for unicode (what else can be a line separator in unicode?) */ - while(pos - str < len && *pos != '\r' && *pos != '\n' && *pos != '\t') + while (pos - str < len && *pos != '\r' && *pos != '\n' && *pos != '\t') pos++;
- if (pos != str) { /* handle text */ - ME_InternalInsertTextFromCursor(editor, nCursor, str, pos-str, style, 0); - } else if (*pos == '\t') { /* handle tabs */ - WCHAR tab = '\t'; - ME_InternalInsertTextFromCursor(editor, nCursor, &tab, 1, style, MERF_TAB); + if (pos != str) /* handle text */ + run_insert( editor, cursor, style, str, pos - str, 0 ); + else if (*pos == '\t') /* handle tabs */ + { + const WCHAR tab = '\t'; + run_insert( editor, cursor, style, &tab, 1, MERF_TAB ); pos++; - } else { /* handle EOLs */ - ME_DisplayItem *tp, *end_run, *run, *prev; + } + else /* handle EOLs */ + { + ME_Run *end_run, *run, *prev; + ME_Paragraph *new_para; int eol_len = 0;
/* Check if new line is allowed for this control */ - if (!(editor->styleFlags & ES_MULTILINE)) + if (!(editor->props & TXTBIT_MULTILINE)) break;
/* Find number of CR and LF in end of paragraph run */ @@ -651,7 +608,9 @@ void ME_InsertTextFromCursor(ME_TextEditor *editor, int nCursor, eol_len = 3; else eol_len = 1; - } else { + } + else + { assert(*pos == '\n'); eol_len = 1; } @@ -660,9 +619,11 @@ void ME_InsertTextFromCursor(ME_TextEditor *editor, int nCursor, if (!editor->bEmulateVersion10 && eol_len == 3) { /* handle special \r\r\n sequence (richedit 2.x and higher only) */ - WCHAR space = ' '; - ME_InternalInsertTextFromCursor(editor, nCursor, &space, 1, style, 0); - } else { + const WCHAR space = ' '; + run_insert( editor, cursor, style, &space, 1, 0 ); + } + else + { const WCHAR cr = '\r', *eol_str = str;
if (!editor->bEmulateVersion10) @@ -671,35 +632,32 @@ void ME_InsertTextFromCursor(ME_TextEditor *editor, int nCursor, eol_len = 1; }
- p = &editor->pCursors[nCursor]; - - if (p->nOffset == p->pRun->member.run.len) + if (cursor->nOffset == cursor->run->len) { - run = ME_FindItemFwd( p->pRun, diRun ); - if (!run) run = p->pRun; + run = run_next( cursor->run ); + if (!run) run = cursor->run; } else { - if (p->nOffset) ME_SplitRunSimple(editor, p); - run = p->pRun; + if (cursor->nOffset) run_split( editor, cursor ); + run = cursor->run; }
- tp = ME_SplitParagraph(editor, run, style, eol_str, eol_len, 0); - - end_run = ME_FindItemBack(tp, diRun); + new_para = para_split( editor, run, style, eol_str, eol_len, 0 ); + end_run = para_end_run( para_prev( new_para ) );
/* Move any cursors that were at the end of the previous run to the beginning of the new para */ - prev = ME_FindItemBack( end_run, diRun ); + prev = run_prev( end_run ); if (prev) { int i; for (i = 0; i < editor->nCursors; i++) { - if (editor->pCursors[i].pRun == prev && - editor->pCursors[i].nOffset == prev->member.run.len) + if (editor->pCursors[i].run == prev && + editor->pCursors[i].nOffset == prev->len) { - editor->pCursors[i].pPara = tp; - editor->pCursors[i].pRun = run; + editor->pCursors[i].para = new_para; + editor->pCursors[i].run = run; editor->pCursors[i].nOffset = 0; } } @@ -722,18 +680,18 @@ int ME_MoveCursorChars(ME_TextEditor *editor, ME_Cursor *cursor, int nRelOfs, BO cursor->nOffset += nRelOfs; if (cursor->nOffset < 0) { - cursor->nOffset += cursor->pRun->member.run.nCharOfs; + cursor->nOffset += cursor->run->nCharOfs; if (cursor->nOffset >= 0) { /* new offset in the same paragraph */ do { - cursor->pRun = ME_FindItemBack(cursor->pRun, diRun); - } while (cursor->nOffset < cursor->pRun->member.run.nCharOfs); - cursor->nOffset -= cursor->pRun->member.run.nCharOfs; + cursor->run = run_prev( cursor->run ); + } while (cursor->nOffset < cursor->run->nCharOfs); + cursor->nOffset -= cursor->run->nCharOfs; return nRelOfs; }
- cursor->nOffset += cursor->pPara->member.para.nCharOfs; + cursor->nOffset += cursor->para->nCharOfs; if (cursor->nOffset <= 0) { /* moved to the start of the text */ @@ -744,28 +702,29 @@ int ME_MoveCursorChars(ME_TextEditor *editor, ME_Cursor *cursor, int nRelOfs, BO
/* new offset in a previous paragraph */ do { - cursor->pPara = cursor->pPara->member.para.prev_para; - } while (cursor->nOffset < cursor->pPara->member.para.nCharOfs); - cursor->nOffset -= cursor->pPara->member.para.nCharOfs; - - cursor->pRun = ME_FindItemBack(cursor->pPara->member.para.next_para, diRun); - while (cursor->nOffset < cursor->pRun->member.run.nCharOfs) { - cursor->pRun = ME_FindItemBack(cursor->pRun, diRun); - } - cursor->nOffset -= cursor->pRun->member.run.nCharOfs; - } else if (cursor->nOffset >= cursor->pRun->member.run.len) { - ME_DisplayItem *next_para; + cursor->para = para_prev( cursor->para ); + } while (cursor->nOffset < cursor->para->nCharOfs); + cursor->nOffset -= cursor->para->nCharOfs; + + cursor->run = para_end_run( cursor->para ); + while (cursor->nOffset < cursor->run->nCharOfs) + cursor->run = run_prev( cursor->run ); + cursor->nOffset -= cursor->run->nCharOfs; + } + else if (cursor->nOffset >= cursor->run->len) + { + ME_Paragraph *next_para; int new_offset;
new_offset = ME_GetCursorOfs(cursor); - next_para = cursor->pPara->member.para.next_para; - if (new_offset < next_para->member.para.nCharOfs) + next_para = para_next( cursor->para ); + if (new_offset < next_para->nCharOfs) { /* new offset in the same paragraph */ do { - cursor->nOffset -= cursor->pRun->member.run.len; - cursor->pRun = ME_FindItemFwd(cursor->pRun, diRun); - } while (cursor->nOffset >= cursor->pRun->member.run.len); + cursor->nOffset -= cursor->run->len; + cursor->run = run_next( cursor->run ); + } while (cursor->nOffset >= cursor->run->len); return nRelOfs; }
@@ -779,16 +738,16 @@ int ME_MoveCursorChars(ME_TextEditor *editor, ME_Cursor *cursor, int nRelOfs, BO
/* new offset in a following paragraph */ do { - cursor->pPara = next_para; - next_para = next_para->member.para.next_para; - } while (new_offset >= next_para->member.para.nCharOfs); + cursor->para = next_para; + next_para = para_next( next_para ); + } while (new_offset >= next_para->nCharOfs);
- cursor->nOffset = new_offset - cursor->pPara->member.para.nCharOfs; - cursor->pRun = ME_FindItemFwd(cursor->pPara, diRun); - while (cursor->nOffset >= cursor->pRun->member.run.len) + cursor->nOffset = new_offset - cursor->para->nCharOfs; + cursor->run = para_first_run( cursor->para ); + while (cursor->nOffset >= cursor->run->len) { - cursor->nOffset -= cursor->pRun->member.run.len; - cursor->pRun = ME_FindItemFwd(cursor->pRun, diRun); + cursor->nOffset -= cursor->run->len; + cursor->run = run_next( cursor->run ); } } /* else new offset is in the same run */ return nRelOfs; @@ -798,8 +757,8 @@ int ME_MoveCursorChars(ME_TextEditor *editor, ME_Cursor *cursor, int nRelOfs, BO BOOL ME_MoveCursorWords(ME_TextEditor *editor, ME_Cursor *cursor, int nRelOfs) { - ME_DisplayItem *pRun = cursor->pRun, *pOtherRun; - ME_DisplayItem *pPara = cursor->pPara; + ME_Run *run = cursor->run, *other_run; + ME_Paragraph *para = cursor->para; int nOffset = cursor->nOffset;
if (nRelOfs == -1) @@ -807,40 +766,31 @@ ME_MoveCursorWords(ME_TextEditor *editor, ME_Cursor *cursor, int nRelOfs) /* Backward movement */ while (TRUE) { - nOffset = ME_CallWordBreakProc(editor, get_text( &pRun->member.run, 0 ), - pRun->member.run.len, nOffset, WB_MOVEWORDLEFT); - if (nOffset) - break; - pOtherRun = ME_FindItemBack(pRun, diRunOrParagraph); - if (pOtherRun->type == diRun) + nOffset = ME_CallWordBreakProc( editor, get_text( run, 0 ), run->len, nOffset, WB_MOVEWORDLEFT ); + if (nOffset) break; + other_run = run_prev( run ); + if (other_run) { - if (ME_CallWordBreakProc(editor, get_text( &pOtherRun->member.run, 0 ), - pOtherRun->member.run.len, - pOtherRun->member.run.len - 1, - WB_ISDELIMITER) - && !(pRun->member.run.nFlags & MERF_ENDPARA) - && !(cursor->pRun == pRun && cursor->nOffset == 0) - && !ME_CallWordBreakProc(editor, get_text( &pRun->member.run, 0 ), - pRun->member.run.len, 0, - WB_ISDELIMITER)) + if (ME_CallWordBreakProc( editor, get_text( other_run, 0 ), other_run->len, other_run->len - 1, WB_ISDELIMITER ) + && !(run->nFlags & MERF_ENDPARA) + && !(cursor->run == run && cursor->nOffset == 0) + && !ME_CallWordBreakProc( editor, get_text( run, 0 ), run->len, 0, WB_ISDELIMITER )) break; - pRun = pOtherRun; - nOffset = pOtherRun->member.run.len; + run = other_run; + nOffset = other_run->len; } - else if (pOtherRun->type == diParagraph) + else { - if (cursor->pRun == pRun && cursor->nOffset == 0) + if (cursor->run == run && cursor->nOffset == 0) { - pPara = pOtherRun; + para = run->para; /* Skip empty start of table row paragraph */ - if (pPara->member.para.prev_para->member.para.nFlags & MEPF_ROWSTART) - pPara = pPara->member.para.prev_para; + if (para_prev( para ) && para_prev( para )->nFlags & MEPF_ROWSTART) + para = para_prev( para ); /* Paragraph breaks are treated as separate words */ - if (pPara->member.para.prev_para->type == diTextStart) - return FALSE; - - pRun = ME_FindItemBack(pPara, diRun); - pPara = pPara->member.para.prev_para; + if (!para_prev( para )) return FALSE; + para = para_prev( para ); + run = para_end_run( para ); } break; } @@ -853,43 +803,35 @@ ME_MoveCursorWords(ME_TextEditor *editor, ME_Cursor *cursor, int nRelOfs)
while (TRUE) { - if (last_delim && !ME_CallWordBreakProc(editor, get_text( &pRun->member.run, 0 ), - pRun->member.run.len, nOffset, WB_ISDELIMITER)) - break; - nOffset = ME_CallWordBreakProc(editor, get_text( &pRun->member.run, 0 ), - pRun->member.run.len, nOffset, WB_MOVEWORDRIGHT); - if (nOffset < pRun->member.run.len) + if (last_delim && !ME_CallWordBreakProc( editor, get_text( run, 0 ), run->len, nOffset, WB_ISDELIMITER )) break; - pOtherRun = ME_FindItemFwd(pRun, diRunOrParagraphOrEnd); - if (pOtherRun->type == diRun) + nOffset = ME_CallWordBreakProc( editor, get_text( run, 0 ), run->len, nOffset, WB_MOVEWORDRIGHT ); + if (nOffset < run->len) break; + other_run = run_next( run ); + if (other_run) { - last_delim = ME_CallWordBreakProc(editor, get_text( &pRun->member.run, 0 ), - pRun->member.run.len, nOffset - 1, WB_ISDELIMITER); - pRun = pOtherRun; + last_delim = ME_CallWordBreakProc( editor, get_text( run, 0 ), run->len, nOffset - 1, WB_ISDELIMITER ); + run = other_run; nOffset = 0; } - else if (pOtherRun->type == diParagraph) + else { - if (pOtherRun->member.para.nFlags & MEPF_ROWSTART) - pOtherRun = pOtherRun->member.para.next_para; - if (cursor->pRun == pRun) { - pPara = pOtherRun; - pRun = ME_FindItemFwd(pPara, diRun); + para = para_next( para ); + if (!para_next( para )) + { + if (cursor->run == run) return FALSE; + nOffset = 0; + break; } - nOffset = 0; - break; - } - else /* diTextEnd */ - { - if (cursor->pRun == pRun) - return FALSE; + if (para->nFlags & MEPF_ROWSTART) para = para_next( para ); + if (cursor->run == run) run = para_first_run( para ); nOffset = 0; break; } } } - cursor->pPara = pPara; - cursor->pRun = pRun; + cursor->para = para; + cursor->run = run; cursor->nOffset = nOffset; return TRUE; } @@ -914,38 +856,28 @@ ME_SelectByType(ME_TextEditor *editor, ME_SelectionType selectionType) editor->pCursors[1] = editor->pCursors[0]; ME_MoveCursorWords(editor, &editor->pCursors[1], -1); break; - case stLine: case stParagraph: - { - ME_DisplayItem *pItem; - ME_DIType fwdSearchType, backSearchType; - if (selectionType == stParagraph) { - backSearchType = diParagraph; - fwdSearchType = diParagraphOrEnd; - } else { - backSearchType = diStartRow; - fwdSearchType = diStartRowOrParagraphOrEnd; - } - pItem = ME_FindItemFwd(editor->pCursors[0].pRun, fwdSearchType); - assert(pItem); - if (pItem->type == diTextEnd) - editor->pCursors[0].pRun = ME_FindItemBack(pItem, diRun); - else - editor->pCursors[0].pRun = ME_FindItemFwd(pItem, diRun); - editor->pCursors[0].pPara = ME_GetParagraph(editor->pCursors[0].pRun); - editor->pCursors[0].nOffset = 0; + editor->pCursors[1] = editor->pCursors[0]; + + editor->pCursors[0].run = para_end_run( editor->pCursors[0].para ); + editor->pCursors[0].para = editor->pCursors[0].run->para; + editor->pCursors[0].nOffset = editor->pCursors[0].run->len;
- pItem = ME_FindItemBack(pItem, backSearchType); - editor->pCursors[1].pRun = ME_FindItemFwd(pItem, diRun); - editor->pCursors[1].pPara = ME_GetParagraph(editor->pCursors[1].pRun); + editor->pCursors[1].run = para_first_run( editor->pCursors[1].para ); editor->pCursors[1].nOffset = 0; break; + case stLine: + { + ME_Row *row = row_from_cursor( editor->pCursors ); + + row_first_cursor( row, editor->pCursors + 1 ); + row_end_cursor( row, editor->pCursors, TRUE ); + break; } case stDocument: /* Select everything with cursor anchored from the start of the text */ - editor->nSelectionType = stDocument; ME_SetCursorToStart(editor, &editor->pCursors[1]); - ME_SetCursorToEnd(editor, &editor->pCursors[0], FALSE); + ME_SetCursorToEnd(editor, &editor->pCursors[0], TRUE); break; default: assert(0); } @@ -956,90 +888,81 @@ ME_SelectByType(ME_TextEditor *editor, ME_SelectionType selectionType)
int ME_GetCursorOfs(const ME_Cursor *cursor) { - return cursor->pPara->member.para.nCharOfs - + cursor->pRun->member.run.nCharOfs + cursor->nOffset; + return cursor->para->nCharOfs + cursor->run->nCharOfs + cursor->nOffset; }
-/* Helper function for ME_FindPixelPos to find paragraph within tables */ -static ME_DisplayItem* ME_FindPixelPosInTableRow(int x, int y, - ME_DisplayItem *para) +/* Helper function for cursor_from_virtual_coords() to find paragraph within tables */ +static ME_Paragraph *pixel_pos_in_table_row( int x, int y, ME_Paragraph *para ) { - ME_DisplayItem *cell, *next_cell; - assert(para->member.para.nFlags & MEPF_ROWSTART); - cell = para->member.para.next_para->member.para.pCell; - assert(cell); + ME_Cell *cell, *next_cell; + + assert( para->nFlags & MEPF_ROWSTART ); + cell = table_row_first_cell( para ); + assert( cell );
/* find the cell we are in */ - while ((next_cell = cell->member.cell.next_cell) != NULL) { - if (x < next_cell->member.cell.pt.x) + while ((next_cell = cell_next( cell )) != NULL) + { + if (x < next_cell->pt.x) { - para = ME_FindItemFwd(cell, diParagraph); + para = cell_first_para( cell ); /* Found the cell, but there might be multiple paragraphs in * the cell, so need to search down the cell for the paragraph. */ - while (cell == para->member.para.pCell) { - if (y < para->member.para.pt.y + para->member.para.nHeight) + while (cell == para_cell( para )) + { + if (y < para->pt.y + para->nHeight) { - if (para->member.para.nFlags & MEPF_ROWSTART) - return ME_FindPixelPosInTableRow(x, y, para); - else - return para; + if (para->nFlags & MEPF_ROWSTART) return pixel_pos_in_table_row( x, y, para ); + else return para; } - para = para->member.para.next_para; + para = para_next( para ); } /* Past the end of the cell, so go back to the last cell paragraph */ - return para->member.para.prev_para; + return para_prev( para ); } cell = next_cell; } /* Return table row delimiter */ - para = ME_FindItemFwd(cell, diParagraph); - assert(para->member.para.nFlags & MEPF_ROWEND); - assert(para->member.para.fmt.dwMask & PFM_TABLEROWDELIMITER); - assert(para->member.para.fmt.wEffects & PFE_TABLEROWDELIMITER); + para = table_row_end( para ); + assert( para->nFlags & MEPF_ROWEND ); + assert( para->fmt.dwMask & PFM_TABLEROWDELIMITER ); + assert( para->fmt.wEffects & PFE_TABLEROWDELIMITER ); return para; }
-static BOOL ME_FindRunInRow(ME_TextEditor *editor, ME_DisplayItem *pRow, - int x, ME_Cursor *cursor, BOOL *pbCaretAtEnd) +static BOOL row_cursor( ME_TextEditor *editor, ME_Row *row, int x, + ME_Cursor *cursor ) { - ME_DisplayItem *pNext, *pLastRun; - ME_Row *row = &pRow->member.row; - BOOL exact = TRUE; + ME_Run *run, *last; + BOOL exact = TRUE;
- if (x < row->pt.x) - { - x = row->pt.x; - exact = FALSE; - } - pNext = ME_FindItemFwd(pRow, diRunOrStartRow); - assert(pNext->type == diRun); - if (pbCaretAtEnd) *pbCaretAtEnd = FALSE; - cursor->nOffset = 0; - do { - int run_x = pNext->member.run.pt.x; - int width = pNext->member.run.nWidth; - - if (x >= run_x && x < run_x+width) + if (x < row->pt.x) { - cursor->nOffset = ME_CharFromPoint(editor, x-run_x, &pNext->member.run, TRUE, TRUE); - cursor->pRun = pNext; - cursor->pPara = ME_GetParagraph( cursor->pRun ); - return exact; + x = row->pt.x; + exact = FALSE; } - pLastRun = pNext; - pNext = ME_FindItemFwd(pNext, diRunOrStartRow); - } while(pNext && pNext->type == diRun);
- if ((pLastRun->member.run.nFlags & MERF_ENDPARA) == 0) - { - cursor->pRun = ME_FindItemFwd(pNext, diRun); - if (pbCaretAtEnd) *pbCaretAtEnd = TRUE; - } - else - cursor->pRun = pLastRun; + run = row_first_run( row ); + assert( run ); + cursor->nOffset = 0; + do + { + if (x >= run->pt.x && x < run->pt.x + run->nWidth) + { + cursor->nOffset = ME_CharFromPoint( editor, x - run->pt.x, run, TRUE, TRUE ); + cursor->run = run; + cursor->para = run->para; + return exact; + } + last = run; + run = row_next_run( row, run ); + } while (run);
- cursor->pPara = ME_GetParagraph( cursor->pRun ); - return FALSE; + run = last; + + cursor->run = run; + cursor->para = run->para; + return FALSE; }
/* Finds the run and offset from the pixel position. @@ -1052,57 +975,51 @@ static BOOL ME_FindRunInRow(ME_TextEditor *editor, ME_DisplayItem *pRow, * returns TRUE if the result was exactly under the cursor, otherwise returns * FALSE, and result is set to the closest position to the coordinates. */ -static BOOL ME_FindPixelPos(ME_TextEditor *editor, int x, int y, - ME_Cursor *result, BOOL *is_eol, BOOL final_eop) +static BOOL cursor_from_virtual_coords( ME_TextEditor *editor, int x, int y, + ME_Cursor *result, BOOL final_eop ) { - ME_DisplayItem *p = editor->pBuffer->pFirst->member.para.next_para; + ME_Paragraph *para = editor_first_para( editor ); + ME_Row *row = NULL, *next_row; BOOL isExact = TRUE;
x -= editor->rcFormat.left; y -= editor->rcFormat.top;
- if (is_eol) - *is_eol = FALSE; - /* find paragraph */ - for (; p != editor->pBuffer->pLast; p = p->member.para.next_para) + for (; para_next( para ); para = para_next( para )) { - assert(p->type == diParagraph); - if (y < p->member.para.pt.y + p->member.para.nHeight) + if (y < para->pt.y + para->nHeight) { - if (p->member.para.nFlags & MEPF_ROWSTART) - p = ME_FindPixelPosInTableRow(x, y, p); - y -= p->member.para.pt.y; - p = ME_FindItemFwd(p, diStartRow); + if (para->nFlags & MEPF_ROWSTART) + para = pixel_pos_in_table_row( x, y, para ); + y -= para->pt.y; + row = para_first_row( para ); break; - } else if (p->member.para.nFlags & MEPF_ROWSTART) { - p = ME_GetTableRowEnd(p); + } + else if (para->nFlags & MEPF_ROWSTART) + { + para = table_row_end( para ); } } /* find row */ - for (; p != editor->pBuffer->pLast; ) + while (row) { - ME_DisplayItem *pp; - assert(p->type == diStartRow); - if (y < p->member.row.pt.y + p->member.row.nHeight) break; - pp = ME_FindItemFwd(p, diStartRow); - if (!pp) break; - p = pp; + if (y < row->pt.y + row->nHeight) break; + next_row = row_next( row ); + if (!next_row) break; + row = next_row; } - if (p == editor->pBuffer->pLast && !final_eop) + + if (!row && !final_eop && para_prev( para )) { /* The position is below the last paragraph, so the last row will be used * rather than the end of the text, so the x position will be used to * determine the offset closest to the pixel position. */ isExact = FALSE; - p = ME_FindItemBack(p, diStartRow); - if (!p) p = editor->pBuffer->pLast; + row = para_end_row( para_prev( para ) ); }
- assert( p->type == diStartRow || p == editor->pBuffer->pLast ); - - if( p->type == diStartRow ) - return ME_FindRunInRow( editor, p, x, result, is_eol ) && isExact; + if (row) return row_cursor( editor, row, x, result ) && isExact;
ME_SetCursorToEnd(editor, result, TRUE); return FALSE; @@ -1132,7 +1049,7 @@ BOOL ME_CharFromPos(ME_TextEditor *editor, int x, int y, } x += editor->horz_si.nPos; y += editor->vert_si.nPos; - bResult = ME_FindPixelPos(editor, x, y, cursor, NULL, FALSE); + bResult = cursor_from_virtual_coords( editor, x, y, cursor, FALSE ); if (isExact) *isExact = bResult; return TRUE; } @@ -1166,37 +1083,53 @@ static void ME_ExtendAnchorSelection(ME_TextEditor *editor) { /* Extend the left side of selection */ editor->pCursors[1] = tmp_cursor; - if (editor->nSelectionType == stWord) + switch (editor->nSelectionType) + { + case stWord: ME_MoveCursorWords(editor, &editor->pCursors[1], -1); - else + break; + + case stLine: { - ME_DisplayItem *pItem; - ME_DIType searchType = ((editor->nSelectionType == stLine) ? - diStartRowOrParagraph:diParagraph); - pItem = ME_FindItemBack(editor->pCursors[1].pRun, searchType); - editor->pCursors[1].pRun = ME_FindItemFwd(pItem, diRun); - editor->pCursors[1].pPara = ME_GetParagraph(editor->pCursors[1].pRun); + ME_Row *row = row_from_cursor( editor->pCursors + 1 ); + row_first_cursor( row, editor->pCursors + 1 ); + break; + } + + case stParagraph: + editor->pCursors[1].run = para_first_run( editor->pCursors[1].para ); editor->pCursors[1].nOffset = 0; + break; + + default: + break; } } else if (curOfs >= anchorEndOfs) { /* Extend the right side of selection */ editor->pCursors[0] = tmp_cursor; - if (editor->nSelectionType == stWord) - ME_MoveCursorWords(editor, &editor->pCursors[0], +1); - else + switch (editor->nSelectionType) { - ME_DisplayItem *pItem; - ME_DIType searchType = ((editor->nSelectionType == stLine) ? - diStartRowOrParagraphOrEnd:diParagraphOrEnd); - pItem = ME_FindItemFwd(editor->pCursors[0].pRun, searchType); - if (pItem->type == diTextEnd) - editor->pCursors[0].pRun = ME_FindItemBack(pItem, diRun); - else - editor->pCursors[0].pRun = ME_FindItemFwd(pItem, diRun); - editor->pCursors[0].pPara = ME_GetParagraph(editor->pCursors[0].pRun); - editor->pCursors[0].nOffset = 0; + case stWord: + ME_MoveCursorWords( editor, &editor->pCursors[0], +1 ); + break; + + case stLine: + { + ME_Row *row = row_from_cursor( editor->pCursors ); + row_end_cursor( row, editor->pCursors, TRUE ); + break; + } + + case stParagraph: + editor->pCursors[0].run = para_end_run( editor->pCursors[0].para ); + editor->pCursors[0].para = editor->pCursors[0].run->para; + editor->pCursors[0].nOffset = editor->pCursors[0].run->len; + break; + + default: + break; } } } @@ -1215,7 +1148,7 @@ void ME_LButtonDown(ME_TextEditor *editor, int x, int y, int clickNum) is_selection = ME_IsSelection(editor); is_shift = GetKeyState(VK_SHIFT) < 0;
- ME_FindPixelPos(editor, x, y, &editor->pCursors[0], &editor->bCaretAtEnd, FALSE); + cursor_from_virtual_coords( editor, x, y, &editor->pCursors[0], FALSE );
if (x >= editor->rcFormat.left || is_shift) { @@ -1273,8 +1206,8 @@ void ME_MouseMove(ME_TextEditor *editor, int x, int y) y += editor->vert_si.nPos;
tmp_cursor = editor->pCursors[0]; - /* FIXME: do something with the return value of ME_FindPixelPos */ - ME_FindPixelPos(editor, x, y, &tmp_cursor, &editor->bCaretAtEnd, TRUE); + /* FIXME: do something with the return value of cursor_from_virtual_coords */ + cursor_from_virtual_coords( editor, x, y, &tmp_cursor, TRUE );
ME_InvalidateSelection(editor); editor->pCursors[0] = tmp_cursor; @@ -1282,13 +1215,11 @@ void ME_MouseMove(ME_TextEditor *editor, int x, int y)
if (editor->nSelectionType != stPosition && memcmp(&editor->pCursors[1], &editor->pCursors[3], sizeof(ME_Cursor))) - { /* The scroll the cursor towards the other end, since it was the one * extended by ME_ExtendAnchorSelection */ - ME_EnsureVisible(editor, &editor->pCursors[1]); - } else { - ME_EnsureVisible(editor, &editor->pCursors[0]); - } + editor_ensure_visible( editor, &editor->pCursors[1] ); + else + editor_ensure_visible( editor, &editor->pCursors[0] );
ME_InvalidateSelection(editor); update_caret(editor); @@ -1297,287 +1228,178 @@ void ME_MouseMove(ME_TextEditor *editor, int x, int y)
static int ME_GetXForArrow(ME_TextEditor *editor, ME_Cursor *pCursor) { - ME_DisplayItem *pRun = pCursor->pRun; + ME_Run *run = pCursor->run; int x;
if (editor->nUDArrowX != -1) x = editor->nUDArrowX; - else { - if (editor->bCaretAtEnd) - { - pRun = ME_FindItemBack(pRun, diRun); - assert(pRun); - x = pRun->member.run.pt.x + pRun->member.run.nWidth; - } - else { - x = pRun->member.run.pt.x; - x += ME_PointFromChar(editor, &pRun->member.run, pCursor->nOffset, TRUE); - } + else + { + x = run->pt.x; + x += ME_PointFromChar( editor, run, pCursor->nOffset, TRUE ); editor->nUDArrowX = x; } return x; }
-static void -ME_MoveCursorLines(ME_TextEditor *editor, ME_Cursor *pCursor, int nRelOfs, BOOL extend) +static void cursor_move_line( ME_TextEditor *editor, ME_Cursor *cursor, BOOL up, BOOL extend ) { - ME_DisplayItem *pRun = pCursor->pRun; - ME_DisplayItem *pOldPara = pCursor->pPara; - ME_DisplayItem *pItem, *pNewPara; - int x = ME_GetXForArrow(editor, pCursor); - - if (editor->bCaretAtEnd && !pCursor->nOffset) - if (!ME_PrevRun(&pOldPara, &pRun, TRUE)) - return; + ME_Paragraph *old_para = cursor->para, *new_para; + ME_Row *row = row_from_cursor( cursor ); + int x = ME_GetXForArrow( editor, cursor );
- if (nRelOfs == -1) - { - /* start of this row */ - pItem = ME_FindItemBack(pRun, diStartRow); - assert(pItem); - /* start of the previous row */ - pItem = ME_FindItemBack(pItem, diStartRow); - if (!pItem) /* row not found */ - { - if (extend) - ME_SetCursorToStart(editor, pCursor); - return; - } - pNewPara = ME_GetParagraph(pItem); - if (pOldPara->member.para.nFlags & MEPF_ROWEND || - (pOldPara->member.para.pCell && - pOldPara->member.para.pCell != pNewPara->member.para.pCell)) - { - /* Brought out of a cell */ - pNewPara = ME_GetTableRowStart(pOldPara)->member.para.prev_para; - if (pNewPara->type == diTextStart) - return; /* At the top, so don't go anywhere. */ - pItem = ME_FindItemFwd(pNewPara, diStartRow); - } - if (pNewPara->member.para.nFlags & MEPF_ROWEND) + if (up) { - /* Brought into a table row */ - ME_Cell *cell = &ME_FindItemBack(pNewPara, diCell)->member.cell; - while (x < cell->pt.x && cell->prev_cell) - cell = &cell->prev_cell->member.cell; - if (cell->next_cell) /* else - we are still at the end of the row */ - pItem = ME_FindItemBack(cell->next_cell, diStartRow); - } - } - else - { - /* start of the next row */ - pItem = ME_FindItemFwd(pRun, diStartRow); - if (!pItem) /* row not found */ - { - if (extend) - ME_SetCursorToEnd(editor, pCursor, TRUE); - return; - } - pNewPara = ME_GetParagraph(pItem); - if (pOldPara->member.para.nFlags & MEPF_ROWSTART || - (pOldPara->member.para.pCell && - pOldPara->member.para.pCell != pNewPara->member.para.pCell)) - { - /* Brought out of a cell */ - pNewPara = ME_GetTableRowEnd(pOldPara)->member.para.next_para; - if (pNewPara->type == diTextEnd) - return; /* At the bottom, so don't go anywhere. */ - pItem = ME_FindItemFwd(pNewPara, diStartRow); + /* start of the previous row */ + row = row_prev_all_paras( row ); + if (!row) + { + if (extend) ME_SetCursorToStart( editor, cursor ); + return; + } + new_para = row_para( row ); + if (old_para->nFlags & MEPF_ROWEND || + (para_cell( old_para ) && para_cell( old_para ) != para_cell( new_para ))) + { + /* Brought out of a cell */ + new_para = para_prev( table_row_start( old_para )); + if (!new_para) return; /* At the top, so don't go anywhere. */ + row = para_first_row( new_para ); + } + if (new_para->nFlags & MEPF_ROWEND) + { + /* Brought into a table row */ + ME_Cell *cell = table_row_end_cell( new_para ); + while (x < cell->pt.x && cell_prev( cell )) + cell = cell_prev( cell ); + if (cell_next( cell )) /* else - we are still at the end of the row */ + row = para_end_row( cell_end_para( cell ) ); + } } - if (pNewPara->member.para.nFlags & MEPF_ROWSTART) + else { - /* Brought into a table row */ - ME_DisplayItem *cell = ME_FindItemFwd(pNewPara, diCell); - while (cell->member.cell.next_cell && - x >= cell->member.cell.next_cell->member.cell.pt.x) - cell = cell->member.cell.next_cell; - pItem = ME_FindItemFwd(cell, diStartRow); + /* start of the next row */ + row = row_next_all_paras( row ); + if (!row) + { + if (extend) ME_SetCursorToEnd( editor, cursor, TRUE ); + return; + } + new_para = row_para( row ); + if (old_para->nFlags & MEPF_ROWSTART || + (para_cell( old_para ) && para_cell( old_para ) != para_cell( new_para ))) + { + /* Brought out of a cell */ + new_para = para_next( table_row_end( old_para ) ); + if (!para_next( new_para )) return; /* At the bottom, so don't go anywhere. */ + row = para_first_row( new_para ); + } + if (new_para->nFlags & MEPF_ROWSTART) + { + /* Brought into a table row */ + ME_Cell *cell = table_row_first_cell( new_para ); + while (cell_next( cell ) && x >= cell_next( cell )->pt.x) + cell = cell_next( cell ); + row = para_first_row( cell_first_para( cell ) ); + } } - } - if (!pItem) - { - /* row not found - ignore */ - return; - } - ME_FindRunInRow(editor, pItem, x, pCursor, &editor->bCaretAtEnd); - assert(pCursor->pRun); - assert(pCursor->pRun->type == diRun); + if (!row) return; + + row_cursor( editor, row, x, cursor ); }
-static void ME_ArrowPageUp(ME_TextEditor *editor, ME_Cursor *pCursor) +static void ME_ArrowPageUp( ME_TextEditor *editor, ME_Cursor *cursor ) { - ME_DisplayItem *p = ME_FindItemFwd(editor->pBuffer->pFirst, diStartRow); + ME_Row *row = para_first_row( editor_first_para( editor ) ), *last_row; + int x, yd, old_scroll_pos = editor->vert_si.nPos;
- if (editor->vert_si.nPos < p->member.row.nHeight) - { - ME_SetCursorToStart(editor, pCursor); - editor->bCaretAtEnd = FALSE; - /* Native clears seems to clear this x value on page up at the top - * of the text, but not on page down at the end of the text. - * Doesn't make sense, but we try to be bug for bug compatible. */ - editor->nUDArrowX = -1; - } else { - ME_DisplayItem *pRun = pCursor->pRun; - ME_DisplayItem *pLast; - int x, y, yd, yp; - int yOldScrollPos = editor->vert_si.nPos; - - x = ME_GetXForArrow(editor, pCursor); - if (!pCursor->nOffset && editor->bCaretAtEnd) - pRun = ME_FindItemBack(pRun, diRun); - - p = ME_FindItemBack(pRun, diStartRowOrParagraph); - assert(p->type == diStartRow); - yp = ME_FindItemBack(p, diParagraph)->member.para.pt.y; - y = yp + p->member.row.pt.y; + if (editor->vert_si.nPos < row->nHeight) + { + ME_SetCursorToStart( editor, cursor ); + /* Native clears seems to clear this x value on page up at the top + * of the text, but not on page down at the end of the text. + * Doesn't make sense, but we try to be bug for bug compatible. */ + editor->nUDArrowX = -1; + } + else + { + x = ME_GetXForArrow( editor, cursor ); + row = row_from_cursor( cursor );
- ME_ScrollUp(editor, editor->sizeWindow.cy); - /* Only move the cursor by the amount scrolled. */ - yd = y + editor->vert_si.nPos - yOldScrollPos; - pLast = p; + ME_ScrollUp( editor, editor->sizeWindow.cy ); + /* Only move the cursor by the amount scrolled. */ + yd = cursor->para->pt.y + row->pt.y + editor->vert_si.nPos - old_scroll_pos; + last_row = row;
- do { - p = ME_FindItemBack(p, diStartRowOrParagraph); - if (!p) - break; - if (p->type == diParagraph) { /* crossing paragraphs */ - if (p->member.para.prev_para == NULL) - break; - yp = p->member.para.prev_para->member.para.pt.y; - continue; - } - y = yp + p->member.row.pt.y; - if (y < yd) - break; - pLast = p; - } while(1); + while ((row = row_prev_all_paras( row ))) + { + if (row_para( row )->pt.y + row->pt.y < yd) break; + last_row = row; + }
- ME_FindRunInRow(editor, pLast, x, pCursor, &editor->bCaretAtEnd); - } - assert(pCursor->pRun); - assert(pCursor->pRun->type == diRun); + row_cursor( editor, last_row, x, cursor ); + } }
-static void ME_ArrowPageDown(ME_TextEditor *editor, ME_Cursor *pCursor) +static void ME_ArrowPageDown( ME_TextEditor *editor, ME_Cursor *cursor ) { - ME_DisplayItem *pLast; - int x, y; + ME_Row *row = para_end_row( para_prev( editor_end_para( editor ) ) ), *last_row; + int x, yd, old_scroll_pos = editor->vert_si.nPos;
- /* Find y position of the last row */ - pLast = editor->pBuffer->pLast; - y = pLast->member.para.prev_para->member.para.pt.y - + ME_FindItemBack(pLast, diStartRow)->member.row.pt.y; + x = ME_GetXForArrow( editor, cursor );
- x = ME_GetXForArrow(editor, pCursor); + if (editor->vert_si.nPos >= row_para( row )->pt.y + row->pt.y - editor->sizeWindow.cy) + ME_SetCursorToEnd( editor, cursor, FALSE ); + else + { + row = row_from_cursor( cursor );
- if (editor->vert_si.nPos >= y - editor->sizeWindow.cy) - { - ME_SetCursorToEnd(editor, pCursor, FALSE); - editor->bCaretAtEnd = FALSE; - } else { - ME_DisplayItem *pRun = pCursor->pRun; - ME_DisplayItem *p; - int yd, yp; - int yOldScrollPos = editor->vert_si.nPos; - - if (!pCursor->nOffset && editor->bCaretAtEnd) - pRun = ME_FindItemBack(pRun, diRun); - - p = ME_FindItemBack(pRun, diStartRowOrParagraph); - assert(p->type == diStartRow); - yp = ME_FindItemBack(p, diParagraph)->member.para.pt.y; - y = yp + p->member.row.pt.y; - - /* For native richedit controls: - * v1.0 - v3.1 can only scroll down as far as the scrollbar lets us - * v4.1 can scroll past this position here. */ - ME_ScrollDown(editor, editor->sizeWindow.cy); - /* Only move the cursor by the amount scrolled. */ - yd = y + editor->vert_si.nPos - yOldScrollPos; - pLast = p; + /* For native richedit controls: + * v1.0 - v3.1 can only scroll down as far as the scrollbar lets us + * v4.1 can scroll past this position here. */ + ME_ScrollDown( editor, editor->sizeWindow.cy ); + /* Only move the cursor by the amount scrolled. */ + yd = cursor->para->pt.y + row->pt.y + editor->vert_si.nPos - old_scroll_pos; + last_row = row;
- do { - p = ME_FindItemFwd(p, diStartRowOrParagraph); - if (!p) - break; - if (p->type == diParagraph) { - yp = p->member.para.pt.y; - continue; - } - y = yp + p->member.row.pt.y; - if (y >= yd) - break; - pLast = p; - } while(1); + while ((row = row_next_all_paras( row ))) + { + if (row_para( row )->pt.y + row->pt.y >= yd) break; + last_row = row; + }
- ME_FindRunInRow(editor, pLast, x, pCursor, &editor->bCaretAtEnd); - } - assert(pCursor->pRun); - assert(pCursor->pRun->type == diRun); + row_cursor( editor, last_row, x, cursor ); + } }
-static void ME_ArrowHome(ME_TextEditor *editor, ME_Cursor *pCursor) +static void ME_ArrowHome( ME_TextEditor *editor, ME_Cursor *cursor ) { - ME_DisplayItem *pRow = ME_FindItemBack(pCursor->pRun, diStartRow); - if (pRow) { - ME_DisplayItem *pRun; - if (editor->bCaretAtEnd && !pCursor->nOffset) { - pRow = ME_FindItemBack(pRow, diStartRow); - if (!pRow) - return; - } - pRun = ME_FindItemFwd(pRow, diRun); - if (pRun) { - pCursor->pRun = pRun; - assert(pCursor->pPara == ME_GetParagraph(pRun)); - pCursor->nOffset = 0; - } - } - editor->bCaretAtEnd = FALSE; + ME_Row *row = row_from_cursor( cursor ); + + row_first_cursor( row, cursor ); }
static void ME_ArrowCtrlHome(ME_TextEditor *editor, ME_Cursor *pCursor) { ME_SetCursorToStart(editor, pCursor); - editor->bCaretAtEnd = FALSE; }
-static void ME_ArrowEnd(ME_TextEditor *editor, ME_Cursor *pCursor) +static void ME_ArrowEnd( ME_TextEditor *editor, ME_Cursor *cursor ) { - ME_DisplayItem *pRow; - - if (editor->bCaretAtEnd && !pCursor->nOffset) - return; - - pRow = ME_FindItemFwd(pCursor->pRun, diStartRowOrParagraphOrEnd); - assert(pRow); - if (pRow->type == diStartRow) { - ME_DisplayItem *pRun = ME_FindItemFwd(pRow, diRun); - assert(pRun); - pCursor->pRun = pRun; - assert(pCursor->pPara == ME_GetParagraph(pCursor->pRun)); - pCursor->nOffset = 0; - editor->bCaretAtEnd = TRUE; - return; - } - pCursor->pRun = ME_FindItemBack(pRow, diRun); - assert(pCursor->pRun && pCursor->pRun->member.run.nFlags & MERF_ENDPARA); - assert(pCursor->pPara == ME_GetParagraph(pCursor->pRun)); - pCursor->nOffset = 0; - editor->bCaretAtEnd = FALSE; + ME_Row *row = row_from_cursor( cursor ); + + row_end_cursor( row, cursor, FALSE ); }
static void ME_ArrowCtrlEnd(ME_TextEditor *editor, ME_Cursor *pCursor) { ME_SetCursorToEnd(editor, pCursor, FALSE); - editor->bCaretAtEnd = FALSE; }
BOOL ME_IsSelection(ME_TextEditor *editor) { - return editor->pCursors[0].pRun != editor->pCursors[1].pRun || + return editor->pCursors[0].run != editor->pCursors[1].run || editor->pCursors[0].nOffset != editor->pCursors[1].nOffset; }
@@ -1592,7 +1414,7 @@ void ME_DeleteSelection(ME_TextEditor *editor)
ME_Style *ME_GetSelectionInsertStyle(ME_TextEditor *editor) { - return ME_GetInsertStyle(editor, 0); + return style_get_insert_style( editor, editor->pCursors ); }
void ME_SendSelChange(ME_TextEditor *editor) @@ -1637,24 +1459,22 @@ ME_ArrowKey(ME_TextEditor *editor, int nVKey, BOOL extend, BOOL ctrl) ME_CheckCharOffsets(editor); switch(nVKey) { case VK_LEFT: - editor->bCaretAtEnd = FALSE; if (ctrl) success = ME_MoveCursorWords(editor, &tmp_curs, -1); else success = ME_MoveCursorChars(editor, &tmp_curs, -1, extend); break; case VK_RIGHT: - editor->bCaretAtEnd = FALSE; if (ctrl) success = ME_MoveCursorWords(editor, &tmp_curs, +1); else success = ME_MoveCursorChars(editor, &tmp_curs, +1, extend); break; case VK_UP: - ME_MoveCursorLines(editor, &tmp_curs, -1, extend); + cursor_move_line( editor, &tmp_curs, TRUE, extend ); break; case VK_DOWN: - ME_MoveCursorLines(editor, &tmp_curs, +1, extend); + cursor_move_line( editor, &tmp_curs, FALSE, extend ); break; case VK_PRIOR: ME_ArrowPageUp(editor, &tmp_curs); @@ -1667,7 +1487,6 @@ ME_ArrowKey(ME_TextEditor *editor, int nVKey, BOOL extend, BOOL ctrl) ME_ArrowCtrlHome(editor, &tmp_curs); else ME_ArrowHome(editor, &tmp_curs); - editor->bCaretAtEnd = FALSE; break; } case VK_END: @@ -1685,7 +1504,7 @@ ME_ArrowKey(ME_TextEditor *editor, int nVKey, BOOL extend, BOOL ctrl) ME_InvalidateSelection(editor); ME_Repaint(editor); hide_caret(editor); - ME_EnsureVisible(editor, &tmp_curs); + editor_ensure_visible( editor, &tmp_curs ); update_caret(editor); ME_SendSelChange(editor); return success; diff --git a/dll/win32/riched20/clipboard.c b/dll/win32/riched20/clipboard.c index 578fb02fd99..10a814214be 100644 --- a/dll/win32/riched20/clipboard.c +++ b/dll/win32/riched20/clipboard.c @@ -344,13 +344,12 @@ static HGLOBAL get_unicode_text(ME_TextEditor *editor, const ME_Cursor *start, i int pars = 0; WCHAR *data; HANDLE ret; - ME_DisplayItem *para; + ME_Paragraph *para; int nEnd = ME_GetCursorOfs(start) + nChars;
/* count paragraphs in range */ - para = start->pPara; - while((para = para->member.para.next_para) && - para->member.para.nCharOfs <= nEnd) + para = start->para; + while ((para = para_next( para )) && para->nCharOfs <= nEnd) pars++;
ret = GlobalAlloc(GMEM_MOVEABLE, sizeof(WCHAR) * (nChars + pars + 1)); diff --git a/dll/win32/riched20/editor.c b/dll/win32/riched20/editor.c index cbc959851ec..a7794ab7901 100644 --- a/dll/win32/riched20/editor.c +++ b/dll/win32/riched20/editor.c @@ -250,24 +250,12 @@
WINE_DEFAULT_DEBUG_CHANNEL(richedit);
-static BOOL ME_RegisterEditorClass(HINSTANCE); static BOOL ME_UpdateLinkAttribute(ME_TextEditor *editor, ME_Cursor *start, int nChars);
-static const WCHAR REListBox20W[] = {'R','E','L','i','s','t','B','o','x','2','0','W', 0}; -static const WCHAR REComboBox20W[] = {'R','E','C','o','m','b','o','B','o','x','2','0','W', 0}; -static HCURSOR hLeft; - +HINSTANCE dll_instance = NULL; BOOL me_debug = FALSE; HANDLE me_heap = NULL;
-static BOOL ME_ListBoxRegistered = FALSE; -static BOOL ME_ComboBoxRegistered = FALSE; - -static inline BOOL is_version_nt(void) -{ - return !(GetVersion() & 0x80000000); -} - static ME_TextBuffer *ME_MakeText(void) { ME_TextBuffer *buf = heap_alloc(sizeof(*buf)); ME_DisplayItem *p1 = ME_MakeDI(diTextStart); @@ -288,6 +276,21 @@ static ME_TextBuffer *ME_MakeText(void) { return buf; }
+ME_Paragraph *editor_first_para( ME_TextEditor *editor ) +{ + return para_next( &editor->pBuffer->pFirst->member.para ); +} + +/* Note, returns the diTextEnd sentinel paragraph */ +ME_Paragraph *editor_end_para( ME_TextEditor *editor ) +{ + return &editor->pBuffer->pLast->member.para; +} + +static BOOL editor_beep( ME_TextEditor *editor, UINT type ) +{ + return editor->props & TXTBIT_ALLOWBEEP && MessageBeep( type ); +}
static LRESULT ME_StreamInText(ME_TextEditor *editor, DWORD dwFormat, ME_InStream *stream, ME_Style *style) { @@ -583,27 +586,29 @@ void ME_RTFParAttrHook(RTF_Info *info)
if (!info->editor->bEmulateVersion10) /* v4.1 */ { - if (info->tableDef && info->tableDef->tableRowStart && - info->tableDef->tableRowStart->member.para.nFlags & MEPF_ROWEND) + if (info->tableDef && info->tableDef->row_start && + info->tableDef->row_start->nFlags & MEPF_ROWEND) { ME_Cursor cursor; - ME_DisplayItem *para; + ME_Paragraph *para; /* We are just after a table row. */ RTFFlushOutputBuffer(info); cursor = info->editor->pCursors[0]; - para = cursor.pPara; - if (para == info->tableDef->tableRowStart->member.para.next_para - && !cursor.nOffset && !cursor.pRun->member.run.nCharOfs) + para = cursor.para; + if (para == para_next( info->tableDef->row_start ) + && !cursor.nOffset && !cursor.run->nCharOfs) { /* Since the table row end, no text has been inserted, and the \intbl * control word has not be used. We can confirm that we are not in a * table anymore. */ - info->tableDef->tableRowStart = NULL; + info->tableDef->row_start = NULL; info->canInheritInTbl = FALSE; } } - } else { /* v1.0 - v3.0 */ + } + else /* v1.0 - v3.0 */ + { info->fmt.dwMask |= PFM_TABLE; info->fmt.wEffects &= ~PFE_TABLE; } @@ -611,26 +616,25 @@ void ME_RTFParAttrHook(RTF_Info *info) case rtfNestLevel: if (!info->editor->bEmulateVersion10) /* v4.1 */ { - while (info->rtfParam > info->nestingLevel) { + while (info->rtfParam > info->nestingLevel) + { RTFTable *tableDef = heap_alloc_zero(sizeof(*tableDef)); tableDef->parent = info->tableDef; info->tableDef = tableDef;
RTFFlushOutputBuffer(info); - if (tableDef->tableRowStart && - tableDef->tableRowStart->member.para.nFlags & MEPF_ROWEND) + if (tableDef->row_start && tableDef->row_start->nFlags & MEPF_ROWEND) + { + ME_Paragraph *para = para_next( tableDef->row_start ); + tableDef->row_start = table_insert_row_start_at_para( info->editor, para ); + } + else { - ME_DisplayItem *para = tableDef->tableRowStart; - para = para->member.para.next_para; - para = ME_InsertTableRowStartAtParagraph(info->editor, para); - tableDef->tableRowStart = para; - } else { ME_Cursor cursor; - WCHAR endl = '\r'; cursor = info->editor->pCursors[0]; - if (cursor.nOffset || cursor.pRun->member.run.nCharOfs) - ME_InsertTextFromCursor(info->editor, 0, &endl, 1, info->style); - tableDef->tableRowStart = ME_InsertTableRowStartFromCursor(info->editor); + if (cursor.nOffset || cursor.run->nCharOfs) + ME_InsertTextFromCursor(info->editor, 0, L"\r", 1, info->style); + tableDef->row_start = table_insert_row_start( info->editor, info->editor->pCursors ); }
info->nestingLevel++; @@ -645,25 +649,19 @@ void ME_RTFParAttrHook(RTF_Info *info) if (info->nestingLevel < 1) { RTFTable *tableDef; + ME_Paragraph *para; + if (!info->tableDef) info->tableDef = heap_alloc_zero(sizeof(*info->tableDef)); tableDef = info->tableDef; RTFFlushOutputBuffer(info); - if (tableDef->tableRowStart && - tableDef->tableRowStart->member.para.nFlags & MEPF_ROWEND) - { - ME_DisplayItem *para = tableDef->tableRowStart; - para = para->member.para.next_para; - para = ME_InsertTableRowStartAtParagraph(info->editor, para); - tableDef->tableRowStart = para; - } else { - ME_Cursor cursor; - WCHAR endl = '\r'; - cursor = info->editor->pCursors[0]; - if (cursor.nOffset || cursor.pRun->member.run.nCharOfs) - ME_InsertTextFromCursor(info->editor, 0, &endl, 1, info->style); - tableDef->tableRowStart = ME_InsertTableRowStartFromCursor(info->editor); - } + if (tableDef->row_start && tableDef->row_start->nFlags & MEPF_ROWEND) + para = para_next( tableDef->row_start ); + else + para = info->editor->pCursors[0].para; + + tableDef->row_start = table_insert_row_start_at_para( info->editor, para ); + info->nestingLevel = 1; info->canInheritInTbl = TRUE; } @@ -680,7 +678,7 @@ void ME_RTFParAttrHook(RTF_Info *info) { PARAFORMAT2 fmt; fmt.cbSize = sizeof(fmt); - ME_GetSelectionParaFormat(info->editor, &fmt); + editor_get_selection_para_fmt( info->editor, &fmt ); info->fmt.dwMask |= PFM_STARTINDENT | PFM_OFFSET; info->fmt.dxStartIndent = fmt.dxStartIndent; info->fmt.dxOffset = fmt.dxOffset; @@ -715,7 +713,7 @@ void ME_RTFParAttrHook(RTF_Info *info) { PARAFORMAT2 fmt; fmt.cbSize = sizeof(fmt); - ME_GetSelectionParaFormat(info->editor, &fmt); + editor_get_selection_para_fmt( info->editor, &fmt ); memcpy(info->fmt.rgxTabs, fmt.rgxTabs, fmt.cTabCount * sizeof(fmt.rgxTabs[0])); info->fmt.cTabCount = fmt.cTabCount; @@ -899,13 +897,13 @@ void ME_RTFTblAttrHook(RTF_Info *info) if (cellNum >= MAX_TABLE_CELLS) break; info->tableDef->cells[cellNum].rightBoundary = info->rtfParam; - if (cellNum < MAX_TAB_STOPS) { + if (cellNum < MAX_TAB_STOPS) + { /* Tab stops were used to store cell positions before v4.1 but v4.1 * still seems to set the tabstops without using them. */ - ME_DisplayItem *para = info->editor->pCursors[0].pPara; - PARAFORMAT2 *pFmt = ¶->member.para.fmt; - pFmt->rgxTabs[cellNum] &= ~0x00FFFFFF; - pFmt->rgxTabs[cellNum] |= 0x00FFFFFF & info->rtfParam; + PARAFORMAT2 *fmt = &info->editor->pCursors[0].para->fmt; + fmt->rgxTabs[cellNum] &= ~0x00FFFFFF; + fmt->rgxTabs[cellNum] |= 0x00FFFFFF & info->rtfParam; } info->tableDef->numCellsDefined++; break; @@ -958,25 +956,24 @@ void ME_RTFSpecialCharHook(RTF_Info *info) if (!tableDef) break; RTFFlushOutputBuffer(info); - if (!info->editor->bEmulateVersion10) { /* v4.1 */ - if (tableDef->tableRowStart) + if (!info->editor->bEmulateVersion10) /* v4.1 */ + { + if (tableDef->row_start) { - if (!info->nestingLevel && - tableDef->tableRowStart->member.para.nFlags & MEPF_ROWEND) + if (!info->nestingLevel && tableDef->row_start->nFlags & MEPF_ROWEND) { - ME_DisplayItem *para = tableDef->tableRowStart; - para = para->member.para.next_para; - para = ME_InsertTableRowStartAtParagraph(info->editor, para); - tableDef->tableRowStart = para; + ME_Paragraph *para = para_next( tableDef->row_start ); + tableDef->row_start = table_insert_row_start_at_para( info->editor, para ); info->nestingLevel = 1; } - ME_InsertTableCellFromCursor(info->editor); + table_insert_cell( info->editor, info->editor->pCursors ); } - } else { /* v1.0 - v3.0 */ - ME_DisplayItem *para = info->editor->pCursors[0].pPara; - PARAFORMAT2 *pFmt = ¶->member.para.fmt; - if (pFmt->dwMask & PFM_TABLE && pFmt->wEffects & PFE_TABLE && - tableDef->numCellsInserted < tableDef->numCellsDefined) + } + else /* v1.0 - v3.0 */ + { + ME_Paragraph *para = info->editor->pCursors[0].para; + + if (para_in_table( para ) && tableDef->numCellsInserted < tableDef->numCellsDefined) { WCHAR tab = '\t'; ME_InsertTextFromCursor(info->editor, 0, &tab, 1, info->style); @@ -990,68 +987,68 @@ void ME_RTFSpecialCharHook(RTF_Info *info) /* else fall through since v4.1 treats rtfNestRow and rtfRow the same */ case rtfRow: { - ME_DisplayItem *para, *cell, *run; + ME_Run *run; + ME_Paragraph *para; + ME_Cell *cell; int i;
if (!tableDef) break; RTFFlushOutputBuffer(info); - if (!info->editor->bEmulateVersion10) { /* v4.1 */ - if (!tableDef->tableRowStart) - break; - if (!info->nestingLevel && - tableDef->tableRowStart->member.para.nFlags & MEPF_ROWEND) + if (!info->editor->bEmulateVersion10) /* v4.1 */ + { + if (!tableDef->row_start) break; + if (!info->nestingLevel && tableDef->row_start->nFlags & MEPF_ROWEND) { - para = tableDef->tableRowStart; - para = para->member.para.next_para; - para = ME_InsertTableRowStartAtParagraph(info->editor, para); - tableDef->tableRowStart = para; + para = para_next( tableDef->row_start ); + tableDef->row_start = table_insert_row_start_at_para( info->editor, para ); info->nestingLevel++; } - para = tableDef->tableRowStart; - cell = ME_FindItemFwd(para, diCell); - assert(cell && !cell->member.cell.prev_cell); + para = tableDef->row_start; + cell = table_row_first_cell( para ); + assert( cell && !cell_prev( cell ) ); if (tableDef->numCellsDefined < 1) { /* 2000 twips appears to be the cell size that native richedit uses * when no cell sizes are specified. */ - const int defaultCellSize = 2000; - int nRightBoundary = defaultCellSize; - cell->member.cell.nRightBoundary = nRightBoundary; - while (cell->member.cell.next_cell) { - cell = cell->member.cell.next_cell; - nRightBoundary += defaultCellSize; - cell->member.cell.nRightBoundary = nRightBoundary; + const int default_size = 2000; + int right_boundary = default_size; + cell->nRightBoundary = right_boundary; + while (cell_next( cell )) + { + cell = cell_next( cell ); + right_boundary += default_size; + cell->nRightBoundary = right_boundary; } - para = ME_InsertTableCellFromCursor(info->editor); - cell = para->member.para.pCell; - cell->member.cell.nRightBoundary = nRightBoundary; - } else { + para = table_insert_cell( info->editor, info->editor->pCursors ); + cell = para_cell( para ); + cell->nRightBoundary = right_boundary; + } + else + { for (i = 0; i < tableDef->numCellsDefined; i++) { RTFCell *cellDef = &tableDef->cells[i]; - cell->member.cell.nRightBoundary = cellDef->rightBoundary; - ME_ApplyBorderProperties(info, &cell->member.cell.border, - cellDef->border); - cell = cell->member.cell.next_cell; + cell->nRightBoundary = cellDef->rightBoundary; + ME_ApplyBorderProperties( info, &cell->border, cellDef->border ); + cell = cell_next( cell ); if (!cell) { - para = ME_InsertTableCellFromCursor(info->editor); - cell = para->member.para.pCell; + para = table_insert_cell( info->editor, info->editor->pCursors ); + cell = para_cell( para ); } } /* Cell for table row delimiter is empty */ - cell->member.cell.nRightBoundary = tableDef->cells[i-1].rightBoundary; + cell->nRightBoundary = tableDef->cells[i - 1].rightBoundary; }
- run = ME_FindItemFwd(cell, diRun); - if (info->editor->pCursors[0].pRun != run || - info->editor->pCursors[0].nOffset) + run = para_first_run( cell_first_para( cell ) ); + if (info->editor->pCursors[0].run != run || info->editor->pCursors[0].nOffset) { int nOfs, nChars; /* Delete inserted cells that aren't defined. */ - info->editor->pCursors[1].pRun = run; - info->editor->pCursors[1].pPara = ME_GetParagraph(run); + info->editor->pCursors[1].run = run; + info->editor->pCursors[1].para = run->para; info->editor->pCursors[1].nOffset = 0; nOfs = ME_GetCursorOfs(&info->editor->pCursors[1]); nChars = ME_GetCursorOfs(&info->editor->pCursors[0]) - nOfs; @@ -1059,59 +1056,59 @@ void ME_RTFSpecialCharHook(RTF_Info *info) nChars, TRUE); }
- para = ME_InsertTableRowEndFromCursor(info->editor); - para->member.para.fmt.dxOffset = abs(info->tableDef->gapH); - para->member.para.fmt.dxStartIndent = info->tableDef->leftEdge; - ME_ApplyBorderProperties(info, ¶->member.para.border, - tableDef->border); + para = table_insert_row_end( info->editor, info->editor->pCursors ); + para->fmt.dxOffset = abs(info->tableDef->gapH); + para->fmt.dxStartIndent = info->tableDef->leftEdge; + ME_ApplyBorderProperties( info, ¶->border, tableDef->border ); info->nestingLevel--; if (!info->nestingLevel) { - if (info->canInheritInTbl) { - tableDef->tableRowStart = para; - } else { - while (info->tableDef) { + if (info->canInheritInTbl) tableDef->row_start = para; + else + { + while (info->tableDef) + { tableDef = info->tableDef; info->tableDef = tableDef->parent; heap_free(tableDef); } } - } else { + } + else + { info->tableDef = tableDef->parent; heap_free(tableDef); } - } else { /* v1.0 - v3.0 */ - WCHAR endl = '\r'; - ME_DisplayItem *para = info->editor->pCursors[0].pPara; - PARAFORMAT2 *pFmt = ¶->member.para.fmt; - pFmt->dxOffset = info->tableDef->gapH; - pFmt->dxStartIndent = info->tableDef->leftEdge; - - ME_ApplyBorderProperties(info, ¶->member.para.border, - tableDef->border); + } + else /* v1.0 - v3.0 */ + { + para = info->editor->pCursors[0].para; + para->fmt.dxOffset = info->tableDef->gapH; + para->fmt.dxStartIndent = info->tableDef->leftEdge; + + ME_ApplyBorderProperties( info, ¶->border, tableDef->border ); while (tableDef->numCellsInserted < tableDef->numCellsDefined) { WCHAR tab = '\t'; ME_InsertTextFromCursor(info->editor, 0, &tab, 1, info->style); tableDef->numCellsInserted++; } - pFmt->cTabCount = min(tableDef->numCellsDefined, MAX_TAB_STOPS); - if (!tableDef->numCellsDefined) - pFmt->wEffects &= ~PFE_TABLE; - ME_InsertTextFromCursor(info->editor, 0, &endl, 1, info->style); + para->fmt.cTabCount = min(tableDef->numCellsDefined, MAX_TAB_STOPS); + if (!tableDef->numCellsDefined) para->fmt.wEffects &= ~PFE_TABLE; + ME_InsertTextFromCursor(info->editor, 0, L"\r", 1, info->style); tableDef->numCellsInserted = 0; } break; } case rtfTab: case rtfPar: - if (info->editor->bEmulateVersion10) { /* v1.0 - 3.0 */ - ME_DisplayItem *para; - PARAFORMAT2 *pFmt; + if (info->editor->bEmulateVersion10) /* v1.0 - 3.0 */ + { + ME_Paragraph *para; + RTFFlushOutputBuffer(info); - para = info->editor->pCursors[0].pPara; - pFmt = ¶->member.para.fmt; - if (pFmt->dwMask & PFM_TABLE && pFmt->wEffects & PFE_TABLE) + para = info->editor->pCursors[0].para; + if (para_in_table( para )) { /* rtfPar is treated like a space within a table. */ info->rtfClass = rtfText; @@ -1132,7 +1129,6 @@ static HRESULT insert_static_object(ME_TextEditor *editor, HENHMETAFILE hemf, HB LPOLECLIENTSITE lpClientSite = NULL; LPDATAOBJECT lpDataObject = NULL; LPOLECACHE lpOleCache = NULL; - LPRICHEDITOLE lpReOle = NULL; STGMEDIUM stgm; FORMATETC fm; CLSID clsid; @@ -1151,6 +1147,8 @@ static HRESULT insert_static_object(ME_TextEditor *editor, HENHMETAFILE hemf, HB stgm.u.hBitmap = hbmp; fm.cfFormat = CF_BITMAP; } + else return E_FAIL; + stgm.pUnkForRelease = NULL;
fm.ptd = NULL; @@ -1158,15 +1156,8 @@ static HRESULT insert_static_object(ME_TextEditor *editor, HENHMETAFILE hemf, HB fm.lindex = -1; fm.tymed = stgm.tymed;
- if (!editor->reOle) - { - if (!CreateIRichEditOle(NULL, editor, (LPVOID *)&editor->reOle)) - return hr; - } - if (OleCreateDefaultHandler(&CLSID_NULL, NULL, &IID_IOleObject, (void**)&lpObject) == S_OK && - IUnknown_QueryInterface(editor->reOle, &IID_IRichEditOle, (void**)&lpReOle) == S_OK && - IRichEditOle_GetClientSite(lpReOle, &lpClientSite) == S_OK && + IRichEditOle_GetClientSite(editor->richole, &lpClientSite) == S_OK && IOleObject_SetClientSite(lpObject, lpClientSite) == S_OK && IOleObject_GetUserClassID(lpObject, &clsid) == S_OK && IOleObject_QueryInterface(lpObject, &IID_IOleCache, (void**)&lpOleCache) == S_OK && @@ -1198,7 +1189,6 @@ static HRESULT insert_static_object(ME_TextEditor *editor, HENHMETAFILE hemf, HB if (lpStorage) IStorage_Release(lpStorage); if (lpDataObject) IDataObject_Release(lpDataObject); if (lpOleCache) IOleCache_Release(lpOleCache); - if (lpReOle) IRichEditOle_Release(lpReOle);
return hr; } @@ -1605,29 +1595,27 @@ static LRESULT ME_StreamIn(ME_TextEditor *editor, DWORD format, EDITSTREAM *stre ME_InternalDeleteText(editor, selStart, to - from, FALSE);
/* Don't insert text at the end of the table row */ - if (!editor->bEmulateVersion10) { /* v4.1 */ - ME_DisplayItem *para = editor->pCursors->pPara; - if (para->member.para.nFlags & MEPF_ROWEND) - { - para = para->member.para.next_para; - editor->pCursors[0].pPara = para; - editor->pCursors[0].pRun = ME_FindItemFwd(para, diRun); - editor->pCursors[0].nOffset = 0; - } - if (para->member.para.nFlags & MEPF_ROWSTART) + if (!editor->bEmulateVersion10) /* v4.1 */ + { + ME_Paragraph *para = editor->pCursors->para; + if (para->nFlags & (MEPF_ROWSTART | MEPF_ROWEND)) { - para = para->member.para.next_para; - editor->pCursors[0].pPara = para; - editor->pCursors[0].pRun = ME_FindItemFwd(para, diRun); + para = para_next( para ); + editor->pCursors[0].para = para; + editor->pCursors[0].run = para_first_run( para ); editor->pCursors[0].nOffset = 0; } editor->pCursors[1] = editor->pCursors[0]; - } else { /* v1.0 - 3.0 */ - if (editor->pCursors[0].pRun->member.run.nFlags & MERF_ENDPARA && - ME_IsInTable(editor->pCursors[0].pRun)) + } + else /* v1.0 - 3.0 */ + { + if (editor->pCursors[0].run->nFlags & MERF_ENDPARA && + para_in_table( editor->pCursors[0].para )) return 0; } - } else { + } + else + { style = editor->pBuffer->pDefaultStyle; ME_AddRefStyle(style); set_selection_cursors(editor, 0, 0); @@ -1635,7 +1623,7 @@ static LRESULT ME_StreamIn(ME_TextEditor *editor, DWORD format, EDITSTREAM *stre ME_GetTextLength(editor), FALSE); from = to = 0; ME_ClearTempStyle(editor); - ME_SetDefaultParaFormat(editor, &editor->pCursors[0].pPara->member.para.fmt); + editor_set_default_para_fmt( editor, &editor->pCursors[0].para->fmt ); }
@@ -1695,13 +1683,14 @@ static LRESULT ME_StreamIn(ME_TextEditor *editor, DWORD format, EDITSTREAM *stre /* do the parsing */ RTFRead(&parser); RTFFlushOutputBuffer(&parser); - if (!editor->bEmulateVersion10) { /* v4.1 */ - if (parser.tableDef && parser.tableDef->tableRowStart && + if (!editor->bEmulateVersion10) /* v4.1 */ + { + if (parser.tableDef && parser.tableDef->row_start && (parser.nestingLevel > 0 || parser.canInheritInTbl)) { /* Delete any incomplete table row at the end of the rich text. */ int nOfs, nChars; - ME_DisplayItem *para; + ME_Paragraph *para;
parser.rtfMinor = rtfRow; /* Complete the table row before deleting it. @@ -1712,26 +1701,26 @@ static LRESULT ME_StreamIn(ME_TextEditor *editor, DWORD format, EDITSTREAM *stre { while (parser.nestingLevel > 1) ME_RTFSpecialCharHook(&parser); /* Decrements nestingLevel */ - para = parser.tableDef->tableRowStart; + para = parser.tableDef->row_start; ME_RTFSpecialCharHook(&parser); - } else { - para = parser.tableDef->tableRowStart; + } + else + { + para = parser.tableDef->row_start; ME_RTFSpecialCharHook(&parser); - assert(para->member.para.nFlags & MEPF_ROWEND); - para = para->member.para.next_para; + assert( para->nFlags & MEPF_ROWEND ); + para = para_next( para ); }
- editor->pCursors[1].pPara = para; - editor->pCursors[1].pRun = ME_FindItemFwd(para, diRun); + editor->pCursors[1].para = para; + editor->pCursors[1].run = para_first_run( para ); editor->pCursors[1].nOffset = 0; nOfs = ME_GetCursorOfs(&editor->pCursors[1]); nChars = ME_GetCursorOfs(&editor->pCursors[0]) - nOfs; ME_InternalDeleteText(editor, &editor->pCursors[1], nChars, TRUE); - if (parser.tableDef) - parser.tableDef->tableRowStart = NULL; + if (parser.tableDef) parser.tableDef->row_start = NULL; } } - ME_CheckTablesForCorruption(editor); RTFDestroy(&parser);
if (parser.stackTop > 0) @@ -1790,7 +1779,7 @@ static LRESULT ME_StreamIn(ME_TextEditor *editor, DWORD format, EDITSTREAM *stre /* put the cursor at the top */ if (!(format & SFF_SELECTION)) set_selection_cursors(editor, 0, 0); - ME_CursorFromCharOfs(editor, from, &start); + cursor_from_char_ofs( editor, from, &start ); ME_UpdateLinkAttribute(editor, &start, to - from); }
@@ -1810,7 +1799,6 @@ static LRESULT ME_StreamIn(ME_TextEditor *editor, DWORD format, EDITSTREAM *stre if (!(format & SFF_SELECTION)) { ME_ClearTempStyle(editor); } - update_caret(editor); ME_SendSelChange(editor); ME_SendRequestResize(editor, FALSE);
@@ -1919,20 +1907,19 @@ ME_FindText(ME_TextEditor *editor, DWORD flags, const CHARRANGE *chrg, const WCH /* If possible, find the character before where the search starts */ if ((flags & FR_WHOLEWORD) && nMin) { - ME_CursorFromCharOfs(editor, nMin - 1, &cursor); - wLastChar = *get_text( &cursor.pRun->member.run, cursor.nOffset ); + cursor_from_char_ofs( editor, nMin - 1, &cursor ); + wLastChar = *get_text( cursor.run, cursor.nOffset ); ME_MoveCursorChars(editor, &cursor, 1, FALSE); - } else { - ME_CursorFromCharOfs(editor, nMin, &cursor); } + else cursor_from_char_ofs( editor, nMin, &cursor );
- while (cursor.pRun && ME_GetCursorOfs(&cursor) + nLen <= nMax) + while (cursor.run && ME_GetCursorOfs(&cursor) + nLen <= nMax) { - ME_DisplayItem *pCurItem = cursor.pRun; + ME_Run *run = cursor.run; int nCurStart = cursor.nOffset; int nMatched = 0;
- while (pCurItem && ME_CharCompare( *get_text( &pCurItem->member.run, nCurStart + nMatched ), text[nMatched], (flags & FR_MATCHCASE))) + while (run && ME_CharCompare( *get_text( run, nCurStart + nMatched ), text[nMatched], (flags & FR_MATCHCASE))) { if ((flags & FR_WHOLEWORD) && iswalnum(wLastChar)) break; @@ -1940,21 +1927,21 @@ ME_FindText(ME_TextEditor *editor, DWORD flags, const CHARRANGE *chrg, const WCH nMatched++; if (nMatched == nLen) { - ME_DisplayItem *pNextItem = pCurItem; + ME_Run *next_run = run; int nNextStart = nCurStart; WCHAR wNextChar;
/* Check to see if next character is a whitespace */ if (flags & FR_WHOLEWORD) { - if (nCurStart + nMatched == pCurItem->member.run.len) + if (nCurStart + nMatched == run->len) { - pNextItem = ME_FindItemFwd(pCurItem, diRun); + next_run = run_next_all_paras( run ); nNextStart = -nMatched; }
- if (pNextItem) - wNextChar = *get_text( &pNextItem->member.run, nNextStart + nMatched ); + if (next_run) + wNextChar = *get_text( next_run, nNextStart + nMatched ); else wNextChar = ' ';
@@ -1962,7 +1949,7 @@ ME_FindText(ME_TextEditor *editor, DWORD flags, const CHARRANGE *chrg, const WCH break; }
- cursor.nOffset += cursor.pPara->member.para.nCharOfs + cursor.pRun->member.run.nCharOfs; + cursor.nOffset += cursor.para->nCharOfs + cursor.run->nCharOfs; if (chrgText) { chrgText->cpMin = cursor.nOffset; @@ -1971,22 +1958,28 @@ ME_FindText(ME_TextEditor *editor, DWORD flags, const CHARRANGE *chrg, const WCH TRACE("found at %d-%d\n", cursor.nOffset, cursor.nOffset + nLen); return cursor.nOffset; } - if (nCurStart + nMatched == pCurItem->member.run.len) + if (nCurStart + nMatched == run->len) { - pCurItem = ME_FindItemFwd(pCurItem, diRun); + run = run_next_all_paras( run ); nCurStart = -nMatched; } } - if (pCurItem) - wLastChar = *get_text( &pCurItem->member.run, nCurStart + nMatched ); + if (run) + wLastChar = *get_text( run, nCurStart + nMatched ); else wLastChar = ' ';
cursor.nOffset++; - if (cursor.nOffset == cursor.pRun->member.run.len) + if (cursor.nOffset == cursor.run->len) { - ME_NextRun(&cursor.pPara, &cursor.pRun, TRUE); - cursor.nOffset = 0; + if (run_next_all_paras( cursor.run )) + { + cursor.run = run_next_all_paras( cursor.run ); + cursor.para = cursor.run->para; + cursor.nOffset = 0; + } + else + cursor.run = NULL; } } } @@ -1995,28 +1988,28 @@ ME_FindText(ME_TextEditor *editor, DWORD flags, const CHARRANGE *chrg, const WCH /* If possible, find the character after where the search ends */ if ((flags & FR_WHOLEWORD) && nMax < nTextLen - 1) { - ME_CursorFromCharOfs(editor, nMax + 1, &cursor); - wLastChar = *get_text( &cursor.pRun->member.run, cursor.nOffset ); + cursor_from_char_ofs( editor, nMax + 1, &cursor ); + wLastChar = *get_text( cursor.run, cursor.nOffset ); ME_MoveCursorChars(editor, &cursor, -1, FALSE); - } else { - ME_CursorFromCharOfs(editor, nMax, &cursor); } + else cursor_from_char_ofs( editor, nMax, &cursor );
- while (cursor.pRun && ME_GetCursorOfs(&cursor) - nLen >= nMin) + while (cursor.run && ME_GetCursorOfs(&cursor) - nLen >= nMin) { - ME_DisplayItem *pCurItem = cursor.pRun; - ME_DisplayItem *pCurPara = cursor.pPara; + ME_Run *run = cursor.run; + ME_Paragraph *para = cursor.para; int nCurEnd = cursor.nOffset; int nMatched = 0;
- if (nCurEnd == 0) + if (nCurEnd == 0 && run_prev_all_paras( run )) { - ME_PrevRun(&pCurPara, &pCurItem, TRUE); - nCurEnd = pCurItem->member.run.len; + run = run_prev_all_paras( run ); + para = run->para; + nCurEnd = run->len; }
- while (pCurItem && ME_CharCompare( *get_text( &pCurItem->member.run, nCurEnd - nMatched - 1 ), - text[nLen - nMatched - 1], (flags & FR_MATCHCASE) )) + while (run && ME_CharCompare( *get_text( run, nCurEnd - nMatched - 1 ), + text[nLen - nMatched - 1], (flags & FR_MATCHCASE) )) { if ((flags & FR_WHOLEWORD) && iswalnum(wLastChar)) break; @@ -2024,7 +2017,7 @@ ME_FindText(ME_TextEditor *editor, DWORD flags, const CHARRANGE *chrg, const WCH nMatched++; if (nMatched == nLen) { - ME_DisplayItem *pPrevItem = pCurItem; + ME_Run *prev_run = run; int nPrevEnd = nCurEnd; WCHAR wPrevChar; int nStart; @@ -2034,22 +2027,18 @@ ME_FindText(ME_TextEditor *editor, DWORD flags, const CHARRANGE *chrg, const WCH { if (nPrevEnd - nMatched == 0) { - pPrevItem = ME_FindItemBack(pCurItem, diRun); - if (pPrevItem) - nPrevEnd = pPrevItem->member.run.len + nMatched; + prev_run = run_prev_all_paras( run ); + if (prev_run) nPrevEnd = prev_run->len + nMatched; }
- if (pPrevItem) - wPrevChar = *get_text( &pPrevItem->member.run, nPrevEnd - nMatched - 1 ); - else - wPrevChar = ' '; + if (prev_run) wPrevChar = *get_text( prev_run, nPrevEnd - nMatched - 1 ); + else wPrevChar = ' ';
if (iswalnum(wPrevChar)) break; }
- nStart = pCurPara->member.para.nCharOfs - + pCurItem->member.run.nCharOfs + nCurEnd - nMatched; + nStart = para->nCharOfs + run->nCharOfs + nCurEnd - nMatched; if (chrgText) { chrgText->cpMin = nStart; @@ -2060,22 +2049,32 @@ ME_FindText(ME_TextEditor *editor, DWORD flags, const CHARRANGE *chrg, const WCH } if (nCurEnd - nMatched == 0) { - ME_PrevRun(&pCurPara, &pCurItem, TRUE); + if (run_prev_all_paras( run )) + { + run = run_prev_all_paras( run ); + para = run->para; + } /* Don't care about pCurItem becoming NULL here; it's already taken * care of in the exterior loop condition */ - nCurEnd = pCurItem->member.run.len + nMatched; + nCurEnd = run->len + nMatched; } } - if (pCurItem) - wLastChar = *get_text( &pCurItem->member.run, nCurEnd - nMatched - 1 ); + if (run) + wLastChar = *get_text( run, nCurEnd - nMatched - 1 ); else wLastChar = ' ';
cursor.nOffset--; if (cursor.nOffset < 0) { - ME_PrevRun(&cursor.pPara, &cursor.pRun, TRUE); - cursor.nOffset = cursor.pRun->member.run.len; + if (run_prev_all_paras( cursor.run ) ) + { + cursor.run = run_prev_all_paras( cursor.run ); + cursor.para = cursor.run->para; + cursor.nOffset = cursor.run->len; + } + else + cursor.run = NULL; } } } @@ -2137,22 +2136,11 @@ static int ME_GetTextEx(ME_TextEditor *editor, GETTEXTEX *ex, LPARAM pText) } }
-static int ME_GetTextRange(ME_TextEditor *editor, WCHAR *strText, - const ME_Cursor *start, int nLen, BOOL unicode) +static int get_text_range( ME_TextEditor *editor, WCHAR *buffer, + const ME_Cursor *start, int len ) { - if (!strText) return 0; - if (unicode) { - return ME_GetTextW(editor, strText, INT_MAX, start, nLen, FALSE, FALSE); - } else { - int nChars; - WCHAR *p = heap_alloc((nLen+1) * sizeof(*p)); - if (!p) return 0; - nChars = ME_GetTextW(editor, p, nLen, start, nLen, FALSE, FALSE); - WideCharToMultiByte(CP_ACP, 0, p, nChars+1, (char *)strText, - nLen+1, NULL, NULL); - heap_free(p); - return nChars; - } + if (!buffer) return 0; + return ME_GetTextW( editor, buffer, INT_MAX, start, len, FALSE, FALSE ); }
int set_selection( ME_TextEditor *editor, int to, int from ) @@ -2211,8 +2199,6 @@ static DWORD CALLBACK ME_ReadFromHGLOBALRTF(DWORD_PTR dwCookie, LPBYTE lpBuff, L return 0; }
-static const WCHAR rtfW[] = {'R','i','c','h',' ','T','e','x','t',' ','F','o','r','m','a','t',0}; - static HRESULT paste_rtf(ME_TextEditor *editor, FORMATETC *fmt, STGMEDIUM *med) { EDITSTREAM es; @@ -2267,7 +2253,7 @@ static struct paste_format const WCHAR *name; } paste_formats[] = { - {{ -1, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL }, paste_rtf, rtfW }, + {{ -1, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL }, paste_rtf, L"Rich Text Format" }, {{ CF_UNICODETEXT, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL }, paste_text }, {{ CF_ENHMETAFILE, NULL, DVASPECT_CONTENT, -1, TYMED_ENHMF }, paste_emf }, {{ 0 }} @@ -2297,10 +2283,9 @@ static BOOL paste_special(ME_TextEditor *editor, UINT cf, REPASTESPECIAL *ps, BO IDataObject *data;
/* Protect read-only edit control from modification */ - if (editor->styleFlags & ES_READONLY) + if (editor->props & TXTBIT_READONLY) { - if (!check_only) - MessageBeep(MB_ICONERROR); + if (!check_only) editor_beep( editor, MB_ICONERROR ); return FALSE; }
@@ -2337,146 +2322,111 @@ done: return hr == S_OK; }
-static BOOL ME_Copy(ME_TextEditor *editor, const ME_Cursor *start, int nChars) +static HRESULT editor_copy( ME_TextEditor *editor, ME_Cursor *start, int chars, IDataObject **data_out ) { - LPDATAOBJECT dataObj = NULL; - HRESULT hr = S_OK; + IDataObject *data = NULL; + HRESULT hr = S_OK;
- if (editor->cPasswordMask) - return FALSE; /* Copying or Cutting masked text isn't allowed */ + if (editor->lpOleCallback) + { + CHARRANGE range; + range.cpMin = ME_GetCursorOfs( start ); + range.cpMax = range.cpMin + chars; + hr = IRichEditOleCallback_GetClipboardData( editor->lpOleCallback, &range, RECO_COPY, &data ); + }
- if(editor->lpOleCallback) - { - CHARRANGE range; - range.cpMin = ME_GetCursorOfs(start); - range.cpMax = range.cpMin + nChars; - hr = IRichEditOleCallback_GetClipboardData(editor->lpOleCallback, &range, RECO_COPY, &dataObj); - } - if(FAILED(hr) || !dataObj) - hr = ME_GetDataObject(editor, start, nChars, &dataObj); - if(SUCCEEDED(hr)) { - hr = OleSetClipboard(dataObj); - IDataObject_Release(dataObj); - } - return SUCCEEDED(hr); + if (FAILED( hr ) || !data) + hr = ME_GetDataObject( editor, start, chars, &data ); + + if (SUCCEEDED( hr )) + { + if (data_out) + *data_out = data; + else + { + hr = OleSetClipboard( data ); + IDataObject_Release( data ); + } + } + + return hr; }
-static BOOL copy_or_cut(ME_TextEditor *editor, BOOL cut) +HRESULT editor_copy_or_cut( ME_TextEditor *editor, BOOL cut, ME_Cursor *start, int count, + IDataObject **data_out ) { - BOOL result; - int offs, num_chars; - int start_cursor = ME_GetSelectionOfs(editor, &offs, &num_chars); - ME_Cursor *sel_start = &editor->pCursors[start_cursor]; + HRESULT hr;
- if (cut && (editor->styleFlags & ES_READONLY)) + if (cut && (editor->props & TXTBIT_READONLY)) { - MessageBeep(MB_ICONERROR); - return FALSE; + return E_ACCESSDENIED; }
- num_chars -= offs; - result = ME_Copy(editor, sel_start, num_chars); - if (result && cut) + hr = editor_copy( editor, start, count, data_out ); + if (SUCCEEDED(hr) && cut) { - ME_InternalDeleteText(editor, sel_start, num_chars, FALSE); - ME_CommitUndo(editor); - ME_UpdateRepaint(editor, TRUE); + ME_InternalDeleteText( editor, start, count, FALSE ); + ME_CommitUndo( editor ); + ME_UpdateRepaint( editor, TRUE ); } - return result; + return hr; }
-/* helper to send a msg filter notification */ -static BOOL -ME_FilterEvent(ME_TextEditor *editor, UINT msg, WPARAM* wParam, LPARAM* lParam) +static BOOL copy_or_cut( ME_TextEditor *editor, BOOL cut ) { - MSGFILTER msgf; - - if (!editor->hWnd || !editor->hwndParent) return FALSE; - msgf.nmhdr.hwndFrom = editor->hWnd; - msgf.nmhdr.idFrom = GetWindowLongW(editor->hWnd, GWLP_ID); - msgf.nmhdr.code = EN_MSGFILTER; - msgf.msg = msg; - msgf.wParam = *wParam; - msgf.lParam = *lParam; - if (SendMessageW(editor->hwndParent, WM_NOTIFY, msgf.nmhdr.idFrom, (LPARAM)&msgf)) - return FALSE; - *wParam = msgf.wParam; - *lParam = msgf.lParam; - msgf.wParam = *wParam; + HRESULT hr; + int offs, count; + int start_cursor = ME_GetSelectionOfs( editor, &offs, &count ); + ME_Cursor *sel_start = &editor->pCursors[start_cursor];
- return TRUE; + if (editor->password_char) return FALSE; + + count -= offs; + hr = editor_copy_or_cut( editor, cut, sel_start, count, NULL ); + if (FAILED( hr )) editor_beep( editor, MB_ICONERROR ); + + return SUCCEEDED( hr ); }
static void ME_UpdateSelectionLinkAttribute(ME_TextEditor *editor) { - ME_DisplayItem *startPara, *endPara; - ME_DisplayItem *prev_para; - ME_Cursor *from, *to; - ME_Cursor start; - int nChars; + ME_Paragraph *start_para, *end_para; + ME_Cursor *from, *to, start; + int num_chars;
if (!editor->AutoURLDetect_bEnable) return;
ME_GetSelection(editor, &from, &to);
/* Find paragraph previous to the one that contains start cursor */ - startPara = from->pPara; - prev_para = startPara->member.para.prev_para; - if (prev_para->type == diParagraph) startPara = prev_para; + start_para = from->para; + if (para_prev( start_para )) start_para = para_prev( start_para );
/* Find paragraph that contains end cursor */ - endPara = to->pPara->member.para.next_para; + end_para = para_next( to->para );
- start.pPara = startPara; - start.pRun = ME_FindItemFwd(startPara, diRun); + start.para = start_para; + start.run = para_first_run( start_para ); start.nOffset = 0; - nChars = endPara->member.para.nCharOfs - startPara->member.para.nCharOfs; + num_chars = end_para->nCharOfs - start_para->nCharOfs;
- ME_UpdateLinkAttribute(editor, &start, nChars); + ME_UpdateLinkAttribute( editor, &start, num_chars ); }
static BOOL handle_enter(ME_TextEditor *editor) { - BOOL ctrl_is_down = GetKeyState(VK_CONTROL) & 0x8000; BOOL shift_is_down = GetKeyState(VK_SHIFT) & 0x8000;
- if (editor->bDialogMode) - { - if (ctrl_is_down) - return TRUE; - - if (!(editor->styleFlags & ES_WANTRETURN)) - { - if (editor->hwndParent) - { - DWORD dw; - dw = SendMessageW(editor->hwndParent, DM_GETDEFID, 0, 0); - if (HIWORD(dw) == DC_HASDEFID) - { - HWND hwDefCtrl = GetDlgItem(editor->hwndParent, LOWORD(dw)); - if (hwDefCtrl) - { - SendMessageW(editor->hwndParent, WM_NEXTDLGCTL, (WPARAM)hwDefCtrl, TRUE); - PostMessageW(hwDefCtrl, WM_KEYDOWN, VK_RETURN, 0); - } - } - } - return TRUE; - } - } - - if (editor->styleFlags & ES_MULTILINE) + if (editor->props & TXTBIT_MULTILINE) { - static const WCHAR endl = '\r'; - static const WCHAR endlv10[] = {'\r','\n'}; ME_Cursor cursor = editor->pCursors[0]; - ME_DisplayItem *para = cursor.pPara; + ME_Paragraph *para = cursor.para; int from, to; ME_Style *style, *eop_style;
- if (editor->styleFlags & ES_READONLY) + if (editor->props & TXTBIT_READONLY) { - MessageBeep(MB_ICONERROR); + editor_beep( editor, MB_ICONERROR ); return TRUE; }
@@ -2485,60 +2435,57 @@ static BOOL handle_enter(ME_TextEditor *editor) { if (!editor->bEmulateVersion10) /* v4.1 */ { - if (para->member.para.nFlags & MEPF_ROWEND) + if (para->nFlags & MEPF_ROWEND) { /* Add a new table row after this row. */ - para = ME_AppendTableRow(editor, para); - para = para->member.para.next_para; - editor->pCursors[0].pPara = para; - editor->pCursors[0].pRun = ME_FindItemFwd(para, diRun); + para = table_append_row( editor, para ); + para = para_next( para ); + editor->pCursors[0].para = para; + editor->pCursors[0].run = para_first_run( para ); editor->pCursors[0].nOffset = 0; editor->pCursors[1] = editor->pCursors[0]; ME_CommitUndo(editor); - ME_CheckTablesForCorruption(editor); ME_UpdateRepaint(editor, FALSE); return TRUE; } - else if (para == editor->pCursors[1].pPara && - cursor.nOffset + cursor.pRun->member.run.nCharOfs == 0 && - para->member.para.prev_para->member.para.nFlags & MEPF_ROWSTART && - !para->member.para.prev_para->member.para.nCharOfs) + else if (para == editor->pCursors[1].para && + cursor.nOffset + cursor.run->nCharOfs == 0 && + para_prev( para ) && para_prev( para )->nFlags & MEPF_ROWSTART && + !para_prev( para )->nCharOfs) { /* Insert a newline before the table. */ - para = para->member.para.prev_para; - para->member.para.nFlags &= ~MEPF_ROWSTART; - editor->pCursors[0].pPara = para; - editor->pCursors[0].pRun = ME_FindItemFwd(para, diRun); + para = para_prev( para ); + para->nFlags &= ~MEPF_ROWSTART; + editor->pCursors[0].para = para; + editor->pCursors[0].run = para_first_run( para ); editor->pCursors[1] = editor->pCursors[0]; - ME_InsertTextFromCursor(editor, 0, &endl, 1, - editor->pCursors[0].pRun->member.run.style); - para = editor->pBuffer->pFirst->member.para.next_para; - ME_SetDefaultParaFormat(editor, ¶->member.para.fmt); - para->member.para.nFlags = 0; - mark_para_rewrap(editor, para); - editor->pCursors[0].pPara = para; - editor->pCursors[0].pRun = ME_FindItemFwd(para, diRun); + ME_InsertTextFromCursor( editor, 0, L"\r", 1, editor->pCursors[0].run->style ); + para = editor_first_para( editor ); + editor_set_default_para_fmt( editor, ¶->fmt ); + para->nFlags = 0; + para_mark_rewrap( editor, para ); + editor->pCursors[0].para = para; + editor->pCursors[0].run = para_first_run( para ); editor->pCursors[1] = editor->pCursors[0]; - para->member.para.next_para->member.para.nFlags |= MEPF_ROWSTART; + para_next( para )->nFlags |= MEPF_ROWSTART; ME_CommitCoalescingUndo(editor); - ME_CheckTablesForCorruption(editor); ME_UpdateRepaint(editor, FALSE); return TRUE; } } else /* v1.0 - 3.0 */ { - ME_DisplayItem *para = cursor.pPara; - if (ME_IsInTable(para)) + ME_Paragraph *para = cursor.para; + if (para_in_table( para )) { - if (cursor.pRun->member.run.nFlags & MERF_ENDPARA) + if (cursor.run->nFlags & MERF_ENDPARA) { if (from == to) { ME_ContinueCoalescingTransaction(editor); - para = ME_AppendTableRow(editor, para); - editor->pCursors[0].pPara = para; - editor->pCursors[0].pRun = ME_FindItemFwd(para, diRun); + para = table_append_row( editor, para ); + editor->pCursors[0].para = para; + editor->pCursors[0].run = para_first_run( para ); editor->pCursors[0].nOffset = 0; editor->pCursors[1] = editor->pCursors[0]; ME_CommitCoalescingUndo(editor); @@ -2549,27 +2496,26 @@ static BOOL handle_enter(ME_TextEditor *editor) else { ME_ContinueCoalescingTransaction(editor); - if (cursor.pRun->member.run.nCharOfs + cursor.nOffset == 0 && - !ME_IsInTable(para->member.para.prev_para)) + if (cursor.run->nCharOfs + cursor.nOffset == 0 && + para_prev( para ) && !para_in_table( para_prev( para ) )) { /* Insert newline before table */ - cursor.pRun = ME_FindItemBack(para, diRun); - if (cursor.pRun) + cursor.run = para_end_run( para_prev( para ) ); + if (cursor.run) { - editor->pCursors[0].pRun = cursor.pRun; - editor->pCursors[0].pPara = para->member.para.prev_para; + editor->pCursors[0].run = cursor.run; + editor->pCursors[0].para = para_prev( para ); } editor->pCursors[0].nOffset = 0; editor->pCursors[1] = editor->pCursors[0]; - ME_InsertTextFromCursor(editor, 0, &endl, 1, - editor->pCursors[0].pRun->member.run.style); + ME_InsertTextFromCursor( editor, 0, L"\r", 1, editor->pCursors[0].run->style ); } else { editor->pCursors[1] = editor->pCursors[0]; - para = ME_AppendTableRow(editor, para); - editor->pCursors[0].pPara = para; - editor->pCursors[0].pRun = ME_FindItemFwd(para, diRun); + para = table_append_row( editor, para ); + editor->pCursors[0].para = para; + editor->pCursors[0].run = para_first_run( para ); editor->pCursors[0].nOffset = 0; editor->pCursors[1] = editor->pCursors[0]; } @@ -2580,13 +2526,13 @@ static BOOL handle_enter(ME_TextEditor *editor) } }
- style = ME_GetInsertStyle(editor, 0); + style = style_get_insert_style( editor, editor->pCursors );
/* Normally the new eop style is the insert style, however in a list it is copied from the existing eop style (this prevents the list label style changing when the new eop is inserted). No extra ref is taken here on eop_style. */ - if (para->member.para.fmt.wNumbering) - eop_style = para->member.para.eop_run->style; + if (para->fmt.wNumbering) + eop_style = para->eop_run->style; else eop_style = style; ME_ContinueCoalescingTransaction(editor); @@ -2594,9 +2540,9 @@ static BOOL handle_enter(ME_TextEditor *editor) ME_InsertEndRowFromCursor(editor, 0); else if (!editor->bEmulateVersion10) - ME_InsertTextFromCursor(editor, 0, &endl, 1, eop_style); + ME_InsertTextFromCursor(editor, 0, L"\r", 1, eop_style); else - ME_InsertTextFromCursor(editor, 0, endlv10, 2, eop_style); + ME_InsertTextFromCursor(editor, 0, L"\r\n", 2, eop_style); ME_CommitCoalescingUndo(editor); SetCursor(NULL);
@@ -2640,7 +2586,7 @@ ME_KeyDown(ME_TextEditor *editor, WORD nKey) case VK_DELETE: editor->nUDArrowX = -1; /* FIXME backspace and delete aren't the same, they act different wrt paragraph style of the merged paragraph */ - if (editor->styleFlags & ES_READONLY) + if (editor->props & TXTBIT_READONLY) return FALSE; if (ME_IsSelection(editor)) { @@ -2670,7 +2616,7 @@ ME_KeyDown(ME_TextEditor *editor, WORD nKey) } else return TRUE; - ME_MoveCursorFromTableRowStartParagraph(editor); + table_move_from_row_start( editor ); ME_UpdateSelectionLinkAttribute(editor); ME_UpdateRepaint(editor, FALSE); ME_SendRequestResize(editor, FALSE); @@ -2679,14 +2625,6 @@ ME_KeyDown(ME_TextEditor *editor, WORD nKey) if (!editor->bEmulateVersion10) return handle_enter(editor); break; - case VK_ESCAPE: - if (editor->bDialogMode && editor->hwndParent) - PostMessageW(editor->hwndParent, WM_CLOSE, 0, 0); - return TRUE; - case VK_TAB: - if (editor->bDialogMode && editor->hwndParent) - SendMessageW(editor->hwndParent, WM_NEXTDLGCTL, shift_is_down, 0); - return TRUE; case 'A': if (ctrl_is_down) { @@ -2742,35 +2680,24 @@ ME_KeyDown(ME_TextEditor *editor, WORD nKey) return FALSE; }
-static LRESULT ME_Char(ME_TextEditor *editor, WPARAM charCode, - LPARAM flags, BOOL unicode) +static LRESULT handle_wm_char( ME_TextEditor *editor, WCHAR wstr, LPARAM flags ) { - WCHAR wstr; - if (editor->bMouseCaptured) return 0;
- if (editor->styleFlags & ES_READONLY) + if (editor->props & TXTBIT_READONLY) { - MessageBeep(MB_ICONERROR); + editor_beep( editor, MB_ICONERROR ); return 0; /* FIXME really 0 ? */ }
- if (unicode) - wstr = (WCHAR)charCode; - else - { - CHAR charA = charCode; - MultiByteToWideChar(CP_ACP, 0, &charA, 1, &wstr, 1); - } - if (editor->bEmulateVersion10 && wstr == '\r') handle_enter(editor);
if ((unsigned)wstr >= ' ' || wstr == '\t') { ME_Cursor cursor = editor->pCursors[0]; - ME_DisplayItem *para = cursor.pPara; + ME_Paragraph *para = cursor.para; int from, to; BOOL ctrl_is_down = GetKeyState(VK_CONTROL) & 0x8000; ME_GetSelectionOfs(editor, &from, &to); @@ -2778,43 +2705,43 @@ static LRESULT ME_Char(ME_TextEditor *editor, WPARAM charCode, /* v4.1 allows tabs to be inserted with ctrl key down */ !(ctrl_is_down && !editor->bEmulateVersion10)) { - ME_DisplayItem *para; - BOOL bSelectedRow = FALSE; + BOOL selected_row = FALSE;
- para = cursor.pPara; if (ME_IsSelection(editor) && - cursor.pRun->member.run.nCharOfs + cursor.nOffset == 0 && - to == ME_GetCursorOfs(&editor->pCursors[0]) && - para->member.para.prev_para->type == diParagraph) + cursor.run->nCharOfs + cursor.nOffset == 0 && + to == ME_GetCursorOfs(&editor->pCursors[0]) && para_prev( para )) { - para = para->member.para.prev_para; - bSelectedRow = TRUE; + para = para_prev( para ); + selected_row = TRUE; } - if (ME_IsInTable(para)) + if (para_in_table( para )) { - ME_TabPressedInTable(editor, bSelectedRow); + table_handle_tab( editor, selected_row ); ME_CommitUndo(editor); return 0; } - } else if (!editor->bEmulateVersion10) { /* v4.1 */ - if (para->member.para.nFlags & MEPF_ROWEND) { - if (from == to) { - para = para->member.para.next_para; - if (para->member.para.nFlags & MEPF_ROWSTART) - para = para->member.para.next_para; - editor->pCursors[0].pPara = para; - editor->pCursors[0].pRun = ME_FindItemFwd(para, diRun); + } + else if (!editor->bEmulateVersion10) /* v4.1 */ + { + if (para->nFlags & MEPF_ROWEND) + { + if (from == to) + { + para = para_next( para ); + if (para->nFlags & MEPF_ROWSTART) para = para_next( para ); + editor->pCursors[0].para = para; + editor->pCursors[0].run = para_first_run( para ); editor->pCursors[0].nOffset = 0; editor->pCursors[1] = editor->pCursors[0]; } } - } else { /* v1.0 - 3.0 */ - if (ME_IsInTable(cursor.pRun) && - cursor.pRun->member.run.nFlags & MERF_ENDPARA && - from == to) + } + else /* v1.0 - 3.0 */ + { + if (para_in_table( para ) && cursor.run->nFlags & MERF_ENDPARA && from == to) { /* Text should not be inserted at the end of the table. */ - MessageBeep(-1); + editor_beep( editor, -1 ); return 0; } } @@ -2822,7 +2749,7 @@ static LRESULT ME_Char(ME_TextEditor *editor, WPARAM charCode, /* WM_CHAR is restricted to nTextLimit */ if(editor->nTextLimit > ME_GetTextLength(editor) - (to-from)) { - ME_Style *style = ME_GetInsertStyle(editor, 0); + ME_Style *style = style_get_insert_style( editor, editor->pCursors ); ME_ContinueCoalescingTransaction(editor); ME_InsertTextFromCursor(editor, 0, &wstr, 1, style); ME_ReleaseStyle(style); @@ -2894,104 +2821,52 @@ static BOOL is_link( ME_Run *run ) return (run->style->fmt.dwMask & CFM_LINK) && (run->style->fmt.dwEffects & CFE_LINK); }
-static BOOL ME_SetCursor(ME_TextEditor *editor) +void editor_set_cursor( ME_TextEditor *editor, int x, int y ) { - ME_Cursor cursor; - POINT pt; - BOOL isExact; - SCROLLBARINFO sbi; - DWORD messagePos = GetMessagePos(); - pt.x = (short)LOWORD(messagePos); - pt.y = (short)HIWORD(messagePos); + ME_Cursor pos; + BOOL is_exact; + static HCURSOR cursor_arrow, cursor_hand, cursor_ibeam, cursor_reverse; + HCURSOR cursor;
- if (editor->hWnd) - { - sbi.cbSize = sizeof(sbi); - GetScrollBarInfo(editor->hWnd, OBJID_HSCROLL, &sbi); - if (!(sbi.rgstate[0] & (STATE_SYSTEM_INVISIBLE|STATE_SYSTEM_OFFSCREEN)) && - PtInRect(&sbi.rcScrollBar, pt)) + if (!cursor_arrow) { - ITextHost_TxSetCursor(editor->texthost, - LoadCursorW(NULL, (WCHAR*)IDC_ARROW), FALSE); - return TRUE; + cursor_arrow = LoadCursorW( NULL, MAKEINTRESOURCEW( IDC_ARROW ) ); + cursor_hand = LoadCursorW( NULL, MAKEINTRESOURCEW( IDC_HAND ) ); + cursor_ibeam = LoadCursorW( NULL, MAKEINTRESOURCEW( IDC_IBEAM ) ); + cursor_reverse = LoadCursorW( dll_instance, MAKEINTRESOURCEW( OCR_REVERSE ) ); } - sbi.cbSize = sizeof(sbi); - GetScrollBarInfo(editor->hWnd, OBJID_VSCROLL, &sbi); - if (!(sbi.rgstate[0] & (STATE_SYSTEM_INVISIBLE|STATE_SYSTEM_OFFSCREEN)) && - PtInRect(&sbi.rcScrollBar, pt)) + + cursor = cursor_ibeam; + + if ((editor->nSelectionType == stLine && editor->bMouseCaptured) || + (!editor->bEmulateVersion10 && y < editor->rcFormat.top && x < editor->rcFormat.left)) + cursor = cursor_reverse; + else if (y < editor->rcFormat.top || y > editor->rcFormat.bottom) { - ITextHost_TxSetCursor(editor->texthost, - LoadCursorW(NULL, (WCHAR*)IDC_ARROW), FALSE); - return TRUE; + if (editor->bEmulateVersion10) cursor = cursor_arrow; + else cursor = cursor_ibeam; } - } - ITextHost_TxScreenToClient(editor->texthost, &pt); + else if (x < editor->rcFormat.left) cursor = cursor_reverse; + else + { + ME_CharFromPos( editor, x, y, &pos, &is_exact ); + if (is_exact) + { + ME_Run *run = pos.run;
- if (editor->nSelectionType == stLine && editor->bMouseCaptured) { - ITextHost_TxSetCursor(editor->texthost, hLeft, FALSE); - return TRUE; - } - if (!editor->bEmulateVersion10 /* v4.1 */ && - pt.y < editor->rcFormat.top && - pt.x < editor->rcFormat.left) - { - ITextHost_TxSetCursor(editor->texthost, hLeft, FALSE); - return TRUE; - } - if (pt.y < editor->rcFormat.top || pt.y > editor->rcFormat.bottom) - { - if (editor->bEmulateVersion10) /* v1.0 - 3.0 */ - ITextHost_TxSetCursor(editor->texthost, - LoadCursorW(NULL, (WCHAR*)IDC_ARROW), FALSE); - else /* v4.1 */ - ITextHost_TxSetCursor(editor->texthost, - LoadCursorW(NULL, (WCHAR*)IDC_IBEAM), TRUE); - return TRUE; - } - if (pt.x < editor->rcFormat.left) - { - ITextHost_TxSetCursor(editor->texthost, hLeft, FALSE); - return TRUE; - } - ME_CharFromPos(editor, pt.x, pt.y, &cursor, &isExact); - if (isExact) - { - ME_Run *run; + if (is_link( run )) cursor = cursor_hand;
- run = &cursor.pRun->member.run; - if (is_link( run )) - { - ITextHost_TxSetCursor(editor->texthost, - LoadCursorW(NULL, (WCHAR*)IDC_HAND), - FALSE); - return TRUE; - } + else if (ME_IsSelection( editor )) + { + int start, end, offset = ME_GetCursorOfs( &pos );
- if (ME_IsSelection(editor)) - { - int selStart, selEnd; - int offset = ME_GetCursorOfs(&cursor); - - ME_GetSelectionOfs(editor, &selStart, &selEnd); - if (selStart <= offset && selEnd >= offset) { - ITextHost_TxSetCursor(editor->texthost, - LoadCursorW(NULL, (WCHAR*)IDC_ARROW), - FALSE); - return TRUE; - } - } - } - ITextHost_TxSetCursor(editor->texthost, - LoadCursorW(NULL, (WCHAR*)IDC_IBEAM), TRUE); - return TRUE; -} + ME_GetSelectionOfs( editor, &start, &end ); + if (start <= offset && end >= offset) cursor = cursor_arrow; + } + } + }
-static void ME_SetDefaultFormatRect(ME_TextEditor *editor) -{ - ITextHost_TxGetClientRect(editor->texthost, &editor->rcFormat); - editor->rcFormat.top += editor->exStyleFlags & WS_EX_CLIENTEDGE ? 1 : 0; - editor->rcFormat.left += 1 + editor->selofs; - editor->rcFormat.right -= 1; + ITextHost_TxSetCursor( editor->texthost, cursor, cursor == cursor_ibeam ); }
static LONG ME_GetSelectionType(ME_TextEditor *editor) @@ -3011,11 +2886,9 @@ static LONG ME_GetSelectionType(ME_TextEditor *editor) { ME_Cursor cursor;
- ME_CursorFromCharOfs(editor, start + i, &cursor); - if (cursor.pRun->member.run.reobj) - object_count++; - else - character_count++; + cursor_from_char_ofs( editor, start + i, &cursor ); + if (cursor.run->reobj) object_count++; + else character_count++; if (character_count >= 2 && object_count >= 2) return (SEL_TEXT | SEL_MULTICHAR | SEL_OBJECT | SEL_MULTIOBJECT); } @@ -3037,49 +2910,54 @@ static LONG ME_GetSelectionType(ME_TextEditor *editor)
static BOOL ME_ShowContextMenu(ME_TextEditor *editor, int x, int y) { - CHARRANGE selrange; - HMENU menu; - int seltype; - - if(!editor->lpOleCallback || !editor->hWnd) - return FALSE; - ME_GetSelectionOfs(editor, &selrange.cpMin, &selrange.cpMax); - seltype = ME_GetSelectionType(editor); - if(SUCCEEDED(IRichEditOleCallback_GetContextMenu(editor->lpOleCallback, seltype, NULL, &selrange, &menu))) - { - TrackPopupMenu(menu, TPM_LEFTALIGN | TPM_RIGHTBUTTON, x, y, 0, editor->hwndParent, NULL); - DestroyMenu(menu); - } - return TRUE; + CHARRANGE selrange; + HMENU menu; + int seltype; + HWND hwnd, parent; + + if (!editor->lpOleCallback || !editor->have_texthost2) return FALSE; + if (FAILED( ITextHost2_TxGetWindow( editor->texthost, &hwnd ))) return FALSE; + parent = GetParent( hwnd ); + if (!parent) parent = hwnd; + + ME_GetSelectionOfs( editor, &selrange.cpMin, &selrange.cpMax ); + seltype = ME_GetSelectionType( editor ); + if (SUCCEEDED( IRichEditOleCallback_GetContextMenu( editor->lpOleCallback, seltype, NULL, &selrange, &menu ) )) + { + TrackPopupMenu( menu, TPM_LEFTALIGN | TPM_RIGHTBUTTON, x, y, 0, parent, NULL ); + DestroyMenu( menu ); + } + return TRUE; }
ME_TextEditor *ME_MakeEditor(ITextHost *texthost, BOOL bEmulateVersion10) { ME_TextEditor *ed = heap_alloc(sizeof(*ed)); int i; - DWORD props; LONG selbarwidth; + HRESULT hr;
- ed->hWnd = NULL; - ed->hwndParent = NULL; ed->sizeWindow.cx = ed->sizeWindow.cy = 0; - ed->texthost = texthost; - ed->reOle = NULL; + if (ITextHost_QueryInterface( texthost, &IID_ITextHost2, (void **)&ed->texthost ) == S_OK) + { + ITextHost_Release( texthost ); + ed->have_texthost2 = TRUE; + } + else + { + ed->texthost = (ITextHost2 *)texthost; + ed->have_texthost2 = FALSE; + } + ed->bEmulateVersion10 = bEmulateVersion10; - ed->styleFlags = 0; - ed->exStyleFlags = 0; - ed->first_marked_para = NULL; + ed->in_place_active = FALSE; ed->total_rows = 0; - ITextHost_TxGetPropertyBits(texthost, - (TXTBIT_RICHTEXT|TXTBIT_MULTILINE| - TXTBIT_READONLY|TXTBIT_USEPASSWORD| - TXTBIT_HIDESELECTION|TXTBIT_SAVESELECTION| - TXTBIT_AUTOWORDSEL|TXTBIT_VERTICAL| - TXTBIT_WORDWRAP|TXTBIT_DISABLEDRAG), - &props); - ITextHost_TxGetScrollBars(texthost, &ed->styleFlags); - ed->styleFlags &= (WS_VSCROLL|WS_HSCROLL|ES_AUTOVSCROLL| - ES_AUTOHSCROLL|ES_DISABLENOSCROLL); + ITextHost_TxGetPropertyBits( ed->texthost, TXTBIT_RICHTEXT | TXTBIT_MULTILINE | TXTBIT_READONLY | + TXTBIT_USEPASSWORD | TXTBIT_HIDESELECTION | TXTBIT_SAVESELECTION | + TXTBIT_AUTOWORDSEL | TXTBIT_VERTICAL | TXTBIT_WORDWRAP | TXTBIT_ALLOWBEEP | + TXTBIT_DISABLEDRAG, + &ed->props ); + ITextHost_TxGetScrollBars( ed->texthost, &ed->scrollbars ); ed->pBuffer = ME_MakeText(); ed->nZoomNumerator = ed->nZoomDenominator = 0; ed->nAvailWidth = 0; /* wrap to client area */ @@ -3100,9 +2978,6 @@ ME_TextEditor *ME_MakeEditor(ITextHost *texthost, BOOL bEmulateVersion10) ed->nLastTotalLength = ed->nTotalLength = 0; ed->nLastTotalWidth = ed->nTotalWidth = 0; ed->nUDArrowX = -1; - ed->rgbBackColor = -1; - ed->hbrBackground = GetSysColorBrush(COLOR_WINDOW); - ed->bCaretAtEnd = FALSE; ed->nEventMask = 0; ed->nModifyStep = 0; ed->nTextLimit = TEXT_LIMIT_DEFAULT; @@ -3113,15 +2988,15 @@ ME_TextEditor *ME_MakeEditor(ITextHost *texthost, BOOL bEmulateVersion10) ed->nUndoMode = umAddToUndo; ed->nParagraphs = 1; ed->nLastSelStart = ed->nLastSelEnd = 0; - ed->pLastSelStartPara = ed->pLastSelEndPara = ed->pCursors[0].pPara; + ed->last_sel_start_para = ed->last_sel_end_para = ed->pCursors[0].para; ed->bHideSelection = FALSE; ed->pfnWordBreak = NULL; + ed->richole = NULL; ed->lpOleCallback = NULL; ed->mode = TM_MULTILEVELUNDO | TM_MULTICODEPAGE; - ed->mode |= (props & TXTBIT_RICHTEXT) ? TM_RICHTEXT : TM_PLAINTEXT; + ed->mode |= (ed->props & TXTBIT_RICHTEXT) ? TM_RICHTEXT : TM_PLAINTEXT; ed->AutoURLDetect_bEnable = FALSE; ed->bHaveFocus = FALSE; - ed->bDialogMode = FALSE; ed->bMouseCaptured = FALSE; ed->caret_hidden = FALSE; ed->caret_height = 0; @@ -3134,39 +3009,17 @@ ME_TextEditor *ME_MakeEditor(ITextHost *texthost, BOOL bEmulateVersion10)
ME_CheckCharOffsets(ed); SetRectEmpty(&ed->rcFormat); - ed->bDefaultFormatRect = TRUE; - ITextHost_TxGetSelectionBarWidth(ed->texthost, &selbarwidth); - if (selbarwidth) { - /* FIXME: Convert selbarwidth from HIMETRIC to pixels */ - ed->selofs = SELECTIONBAR_WIDTH; - ed->styleFlags |= ES_SELECTIONBAR; - } else { - ed->selofs = 0; - } + hr = ITextHost_TxGetSelectionBarWidth( ed->texthost, &selbarwidth ); + /* FIXME: Convert selbarwidth from HIMETRIC to pixels */ + if (hr == S_OK && selbarwidth) ed->selofs = SELECTIONBAR_WIDTH; + else ed->selofs = 0; ed->nSelectionType = stPosition;
- ed->cPasswordMask = 0; - if (props & TXTBIT_USEPASSWORD) - ITextHost_TxGetPasswordChar(texthost, &ed->cPasswordMask); - - if (props & TXTBIT_AUTOWORDSEL) - ed->styleFlags |= ECO_AUTOWORDSELECTION; - if (props & TXTBIT_MULTILINE) { - ed->styleFlags |= ES_MULTILINE; - ed->bWordWrap = (props & TXTBIT_WORDWRAP) != 0; - } else { - ed->bWordWrap = FALSE; - } - if (props & TXTBIT_READONLY) - ed->styleFlags |= ES_READONLY; - if (!(props & TXTBIT_HIDESELECTION)) - ed->styleFlags |= ES_NOHIDESEL; - if (props & TXTBIT_SAVESELECTION) - ed->styleFlags |= ES_SAVESEL; - if (props & TXTBIT_VERTICAL) - ed->styleFlags |= ES_VERTICAL; - if (props & TXTBIT_DISABLEDRAG) - ed->styleFlags |= ES_NOOLEDRAGDROP; + ed->password_char = 0; + if (ed->props & TXTBIT_USEPASSWORD) + ITextHost_TxGetPasswordChar( ed->texthost, &ed->password_char ); + + ed->bWordWrap = (ed->props & TXTBIT_WORDWRAP) && (ed->props & TXTBIT_MULTILINE);
ed->notified_cr.cpMin = ed->notified_cr.cpMax = 0;
@@ -3176,15 +3029,34 @@ ME_TextEditor *ME_MakeEditor(ITextHost *texthost, BOOL bEmulateVersion10) ed->vert_si.nMax = 0; ed->vert_si.nPage = 0; ed->vert_si.nPos = 0; + ed->vert_sb_enabled = 0;
ed->horz_si.cbSize = sizeof(SCROLLINFO); ed->horz_si.nMin = 0; ed->horz_si.nMax = 0; ed->horz_si.nPage = 0; ed->horz_si.nPos = 0; + ed->horz_sb_enabled = 0; + + if (ed->scrollbars & ES_DISABLENOSCROLL) + { + if (ed->scrollbars & WS_VSCROLL) + { + ITextHost_TxSetScrollRange( ed->texthost, SB_VERT, 0, 1, TRUE ); + ITextHost_TxEnableScrollBar( ed->texthost, SB_VERT, ESB_DISABLE_BOTH ); + } + if (ed->scrollbars & WS_HSCROLL) + { + ITextHost_TxSetScrollRange( ed->texthost, SB_HORZ, 0, 1, TRUE ); + ITextHost_TxEnableScrollBar( ed->texthost, SB_HORZ, ESB_DISABLE_BOTH ); + } + }
ed->wheel_remain = 0;
+ ed->back_style = TXTBACK_OPAQUE; + ITextHost_TxGetBackStyle( ed->texthost, &ed->back_style ); + list_init( &ed->reobj_list ); OleInitialize(NULL);
@@ -3200,10 +3072,11 @@ void ME_DestroyEditor(ME_TextEditor *editor) ME_ClearTempStyle(editor); ME_EmptyUndoStack(editor); editor->pBuffer->pFirst = NULL; - while(p) { + while(p) + { pNext = p->next; if (p->type == diParagraph) - destroy_para(editor, p); + para_destroy( editor, &p->member.para ); else ME_DestroyDisplayItem(p); p = pNext; @@ -3218,16 +3091,9 @@ void ME_DestroyEditor(ME_TextEditor *editor) if (editor->pFontCache[i].hFont) DeleteObject(editor->pFontCache[i].hFont); } - if (editor->rgbBackColor != -1) - DeleteObject(editor->hbrBackground); if(editor->lpOleCallback) IRichEditOleCallback_Release(editor->lpOleCallback); - ITextHost_Release(editor->texthost); - if (editor->reOle) - { - IUnknown_Release(editor->reOle); - editor->reOle = NULL; - } + OleUninitialize();
heap_free(editor->pBuffer); @@ -3235,37 +3101,6 @@ void ME_DestroyEditor(ME_TextEditor *editor) heap_free(editor); }
-BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) -{ - TRACE("\n"); - switch (fdwReason) - { - case DLL_PROCESS_ATTACH: - DisableThreadLibraryCalls(hinstDLL); - me_heap = HeapCreate (0, 0x10000, 0); - if (!ME_RegisterEditorClass(hinstDLL)) return FALSE; - hLeft = LoadCursorW(hinstDLL, MAKEINTRESOURCEW(OCR_REVERSE)); - LookupInit(); - break; - - case DLL_PROCESS_DETACH: - if (lpvReserved) break; - UnregisterClassW(RICHEDIT_CLASS20W, 0); - UnregisterClassW(MSFTEDIT_CLASS, 0); - UnregisterClassA(RICHEDIT_CLASS20A, 0); - UnregisterClassA("RichEdit50A", 0); - if (ME_ListBoxRegistered) - UnregisterClassW(REListBox20W, 0); - if (ME_ComboBoxRegistered) - UnregisterClassW(REComboBox20W, 0); - LookupCleanup(); - HeapDestroy (me_heap); - release_typelib(); - break; - } - return TRUE; -} - static inline int get_default_line_height( ME_TextEditor *editor ) { int height = 0; @@ -3284,158 +3119,21 @@ static inline int calc_wheel_change( int *remain, int amount_per_click ) return change; }
-static const char * const edit_messages[] = { - "EM_GETSEL", - "EM_SETSEL", - "EM_GETRECT", - "EM_SETRECT", - "EM_SETRECTNP", - "EM_SCROLL", - "EM_LINESCROLL", - "EM_SCROLLCARET", - "EM_GETMODIFY", - "EM_SETMODIFY", - "EM_GETLINECOUNT", - "EM_LINEINDEX", - "EM_SETHANDLE", - "EM_GETHANDLE", - "EM_GETTHUMB", - "EM_UNKNOWN_BF", - "EM_UNKNOWN_C0", - "EM_LINELENGTH", - "EM_REPLACESEL", - "EM_UNKNOWN_C3", - "EM_GETLINE", - "EM_LIMITTEXT", - "EM_CANUNDO", - "EM_UNDO", - "EM_FMTLINES", - "EM_LINEFROMCHAR", - "EM_UNKNOWN_CA", - "EM_SETTABSTOPS", - "EM_SETPASSWORDCHAR", - "EM_EMPTYUNDOBUFFER", - "EM_GETFIRSTVISIBLELINE", - "EM_SETREADONLY", - "EM_SETWORDBREAKPROC", - "EM_GETWORDBREAKPROC", - "EM_GETPASSWORDCHAR", - "EM_SETMARGINS", - "EM_GETMARGINS", - "EM_GETLIMITTEXT", - "EM_POSFROMCHAR", - "EM_CHARFROMPOS", - "EM_SETIMESTATUS", - "EM_GETIMESTATUS" -}; - -static const char * const richedit_messages[] = { - "EM_CANPASTE", - "EM_DISPLAYBAND", - "EM_EXGETSEL", - "EM_EXLIMITTEXT", - "EM_EXLINEFROMCHAR", - "EM_EXSETSEL", - "EM_FINDTEXT", - "EM_FORMATRANGE", - "EM_GETCHARFORMAT", - "EM_GETEVENTMASK", - "EM_GETOLEINTERFACE", - "EM_GETPARAFORMAT", - "EM_GETSELTEXT", - "EM_HIDESELECTION", - "EM_PASTESPECIAL", - "EM_REQUESTRESIZE", - "EM_SELECTIONTYPE", - "EM_SETBKGNDCOLOR", - "EM_SETCHARFORMAT", - "EM_SETEVENTMASK", - "EM_SETOLECALLBACK", - "EM_SETPARAFORMAT", - "EM_SETTARGETDEVICE", - "EM_STREAMIN", - "EM_STREAMOUT", - "EM_GETTEXTRANGE", - "EM_FINDWORDBREAK", - "EM_SETOPTIONS", - "EM_GETOPTIONS", - "EM_FINDTEXTEX", - "EM_GETWORDBREAKPROCEX", - "EM_SETWORDBREAKPROCEX", - "EM_SETUNDOLIMIT", - "EM_UNKNOWN_USER_83", - "EM_REDO", - "EM_CANREDO", - "EM_GETUNDONAME", - "EM_GETREDONAME", - "EM_STOPGROUPTYPING", - "EM_SETTEXTMODE", - "EM_GETTEXTMODE", - "EM_AUTOURLDETECT", - "EM_GETAUTOURLDETECT", - "EM_SETPALETTE", - "EM_GETTEXTEX", - "EM_GETTEXTLENGTHEX", - "EM_SHOWSCROLLBAR", - "EM_SETTEXTEX", - "EM_UNKNOWN_USER_98", - "EM_UNKNOWN_USER_99", - "EM_SETPUNCTUATION", - "EM_GETPUNCTUATION", - "EM_SETWORDWRAPMODE", - "EM_GETWORDWRAPMODE", - "EM_SETIMECOLOR", - "EM_GETIMECOLOR", - "EM_SETIMEOPTIONS", - "EM_GETIMEOPTIONS", - "EM_CONVPOSITION", - "EM_UNKNOWN_USER_109", - "EM_UNKNOWN_USER_110", - "EM_UNKNOWN_USER_111", - "EM_UNKNOWN_USER_112", - "EM_UNKNOWN_USER_113", - "EM_UNKNOWN_USER_114", - "EM_UNKNOWN_USER_115", - "EM_UNKNOWN_USER_116", - "EM_UNKNOWN_USER_117", - "EM_UNKNOWN_USER_118", - "EM_UNKNOWN_USER_119", - "EM_SETLANGOPTIONS", - "EM_GETLANGOPTIONS", - "EM_GETIMECOMPMODE", - "EM_FINDTEXTW", - "EM_FINDTEXTEXW", - "EM_RECONVERSION", - "EM_SETIMEMODEBIAS", - "EM_GETIMEMODEBIAS" -}; - -static const char * -get_msg_name(UINT msg) -{ - if (msg >= EM_GETSEL && msg <= EM_CHARFROMPOS) - return edit_messages[msg - EM_GETSEL]; - if (msg >= EM_CANPASTE && msg <= EM_GETIMEMODEBIAS) - return richedit_messages[msg - EM_CANPASTE]; - return ""; -} - -static void ME_LinkNotify(ME_TextEditor *editor, UINT msg, WPARAM wParam, LPARAM lParam) +void link_notify(ME_TextEditor *editor, UINT msg, WPARAM wParam, LPARAM lParam) { int x,y; BOOL isExact; ME_Cursor cursor; /* The start of the clicked text. */ - + ME_Run *run; ENLINK info; + x = (short)LOWORD(lParam); y = (short)HIWORD(lParam); ME_CharFromPos(editor, x, y, &cursor, &isExact); if (!isExact) return;
- if (is_link( &cursor.pRun->member.run )) + if (is_link( cursor.run )) { /* The clicked run has CFE_LINK set */ - ME_DisplayItem *di; - info.nmhdr.hwndFrom = NULL; info.nmhdr.idFrom = 0; info.nmhdr.code = EN_LINK; @@ -3446,15 +3144,15 @@ static void ME_LinkNotify(ME_TextEditor *editor, UINT msg, WPARAM wParam, LPARAM
/* find the first contiguous run with CFE_LINK set */ info.chrg.cpMin = ME_GetCursorOfs(&cursor); - di = cursor.pRun; - while (ME_PrevRun( NULL, &di, FALSE ) && is_link( &di->member.run )) - info.chrg.cpMin -= di->member.run.len; + run = cursor.run; + while ((run = run_prev( run )) && is_link( run )) + info.chrg.cpMin -= run->len;
/* find the last contiguous run with CFE_LINK set */ - info.chrg.cpMax = ME_GetCursorOfs(&cursor) + cursor.pRun->member.run.len; - di = cursor.pRun; - while (ME_NextRun( NULL, &di, FALSE ) && is_link( &di->member.run )) - info.chrg.cpMax += di->member.run.len; + info.chrg.cpMax = ME_GetCursorOfs(&cursor) + cursor.run->len; + run = cursor.run; + while ((run = run_next( run )) && is_link( run )) + info.chrg.cpMax += run->len;
ITextHost_TxNotify(editor->texthost, info.nmhdr.code, &info); } @@ -3494,52 +3192,6 @@ static void ME_SetText(ME_TextEditor *editor, void *text, BOOL unicode) ME_EndToUnicode(codepage, wszText); }
-static LRESULT ME_WmCreate(ME_TextEditor *editor, LPARAM lParam, BOOL unicode) -{ - CREATESTRUCTW *createW = (CREATESTRUCTW*)lParam; - CREATESTRUCTA *createA = (CREATESTRUCTA*)lParam; - void *text = NULL; - INT max; - - if (lParam) - text = unicode ? (void*)createW->lpszName : (void*)createA->lpszName; - - ME_SetDefaultFormatRect(editor); - - max = (editor->styleFlags & ES_DISABLENOSCROLL) ? 1 : 0; - if (~editor->styleFlags & ES_DISABLENOSCROLL || editor->styleFlags & WS_VSCROLL) - ITextHost_TxSetScrollRange(editor->texthost, SB_VERT, 0, max, TRUE); - - if (~editor->styleFlags & ES_DISABLENOSCROLL || editor->styleFlags & WS_HSCROLL) - ITextHost_TxSetScrollRange(editor->texthost, SB_HORZ, 0, max, TRUE); - - if (editor->styleFlags & ES_DISABLENOSCROLL) - { - if (editor->styleFlags & WS_VSCROLL) - { - ITextHost_TxEnableScrollBar(editor->texthost, SB_VERT, ESB_DISABLE_BOTH); - ITextHost_TxShowScrollBar(editor->texthost, SB_VERT, TRUE); - } - if (editor->styleFlags & WS_HSCROLL) - { - ITextHost_TxEnableScrollBar(editor->texthost, SB_HORZ, ESB_DISABLE_BOTH); - ITextHost_TxShowScrollBar(editor->texthost, SB_HORZ, TRUE); - } - } - - if (text) - { - ME_SetText(editor, text, unicode); - ME_SetCursorToStart(editor, &editor->pCursors[0]); - ME_SetCursorToStart(editor, &editor->pCursors[1]); - } - - ME_CommitUndo(editor); - ME_WrapMarkedParagraphs(editor); - update_caret(editor); - return 0; -} - static LRESULT handle_EM_SETCHARFORMAT( ME_TextEditor *editor, WPARAM flags, const CHARFORMAT2W *fmt_in ) { CHARFORMAT2W fmt; @@ -3601,8 +3253,8 @@ static LRESULT handle_EM_SETCHARFORMAT( ME_TextEditor *editor, WPARAM flags, con * The LRESULT that is returned is a return value for window procs, * and the phresult parameter is the COM return code needed by the * text services interface. */ -LRESULT ME_HandleMessage(ME_TextEditor *editor, UINT msg, WPARAM wParam, - LPARAM lParam, BOOL unicode, HRESULT* phresult) +LRESULT editor_handle_message( ME_TextEditor *editor, UINT msg, WPARAM wParam, + LPARAM lParam, HRESULT* phresult ) { *phresult = S_OK;
@@ -3637,18 +3289,6 @@ LRESULT ME_HandleMessage(ME_TextEditor *editor, UINT msg, WPARAM wParam, return ME_StreamIn(editor, wParam, (EDITSTREAM*)lParam, TRUE); case EM_STREAMOUT: return ME_StreamOut(editor, wParam, (EDITSTREAM *)lParam); - case WM_GETDLGCODE: - { - UINT code = DLGC_WANTCHARS|DLGC_WANTTAB|DLGC_WANTARROWS; - - if (lParam) - editor->bDialogMode = TRUE; - if (editor->styleFlags & ES_MULTILINE) - code |= DLGC_WANTMESSAGE; - if (!(editor->styleFlags & ES_SAVESEL)) - code |= DLGC_HASSETSEL; - return code; - } case EM_EMPTYUNDOBUFFER: ME_EmptyUndoStack(editor); return 0; @@ -3690,16 +3330,7 @@ LRESULT ME_HandleMessage(ME_TextEditor *editor, UINT msg, WPARAM wParam, return ME_Undo(editor); case EM_REDO: return ME_Redo(editor); - case EM_GETOPTIONS: - { - /* these flags are equivalent to the ES_* counterparts */ - DWORD mask = ECO_VERTICAL | ECO_AUTOHSCROLL | ECO_AUTOVSCROLL | - ECO_NOHIDESEL | ECO_READONLY | ECO_WANTRETURN | ECO_SELECTIONBAR; - DWORD settings = editor->styleFlags & mask; - - return settings; - } - case EM_SETFONTSIZE: + case EM_SETFONTSIZE: { CHARFORMAT2W cf; LONG tmp_size, size; @@ -3740,68 +3371,6 @@ LRESULT ME_HandleMessage(ME_TextEditor *editor, UINT msg, WPARAM wParam,
return TRUE; } - case EM_SETOPTIONS: - { - /* these flags are equivalent to ES_* counterparts, except for - * ECO_AUTOWORDSELECTION that doesn't have an ES_* counterpart, - * but is still stored in editor->styleFlags. */ - const DWORD mask = ECO_VERTICAL | ECO_AUTOHSCROLL | ECO_AUTOVSCROLL | - ECO_NOHIDESEL | ECO_READONLY | ECO_WANTRETURN | - ECO_SELECTIONBAR | ECO_AUTOWORDSELECTION; - DWORD settings = mask & editor->styleFlags; - DWORD oldSettings = settings; - DWORD changedSettings; - - switch(wParam) - { - case ECOOP_SET: - settings = lParam; - break; - case ECOOP_OR: - settings |= lParam; - break; - case ECOOP_AND: - settings &= lParam; - break; - case ECOOP_XOR: - settings ^= lParam; - } - changedSettings = oldSettings ^ settings; - - if (changedSettings) { - editor->styleFlags = (editor->styleFlags & ~mask) | (settings & mask); - - if (changedSettings & ECO_SELECTIONBAR) - { - ITextHost_TxInvalidateRect(editor->texthost, &editor->rcFormat, TRUE); - if (settings & ECO_SELECTIONBAR) { - assert(!editor->selofs); - editor->selofs = SELECTIONBAR_WIDTH; - editor->rcFormat.left += editor->selofs; - } else { - editor->rcFormat.left -= editor->selofs; - editor->selofs = 0; - } - ME_RewrapRepaint(editor); - } - - if ((changedSettings & settings & ES_NOHIDESEL) && !editor->bHaveFocus) - ME_InvalidateSelection( editor ); - - if (changedSettings & settings & ECO_VERTICAL) - FIXME("ECO_VERTICAL not implemented yet!\n"); - if (changedSettings & settings & ECO_AUTOHSCROLL) - FIXME("ECO_AUTOHSCROLL not implemented yet!\n"); - if (changedSettings & settings & ECO_AUTOVSCROLL) - FIXME("ECO_AUTOVSCROLL not implemented yet!\n"); - if (changedSettings & settings & ECO_WANTRETURN) - FIXME("ECO_WANTRETURN not implemented yet!\n"); - if (changedSettings & settings & ECO_AUTOWORDSELECTION) - FIXME("ECO_AUTOWORDSELECTION not implemented yet!\n"); - } - - return settings; - } case EM_SETSEL: { return set_selection( editor, wParam, lParam ); @@ -3809,7 +3378,7 @@ LRESULT ME_HandleMessage(ME_TextEditor *editor, UINT msg, WPARAM wParam, case EM_SETSCROLLPOS: { POINT *point = (POINT *)lParam; - ME_ScrollAbs(editor, point->x, point->y); + scroll_abs( editor, point->x, point->y, TRUE ); return 0; } case EM_AUTOURLDETECT: @@ -3831,39 +3400,6 @@ LRESULT ME_HandleMessage(ME_TextEditor *editor, UINT msg, WPARAM wParam,
return set_selection( editor, range.cpMin, range.cpMax ); } - case EM_SHOWSCROLLBAR: - { - DWORD flags; - - switch (wParam) - { - case SB_HORZ: - flags = WS_HSCROLL; - break; - case SB_VERT: - flags = WS_VSCROLL; - break; - case SB_BOTH: - flags = WS_HSCROLL|WS_VSCROLL; - break; - default: - return 0; - } - - if (lParam) { - editor->styleFlags |= flags; - if (flags & WS_HSCROLL) - ITextHost_TxShowScrollBar(editor->texthost, SB_HORZ, - editor->nTotalWidth > editor->sizeWindow.cx); - if (flags & WS_VSCROLL) - ITextHost_TxShowScrollBar(editor->texthost, SB_VERT, - editor->nTotalLength > editor->sizeWindow.cy); - } else { - editor->styleFlags &= ~flags; - ITextHost_TxShowScrollBar(editor->texthost, wParam, FALSE); - } - return 0; - } case EM_SETTEXTEX: { LPWSTR wszText; @@ -3938,28 +3474,6 @@ LRESULT ME_HandleMessage(ME_TextEditor *editor, UINT msg, WPARAM wParam, } case EM_SELECTIONTYPE: return ME_GetSelectionType(editor); - case EM_SETBKGNDCOLOR: - { - LRESULT lColor; - if (editor->rgbBackColor != -1) { - DeleteObject(editor->hbrBackground); - lColor = editor->rgbBackColor; - } - else lColor = ITextHost_TxGetSysColor(editor->texthost, COLOR_WINDOW); - - if (wParam) - { - editor->rgbBackColor = -1; - editor->hbrBackground = GetSysColorBrush(COLOR_WINDOW); - } - else - { - editor->rgbBackColor = lParam; - editor->hbrBackground = CreateSolidBrush(editor->rgbBackColor); - } - ITextHost_TxInvalidateRect(editor->texthost, NULL, TRUE); - return lColor; - } case EM_GETMODIFY: return editor->nModifyStep == 0 ? 0 : -1; case EM_SETMODIFY: @@ -3971,14 +3485,6 @@ LRESULT ME_HandleMessage(ME_TextEditor *editor, UINT msg, WPARAM wParam,
return 0; } - case EM_SETREADONLY: - { - if (wParam) - editor->styleFlags |= ES_READONLY; - else - editor->styleFlags &= ~ES_READONLY; - return 1; - } case EM_SETEVENTMASK: { DWORD nOldMask = editor->nEventMask; @@ -4008,36 +3514,35 @@ LRESULT ME_HandleMessage(ME_TextEditor *editor, UINT msg, WPARAM wParam, } case EM_SETPARAFORMAT: { - BOOL result = ME_SetSelectionParaFormat(editor, (PARAFORMAT2 *)lParam); + BOOL result = editor_set_selection_para_fmt( editor, (PARAFORMAT2 *)lParam ); ME_WrapMarkedParagraphs(editor); ME_UpdateScrollBar(editor); ME_CommitUndo(editor); return result; } case EM_GETPARAFORMAT: - ME_GetSelectionParaFormat(editor, (PARAFORMAT2 *)lParam); + editor_get_selection_para_fmt( editor, (PARAFORMAT2 *)lParam ); return ((PARAFORMAT2 *)lParam)->dwMask; case EM_GETFIRSTVISIBLELINE: { - ME_DisplayItem *p = editor->pBuffer->pFirst; + ME_Paragraph *para = editor_first_para( editor ); + ME_Row *row; int y = editor->vert_si.nPos; - int ypara = 0; int count = 0; - int ystart, yend; - while(p) { - p = ME_FindItemFwd(p, diStartRowOrParagraphOrEnd); - if (p->type == diTextEnd) - break; - if (p->type == diParagraph) { - ypara = p->member.para.pt.y; - continue; - } - ystart = ypara + p->member.row.pt.y; - yend = ystart + p->member.row.nHeight; - if (y < yend) { - break; - } + + while (para_next( para )) + { + if (y < para->pt.y + para->nHeight) break; + count += para->nRows; + para = para_next( para ); + } + + row = para_first_row( para ); + while (row) + { + if (y < para->pt.y + row->pt.y + row->nHeight) break; count++; + row = row_next( row ); } return count; } @@ -4049,7 +3554,7 @@ LRESULT ME_HandleMessage(ME_TextEditor *editor, UINT msg, WPARAM wParam, } case EM_LINESCROLL: { - if (!(editor->styleFlags & ES_MULTILINE)) + if (!(editor->props & TXTBIT_MULTILINE)) return FALSE; ME_ScrollDown( editor, lParam * get_default_line_height( editor ) ); return TRUE; @@ -4065,18 +3570,15 @@ LRESULT ME_HandleMessage(ME_TextEditor *editor, UINT msg, WPARAM wParam, } case EM_REPLACESEL: { - int len = 0; - LONG codepage = unicode ? CP_UNICODE : CP_ACP; - LPWSTR wszText = ME_ToUnicode(codepage, (void *)lParam, &len); + WCHAR *text = (WCHAR *)lParam; + int len = text ? lstrlenW( text ) : 0;
- TRACE("EM_REPLACESEL - %s\n", debugstr_w(wszText)); - - ME_ReplaceSel(editor, !!wParam, wszText, len); - ME_EndToUnicode(codepage, wszText); + TRACE( "EM_REPLACESEL - %s\n", debugstr_w( text ) ); + ME_ReplaceSel( editor, !!wParam, text, len ); return len; } case EM_SCROLLCARET: - ME_EnsureVisible(editor, &editor->pCursors[0]); + editor_ensure_visible( editor, &editor->pCursors[0] ); return 0; case WM_SETFONT: { @@ -4102,7 +3604,7 @@ LRESULT ME_HandleMessage(ME_TextEditor *editor, UINT msg, WPARAM wParam, ME_SetDefaultCharFormat(editor, &fmt);
ME_CommitUndo(editor); - ME_MarkAllForWrapping(editor); + editor_mark_rewrap_all( editor ); ME_WrapMarkedParagraphs(editor); ME_UpdateScrollBar(editor); if (bRepaint) @@ -4132,7 +3634,7 @@ LRESULT ME_HandleMessage(ME_TextEditor *editor, UINT msg, WPARAM wParam, ME_StreamInRTFString(editor, 0, (char *)lParam); } else - ME_SetText(editor, (void*)lParam, unicode); + ME_SetText( editor, (void*)lParam, TRUE ); } else TRACE("WM_SETTEXT - NULL\n"); @@ -4162,10 +3664,8 @@ LRESULT ME_HandleMessage(ME_TextEditor *editor, UINT msg, WPARAM wParam, case WM_GETTEXTLENGTH: { 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 ? CP_UNICODE : CP_ACP; + how.codepage = CP_UNICODE; return ME_GetTextLengthEx(editor, &how); } case EM_GETTEXTLENGTHEX: @@ -4173,9 +3673,9 @@ LRESULT ME_HandleMessage(ME_TextEditor *editor, UINT msg, WPARAM wParam, case WM_GETTEXT: { GETTEXTEX ex; - ex.cb = wParam * (unicode ? sizeof(WCHAR) : sizeof(CHAR)); + ex.cb = wParam * sizeof(WCHAR); ex.flags = GT_USECRLF; - ex.codepage = unicode ? CP_UNICODE : CP_ACP; + ex.codepage = CP_UNICODE; ex.lpDefaultChar = NULL; ex.lpUsedDefChar = NULL; return ME_GetTextEx(editor, &ex, lParam); @@ -4186,8 +3686,7 @@ LRESULT ME_HandleMessage(ME_TextEditor *editor, UINT msg, WPARAM wParam, { int nFrom, nTo, nStartCur = ME_GetSelectionOfs(editor, &nFrom, &nTo); ME_Cursor *from = &editor->pCursors[nStartCur]; - return ME_GetTextRange(editor, (WCHAR *)lParam, from, - nTo - nFrom, unicode); + return get_text_range( editor, (WCHAR *)lParam, from, nTo - nFrom ); } case EM_GETSCROLLPOS: { @@ -4209,122 +3708,106 @@ LRESULT ME_HandleMessage(ME_TextEditor *editor, UINT msg, WPARAM wParam, int nEnd = rng->chrg.cpMax; int textlength = ME_GetTextLength(editor);
- TRACE("EM_GETTEXTRANGE min=%d max=%d unicode=%d textlength=%d\n", - rng->chrg.cpMin, rng->chrg.cpMax, unicode, textlength); + TRACE( "EM_GETTEXTRANGE min = %d max = %d textlength = %d\n", rng->chrg.cpMin, rng->chrg.cpMax, textlength ); if (nStart < 0) return 0; if ((nStart == 0 && nEnd == -1) || nEnd > textlength) nEnd = textlength; if (nStart >= nEnd) return 0;
- ME_CursorFromCharOfs(editor, nStart, &start); - return ME_GetTextRange(editor, rng->lpstrText, &start, nEnd - nStart, unicode); + cursor_from_char_ofs( editor, nStart, &start ); + return get_text_range( editor, rng->lpstrText, &start, nEnd - nStart ); } case EM_GETLINE: { - ME_DisplayItem *run; + ME_Row *row; + ME_Run *run; const unsigned int nMaxChars = *(WORD *) lParam; unsigned int nCharsLeft = nMaxChars; char *dest = (char *) lParam; - BOOL wroteNull = FALSE; + ME_Cursor start, end;
- TRACE("EM_GETLINE: row=%d, nMaxChars=%d (%s)\n", (int) wParam, nMaxChars, - unicode ? "Unicode" : "Ansi"); + TRACE( "EM_GETLINE: row=%d, nMaxChars=%d\n", (int)wParam, nMaxChars );
- run = ME_FindRowWithNumber(editor, wParam); - if (run == NULL) - return 0; + row = row_from_row_number( editor, wParam ); + if (row == NULL) return 0;
- while (nCharsLeft && (run = ME_FindItemFwd(run, diRunOrStartRow)) - && run->type == diRun) + row_first_cursor( row, &start ); + row_end_cursor( row, &end, TRUE ); + run = start.run; + while (nCharsLeft) { - WCHAR *str = get_text( &run->member.run, 0 ); + WCHAR *str; unsigned int nCopy; + int ofs = (run == start.run) ? start.nOffset : 0; + int len = (run == end.run) ? end.nOffset : run->len;
- nCopy = min(nCharsLeft, run->member.run.len); + str = get_text( run, ofs ); + nCopy = min( nCharsLeft, len );
- if (unicode) - memcpy(dest, str, nCopy * sizeof(WCHAR)); - else - nCopy = WideCharToMultiByte(CP_ACP, 0, str, nCopy, dest, - nCharsLeft, NULL, NULL); - dest += nCopy * (unicode ? sizeof(WCHAR) : 1); + memcpy(dest, str, nCopy * sizeof(WCHAR)); + dest += nCopy * sizeof(WCHAR); nCharsLeft -= nCopy; + if (run == end.run) break; + run = row_next_run( row, run ); }
/* append line termination, space allowing */ - if (nCharsLeft > 0) - { - if (unicode) - *((WCHAR *)dest) = '\0'; - else - *dest = '\0'; - nCharsLeft--; - wroteNull = TRUE; - } + if (nCharsLeft > 0) *((WCHAR *)dest) = '\0';
TRACE("EM_GETLINE: got %u characters\n", nMaxChars - nCharsLeft); - return nMaxChars - nCharsLeft - (wroteNull ? 1 : 0); + return nMaxChars - nCharsLeft; } case EM_GETLINECOUNT: { - ME_DisplayItem *item = editor->pBuffer->pLast; - int nRows = editor->total_rows; - ME_DisplayItem *prev_para = NULL, *last_para = NULL; - - last_para = ME_FindItemBack(item, diRun); - prev_para = ME_FindItemBack(last_para, 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.len == 1 && - *get_text( &prev_para->member.run, 0 ) == '\r') + int count = editor->total_rows; + ME_Run *prev_run, *last_run; + + last_run = para_end_run( para_prev( editor_end_para( editor ) ) ); + prev_run = run_prev_all_paras( last_run ); + + if (editor->bEmulateVersion10 && prev_run && last_run->nCharOfs == 0 && + prev_run->len == 1 && *get_text( prev_run, 0 ) == '\r') { /* 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--; + count--; }
- TRACE("EM_GETLINECOUNT: nRows==%d\n", nRows); - return max(1, nRows); + count = max(1, count); + TRACE("EM_GETLINECOUNT: count==%d\n", count); + return count; } case EM_LINEFROMCHAR: { - if (wParam == -1) - return ME_RowNumberFromCharOfs(editor, ME_GetCursorOfs(&editor->pCursors[1])); - else - return ME_RowNumberFromCharOfs(editor, wParam); + if (wParam == -1) wParam = ME_GetCursorOfs( editor->pCursors + 1 ); + return row_number_from_char_ofs( editor, wParam ); } case EM_EXLINEFROMCHAR: { - if (lParam == -1) - return ME_RowNumberFromCharOfs(editor, ME_GetCursorOfs(&editor->pCursors[1])); - else - return ME_RowNumberFromCharOfs(editor, lParam); + if (lParam == -1) lParam = ME_GetCursorOfs( editor->pCursors + 1 ); + return row_number_from_char_ofs( editor, lParam ); } case EM_LINEINDEX: { - ME_DisplayItem *item, *para; - int nCharOfs; + ME_Row *row; + ME_Cursor cursor; + int ofs;
- if (wParam == -1) - item = ME_FindItemBack(editor->pCursors[0].pRun, diStartRow); - else - item = ME_FindRowWithNumber(editor, wParam); - if (!item) - return -1; - para = ME_GetParagraph(item); - item = ME_FindItemFwd(item, diRun); - nCharOfs = para->member.para.nCharOfs + item->member.run.nCharOfs; - TRACE("EM_LINEINDEX: nCharOfs==%d\n", nCharOfs); - return nCharOfs; + if (wParam == -1) row = row_from_cursor( editor->pCursors ); + else row = row_from_row_number( editor, wParam ); + if (!row) return -1; + + row_first_cursor( row, &cursor ); + ofs = ME_GetCursorOfs( &cursor ); + TRACE( "EM_LINEINDEX: nCharOfs==%d\n", ofs ); + return ofs; } case EM_LINELENGTH: { - ME_DisplayItem *item, *item_end; - int nChars = 0, nThisLineOfs = 0, nNextLineOfs = 0; - ME_DisplayItem *para, *run; + ME_Row *row; + int start_ofs, end_ofs; + ME_Cursor cursor;
if (wParam > ME_GetTextLength(editor)) return 0; @@ -4333,20 +3816,14 @@ LRESULT ME_HandleMessage(ME_TextEditor *editor, UINT msg, WPARAM wParam, FIXME("EM_LINELENGTH: returning number of unselected characters on lines with selection unsupported.\n"); return 0; } - ME_RunOfsFromCharOfs(editor, wParam, ¶, &run, NULL); - item = ME_RowStart(run); - nThisLineOfs = ME_CharOfsFromRunOfs(editor, para, ME_FindItemFwd(item, diRun), 0); - item_end = ME_FindItemFwd(item, diStartRowOrParagraphOrEnd); - if (item_end->type == diStartRow) { - nNextLineOfs = ME_CharOfsFromRunOfs(editor, para, ME_FindItemFwd(item_end, diRun), 0); - } else { - ME_DisplayItem *endRun = ME_FindItemBack(item_end, diRun); - assert(endRun && endRun->member.run.nFlags & MERF_ENDPARA); - nNextLineOfs = item_end->member.para.nCharOfs - endRun->member.run.len; - } - nChars = nNextLineOfs - nThisLineOfs; - TRACE("EM_LINELENGTH(%ld)==%d\n",wParam, nChars); - return nChars; + cursor_from_char_ofs( editor, wParam, &cursor ); + row = row_from_cursor( &cursor ); + row_first_cursor( row, &cursor ); + start_ofs = ME_GetCursorOfs( &cursor ); + row_end_cursor( row, &cursor, FALSE ); + end_ofs = ME_GetCursorOfs( &cursor ); + TRACE( "EM_LINELENGTH(%ld)==%d\n", wParam, end_ofs - start_ofs ); + return end_ofs - start_ofs; } case EM_EXLIMITTEXT: { @@ -4371,46 +3848,12 @@ LRESULT ME_HandleMessage(ME_TextEditor *editor, UINT msg, WPARAM wParam, return editor->nTextLimit; } case EM_FINDTEXT: - { - LRESULT r; - if(!unicode){ - FINDTEXTA *ft = (FINDTEXTA *)lParam; - int nChars = MultiByteToWideChar(CP_ACP, 0, ft->lpstrText, -1, NULL, 0); - WCHAR *tmp; - - if ((tmp = heap_alloc(nChars * sizeof(*tmp))) != NULL) - MultiByteToWideChar(CP_ACP, 0, ft->lpstrText, -1, tmp, nChars); - r = ME_FindText(editor, wParam, &ft->chrg, tmp, NULL); - heap_free(tmp); - }else{ - FINDTEXTW *ft = (FINDTEXTW *)lParam; - r = ME_FindText(editor, wParam, &ft->chrg, ft->lpstrText, NULL); - } - return r; - } - case EM_FINDTEXTEX: - { - LRESULT r; - if(!unicode){ - FINDTEXTEXA *ex = (FINDTEXTEXA *)lParam; - int nChars = MultiByteToWideChar(CP_ACP, 0, ex->lpstrText, -1, NULL, 0); - WCHAR *tmp; - - if ((tmp = heap_alloc(nChars * sizeof(*tmp))) != NULL) - MultiByteToWideChar(CP_ACP, 0, ex->lpstrText, -1, tmp, nChars); - r = ME_FindText(editor, wParam, &ex->chrg, tmp, &ex->chrgText); - heap_free(tmp); - }else{ - FINDTEXTEXW *ex = (FINDTEXTEXW *)lParam; - r = ME_FindText(editor, wParam, &ex->chrg, ex->lpstrText, &ex->chrgText); - } - return r; - } case EM_FINDTEXTW: { FINDTEXTW *ft = (FINDTEXTW *)lParam; return ME_FindText(editor, wParam, &ft->chrg, ft->lpstrText, NULL); } + case EM_FINDTEXTEX: case EM_FINDTEXTEXW: { FINDTEXTEXW *ex = (FINDTEXTEXW *)lParam; @@ -4435,8 +3878,8 @@ LRESULT ME_HandleMessage(ME_TextEditor *editor, UINT msg, WPARAM wParam, } case EM_POSFROMCHAR: { - ME_DisplayItem *pPara, *pRun; - int nCharOfs, nOffset, nLength; + ME_Cursor cursor; + int nCharOfs, nLength; POINTL pt = {0,0};
nCharOfs = wParam; @@ -4447,61 +3890,37 @@ LRESULT ME_HandleMessage(ME_TextEditor *editor, UINT msg, WPARAM wParam, nCharOfs = min(nCharOfs, nLength); nCharOfs = max(nCharOfs, 0);
- ME_RunOfsFromCharOfs(editor, nCharOfs, &pPara, &pRun, &nOffset); - assert(pRun->type == diRun); - pt.y = pRun->member.run.pt.y; - pt.x = pRun->member.run.pt.x + ME_PointFromChar(editor, &pRun->member.run, nOffset, TRUE); - pt.y += pPara->member.para.pt.y + editor->rcFormat.top; + cursor_from_char_ofs( editor, nCharOfs, &cursor ); + pt.y = cursor.run->pt.y; + pt.x = cursor.run->pt.x + + ME_PointFromChar( editor, cursor.run, cursor.nOffset, TRUE ); + pt.y += cursor.para->pt.y + editor->rcFormat.top; pt.x += editor->rcFormat.left;
pt.x -= editor->horz_si.nPos; pt.y -= editor->vert_si.nPos;
- if (wParam >= 0x40000) { - *(POINTL *)wParam = pt; - } + if (wParam >= 0x40000) *(POINTL *)wParam = pt; + return (wParam >= 0x40000) ? 0 : MAKELONG( pt.x, pt.y ); } - case WM_CREATE: - return ME_WmCreate(editor, lParam, unicode); - case WM_DESTROY: - ME_DestroyEditor(editor); - return 0; - case WM_SETCURSOR: - { - POINT cursor_pos; - if (wParam == (WPARAM)editor->hWnd && GetCursorPos(&cursor_pos) && - ScreenToClient(editor->hWnd, &cursor_pos)) - ME_LinkNotify(editor, msg, 0, MAKELPARAM(cursor_pos.x, cursor_pos.y)); - return ME_SetCursor(editor); - } case WM_LBUTTONDBLCLK: case WM_LBUTTONDOWN: { ME_CommitUndo(editor); /* End coalesced undos for typed characters */ - if ((editor->nEventMask & ENM_MOUSEEVENTS) && - !ME_FilterEvent(editor, msg, &wParam, &lParam)) - return 0; ITextHost_TxSetFocus(editor->texthost); ME_LButtonDown(editor, (short)LOWORD(lParam), (short)HIWORD(lParam), ME_CalculateClickCount(editor, msg, wParam, lParam)); ITextHost_TxSetCapture(editor->texthost, TRUE); editor->bMouseCaptured = TRUE; - ME_LinkNotify(editor, msg, wParam, lParam); - if (!ME_SetCursor(editor)) goto do_default; + link_notify( editor, msg, wParam, lParam ); break; } case WM_MOUSEMOVE: - if ((editor->nEventMask & ENM_MOUSEEVENTS) && - !ME_FilterEvent(editor, msg, &wParam, &lParam)) - return 0; if (editor->bMouseCaptured) ME_MouseMove(editor, (short)LOWORD(lParam), (short)HIWORD(lParam)); else - ME_LinkNotify(editor, msg, wParam, lParam); - /* Set cursor if mouse is captured, since WM_SETCURSOR won't be received. */ - if (editor->bMouseCaptured) - ME_SetCursor(editor); + link_notify( editor, msg, wParam, lParam ); break; case WM_LBUTTONUP: if (editor->bMouseCaptured) { @@ -4510,23 +3929,16 @@ LRESULT ME_HandleMessage(ME_TextEditor *editor, UINT msg, WPARAM wParam, } if (editor->nSelectionType == stDocument) editor->nSelectionType = stPosition; - if ((editor->nEventMask & ENM_MOUSEEVENTS) && - !ME_FilterEvent(editor, msg, &wParam, &lParam)) - return 0; else { - ME_SetCursor(editor); - ME_LinkNotify(editor, msg, wParam, lParam); + link_notify( editor, msg, wParam, lParam ); } break; case WM_RBUTTONUP: case WM_RBUTTONDOWN: case WM_RBUTTONDBLCLK: ME_CommitUndo(editor); /* End coalesced undos for typed characters */ - if ((editor->nEventMask & ENM_MOUSEEVENTS) && - !ME_FilterEvent(editor, msg, &wParam, &lParam)) - return 0; - ME_LinkNotify(editor, msg, wParam, lParam); + link_notify( editor, msg, wParam, lParam ); goto do_default; case WM_CONTEXTMENU: if (!ME_ShowContextMenu(editor, (short)LOWORD(lParam), (short)HIWORD(lParam))) @@ -4536,8 +3948,8 @@ LRESULT ME_HandleMessage(ME_TextEditor *editor, UINT msg, WPARAM wParam, editor->bHaveFocus = TRUE; create_caret(editor); update_caret(editor); - ME_SendOldNotify(editor, EN_SETFOCUS); - if (!editor->bHideSelection && !(editor->styleFlags & ES_NOHIDESEL)) + ITextHost_TxNotify( editor->texthost, EN_SETFOCUS, NULL ); + if (!editor->bHideSelection && (editor->props & TXTBIT_HIDESELECTION)) ME_InvalidateSelection( editor ); return 0; case WM_KILLFOCUS: @@ -4546,48 +3958,33 @@ LRESULT ME_HandleMessage(ME_TextEditor *editor, UINT msg, WPARAM wParam, editor->wheel_remain = 0; hide_caret(editor); DestroyCaret(); - ME_SendOldNotify(editor, EN_KILLFOCUS); - if (!editor->bHideSelection && !(editor->styleFlags & ES_NOHIDESEL)) + ITextHost_TxNotify( editor->texthost, EN_KILLFOCUS, NULL ); + if (!editor->bHideSelection && (editor->props & TXTBIT_HIDESELECTION)) ME_InvalidateSelection( editor ); return 0; case WM_COMMAND: TRACE("editor wnd command = %d\n", LOWORD(wParam)); return 0; - case WM_KEYUP: - if ((editor->nEventMask & ENM_KEYEVENTS) && - !ME_FilterEvent(editor, msg, &wParam, &lParam)) - return 0; - goto do_default; case WM_KEYDOWN: - if ((editor->nEventMask & ENM_KEYEVENTS) && - !ME_FilterEvent(editor, msg, &wParam, &lParam)) - return 0; if (ME_KeyDown(editor, LOWORD(wParam))) return 0; goto do_default; case WM_CHAR: - if ((editor->nEventMask & ENM_KEYEVENTS) && - !ME_FilterEvent(editor, msg, &wParam, &lParam)) - return 0; - return ME_Char(editor, wParam, lParam, unicode); + return handle_wm_char( editor, wParam, lParam ); case WM_UNICHAR: - if (unicode) - { - if(wParam == UNICODE_NOCHAR) return TRUE; - if(wParam <= 0x000fffff) - { - if(wParam > 0xffff) /* convert to surrogates */ - { - wParam -= 0x10000; - ME_Char(editor, (wParam >> 10) + 0xd800, 0, TRUE); - ME_Char(editor, (wParam & 0x03ff) + 0xdc00, 0, TRUE); - } else { - ME_Char(editor, wParam, 0, TRUE); - } - } - return 0; - } - break; + if (wParam == UNICODE_NOCHAR) return TRUE; + if (wParam <= 0x000fffff) + { + if (wParam > 0xffff) /* convert to surrogates */ + { + wParam -= 0x10000; + handle_wm_char( editor, (wParam >> 10) + 0xd800, 0 ); + handle_wm_char( editor, (wParam & 0x03ff) + 0xdc00, 0 ); + } + else + handle_wm_char( editor, wParam, 0 ); + } + return 0; case EM_STOPGROUPTYPING: ME_CommitUndo(editor); /* End coalesced undos for typed characters */ return 0; @@ -4598,12 +3995,11 @@ LRESULT ME_HandleMessage(ME_TextEditor *editor, UINT msg, WPARAM wParam, switch(LOWORD(wParam)) { case SB_LEFT: - ME_ScrollAbs(editor, 0, 0); + scroll_abs( editor, 0, 0, TRUE ); break; case SB_RIGHT: - ME_ScrollAbs(editor, - editor->horz_si.nMax - (int)editor->horz_si.nPage, - editor->vert_si.nMax - (int)editor->vert_si.nPage); + scroll_abs( editor, editor->horz_si.nMax - (int)editor->horz_si.nPage, + editor->vert_si.nMax - (int)editor->vert_si.nPage, TRUE ); break; case SB_LINELEFT: ME_ScrollLeft(editor, scrollUnit); @@ -4623,7 +4019,7 @@ LRESULT ME_HandleMessage(ME_TextEditor *editor, UINT msg, WPARAM wParam, int pos = HIWORD(wParam); if (editor->horz_si.nMax > 0xffff) pos = MulDiv(pos, editor->horz_si.nMax, 0xffff); - ME_HScrollAbs(editor, pos); + scroll_h_abs( editor, pos, FALSE ); break; } } @@ -4640,12 +4036,11 @@ LRESULT ME_HandleMessage(ME_TextEditor *editor, UINT msg, WPARAM wParam, switch(LOWORD(wParam)) { case SB_TOP: - ME_ScrollAbs(editor, 0, 0); + scroll_abs( editor, 0, 0, TRUE ); break; case SB_BOTTOM: - ME_ScrollAbs(editor, - editor->horz_si.nMax - (int)editor->horz_si.nPage, - editor->vert_si.nMax - (int)editor->vert_si.nPage); + scroll_abs( editor, editor->horz_si.nMax - (int)editor->horz_si.nPage, + editor->vert_si.nMax - (int)editor->vert_si.nPage, TRUE ); break; case SB_LINEUP: ME_ScrollUp(editor,lineHeight); @@ -4665,7 +4060,7 @@ LRESULT ME_HandleMessage(ME_TextEditor *editor, UINT msg, WPARAM wParam, int pos = HIWORD(wParam); if (editor->vert_si.nMax > 0xffff) pos = MulDiv(pos, editor->vert_si.nMax, 0xffff); - ME_VScrollAbs(editor, pos); + scroll_v_abs( editor, pos, FALSE ); break; } } @@ -4675,16 +4070,8 @@ LRESULT ME_HandleMessage(ME_TextEditor *editor, UINT msg, WPARAM wParam, } case WM_MOUSEWHEEL: { - int delta; - BOOL ctrl_is_down; - - if ((editor->nEventMask & ENM_MOUSEEVENTS) && - !ME_FilterEvent(editor, msg, &wParam, &lParam)) - return 0; - - ctrl_is_down = GetKeyState(VK_CONTROL) & 0x8000; - - delta = GET_WHEEL_DELTA_WPARAM(wParam); + int delta = GET_WHEEL_DELTA_WPARAM( wParam ); + BOOL ctrl_is_down = GetKeyState( VK_CONTROL ) & 0x8000;
/* if scrolling changes direction, ignore left overs */ if ((delta < 0 && editor->wheel_remain < 0) || @@ -4719,78 +4106,9 @@ LRESULT ME_HandleMessage(ME_TextEditor *editor, UINT msg, WPARAM wParam, } break; } - case EM_GETRECT: - { - *((RECT *)lParam) = editor->rcFormat; - if (editor->bDefaultFormatRect) - ((RECT *)lParam)->left -= editor->selofs; - return 0; - } - case EM_SETRECT: - case EM_SETRECTNP: - { - if (lParam) - { - int border = 0; - RECT clientRect; - RECT *rc = (RECT *)lParam; - - border = editor->exStyleFlags & WS_EX_CLIENTEDGE ? 1 : 0; - ITextHost_TxGetClientRect(editor->texthost, &clientRect); - if (wParam == 0) - { - editor->rcFormat.top = max(0, rc->top - border); - editor->rcFormat.left = max(0, rc->left - border); - editor->rcFormat.bottom = min(clientRect.bottom, rc->bottom); - editor->rcFormat.right = min(clientRect.right, rc->right + border); - } else if (wParam == 1) { - /* MSDN incorrectly says a wParam value of 1 causes the - * lParam rect to be used as a relative offset, - * however, the tests show it just prevents min/max bound - * checking. */ - editor->rcFormat.top = rc->top - border; - editor->rcFormat.left = rc->left - border; - editor->rcFormat.bottom = rc->bottom; - editor->rcFormat.right = rc->right + border; - } else { - return 0; - } - editor->bDefaultFormatRect = FALSE; - } - else - { - ME_SetDefaultFormatRect(editor); - editor->bDefaultFormatRect = TRUE; - } - ME_MarkAllForWrapping(editor); - ME_WrapMarkedParagraphs(editor); - ME_UpdateScrollBar(editor); - if (msg != EM_SETRECTNP) - ME_Repaint(editor); - return 0; - } case EM_REQUESTRESIZE: ME_SendRequestResize(editor, TRUE); return 0; - case WM_SETREDRAW: - goto do_default; - case WM_WINDOWPOSCHANGED: - { - RECT clientRect; - WINDOWPOS *winpos = (WINDOWPOS *)lParam; - - if (winpos->flags & SWP_NOCLIENTSIZE) goto do_default; - ITextHost_TxGetClientRect(editor->texthost, &clientRect); - if (editor->bDefaultFormatRect) { - ME_SetDefaultFormatRect(editor); - } else { - editor->rcFormat.right += clientRect.right - editor->prevClientRect.right; - editor->rcFormat.bottom += clientRect.bottom - editor->prevClientRect.bottom; - } - editor->prevClientRect = clientRect; - ME_RewrapRepaint(editor); - goto do_default; - } #ifndef __REACTOS__ /* IME messages to make richedit controls IME aware */ #endif @@ -4843,7 +4161,7 @@ LRESULT ME_HandleMessage(ME_TextEditor *editor, UINT msg, WPARAM wParam, { HIMC hIMC;
- ME_Style *style = ME_GetInsertStyle(editor, 0); + ME_Style *style = style_get_insert_style( editor, editor->pCursors ); hIMC = ITextHost_TxImmGetContext(editor->texthost); ME_DeleteSelection(editor); ME_SaveTempStyle(editor, style); @@ -4890,18 +4208,10 @@ LRESULT ME_HandleMessage(ME_TextEditor *editor, UINT msg, WPARAM wParam, #endif } case EM_GETOLEINTERFACE: - { - if (!editor->reOle) - if (!CreateIRichEditOle(NULL, editor, (LPVOID *)&editor->reOle)) - return 0; - if (IUnknown_QueryInterface(editor->reOle, &IID_IRichEditOle, (LPVOID *)lParam) == S_OK) - return 1; - return 0; - } - case EM_GETPASSWORDCHAR: - { - return editor->cPasswordMask; - } + IRichEditOle_AddRef( editor->richole ); + *(IRichEditOle **)lParam = editor->richole; + return 1; + case EM_SETOLECALLBACK: if(editor->lpOleCallback) IRichEditOleCallback_Release(editor->lpOleCallback); @@ -4947,24 +4257,18 @@ LRESULT ME_HandleMessage(ME_TextEditor *editor, UINT msg, WPARAM wParam, /* plain text can only have the default style. */ ME_ClearTempStyle(editor); ME_AddRefStyle(editor->pBuffer->pDefaultStyle); - ME_ReleaseStyle(editor->pCursors[0].pRun->member.run.style); - editor->pCursors[0].pRun->member.run.style = editor->pBuffer->pDefaultStyle; + ME_ReleaseStyle( editor->pCursors[0].run->style ); + editor->pCursors[0].run->style = editor->pBuffer->pDefaultStyle; } } /* FIXME: Currently no support for undo level and code page options */ editor->mode = (editor->mode & ~mask) | changes; return 0; } - case EM_SETPASSWORDCHAR: - { - editor->cPasswordMask = wParam; - ME_RewrapRepaint(editor); - return 0; - } case EM_SETTARGETDEVICE: if (wParam == 0) { - BOOL new = (lParam == 0 && (editor->styleFlags & ES_MULTILINE)); + BOOL new = (lParam == 0 && (editor->props & TXTBIT_MULTILINE)); if (editor->nAvailWidth || editor->bWordWrap != new) { editor->bWordWrap = new; @@ -4973,7 +4277,7 @@ LRESULT ME_HandleMessage(ME_TextEditor *editor, UINT msg, WPARAM wParam, } } else { int width = max(0, lParam); - if ((editor->styleFlags & ES_MULTILINE) && + if ((editor->props & TXTBIT_MULTILINE) && (!editor->bWordWrap || editor->nAvailWidth != width)) { editor->nAvailWidth = width; @@ -4991,192 +4295,6 @@ LRESULT ME_HandleMessage(ME_TextEditor *editor, UINT msg, WPARAM wParam, return 0L; }
-static BOOL create_windowed_editor(HWND hwnd, CREATESTRUCTW *create, BOOL emulate_10) -{ - ITextHost *host = ME_CreateTextHost( hwnd, create, emulate_10 ); - ME_TextEditor *editor; - - if (!host) return FALSE; - - editor = ME_MakeEditor( host, emulate_10 ); - if (!editor) - { - ITextHost_Release( host ); - return FALSE; - } - - editor->exStyleFlags = GetWindowLongW( hwnd, GWL_EXSTYLE ); - editor->styleFlags |= GetWindowLongW( hwnd, GWL_STYLE ) & ES_WANTRETURN; - editor->hWnd = hwnd; /* FIXME: Remove editor's dependence on hWnd */ - editor->hwndParent = create->hwndParent; - - SetWindowLongPtrW( hwnd, 0, (LONG_PTR)editor ); - - return TRUE; -} - -static LRESULT RichEditWndProc_common(HWND hWnd, UINT msg, WPARAM wParam, - LPARAM lParam, BOOL unicode) -{ - ME_TextEditor *editor; - HRESULT hresult; - LRESULT lresult = 0; - - TRACE("enter hwnd %p msg %04x (%s) %lx %lx, unicode %d\n", - hWnd, msg, get_msg_name(msg), wParam, lParam, unicode); - - editor = (ME_TextEditor *)GetWindowLongPtrW(hWnd, 0); - if (!editor) - { - if (msg == WM_NCCREATE) - { - CREATESTRUCTW *pcs = (CREATESTRUCTW *)lParam; - - TRACE("WM_NCCREATE: hWnd %p style 0x%08x\n", hWnd, pcs->style); - return create_windowed_editor( hWnd, pcs, FALSE ); - } - else - { - return DefWindowProcW(hWnd, msg, wParam, lParam); - } - } - - switch (msg) - { - case WM_PAINT: - { - HDC hdc; - RECT rc; - PAINTSTRUCT ps; - HBRUSH old_brush; - - update_caret(editor); - hdc = BeginPaint(editor->hWnd, &ps); - if (!editor->bEmulateVersion10 || (editor->nEventMask & ENM_UPDATE)) - ME_SendOldNotify(editor, EN_UPDATE); - old_brush = SelectObject(hdc, editor->hbrBackground); - - /* Erase area outside of the formatting rectangle */ - if (ps.rcPaint.top < editor->rcFormat.top) - { - rc = ps.rcPaint; - rc.bottom = editor->rcFormat.top; - PatBlt(hdc, rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.top, PATCOPY); - ps.rcPaint.top = editor->rcFormat.top; - } - if (ps.rcPaint.bottom > editor->rcFormat.bottom) { - rc = ps.rcPaint; - rc.top = editor->rcFormat.bottom; - PatBlt(hdc, rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.top, PATCOPY); - ps.rcPaint.bottom = editor->rcFormat.bottom; - } - if (ps.rcPaint.left < editor->rcFormat.left) { - rc = ps.rcPaint; - rc.right = editor->rcFormat.left; - PatBlt(hdc, rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.top, PATCOPY); - ps.rcPaint.left = editor->rcFormat.left; - } - if (ps.rcPaint.right > editor->rcFormat.right) { - rc = ps.rcPaint; - rc.left = editor->rcFormat.right; - PatBlt(hdc, rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.top, PATCOPY); - ps.rcPaint.right = editor->rcFormat.right; - } - - ME_PaintContent(editor, hdc, &ps.rcPaint); - SelectObject(hdc, old_brush); - EndPaint(editor->hWnd, &ps); - return 0; - } - case WM_ERASEBKGND: - { - HDC hDC = (HDC)wParam; - RECT rc; - - if (GetUpdateRect(editor->hWnd, &rc, TRUE)) - FillRect(hDC, &rc, editor->hbrBackground); - return 1; - } - case EM_SETOPTIONS: - { - DWORD dwStyle; - const DWORD mask = ECO_VERTICAL | ECO_AUTOHSCROLL | ECO_AUTOVSCROLL | - ECO_NOHIDESEL | ECO_READONLY | ECO_WANTRETURN | - ECO_SELECTIONBAR; - lresult = ME_HandleMessage(editor, msg, wParam, lParam, unicode, &hresult); - dwStyle = GetWindowLongW(hWnd, GWL_STYLE); - dwStyle = (dwStyle & ~mask) | (lresult & mask); - SetWindowLongW(hWnd, GWL_STYLE, dwStyle); - return lresult; - } - case EM_SETREADONLY: - { - DWORD dwStyle; - lresult = ME_HandleMessage(editor, msg, wParam, lParam, unicode, &hresult); - dwStyle = GetWindowLongW(hWnd, GWL_STYLE); - dwStyle &= ~ES_READONLY; - if (wParam) - dwStyle |= ES_READONLY; - SetWindowLongW(hWnd, GWL_STYLE, dwStyle); - return lresult; - } - default: - lresult = ME_HandleMessage(editor, msg, wParam, lParam, unicode, &hresult); - } - - if (hresult == S_FALSE) - lresult = DefWindowProcW(hWnd, msg, wParam, lParam); - - TRACE("exit hwnd %p msg %04x (%s) %lx %lx, unicode %d -> %lu\n", - hWnd, msg, get_msg_name(msg), wParam, lParam, unicode, lresult); - - return lresult; -} - -static LRESULT WINAPI RichEditWndProcW(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) -{ - BOOL unicode = TRUE; - - /* Under Win9x RichEdit20W returns ANSI strings, see the tests. */ - if (msg == WM_GETTEXT && (GetVersion() & 0x80000000)) - unicode = FALSE; - - return RichEditWndProc_common(hWnd, msg, wParam, lParam, unicode); -} - -static LRESULT WINAPI RichEditWndProcA(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) -{ - return RichEditWndProc_common(hWnd, msg, wParam, lParam, FALSE); -} - -/****************************************************************** - * RichEditANSIWndProc (RICHED20.10) - */ -LRESULT WINAPI RichEditANSIWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) -{ - return RichEditWndProcA(hWnd, msg, wParam, lParam); -} - -/****************************************************************** - * RichEdit10ANSIWndProc (RICHED20.9) - */ -LRESULT WINAPI RichEdit10ANSIWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) -{ - if (msg == WM_NCCREATE && !GetWindowLongPtrW(hWnd, 0)) - { - CREATESTRUCTW *pcs = (CREATESTRUCTW *)lParam; - - TRACE("WM_NCCREATE: hWnd %p style 0x%08x\n", hWnd, pcs->style); - return create_windowed_editor( hWnd, pcs, TRUE ); - } - return RichEditANSIWndProc(hWnd, msg, wParam, lParam); -} - -void ME_SendOldNotify(ME_TextEditor *editor, int nCode) -{ - ITextHost_TxNotify(editor->texthost, nCode, NULL); -} - /* Fill buffer with srcChars unicode characters from the start cursor. * * buffer: destination buffer @@ -5193,27 +4311,23 @@ int ME_GetTextW(ME_TextEditor *editor, WCHAR *buffer, int buflen, const ME_Cursor *start, int srcChars, BOOL bCRLF, BOOL bEOP) { - ME_DisplayItem *pRun, *pNextRun; + ME_Run *run, *next_run; const WCHAR *pStart = buffer; - const WCHAR cr_lf[] = {'\r', '\n', 0}; const WCHAR *str; int nLen;
/* bCRLF flag is only honored in 2.0 and up. 1.0 must always return text verbatim */ if (editor->bEmulateVersion10) bCRLF = FALSE;
- pRun = start->pRun; - assert(pRun); - pNextRun = ME_FindItemFwd(pRun, diRun); + run = start->run; + next_run = run_next_all_paras( run );
- nLen = pRun->member.run.len - start->nOffset; - str = get_text( &pRun->member.run, start->nOffset ); + nLen = run->len - start->nOffset; + str = get_text( run, start->nOffset );
- while (srcChars && buflen && pNextRun) + while (srcChars && buflen && next_run) { - int nFlags = pRun->member.run.nFlags; - - if (bCRLF && nFlags & MERF_ENDPARA && ~nFlags & MERF_ENDCELL) + if (bCRLF && run->nFlags & MERF_ENDPARA && ~run->nFlags & MERF_ENDCELL) { if (buflen == 1) break; /* FIXME: native fails to reduce srcChars here for WM_GETTEXT or @@ -5221,8 +4335,10 @@ int ME_GetTextW(ME_TextEditor *editor, WCHAR *buffer, int buflen, * also uses this function. */ srcChars -= min(nLen, srcChars); nLen = 2; - str = cr_lf; - } else { + str = L"\r\n"; + } + else + { nLen = min(nLen, srcChars); srcChars -= nLen; } @@ -5234,14 +4350,14 @@ int ME_GetTextW(ME_TextEditor *editor, WCHAR *buffer, int buflen,
buffer += nLen;
- pRun = pNextRun; - pNextRun = ME_FindItemFwd(pRun, diRun); + run = next_run; + next_run = run_next_all_paras( run );
- nLen = pRun->member.run.len; - str = get_text( &pRun->member.run, 0 ); ... 13294 lines suppressed ...