Signed-off-by: Sergio Gómez Del Real sdelreal@codeweavers.com --- dlls/riched20/editor.c | 1 + dlls/riched20/editor.h | 2 ++ dlls/riched20/editstr.h | 2 ++ dlls/riched20/para.c | 76 +++++++++++++++++++++++++++++++++++++++++ dlls/riched20/wrap.c | 60 ++++++++++++++++++++++++-------- 5 files changed, 127 insertions(+), 14 deletions(-)
diff --git a/dlls/riched20/editor.c b/dlls/riched20/editor.c index 9ecba6f824..bf4c8ea0c2 100644 --- a/dlls/riched20/editor.c +++ b/dlls/riched20/editor.c @@ -3035,6 +3035,7 @@ ME_TextEditor *ME_MakeEditor(ITextHost *texthost, BOOL bEmulateVersion10) ed->bEmulateVersion10 = bEmulateVersion10; ed->styleFlags = 0; ed->exStyleFlags = 0; + ed->first_marked_para = NULL; ITextHost_TxGetPropertyBits(texthost, (TXTBIT_RICHTEXT|TXTBIT_MULTILINE| TXTBIT_READONLY|TXTBIT_USEPASSWORD| diff --git a/dlls/riched20/editor.h b/dlls/riched20/editor.h index 3b4dc542a9..2da7365a6e 100644 --- a/dlls/riched20/editor.h +++ b/dlls/riched20/editor.h @@ -205,6 +205,8 @@ void para_num_clear( struct para_num *pn ) DECLSPEC_HIDDEN; int get_total_width(ME_TextEditor *editor) DECLSPEC_HIDDEN; void mark_para_rewrap(ME_TextEditor *editor, ME_DisplayItem *para) DECLSPEC_HIDDEN; ME_DisplayItem *get_di_from_para(ME_Paragraph *para) DECLSPEC_HIDDEN; +void add_marked_para(ME_TextEditor *editor, ME_DisplayItem *para) DECLSPEC_HIDDEN; +void remove_marked_para(ME_TextEditor *editor, ME_DisplayItem *para) DECLSPEC_HIDDEN;
/* paint.c */ void ME_PaintContent(ME_TextEditor *editor, HDC hDC, const RECT *rcUpdate) DECLSPEC_HIDDEN; diff --git a/dlls/riched20/editstr.h b/dlls/riched20/editstr.h index 206ce85287..2cd16c93c8 100644 --- a/dlls/riched20/editstr.h +++ b/dlls/riched20/editstr.h @@ -219,6 +219,7 @@ typedef struct tagME_Paragraph struct para_num para_num; ME_Run *eop_run; /* ptr to the end-of-para run */ struct tagME_DisplayItem *prev_para, *next_para; + struct tagME_DisplayItem *prev_marked, *next_marked; } ME_Paragraph;
typedef struct tagME_Cell /* v4.1 */ @@ -432,6 +433,7 @@ typedef struct tagME_TextEditor int imeStartIndex; DWORD selofs; /* The size of the selection bar on the left side of control */ ME_SelectionType nSelectionType; + ME_DisplayItem *first_marked_para;
/* Track previous notified selection */ CHARRANGE notified_cr; diff --git a/dlls/riched20/para.c b/dlls/riched20/para.c index ae2227e235..aaa2bda06a 100644 --- a/dlls/riched20/para.c +++ b/dlls/riched20/para.c @@ -26,6 +26,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(richedit); void mark_para_rewrap(ME_TextEditor *editor, ME_DisplayItem *para) { para->member.para.nFlags |= MEPF_REWRAP; + add_marked_para(editor, para); }
ME_DisplayItem *get_di_from_para(ME_Paragraph *para) @@ -39,6 +40,8 @@ static ME_DisplayItem *make_para(ME_TextEditor *editor)
ME_SetDefaultParaFormat(editor, &item->member.para.fmt); item->member.para.nFlags = MEPF_REWRAP; + item->member.para.next_marked = item->member.para.prev_marked = NULL; + return item; }
@@ -53,6 +56,7 @@ void destroy_para(ME_TextEditor *editor, ME_DisplayItem *item) } ME_DestroyString(item->member.para.text); para_num_clear( &item->member.para.para_num ); + remove_marked_para(editor, item); ME_DestroyDisplayItem(item); }
@@ -74,6 +78,77 @@ int get_total_width(ME_TextEditor *editor) return total_width; }
+void remove_marked_para(ME_TextEditor *editor, ME_DisplayItem *di) +{ + ME_DisplayItem *head = editor->first_marked_para; + + assert(di->type == diParagraph); + if (!di->member.para.next_marked && !di->member.para.prev_marked) + { + if (di == head) + editor->first_marked_para = NULL; + } + else if (di->member.para.next_marked && di->member.para.prev_marked) + { + di->member.para.prev_marked->member.para.next_marked = di->member.para.next_marked; + di->member.para.next_marked->member.para.prev_marked = di->member.para.prev_marked; + di->member.para.prev_marked = di->member.para.next_marked = NULL; + } + else if (di->member.para.next_marked) + { + assert(di == editor->first_marked_para); + editor->first_marked_para = di->member.para.next_marked; + di->member.para.next_marked->member.para.prev_marked = NULL; + di->member.para.next_marked = NULL; + } + else + { + di->member.para.prev_marked->member.para.next_marked = NULL; + di->member.para.prev_marked = NULL; + } +} + +void add_marked_para(ME_TextEditor *editor, ME_DisplayItem *di) +{ + ME_DisplayItem *iter = editor->first_marked_para; + + if (!iter) + { + editor->first_marked_para = di; + return; + } + while (iter) + { + if (iter == di) + return; + else if (di->member.para.nCharOfs < iter->member.para.nCharOfs) + { + if (iter == editor->first_marked_para) + editor->first_marked_para = di; + di->member.para.next_marked = iter; + iter->member.para.prev_marked = di; + break; + } + else if (di->member.para.nCharOfs >= iter->member.para.nCharOfs) + { + if (!iter->member.para.next_marked || + (iter->member.para.next_marked && + di->member.para.nCharOfs < iter->member.para.next_marked->member.para.nCharOfs)) + { + if (iter->member.para.next_marked) + { + di->member.para.next_marked = iter->member.para.next_marked; + iter->member.para.next_marked->member.para.prev_marked = di; + } + di->member.para.prev_marked = iter; + iter->member.para.next_marked = di; + break; + } + } + iter = iter->member.para.next_marked; + } +} + void ME_MakeFirstParagraph(ME_TextEditor *editor) { ME_Context c; @@ -146,6 +221,7 @@ void ME_MakeFirstParagraph(ME_TextEditor *editor)
text->pLast->member.para.nCharOfs = editor->bEmulateVersion10 ? 2 : 1;
+ add_marked_para(editor, para); ME_DestroyContext(&c); }
diff --git a/dlls/riched20/wrap.c b/dlls/riched20/wrap.c index e1ec692004..c2e3f62162 100644 --- a/dlls/riched20/wrap.c +++ b/dlls/riched20/wrap.c @@ -1098,29 +1098,61 @@ BOOL ME_WrapMarkedParagraphs(ME_TextEditor *editor) { ME_DisplayItem *item; ME_Context c; - int totalWidth = 0; + int totalWidth = editor->nTotalWidth, diff = 0, prev_width; ME_DisplayItem *repaint_start = NULL, *repaint_end = NULL; + ME_Paragraph *para; + + if (!editor->first_marked_para) + return FALSE;
ME_InitContext(&c, editor, ITextHost_TxGetDC(editor->texthost)); - c.pt.x = 0; - item = editor->pBuffer->pFirst->next; - while(item != editor->pBuffer->pLast) { - BOOL bRedraw = FALSE;
+ item = editor->first_marked_para; + c.pt = item->member.para.pt; + while (item != editor->pBuffer->pLast) + { assert(item->type == diParagraph); - if ((item->member.para.nFlags & MEPF_REWRAP) - || (item->member.para.pt.y != c.pt.y)) - bRedraw = TRUE; - item->member.para.pt = c.pt;
+ prev_width = item->member.para.nWidth; ME_WrapTextParagraph(&c, item); + if (prev_width == totalWidth && item->member.para.nWidth < totalWidth) + totalWidth = get_total_width(editor); + else + totalWidth = max(totalWidth, item->member.para.nWidth);
- if (bRedraw) - ME_MarkRepaintEnd(item, &repaint_start, &repaint_end); - + if (!item->member.para.nCharOfs) + ME_MarkRepaintEnd(item->member.para.prev_para, &repaint_start, &repaint_end); + ME_MarkRepaintEnd(item, &repaint_start, &repaint_end); adjust_para_y(item, &c, repaint_start, repaint_end); - totalWidth = max(totalWidth, item->member.para.nWidth); - item = item->member.para.next_para; + + if (item->member.para.next_para) + { + diff = c.pt.y - item->member.para.next_para->member.para.pt.y; + if (diff) + { + para = &item->member.para; + while (para->next_para && para != &item->member.para.next_marked->member.para && + para != &editor->pBuffer->pLast->member.para) + { + ME_MarkRepaintEnd(para->next_para, &repaint_start, &repaint_end); + para->next_para->member.para.pt.y = c.pt.y; + adjust_para_y(para->next_para, &c, repaint_start, repaint_end); + para = ¶->next_para->member.para; + } + } + } + if (item->member.para.next_marked) + { + ME_DisplayItem *rem = item; + item = item->member.para.next_marked; + remove_marked_para(editor, rem); + } + else + { + remove_marked_para(editor, item); + item = editor->pBuffer->pLast; + } + c.pt.y = item->member.para.pt.y; } editor->sizeWindow.cx = c.rcView.right-c.rcView.left; editor->sizeWindow.cy = c.rcView.bottom-c.rcView.top;