Commit d82af6f7 authored by Phil Krylov's avatar Phil Krylov Committed by Alexandre Julliard

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.
parent a8b71c27
...@@ -331,19 +331,13 @@ ME_InternalInsertTextFromCursor(ME_TextEditor *editor, int nCursor, ...@@ -331,19 +331,13 @@ ME_InternalInsertTextFromCursor(ME_TextEditor *editor, int nCursor,
const WCHAR *str, int len, ME_Style *style, const WCHAR *str, int len, ME_Style *style,
int flags) int flags)
{ {
ME_DisplayItem *pNewRun = NULL;
ME_Cursor *p = &editor->pCursors[nCursor]; ME_Cursor *p = &editor->pCursors[nCursor];
editor->bCaretAtEnd = FALSE; editor->bCaretAtEnd = FALSE;
assert(p->pRun->type == diRun); assert(p->pRun->type == diRun);
ME_AddRefStyle(style); ME_InsertRunAtCursor(editor, p, style, str, len, flags);
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);
} }
...@@ -385,14 +379,10 @@ void ME_InsertTextFromCursor(ME_TextEditor *editor, int nCursor, ...@@ -385,14 +379,10 @@ void ME_InsertTextFromCursor(ME_TextEditor *editor, int nCursor,
} }
if (pos-str < len) { /* handle EOLs */ if (pos-str < len) { /* handle EOLs */
ME_DisplayItem *tp, *end_run; ME_DisplayItem *tp, *end_run;
ME_Paragraph *para;
ME_Style *tmp_style; ME_Style *tmp_style;
if (pos!=str) if (pos!=str)
ME_InternalInsertTextFromCursor(editor, nCursor, str, pos-str, style, 0); ME_InternalInsertTextFromCursor(editor, nCursor, str, pos-str, style, 0);
p = &editor->pCursors[nCursor]; p = &editor->pCursors[nCursor];
tp = ME_FindItemBack(p->pRun, diParagraph);
para = &tp->member.para;
assert(tp);
if (p->nOffset) { if (p->nOffset) {
ME_SplitRunSimple(editor, p->pRun, p->nOffset); ME_SplitRunSimple(editor, p->pRun, p->nOffset);
p = &editor->pCursors[nCursor]; p = &editor->pCursors[nCursor];
......
...@@ -107,6 +107,8 @@ int ME_RowNumberFromCharOfs(ME_TextEditor *editor, int nOfs); ...@@ -107,6 +107,8 @@ int ME_RowNumberFromCharOfs(ME_TextEditor *editor, int nOfs);
ME_DisplayItem *ME_MakeRun(ME_Style *s, ME_String *strData, int nFlags); 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 */ /* 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_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_CheckCharOffsets(ME_TextEditor *editor);
void ME_PropagateCharOffset(ME_DisplayItem *p, int shift); void ME_PropagateCharOffset(ME_DisplayItem *p, int shift);
void ME_GetGraphicsSize(ME_TextEditor *editor, ME_Run *run, SIZE *pSize); void ME_GetGraphicsSize(ME_TextEditor *editor, ME_Run *run, SIZE *pSize);
......
...@@ -303,21 +303,37 @@ void ME_SetParaFormat(ME_TextEditor *editor, ME_DisplayItem *para, PARAFORMAT2 * ...@@ -303,21 +303,37 @@ void ME_SetParaFormat(ME_TextEditor *editor, ME_DisplayItem *para, PARAFORMAT2 *
para->member.para.nFlags |= MEPF_REWRAP; para->member.para.nFlags |= MEPF_REWRAP;
} }
void ME_SetSelectionParaFormat(ME_TextEditor *editor, PARAFORMAT2 *pFmt)
void
ME_GetSelectionParas(ME_TextEditor *editor, ME_DisplayItem **para, ME_DisplayItem **para_end)
{ {
int nFrom, nTo; ME_Cursor *pEndCursor = &editor->pCursors[1];
ME_DisplayItem *para, *para_end, *run;
int nOffset;
ME_GetSelection(editor, &nFrom, &nTo); *para = ME_GetParagraph(editor->pCursors[0].pRun);
if (nTo>nFrom) /* selection consists of chars from nFrom up to nTo-1 */ *para_end = ME_GetParagraph(editor->pCursors[1].pRun);
nTo--; if ((*para_end)->member.para.nCharOfs < (*para)->member.para.nCharOfs) {
ME_DisplayItem *tmp = *para;
*para = *para_end;
*para_end = tmp;
pEndCursor = &editor->pCursors[0];
}
ME_RunOfsFromCharOfs(editor, nFrom, &run, &nOffset); /* selection consists of chars from nFrom up to nTo-1 */
para = ME_GetParagraph(run); if ((*para_end)->member.para.nCharOfs > (*para)->member.para.nCharOfs) {
ME_RunOfsFromCharOfs(editor, nTo, &run, &nOffset); if (!pEndCursor->nOffset) {
para_end = ME_GetParagraph(run); *para_end = ME_GetParagraph(ME_FindItemBack(pEndCursor->pRun, diRun));
}
}
}
void ME_SetSelectionParaFormat(ME_TextEditor *editor, PARAFORMAT2 *pFmt)
{
ME_DisplayItem *para, *para_end;
ME_GetSelectionParas(editor, &para, &para_end);
do { do {
ME_SetParaFormat(editor, para, pFmt); ME_SetParaFormat(editor, para, pFmt);
if (para == para_end) if (para == para_end)
...@@ -338,19 +354,10 @@ void ME_GetParaFormat(ME_TextEditor *editor, ME_DisplayItem *para, PARAFORMAT2 * ...@@ -338,19 +354,10 @@ void ME_GetParaFormat(ME_TextEditor *editor, ME_DisplayItem *para, PARAFORMAT2 *
void ME_GetSelectionParaFormat(ME_TextEditor *editor, PARAFORMAT2 *pFmt) void ME_GetSelectionParaFormat(ME_TextEditor *editor, PARAFORMAT2 *pFmt)
{ {
int nFrom, nTo; ME_DisplayItem *para, *para_end;
ME_DisplayItem *para, *para_end, *run;
int nOffset;
PARAFORMAT2 tmp; PARAFORMAT2 tmp;
ME_GetSelection(editor, &nFrom, &nTo); ME_GetSelectionParas(editor, &para, &para_end);
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_GetParaFormat(editor, para, pFmt); ME_GetParaFormat(editor, para, pFmt);
if (para == para_end) return; if (para == para_end) return;
......
...@@ -293,31 +293,47 @@ ME_DisplayItem *ME_MakeRun(ME_Style *s, ME_String *strData, int nFlags) ...@@ -293,31 +293,47 @@ ME_DisplayItem *ME_MakeRun(ME_Style *s, ME_String *strData, int nFlags)
return item; return item;
} }
ME_DisplayItem *ME_InsertRun(ME_TextEditor *editor, int nCharOfs, ME_DisplayItem *pItem) ME_DisplayItem *ME_InsertRun(ME_TextEditor *editor, int nCharOfs, ME_DisplayItem *pItem)
{ {
ME_Cursor tmp; ME_Cursor tmp;
ME_DisplayItem *pDI; ME_DisplayItem *pDI;
ME_UndoItem *pUI;
assert(pItem->type == diRun || pItem->type == diUndoInsertRun); 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); pUI = ME_AddUndoItem(editor, diUndoDeleteRun, NULL);
if (pUI) { if (pUI) {
pUI->nStart = nCharOfs; pUI->nStart = cursor->pRun->member.run.nCharOfs;
pUI->nLen = pItem->member.run.strText->nLen; pUI->nLen = len;
} }
ME_CursorFromCharOfs(editor, nCharOfs, &tmp);
if (tmp.nOffset) { pDI = ME_MakeRun(style, ME_MakeStringN(str, len), flags);
tmp.pRun = ME_SplitRunSimple(editor, tmp.pRun, tmp.nOffset); pDI->member.run.nCharOfs = cursor->pRun->member.run.nCharOfs;
tmp.nOffset = 0; ME_InsertBefore(cursor->pRun, pDI);
} TRACE("Shift length:%d\n", len);
pDI = ME_MakeRun(pItem->member.run.style, ME_StrDup(pItem->member.run.strText), pItem->member.run.nFlags); ME_PropagateCharOffset(cursor->pRun, len);
pDI->member.run.nCharOfs = tmp.pRun->member.run.nCharOfs; ME_GetParagraph(cursor->pRun)->member.para.nFlags |= MEPF_REWRAP;
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;
return pDI; return pDI;
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment