Commit 61308257 authored by Dylan Smith's avatar Dylan Smith Committed by Alexandre Julliard

richedit: Removed redundant ME_FindItemAtOffset using ME_RunOfsFromCharOfs.

The two functions ME_FindItemAtOffset and ME_RunOfsFromCharOfs were almost identically used, since ME_FindItemAtOffset was always used to find a run. The only difference was how they returned the offset within the run for an end of paragraph run. For ME_FindItemAtOffset it would return the next run if it was in between \r and \n. ME_RunOfsFromCharOfs would instead return an nOffset of 0 for end paragraph runs. This subtle difference introduced bugs, so I decided to avoid having special case in this function when creating this patch, and instead let the caller handle this case.
parent 61f189ce
......@@ -151,8 +151,13 @@ int ME_SetSelection(ME_TextEditor *editor, int from, int to)
return len;
}
ME_RunOfsFromCharOfs(editor, from, &editor->pCursors[1].pRun, &editor->pCursors[1].nOffset);
ME_RunOfsFromCharOfs(editor, to, &editor->pCursors[0].pRun, &editor->pCursors[0].nOffset);
ME_CursorFromCharOfs(editor, from, &editor->pCursors[1]);
ME_CursorFromCharOfs(editor, to, &editor->pCursors[0]);
/* Selection is not allowed in the middle of an end paragraph run. */
if (editor->pCursors[1].pRun->member.run.nFlags & MERF_ENDPARA)
editor->pCursors[1].nOffset = 0;
if (editor->pCursors[0].pRun->member.run.nFlags & MERF_ENDPARA)
editor->pCursors[0].nOffset = 0;
return to;
}
......
......@@ -1624,55 +1624,6 @@ ME_StreamInRTFString(ME_TextEditor *editor, BOOL selection, char *string)
}
ME_DisplayItem *
ME_FindItemAtOffset(ME_TextEditor *editor, ME_DIType nItemType, int nOffset, int *nItemOffset)
{
ME_DisplayItem *item = ME_FindItemFwd(editor->pBuffer->pFirst, diParagraph);
int runLength;
while (item && item->member.para.next_para->member.para.nCharOfs <= nOffset)
item = ME_FindItemFwd(item, diParagraph);
if (!item)
return item;
nOffset -= item->member.para.nCharOfs;
if (nItemType == diParagraph) {
if (nItemOffset)
*nItemOffset = nOffset;
return item;
}
do {
item = ME_FindItemFwd(item, diRun);
runLength = ME_StrLen(item->member.run.strText);
if (item->member.run.nFlags & MERF_ENDPARA)
runLength = item->member.run.nCR + item->member.run.nLF;
} while (item && (item->member.run.nCharOfs + runLength <= nOffset));
if (item) {
nOffset -= item->member.run.nCharOfs;
/* Special case: nOffset may not point exactly at the division between the
\r and the \n in 1.0 emulation. If such a case happens, it is sent
into the next run, if one exists
*/
if ( item->member.run.nFlags & MERF_ENDPARA
&& nOffset == item->member.run.nCR
&& item->member.run.nLF > 0) {
ME_DisplayItem *nextItem;
nextItem = ME_FindItemFwd(item, diRun);
if (nextItem) {
nOffset = 0;
item = nextItem;
}
}
if (nItemOffset)
*nItemOffset = nOffset;
}
return item;
}
static int
ME_FindText(ME_TextEditor *editor, DWORD flags, const CHARRANGE *chrg, const WCHAR *text, CHARRANGE *chrgText)
{
......@@ -1743,7 +1694,7 @@ ME_FindText(ME_TextEditor *editor, DWORD flags, const CHARRANGE *chrg, const WCH
if ((flags & FR_WHOLEWORD) && nMin)
{
nStart = nMin - 1;
item = ME_FindItemAtOffset(editor, diRun, nStart, &nStart);
ME_RunOfsFromCharOfs(editor, nStart, &item, &nStart);
if (!item)
{
if (chrgText)
......@@ -1754,7 +1705,7 @@ ME_FindText(ME_TextEditor *editor, DWORD flags, const CHARRANGE *chrg, const WCH
}
nStart = nMin;
item = ME_FindItemAtOffset(editor, diRun, nStart, &nStart);
ME_RunOfsFromCharOfs(editor, nStart, &item, &nStart);
if (!item)
{
if (chrgText)
......@@ -1836,7 +1787,7 @@ ME_FindText(ME_TextEditor *editor, DWORD flags, const CHARRANGE *chrg, const WCH
if ((flags & FR_WHOLEWORD) && nMax < nTextLen - 1)
{
nEnd = nMax + 1;
item = ME_FindItemAtOffset(editor, diRun, nEnd, &nEnd);
ME_RunOfsFromCharOfs(editor, nEnd, &item, &nEnd);
if (!item)
{
if (chrgText)
......@@ -1847,7 +1798,7 @@ ME_FindText(ME_TextEditor *editor, DWORD flags, const CHARRANGE *chrg, const WCH
}
nEnd = nMax;
item = ME_FindItemAtOffset(editor, diRun, nEnd, &nEnd);
ME_RunOfsFromCharOfs(editor, nEnd, &item, &nEnd);
if (!item)
{
if (chrgText)
......@@ -2117,7 +2068,7 @@ static void ME_UpdateSelectionLinkAttribute(ME_TextEditor *editor)
{
ME_DisplayItem * startPara, * endPara;
ME_DisplayItem * item;
int dummy;
ME_Cursor cursor;
int from, to;
ME_GetSelection(editor, &from, &to);
......@@ -2125,15 +2076,17 @@ static void ME_UpdateSelectionLinkAttribute(ME_TextEditor *editor)
startPara = NULL; endPara = NULL;
/* Find paragraph previous to the one that contains start cursor */
item = ME_FindItemAtOffset(editor, diRun, from, &dummy);
ME_CursorFromCharOfs(editor, from, &cursor);
item = cursor.pRun;
if (item) {
startPara = ME_FindItemBack(item, diParagraph);
item = ME_FindItemBack(startPara, diParagraph);
if (item) startPara = item;
item = startPara->member.para.prev_para;
if (item && item->type == diParagraph) startPara = item;
}
/* Find paragraph that contains end cursor */
item = ME_FindItemAtOffset(editor, diRun, to, &dummy);
ME_CursorFromCharOfs(editor, to, &cursor);
item = cursor.pRun;
if (item) {
endPara = ME_FindItemFwd(item, diParagraph);
}
......@@ -4576,8 +4529,6 @@ int ME_GetTextW(ME_TextEditor *editor, WCHAR *buffer, int nStart,
WCHAR *pStart = buffer;
ME_RunOfsFromCharOfs(editor, nStart, &pRun, &nOffset);
/* Get actual offset within run (ME_RunOfsFromCharOfs sets to 0 if MERF_ENDPARA) */
nOffset = nStart - ME_GetParagraph(pRun)->member.para.nCharOfs - pRun->member.run.nCharOfs;
/* bCRLF flag is only honored in 2.0 and up. 1.0 must always return text verbatim */
if (editor->bEmulateVersion10) bCRLF = 0;
......@@ -4772,7 +4723,7 @@ static BOOL ME_FindNextURLCandidate(ME_TextEditor *editor, int sel_min, int sel_
TRACE("sel_min = %d sel_max = %d\n", sel_min, sel_max);
*candidate_min = *candidate_max = -1;
item = ME_FindItemAtOffset(editor, diRun, sel_min, &nStart);
ME_RunOfsFromCharOfs(editor, sel_min, &item, &nStart);
if (!item) return FALSE;
TRACE("nStart = %d\n", nStart);
para = ME_GetParagraph(item);
......
......@@ -265,7 +265,6 @@ LRESULT ME_HandleMessage(ME_TextEditor *editor, UINT msg, WPARAM wParam,
LPARAM lParam, BOOL unicode, HRESULT* phresult);
void ME_SendOldNotify(ME_TextEditor *editor, int nCode);
int ME_GetTextW(ME_TextEditor *editor, WCHAR *buffer, int nStart, int nChars, BOOL bCRLF);
ME_DisplayItem *ME_FindItemAtOffset(ME_TextEditor *editor, ME_DIType nItemType, int nOffset, int *nItemOffset);
void ME_RTFCharAttrHook(struct _RTF_Info *info);
void ME_RTFParAttrHook(struct _RTF_Info *info);
void ME_RTFTblAttrHook(struct _RTF_Info *info);
......
......@@ -185,50 +185,35 @@ void ME_CursorFromCharOfs(ME_TextEditor *editor, int nCharOfs, ME_Cursor *pCurso
*/
void ME_RunOfsFromCharOfs(ME_TextEditor *editor, int nCharOfs, ME_DisplayItem **ppRun, int *pOfs)
{
ME_DisplayItem *pPara;
int nParaOfs;
ME_DisplayItem *item, *next_item;
pPara = editor->pBuffer->pFirst->member.para.next_para;
assert(pPara);
assert(ppRun);
assert(pOfs);
while (pPara->type == diParagraph)
{
nParaOfs = pPara->member.para.nCharOfs;
assert(nCharOfs >= nParaOfs);
if (nCharOfs < pPara->member.para.next_para->member.para.nCharOfs)
{
int eollen = 1;
*ppRun = ME_FindItemFwd(pPara, diRun);
assert(*ppRun);
while (!((*ppRun)->member.run.nFlags & MERF_ENDPARA))
{
ME_DisplayItem *pNext = ME_FindItemFwd(*ppRun, diRun);
assert(pNext);
assert(pNext->type == diRun);
if (nCharOfs < nParaOfs + pNext->member.run.nCharOfs) {
*pOfs = ME_PosToVPos((*ppRun)->member.run.strText,
nCharOfs - nParaOfs - (*ppRun)->member.run.nCharOfs);
return;
}
*ppRun = pNext;
}
/* Recover proper character length of this line break */
eollen = (*ppRun)->member.run.nCR + (*ppRun)->member.run.nLF;
if (nCharOfs >= nParaOfs + (*ppRun)->member.run.nCharOfs &&
nCharOfs < nParaOfs + (*ppRun)->member.run.nCharOfs + eollen) {
/* FIXME: Might cause problems when actually requiring an offset in the
middle of a run that is considered a single line break */
*pOfs = 0;
return;
}
}
pPara = pPara->member.para.next_para;
}
*ppRun = ME_FindItemBack(editor->pBuffer->pLast, diRun);
*pOfs = 0;
assert((*ppRun)->member.run.nFlags & MERF_ENDPARA);
nCharOfs = max(nCharOfs, 0);
nCharOfs = min(nCharOfs, ME_GetTextLength(editor));
/* Find the paragraph at the offset. */
next_item = editor->pBuffer->pFirst->member.para.next_para;
do {
item = next_item;
next_item = item->member.para.next_para;
} while (next_item->member.para.nCharOfs <= nCharOfs);
assert(item->type == diParagraph);
nCharOfs -= item->member.para.nCharOfs;
/* Find the run at the offset. */
next_item = ME_FindItemFwd(item, diRun);
do {
item = next_item;
next_item = ME_FindItemFwd(item, diRunOrParagraphOrEnd);
} while (next_item->type == diRun &&
next_item->member.run.nCharOfs <= nCharOfs);
assert(item->type == diRun);
nCharOfs -= item->member.run.nCharOfs;
*ppRun = item;
*pOfs = nCharOfs;
}
/******************************************************************************
......@@ -621,6 +606,8 @@ int ME_PointFromChar(ME_TextEditor *editor, ME_Run *pRun, int nOffset)
ME_GetOLEObjectSize(&c, pRun, &size);
ITextHost_TxReleaseDC(editor->texthost, c.hDC);
return nOffset != 0;
} else if (pRun->nFlags & MERF_ENDPARA) {
nOffset = 0;
}
if (editor->cPasswordMask)
......
......@@ -916,14 +916,15 @@ ME_StreamOutRTF(ME_TextEditor *editor, ME_OutStream *pStream, int nStart, int nC
static BOOL
ME_StreamOutText(ME_TextEditor *editor, ME_OutStream *pStream, int nStart, int nChars, DWORD dwFormat)
{
/* FIXME: use ME_RunOfsFromCharOfs */
ME_DisplayItem *item = ME_FindItemAtOffset(editor, diRun, nStart, &nStart);
ME_DisplayItem *item;
int nLen;
UINT nCodePage = CP_ACP;
char *buffer = NULL;
int nBufLen = 0;
BOOL success = TRUE;
ME_RunOfsFromCharOfs(editor, nStart, &item, &nStart);
if (!item)
return FALSE;
......
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