[PATCH v2 6/8] riched20: Implement list of marked paragraphs.
Sergio Gómez Del Real
sdelreal at codeweavers.com
Thu Nov 29 07:44:53 CST 2018
Signed-off-by: Sergio Gómez Del Real <sdelreal at 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;
--
2.17.1
More information about the wine-devel
mailing list