Module: wine Branch: refs/heads/master Commit: d82af6f7115b326a75451cbf2de171846d838739 URL: http://source.winehq.org/git/?p=wine.git;a=commit;h=d82af6f7115b326a75451cbf...
Author: Phil Krylov phil@newstar.rinet.ru Date: Tue Jan 10 12:10:49 2006 +0100
riched20: Speed up text insertion. Optimized reading large texts into RichEdit to be an O(n) order algorythm instead of O(n^2) by removing extraneous conversions of character offsets to run offsets.
---
dlls/riched20/caret.c | 12 +---------- dlls/riched20/editor.h | 2 ++ dlls/riched20/para.c | 53 +++++++++++++++++++++++++++--------------------- dlls/riched20/run.c | 46 ++++++++++++++++++++++++++++-------------- 4 files changed, 64 insertions(+), 49 deletions(-)
diff --git a/dlls/riched20/caret.c b/dlls/riched20/caret.c index 69c6ca1..03bfcf3 100644 --- a/dlls/riched20/caret.c +++ b/dlls/riched20/caret.c @@ -331,19 +331,13 @@ ME_InternalInsertTextFromCursor(ME_TextE const WCHAR *str, int len, ME_Style *style, int flags) { - ME_DisplayItem *pNewRun = NULL; ME_Cursor *p = &editor->pCursors[nCursor];
editor->bCaretAtEnd = FALSE;
assert(p->pRun->type == diRun);
- ME_AddRefStyle(style); - - pNewRun = ME_MakeRun(style, ME_MakeStringN(str, len), flags); /* addrefs style */ - ME_InsertRun(editor, ME_CharOfsFromRunOfs(editor, p->pRun, p->nOffset), pNewRun); - ME_DestroyDisplayItem(pNewRun); - ME_ReleaseStyle(style); + ME_InsertRunAtCursor(editor, p, style, str, len, flags); }
@@ -385,14 +379,10 @@ void ME_InsertTextFromCursor(ME_TextEdit } if (pos-str < len) { /* handle EOLs */ ME_DisplayItem *tp, *end_run; - ME_Paragraph *para; ME_Style *tmp_style; if (pos!=str) ME_InternalInsertTextFromCursor(editor, nCursor, str, pos-str, style, 0); p = &editor->pCursors[nCursor]; - tp = ME_FindItemBack(p->pRun, diParagraph); - para = &tp->member.para; - assert(tp); if (p->nOffset) { ME_SplitRunSimple(editor, p->pRun, p->nOffset); p = &editor->pCursors[nCursor]; diff --git a/dlls/riched20/editor.h b/dlls/riched20/editor.h index 420435f..98167c7 100644 --- a/dlls/riched20/editor.h +++ b/dlls/riched20/editor.h @@ -107,6 +107,8 @@ int ME_RowNumberFromCharOfs(ME_TextEdito ME_DisplayItem *ME_MakeRun(ME_Style *s, ME_String *strData, int nFlags); /* note: ME_InsertRun inserts a copy of the specified run - so you need to destroy the original */ ME_DisplayItem *ME_InsertRun(ME_TextEditor *editor, int nCharOfs, ME_DisplayItem *pItem); +ME_DisplayItem *ME_InsertRunAtCursor(ME_TextEditor *editor, ME_Cursor *cursor, + ME_Style *style, const WCHAR *str, int len, int flags); void ME_CheckCharOffsets(ME_TextEditor *editor); void ME_PropagateCharOffset(ME_DisplayItem *p, int shift); void ME_GetGraphicsSize(ME_TextEditor *editor, ME_Run *run, SIZE *pSize); diff --git a/dlls/riched20/para.c b/dlls/riched20/para.c index a6a548f..b2295c7 100644 --- a/dlls/riched20/para.c +++ b/dlls/riched20/para.c @@ -303,21 +303,37 @@ void ME_SetParaFormat(ME_TextEditor *edi para->member.para.nFlags |= MEPF_REWRAP; }
+ +void +ME_GetSelectionParas(ME_TextEditor *editor, ME_DisplayItem **para, ME_DisplayItem **para_end) +{ + ME_Cursor *pEndCursor = &editor->pCursors[1]; + + *para = ME_GetParagraph(editor->pCursors[0].pRun); + *para_end = ME_GetParagraph(editor->pCursors[1].pRun); + if ((*para_end)->member.para.nCharOfs < (*para)->member.para.nCharOfs) { + ME_DisplayItem *tmp = *para; + + *para = *para_end; + *para_end = tmp; + pEndCursor = &editor->pCursors[0]; + } + + /* selection consists of chars from nFrom up to nTo-1 */ + if ((*para_end)->member.para.nCharOfs > (*para)->member.para.nCharOfs) { + if (!pEndCursor->nOffset) { + *para_end = ME_GetParagraph(ME_FindItemBack(pEndCursor->pRun, diRun)); + } + } +} + + void ME_SetSelectionParaFormat(ME_TextEditor *editor, PARAFORMAT2 *pFmt) { - int nFrom, nTo; - ME_DisplayItem *para, *para_end, *run; - int nOffset; - - ME_GetSelection(editor, &nFrom, &nTo); - if (nTo>nFrom) /* selection consists of chars from nFrom up to nTo-1 */ - nTo--; - - ME_RunOfsFromCharOfs(editor, nFrom, &run, &nOffset); - para = ME_GetParagraph(run); - ME_RunOfsFromCharOfs(editor, nTo, &run, &nOffset); - para_end = ME_GetParagraph(run); + ME_DisplayItem *para, *para_end;
+ ME_GetSelectionParas(editor, ¶, ¶_end); + do { ME_SetParaFormat(editor, para, pFmt); if (para == para_end) @@ -338,19 +354,10 @@ void ME_GetParaFormat(ME_TextEditor *edi
void ME_GetSelectionParaFormat(ME_TextEditor *editor, PARAFORMAT2 *pFmt) { - int nFrom, nTo; - ME_DisplayItem *para, *para_end, *run; - int nOffset; + ME_DisplayItem *para, *para_end; PARAFORMAT2 tmp;
- ME_GetSelection(editor, &nFrom, &nTo); - if (nTo>nFrom) /* selection consists of chars from nFrom up to nTo-1 */ - nTo--; - - ME_RunOfsFromCharOfs(editor, nFrom, &run, &nOffset); - para = ME_GetParagraph(run); - ME_RunOfsFromCharOfs(editor, nTo, &run, &nOffset); - para_end = ME_GetParagraph(run); + ME_GetSelectionParas(editor, ¶, ¶_end);
ME_GetParaFormat(editor, para, pFmt); if (para == para_end) return; diff --git a/dlls/riched20/run.c b/dlls/riched20/run.c index 568472c..5c97941 100644 --- a/dlls/riched20/run.c +++ b/dlls/riched20/run.c @@ -293,31 +293,47 @@ ME_DisplayItem *ME_MakeRun(ME_Style *s, return item; }
+ ME_DisplayItem *ME_InsertRun(ME_TextEditor *editor, int nCharOfs, ME_DisplayItem *pItem) { ME_Cursor tmp; ME_DisplayItem *pDI; - ME_UndoItem *pUI;
assert(pItem->type == diRun || pItem->type == diUndoInsertRun);
+ ME_CursorFromCharOfs(editor, nCharOfs, &tmp); + pDI = ME_InsertRunAtCursor(editor, &tmp, pItem->member.run.style, + pItem->member.run.strText->szData, + pItem->member.run.strText->nLen, + pItem->member.run.nFlags); + + return pDI; +} + +ME_DisplayItem * +ME_InsertRunAtCursor(ME_TextEditor *editor, ME_Cursor *cursor, ME_Style *style, + const WCHAR *str, int len, int flags) +{ + ME_DisplayItem *pDI; + ME_UndoItem *pUI; + + if (cursor->nOffset) { + cursor->pRun = ME_SplitRunSimple(editor, cursor->pRun, cursor->nOffset); + cursor->nOffset = 0; + } + pUI = ME_AddUndoItem(editor, diUndoDeleteRun, NULL); if (pUI) { - pUI->nStart = nCharOfs; - pUI->nLen = pItem->member.run.strText->nLen; + pUI->nStart = cursor->pRun->member.run.nCharOfs; + pUI->nLen = len; } - ME_CursorFromCharOfs(editor, nCharOfs, &tmp); - if (tmp.nOffset) { - tmp.pRun = ME_SplitRunSimple(editor, tmp.pRun, tmp.nOffset); - tmp.nOffset = 0; - } - pDI = ME_MakeRun(pItem->member.run.style, ME_StrDup(pItem->member.run.strText), pItem->member.run.nFlags); - pDI->member.run.nCharOfs = tmp.pRun->member.run.nCharOfs; - ME_InsertBefore(tmp.pRun, pDI); - TRACE("Shift length:%d\n", pDI->member.run.strText->nLen); - ME_PropagateCharOffset(tmp.pRun, pDI->member.run.strText->nLen); - ME_GetParagraph(tmp.pRun)->member.para.nFlags |= MEPF_REWRAP; - + + pDI = ME_MakeRun(style, ME_MakeStringN(str, len), flags); + pDI->member.run.nCharOfs = cursor->pRun->member.run.nCharOfs; + ME_InsertBefore(cursor->pRun, pDI); + TRACE("Shift length:%d\n", len); + ME_PropagateCharOffset(cursor->pRun, len); + ME_GetParagraph(cursor->pRun)->member.para.nFlags |= MEPF_REWRAP; return pDI; }