Signed-off-by: Sergio Gómez Del Real sdelreal@codeweavers.com --- dlls/riched20/editor.c | 5 ++++- dlls/riched20/editor.h | 1 + dlls/riched20/list.c | 6 ------ dlls/riched20/para.c | 11 ++++++++++- 4 files changed, 15 insertions(+), 8 deletions(-)
diff --git a/dlls/riched20/editor.c b/dlls/riched20/editor.c index 2571ce97bc..d79888b933 100644 --- a/dlls/riched20/editor.c +++ b/dlls/riched20/editor.c @@ -3164,7 +3164,10 @@ void ME_DestroyEditor(ME_TextEditor *editor) ME_EmptyUndoStack(editor); while(p) { pNext = p->next; - ME_DestroyDisplayItem(p); + if (p->type == diParagraph) + destroy_para(editor, p); + else + ME_DestroyDisplayItem(p); p = pNext; }
diff --git a/dlls/riched20/editor.h b/dlls/riched20/editor.h index eba6d35fc7..e1a002bfaa 100644 --- a/dlls/riched20/editor.h +++ b/dlls/riched20/editor.h @@ -77,6 +77,7 @@ ME_DisplayItem *ME_FindItemBackOrHere(ME_DisplayItem *di, ME_DIType nTypeOrClass ME_DisplayItem *ME_MakeDI(ME_DIType type) DECLSPEC_HIDDEN; void ME_DestroyDisplayItem(ME_DisplayItem *item) DECLSPEC_HIDDEN; void ME_DumpDocument(ME_TextBuffer *buffer) DECLSPEC_HIDDEN; +void destroy_para(ME_TextEditor *editor, ME_DisplayItem *item) DECLSPEC_HIDDEN;
/* string.c */ ME_String *ME_MakeStringN(LPCWSTR szText, int nMaxChars) DECLSPEC_HIDDEN; diff --git a/dlls/riched20/list.c b/dlls/riched20/list.c index ba35a90a98..23d1a38991 100644 --- a/dlls/riched20/list.c +++ b/dlls/riched20/list.c @@ -161,12 +161,6 @@ void ME_DestroyDisplayItem(ME_DisplayItem *item) { if (0) TRACE("type=%s\n", ME_GetDITypeName(item->type)); - if (item->type==diParagraph) - { - ME_DestroyString(item->member.para.text); - para_num_clear( &item->member.para.para_num ); - } - if (item->type==diRun) { if (item->member.run.reobj) diff --git a/dlls/riched20/para.c b/dlls/riched20/para.c index fcd7936807..3d86734aa1 100644 --- a/dlls/riched20/para.c +++ b/dlls/riched20/para.c @@ -32,6 +32,15 @@ static ME_DisplayItem *make_para(ME_TextEditor *editor) return item; }
+void destroy_para(ME_TextEditor *editor, ME_DisplayItem *item) +{ + assert(item->type == diParagraph); + + ME_DestroyString(item->member.para.text); + para_num_clear( &item->member.para.para_num ); + ME_DestroyDisplayItem(item); +} + void ME_MakeFirstParagraph(ME_TextEditor *editor) { ME_Context c; @@ -682,7 +691,7 @@ ME_DisplayItem *ME_JoinParagraphs(ME_TextEditor *editor, ME_DisplayItem *tp, tp->member.para.next_para = pNext->member.para.next_para; pNext->member.para.next_para->member.para.prev_para = tp; ME_Remove(pNext); - ME_DestroyDisplayItem(pNext); + destroy_para(editor, pNext);
ME_PropagateCharOffset(tp->member.para.next_para, -end_len);
Signed-off-by: Sergio Gómez Del Real sdelreal@codeweavers.com --- dlls/riched20/editor.h | 1 + dlls/riched20/para.c | 23 +++++++++++++++++++++++ 2 files changed, 24 insertions(+)
diff --git a/dlls/riched20/editor.h b/dlls/riched20/editor.h index e1a002bfaa..eb37368602 100644 --- a/dlls/riched20/editor.h +++ b/dlls/riched20/editor.h @@ -202,6 +202,7 @@ void ME_MarkAllForWrapping(ME_TextEditor *editor) DECLSPEC_HIDDEN; void ME_SetDefaultParaFormat(ME_TextEditor *editor, PARAFORMAT2 *pFmt) DECLSPEC_HIDDEN; void para_num_init( ME_Context *c, ME_Paragraph *para ) DECLSPEC_HIDDEN; void para_num_clear( struct para_num *pn ) DECLSPEC_HIDDEN; +int get_total_width(ME_TextEditor *editor) DECLSPEC_HIDDEN;
/* paint.c */ void ME_PaintContent(ME_TextEditor *editor, HDC hDC, const RECT *rcUpdate) DECLSPEC_HIDDEN; diff --git a/dlls/riched20/para.c b/dlls/riched20/para.c index 3d86734aa1..c5755b19f4 100644 --- a/dlls/riched20/para.c +++ b/dlls/riched20/para.c @@ -36,11 +36,34 @@ void destroy_para(ME_TextEditor *editor, ME_DisplayItem *item) { assert(item->type == diParagraph);
+ if (item->member.para.nWidth == editor->nTotalWidth) + { + item->member.para.nWidth = 0; + editor->nTotalWidth = get_total_width(editor); + } ME_DestroyString(item->member.para.text); para_num_clear( &item->member.para.para_num ); ME_DestroyDisplayItem(item); }
+int get_total_width(ME_TextEditor *editor) +{ + ME_Paragraph *para; + int total_width = 0; + + if (editor->pBuffer->pFirst && editor->pBuffer->pLast) + { + para = &editor->pBuffer->pFirst->next->member.para; + while (para != &editor->pBuffer->pLast->member.para && para->next_para) + { + total_width = max(total_width, para->nWidth); + para = ¶->next_para->member.para; + } + } + + return total_width; +} + void ME_MakeFirstParagraph(ME_TextEditor *editor) { ME_Context c;
Signed-off-by: Huw Davies huw@codeweavers.com
Signed-off-by: Sergio Gómez Del Real sdelreal@codeweavers.com --- dlls/riched20/wrap.c | 222 ++++++++++++++++++++++--------------------- 1 file changed, 115 insertions(+), 107 deletions(-)
diff --git a/dlls/riched20/wrap.c b/dlls/riched20/wrap.c index 18558258e5..e1ec692004 100644 --- a/dlls/riched20/wrap.c +++ b/dlls/riched20/wrap.c @@ -980,6 +980,120 @@ static void ME_MarkRepaintEnd(ME_DisplayItem *para, *repaint_end = para; }
+static void adjust_para_y(ME_DisplayItem *item, ME_Context *c, ME_DisplayItem *repaint_start, ME_DisplayItem *repaint_end) +{ + if (item->member.para.nFlags & MEPF_ROWSTART) + { + ME_DisplayItem *cell = ME_FindItemFwd(item, diCell); + ME_DisplayItem *endRowPara; + int borderWidth = 0; + cell->member.cell.pt = c->pt; + /* Offset the text by the largest top border width. */ + while (cell->member.cell.next_cell) + { + borderWidth = max(borderWidth, cell->member.cell.border.top.width); + cell = cell->member.cell.next_cell; + } + endRowPara = ME_FindItemFwd(cell, diParagraph); + assert(endRowPara->member.para.nFlags & MEPF_ROWEND); + if (borderWidth > 0) + { + borderWidth = max(ME_twips2pointsY(c, borderWidth), 1); + while (cell) + { + cell->member.cell.yTextOffset = borderWidth; + cell = cell->member.cell.prev_cell; + } + c->pt.y += borderWidth; + } + if (endRowPara->member.para.fmt.dxStartIndent > 0) + { + int dxStartIndent = endRowPara->member.para.fmt.dxStartIndent; + cell = ME_FindItemFwd(item, diCell); + cell->member.cell.pt.x += ME_twips2pointsX(c, dxStartIndent); + c->pt.x = cell->member.cell.pt.x; + } + } + else if (item->member.para.nFlags & MEPF_ROWEND) + { + /* Set all the cells to the height of the largest cell */ + ME_DisplayItem *startRowPara; + int prevHeight, nHeight, bottomBorder = 0; + ME_DisplayItem *cell = ME_FindItemBack(item, diCell); + item->member.para.nWidth = cell->member.cell.pt.x + cell->member.cell.nWidth; + if (!(item->member.para.next_para->member.para.nFlags & MEPF_ROWSTART)) + { + /* Last row, the bottom border is added to the height. */ + cell = cell->member.cell.prev_cell; + while (cell) + { + bottomBorder = max(bottomBorder, cell->member.cell.border.bottom.width); + cell = cell->member.cell.prev_cell; + } + bottomBorder = ME_twips2pointsY(c, bottomBorder); + cell = ME_FindItemBack(item, diCell); + } + prevHeight = cell->member.cell.nHeight; + nHeight = cell->member.cell.prev_cell->member.cell.nHeight + bottomBorder; + cell->member.cell.nHeight = nHeight; + item->member.para.nHeight = nHeight; + cell = cell->member.cell.prev_cell; + cell->member.cell.nHeight = nHeight; + while (cell->member.cell.prev_cell) + { + cell = cell->member.cell.prev_cell; + cell->member.cell.nHeight = nHeight; + } + /* Also set the height of the start row paragraph */ + startRowPara = ME_FindItemBack(cell, diParagraph); + startRowPara->member.para.nHeight = nHeight; + c->pt.x = startRowPara->member.para.pt.x; + c->pt.y = cell->member.cell.pt.y + nHeight; + if (prevHeight < nHeight) + { + /* The height of the cells has grown, so invalidate the bottom of + * the cells. */ + ME_MarkRepaintEnd(item, &repaint_start, &repaint_end); + cell = ME_FindItemBack(item, diCell); + while (cell) + { + ME_MarkRepaintEnd(ME_FindItemBack(cell, diParagraph), &repaint_start, &repaint_end); + cell = cell->member.cell.prev_cell; + } + } + } + else if (item->member.para.pCell && + item->member.para.pCell != item->member.para.next_para->member.para.pCell) + { + /* The next paragraph is in the next cell in the table row. */ + ME_Cell *cell = &item->member.para.pCell->member.cell; + cell->nHeight = c->pt.y + item->member.para.nHeight - cell->pt.y; + + /* Propagate the largest height to the end so that it can be easily + * sent back to all the cells at the end of the row. */ + if (cell->prev_cell) + cell->nHeight = max(cell->nHeight, cell->prev_cell->member.cell.nHeight); + + c->pt.x = cell->pt.x + cell->nWidth; + c->pt.y = cell->pt.y; + cell->next_cell->member.cell.pt = c->pt; + if (!(item->member.para.next_para->member.para.nFlags & MEPF_ROWEND)) + c->pt.y += cell->yTextOffset; + } + else + { + if (item->member.para.pCell) + { + /* Next paragraph in the same cell. */ + c->pt.x = item->member.para.pCell->member.cell.pt.x; + } + else + /* Normal paragraph */ + c->pt.x = 0; + c->pt.y += item->member.para.nHeight; + } +} + BOOL ME_WrapMarkedParagraphs(ME_TextEditor *editor) { ME_DisplayItem *item; @@ -1004,113 +1118,7 @@ BOOL ME_WrapMarkedParagraphs(ME_TextEditor *editor) if (bRedraw) ME_MarkRepaintEnd(item, &repaint_start, &repaint_end);
- if (item->member.para.nFlags & MEPF_ROWSTART) - { - ME_DisplayItem *cell = ME_FindItemFwd(item, diCell); - ME_DisplayItem *endRowPara; - int borderWidth = 0; - cell->member.cell.pt = c.pt; - /* Offset the text by the largest top border width. */ - while (cell->member.cell.next_cell) { - borderWidth = max(borderWidth, cell->member.cell.border.top.width); - cell = cell->member.cell.next_cell; - } - endRowPara = ME_FindItemFwd(cell, diParagraph); - assert(endRowPara->member.para.nFlags & MEPF_ROWEND); - if (borderWidth > 0) - { - borderWidth = max(ME_twips2pointsY(&c, borderWidth), 1); - while (cell) { - cell->member.cell.yTextOffset = borderWidth; - cell = cell->member.cell.prev_cell; - } - c.pt.y += borderWidth; - } - if (endRowPara->member.para.fmt.dxStartIndent > 0) - { - int dxStartIndent = endRowPara->member.para.fmt.dxStartIndent; - cell = ME_FindItemFwd(item, diCell); - cell->member.cell.pt.x += ME_twips2pointsX(&c, dxStartIndent); - c.pt.x = cell->member.cell.pt.x; - } - } - else if (item->member.para.nFlags & MEPF_ROWEND) - { - /* Set all the cells to the height of the largest cell */ - ME_DisplayItem *startRowPara; - int prevHeight, nHeight, bottomBorder = 0; - ME_DisplayItem *cell = ME_FindItemBack(item, diCell); - item->member.para.nWidth = cell->member.cell.pt.x + cell->member.cell.nWidth; - if (!(item->member.para.next_para->member.para.nFlags & MEPF_ROWSTART)) - { - /* Last row, the bottom border is added to the height. */ - cell = cell->member.cell.prev_cell; - while (cell) - { - bottomBorder = max(bottomBorder, cell->member.cell.border.bottom.width); - cell = cell->member.cell.prev_cell; - } - bottomBorder = ME_twips2pointsY(&c, bottomBorder); - cell = ME_FindItemBack(item, diCell); - } - prevHeight = cell->member.cell.nHeight; - nHeight = cell->member.cell.prev_cell->member.cell.nHeight + bottomBorder; - cell->member.cell.nHeight = nHeight; - item->member.para.nHeight = nHeight; - cell = cell->member.cell.prev_cell; - cell->member.cell.nHeight = nHeight; - while (cell->member.cell.prev_cell) - { - cell = cell->member.cell.prev_cell; - cell->member.cell.nHeight = nHeight; - } - /* Also set the height of the start row paragraph */ - startRowPara = ME_FindItemBack(cell, diParagraph); - startRowPara->member.para.nHeight = nHeight; - c.pt.x = startRowPara->member.para.pt.x; - c.pt.y = cell->member.cell.pt.y + nHeight; - if (prevHeight < nHeight) - { - /* The height of the cells has grown, so invalidate the bottom of - * the cells. */ - ME_MarkRepaintEnd(item, &repaint_start, &repaint_end); - cell = ME_FindItemBack(item, diCell); - while (cell) { - ME_MarkRepaintEnd(ME_FindItemBack(cell, diParagraph), &repaint_start, &repaint_end); - cell = cell->member.cell.prev_cell; - } - } - } - else if (item->member.para.pCell && - item->member.para.pCell != item->member.para.next_para->member.para.pCell) - { - /* The next paragraph is in the next cell in the table row. */ - ME_Cell *cell = &item->member.para.pCell->member.cell; - cell->nHeight = c.pt.y + item->member.para.nHeight - cell->pt.y; - - /* Propagate the largest height to the end so that it can be easily - * sent back to all the cells at the end of the row. */ - if (cell->prev_cell) - cell->nHeight = max(cell->nHeight, cell->prev_cell->member.cell.nHeight); - - c.pt.x = cell->pt.x + cell->nWidth; - c.pt.y = cell->pt.y; - cell->next_cell->member.cell.pt = c.pt; - if (!(item->member.para.next_para->member.para.nFlags & MEPF_ROWEND)) - c.pt.y += cell->yTextOffset; - } - else - { - if (item->member.para.pCell) { - /* Next paragraph in the same cell. */ - c.pt.x = item->member.para.pCell->member.cell.pt.x; - } else { - /* Normal paragraph */ - c.pt.x = 0; - } - c.pt.y += item->member.para.nHeight; - } - + adjust_para_y(item, &c, repaint_start, repaint_end); totalWidth = max(totalWidth, item->member.para.nWidth); item = item->member.para.next_para; }
Signed-off-by: Huw Davies huw@codeweavers.com
Signed-off-by: Sergio Gómez Del Real sdelreal@codeweavers.com --- dlls/riched20/caret.c | 2 +- dlls/riched20/editor.c | 3 ++- dlls/riched20/editor.h | 2 ++ dlls/riched20/para.c | 33 ++++++++++++++++++++++----------- dlls/riched20/run.c | 8 ++++---- dlls/riched20/undo.c | 2 +- 6 files changed, 32 insertions(+), 18 deletions(-)
diff --git a/dlls/riched20/caret.c b/dlls/riched20/caret.c index 4664f0ce09..ad72511da4 100644 --- a/dlls/riched20/caret.c +++ b/dlls/riched20/caret.c @@ -380,7 +380,7 @@ BOOL ME_InternalDeleteText(ME_TextEditor *editor, ME_Cursor *start,
c.nOffset -= nCharsToDelete;
- ME_FindItemBack(c.pRun, diParagraph)->member.para.nFlags |= MEPF_REWRAP; + mark_para_rewrap(editor, ME_FindItemBack(c.pRun, diParagraph));
cursor = c; /* nChars is the number of characters that should be deleted from the diff --git a/dlls/riched20/editor.c b/dlls/riched20/editor.c index d79888b933..9ecba6f824 100644 --- a/dlls/riched20/editor.c +++ b/dlls/riched20/editor.c @@ -2564,7 +2564,8 @@ ME_KeyDown(ME_TextEditor *editor, WORD nKey) 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 = MEPF_REWRAP; + para->member.para.nFlags = 0; + mark_para_rewrap(editor, para); editor->pCursors[0].pPara = para; editor->pCursors[0].pRun = ME_FindItemFwd(para, diRun); editor->pCursors[1] = editor->pCursors[0]; diff --git a/dlls/riched20/editor.h b/dlls/riched20/editor.h index eb37368602..3b4dc542a9 100644 --- a/dlls/riched20/editor.h +++ b/dlls/riched20/editor.h @@ -203,6 +203,8 @@ void ME_SetDefaultParaFormat(ME_TextEditor *editor, PARAFORMAT2 *pFmt) DECLSPEC_ void para_num_init( ME_Context *c, ME_Paragraph *para ) DECLSPEC_HIDDEN; 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;
/* paint.c */ void ME_PaintContent(ME_TextEditor *editor, HDC hDC, const RECT *rcUpdate) DECLSPEC_HIDDEN; diff --git a/dlls/riched20/para.c b/dlls/riched20/para.c index c5755b19f4..85703b50cf 100644 --- a/dlls/riched20/para.c +++ b/dlls/riched20/para.c @@ -23,6 +23,16 @@
WINE_DEFAULT_DEBUG_CHANNEL(richedit);
+void mark_para_rewrap(ME_TextEditor *editor, ME_DisplayItem *para) +{ + para->member.para.nFlags |= MEPF_REWRAP; +} + +ME_DisplayItem *get_di_from_para(ME_Paragraph *para) +{ + return (ME_DisplayItem *)((ptrdiff_t)para - offsetof(ME_DisplayItem, member)); +} + static ME_DisplayItem *make_para(ME_TextEditor *editor) { ME_DisplayItem *item = ME_MakeDI(diParagraph); @@ -143,7 +153,7 @@ static void ME_MarkForWrapping(ME_TextEditor *editor, ME_DisplayItem *first, con { while(first != last) { - first->member.para.nFlags |= MEPF_REWRAP; + mark_para_rewrap(editor, first); first = first->member.para.next_para; } } @@ -366,11 +376,11 @@ void para_num_clear( struct para_num *pn ) pn->text = NULL; }
-static void para_num_clear_list( ME_Paragraph *para, const PARAFORMAT2 *orig_fmt ) +static void para_num_clear_list( ME_TextEditor *editor, ME_Paragraph *para, const PARAFORMAT2 *orig_fmt ) { do { - para->nFlags |= MEPF_REWRAP; + mark_para_rewrap(editor, get_di_from_para(para)); para_num_clear( ¶->para_num ); if (para->next_para->type != diParagraph) break; para = ¶->next_para->member.para; @@ -445,12 +455,12 @@ static BOOL ME_SetParaFormat(ME_TextEditor *editor, ME_Paragraph *para, const PA
if (memcmp(©, ¶->fmt, sizeof(PARAFORMAT2))) { - para->nFlags |= MEPF_REWRAP; + mark_para_rewrap(editor, get_di_from_para(para)); if (((dwMask & PFM_NUMBERING) && (copy.wNumbering != para->fmt.wNumbering)) || ((dwMask & PFM_NUMBERINGSTART) && (copy.wNumberingStart != para->fmt.wNumberingStart)) || ((dwMask & PFM_NUMBERINGSTYLE) && (copy.wNumberingStyle != para->fmt.wNumberingStyle))) { - para_num_clear_list( para, © ); + para_num_clear_list( editor, para, © ); } }
@@ -487,7 +497,7 @@ ME_DisplayItem *ME_SplitParagraph(ME_TextEditor *editor, ME_DisplayItem *run,
/* Clear any cached para numbering following this paragraph */ if (run_para->member.para.fmt.wNumbering) - para_num_clear_list( &run_para->member.para, &run_para->member.para.fmt ); + para_num_clear_list( editor, &run_para->member.para, &run_para->member.para.fmt );
new_para->member.para.text = ME_VSplitString( run_para->member.para.text, run->member.run.nCharOfs );
@@ -519,7 +529,8 @@ ME_DisplayItem *ME_SplitParagraph(ME_TextEditor *editor, ME_DisplayItem *run, } new_para->member.para.nCharOfs = run_para->member.para.nCharOfs + ofs; new_para->member.para.nCharOfs += eol_len; - new_para->member.para.nFlags = MEPF_REWRAP; + new_para->member.para.nFlags = 0; + mark_para_rewrap(editor, new_para);
/* FIXME initialize format style and call ME_SetParaFormat blah blah */ new_para->member.para.fmt = run_para->member.para.fmt; @@ -585,8 +596,8 @@ ME_DisplayItem *ME_SplitParagraph(ME_TextEditor *editor, ME_DisplayItem *run, }
/* force rewrap of the */ - run_para->member.para.prev_para->member.para.nFlags |= MEPF_REWRAP; - new_para->member.para.prev_para->member.para.nFlags |= MEPF_REWRAP; + mark_para_rewrap(editor, run_para->member.para.prev_para); + mark_para_rewrap(editor, new_para->member.para.prev_para);
/* we've added the end run, so we need to modify nCharOfs in the next paragraphs */ ME_PropagateCharOffset(next_para, eol_len); @@ -613,7 +624,7 @@ ME_DisplayItem *ME_JoinParagraphs(ME_TextEditor *editor, ME_DisplayItem *tp,
/* Clear any cached para numbering following this paragraph */ if (tp->member.para.fmt.wNumbering) - para_num_clear_list( &tp->member.para, &tp->member.para.fmt ); + para_num_clear_list( editor, &tp->member.para, &tp->member.para.fmt );
pNext = tp->member.para.next_para;
@@ -721,7 +732,7 @@ ME_DisplayItem *ME_JoinParagraphs(ME_TextEditor *editor, ME_DisplayItem *tp, ME_CheckCharOffsets(editor);
editor->nParagraphs--; - tp->member.para.nFlags |= MEPF_REWRAP; + mark_para_rewrap(editor, tp); return tp; }
diff --git a/dlls/riched20/run.c b/dlls/riched20/run.c index 73adc7e637..76f509c5ea 100644 --- a/dlls/riched20/run.c +++ b/dlls/riched20/run.c @@ -224,7 +224,7 @@ void ME_JoinRuns(ME_TextEditor *editor, ME_DisplayItem *p) int i; assert(p->type == diRun && pNext->type == diRun); assert(p->member.run.nCharOfs != -1); - ME_GetParagraph(p)->member.para.nFlags |= MEPF_REWRAP; + mark_para_rewrap(editor, ME_GetParagraph(p));
/* Update all cursors so that they don't contain the soon deleted run */ for (i=0; i<editor->nCursors; i++) { @@ -277,7 +277,7 @@ ME_DisplayItem *ME_SplitRunSimple(ME_TextEditor *editor, ME_Cursor *cursor) editor->pCursors[i].nOffset -= nOffset; } } - cursor->pPara->member.para.nFlags |= MEPF_REWRAP; + mark_para_rewrap(editor, cursor->pPara); return run; }
@@ -345,7 +345,7 @@ ME_InsertRunAtCursor(ME_TextEditor *editor, ME_Cursor *cursor, ME_Style *style, ME_InsertBefore( insert_before, pDI ); TRACE("Shift length:%d\n", len); ME_PropagateCharOffset( insert_before, len ); - insert_before->member.run.para->nFlags |= MEPF_REWRAP; + mark_para_rewrap(editor, get_di_from_para(insert_before->member.run.para));
/* Move any cursors that were at the end of the previous run to the end of the inserted run */ prev = ME_FindItemBack( pDI, diRun ); @@ -766,7 +766,7 @@ void ME_SetCharFormat(ME_TextEditor *editor, ME_Cursor *start, ME_Cursor *end, C ME_ReleaseStyle(para->para_num.style); para->para_num.style = NULL; } - para->nFlags |= MEPF_REWRAP; + mark_para_rewrap(editor, get_di_from_para(para)); } }
diff --git a/dlls/riched20/undo.c b/dlls/riched20/undo.c index 582f88860c..2f18fc78bb 100644 --- a/dlls/riched20/undo.c +++ b/dlls/riched20/undo.c @@ -341,7 +341,7 @@ static void ME_PlayUndoItem(ME_TextEditor *editor, struct undo_item *undo) add_undo_set_para_fmt( editor, ¶->member.para ); para->member.para.fmt = undo->u.set_para_fmt.fmt; para->member.para.border = undo->u.set_para_fmt.border; - para->member.para.nFlags |= MEPF_REWRAP; + mark_para_rewrap(editor, para); break; } case undo_set_char_fmt:
Signed-off-by: Huw Davies huw@codeweavers.com
Signed-off-by: Sergio Gómez Del Real sdelreal@codeweavers.com --- dlls/riched20/para.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/dlls/riched20/para.c b/dlls/riched20/para.c index 85703b50cf..ae2227e235 100644 --- a/dlls/riched20/para.c +++ b/dlls/riched20/para.c @@ -596,7 +596,9 @@ ME_DisplayItem *ME_SplitParagraph(ME_TextEditor *editor, ME_DisplayItem *run, }
/* force rewrap of the */ - mark_para_rewrap(editor, run_para->member.para.prev_para); + if (run_para->member.para.prev_para->type == diParagraph) + mark_para_rewrap(editor, run_para->member.para.prev_para); + mark_para_rewrap(editor, new_para->member.para.prev_para);
/* we've added the end run, so we need to modify nCharOfs in the next paragraphs */
Signed-off-by: Huw Davies huw@codeweavers.com
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;
Signed-off-by: Huw Davies huw@codeweavers.com
Signed-off-by: Sergio Gómez Del Real sdelreal@codeweavers.com --- dlls/riched20/editor.c | 17 ++++------------- dlls/riched20/editstr.h | 1 + dlls/riched20/para.c | 1 + dlls/riched20/wrap.c | 10 ++++++---- 4 files changed, 12 insertions(+), 17 deletions(-)
diff --git a/dlls/riched20/editor.c b/dlls/riched20/editor.c index bf4c8ea0c2..052400c99f 100644 --- a/dlls/riched20/editor.c +++ b/dlls/riched20/editor.c @@ -3036,6 +3036,7 @@ ME_TextEditor *ME_MakeEditor(ITextHost *texthost, BOOL bEmulateVersion10) ed->styleFlags = 0; ed->exStyleFlags = 0; ed->first_marked_para = NULL; + ed->total_rows = 0; ITextHost_TxGetPropertyBits(texthost, (TXTBIT_RICHTEXT|TXTBIT_MULTILINE| TXTBIT_READONLY|TXTBIT_USEPASSWORD| @@ -4215,22 +4216,12 @@ LRESULT ME_HandleMessage(ME_TextEditor *editor, UINT msg, WPARAM wParam, } case EM_GETLINECOUNT: { - ME_DisplayItem *item = editor->pBuffer->pFirst->next; - int nRows = 0; - + ME_DisplayItem *item = editor->pBuffer->pLast; + int nRows = editor->total_rows; ME_DisplayItem *prev_para = NULL, *last_para = NULL;
- while (item != editor->pBuffer->pLast) - { - assert(item->type == diParagraph); - prev_para = ME_FindItemBack(item, diRun); - if (prev_para) { - assert(prev_para->member.run.nFlags & MERF_ENDPARA); - } - nRows += item->member.para.nRows; - item = item->member.para.next_para; - } last_para = ME_FindItemBack(item, diRun); + prev_para = ME_FindItemBack(last_para, diRun); assert(last_para); assert(last_para->member.run.nFlags & MERF_ENDPARA); if (editor->bEmulateVersion10 && prev_para && diff --git a/dlls/riched20/editstr.h b/dlls/riched20/editstr.h index 2cd16c93c8..96c9a1f644 100644 --- a/dlls/riched20/editstr.h +++ b/dlls/riched20/editstr.h @@ -397,6 +397,7 @@ typedef struct tagME_TextEditor int nTotalWidth, nLastTotalWidth; int nAvailWidth; /* 0 = wrap to client area, else wrap width in twips */ int nUDArrowX; + int total_rows; COLORREF rgbBackColor; HBRUSH hbrBackground; BOOL bCaretAtEnd; diff --git a/dlls/riched20/para.c b/dlls/riched20/para.c index aaa2bda06a..c4ddb65d4e 100644 --- a/dlls/riched20/para.c +++ b/dlls/riched20/para.c @@ -54,6 +54,7 @@ void destroy_para(ME_TextEditor *editor, ME_DisplayItem *item) item->member.para.nWidth = 0; editor->nTotalWidth = get_total_width(editor); } + editor->total_rows -= item->member.para.nRows; ME_DestroyString(item->member.para.text); para_num_clear( &item->member.para.para_num ); remove_marked_para(editor, item); diff --git a/dlls/riched20/wrap.c b/dlls/riched20/wrap.c index c2e3f62162..c3444943f0 100644 --- a/dlls/riched20/wrap.c +++ b/dlls/riched20/wrap.c @@ -733,12 +733,13 @@ static int ME_GetParaLineSpace(ME_Context* c, ME_Paragraph* para) return sp * c->editor->nZoomNumerator / c->editor->nZoomDenominator; }
-static void ME_PrepareParagraphForWrapping(ME_Context *c, ME_DisplayItem *tp) { +static void ME_PrepareParagraphForWrapping(ME_TextEditor *editor, ME_Context *c, ME_DisplayItem *tp) { ME_DisplayItem *p;
tp->member.para.nWidth = 0; /* remove row start items as they will be reinserted by the * paragraph wrapper anyway */ + editor->total_rows -= tp->member.para.nRows; tp->member.para.nRows = 0; for (p = tp->next; p != tp->member.para.next_para; p = p->next) { if (p->type == diStartRow) { @@ -870,7 +871,7 @@ static HRESULT shape_para( ME_Context *c, ME_DisplayItem *p ) return hr; }
-static void ME_WrapTextParagraph(ME_Context *c, ME_DisplayItem *tp) { +static void ME_WrapTextParagraph(ME_TextEditor *editor, ME_Context *c, ME_DisplayItem *tp) { ME_DisplayItem *p; ME_WrapContext wc; int border = 0; @@ -881,7 +882,7 @@ static void ME_WrapTextParagraph(ME_Context *c, ME_DisplayItem *tp) { if (!(tp->member.para.nFlags & MEPF_REWRAP)) { return; } - ME_PrepareParagraphForWrapping(c, tp); + ME_PrepareParagraphForWrapping(editor, c, tp);
/* Calculate paragraph numbering label */ para_num_init( c, &tp->member.para ); @@ -969,6 +970,7 @@ static void ME_WrapTextParagraph(ME_Context *c, ME_DisplayItem *tp) { tp->member.para.nFlags &= ~MEPF_REWRAP; tp->member.para.nHeight = wc.pt.y; tp->member.para.nRows = wc.nRow; + editor->total_rows += wc.nRow; }
static void ME_MarkRepaintEnd(ME_DisplayItem *para, @@ -1114,7 +1116,7 @@ BOOL ME_WrapMarkedParagraphs(ME_TextEditor *editor) assert(item->type == diParagraph);
prev_width = item->member.para.nWidth; - ME_WrapTextParagraph(&c, item); + ME_WrapTextParagraph(editor, &c, item); if (prev_width == totalWidth && item->member.para.nWidth < totalWidth) totalWidth = get_total_width(editor); else
Signed-off-by: Huw Davies huw@codeweavers.com
Signed-off-by: Sergio Gómez Del Real sdelreal@codeweavers.com --- dlls/riched20/run.c | 6 ++++-- dlls/riched20/wrap.c | 7 ++----- 2 files changed, 6 insertions(+), 7 deletions(-)
diff --git a/dlls/riched20/run.c b/dlls/riched20/run.c index 76f509c5ea..2cdd3d804a 100644 --- a/dlls/riched20/run.c +++ b/dlls/riched20/run.c @@ -103,6 +103,9 @@ void ME_CheckCharOffsets(ME_TextEditor *editor) ME_DisplayItem *p = editor->pBuffer->pFirst; int ofs = 0, ofsp = 0;
+ if (!TRACE_ON(richedit_check)) + return; + TRACE_(richedit_check)("Checking begin\n"); if(TRACE_ON(richedit_lists)) { @@ -238,8 +241,7 @@ void ME_JoinRuns(ME_TextEditor *editor, ME_DisplayItem *p) ME_Remove(pNext); ME_DestroyDisplayItem(pNext); ME_UpdateRunFlags(editor, &p->member.run); - if(TRACE_ON(richedit_check)) - ME_CheckCharOffsets(editor); + ME_CheckCharOffsets(editor); }
/****************************************************************************** diff --git a/dlls/riched20/wrap.c b/dlls/riched20/wrap.c index c3444943f0..a66137d42c 100644 --- a/dlls/riched20/wrap.c +++ b/dlls/riched20/wrap.c @@ -23,7 +23,6 @@ #include "editor.h"
WINE_DEFAULT_DEBUG_CHANNEL(richedit); -WINE_DECLARE_DEBUG_CHANNEL(richedit_check);
/* * Unsolved problems: @@ -140,8 +139,7 @@ static ME_DisplayItem *split_run_extents(ME_WrapContext *wc, ME_DisplayItem *ite ME_Cursor cursor = {wc->pPara, item, nVChar};
assert(item->member.run.nCharOfs != -1); - if(TRACE_ON(richedit_check)) - ME_CheckCharOffsets(editor); + ME_CheckCharOffsets(editor);
run = &item->member.run;
@@ -160,8 +158,7 @@ static ME_DisplayItem *split_run_extents(ME_WrapContext *wc, ME_DisplayItem *ite run2->pt.x = run->pt.x+run->nWidth; run2->pt.y = run->pt.y;
- if(TRACE_ON(richedit_check)) - ME_CheckCharOffsets(editor); + ME_CheckCharOffsets(editor);
TRACE("After split: %s(%d, %d), %s(%d, %d)\n", debugstr_run( run ), run->pt.x, run->pt.y,
Signed-off-by: Huw Davies huw@codeweavers.com