[7/8] richedit: Use ME_Cursor instead of offsets for stream out functions.
Dylan Smith
dylan.ah.smith at gmail.com
Thu Aug 13 07:44:22 CDT 2009
---
dlls/riched20/clipboard.c | 9 +-
dlls/riched20/editor.h | 2 +-
dlls/riched20/writer.c | 269 ++++++++++++++++++++++-----------------------
3 files changed, 133 insertions(+), 147 deletions(-)
-------------- next part --------------
diff --git a/dlls/riched20/clipboard.c b/dlls/riched20/clipboard.c
index 3a8e547..15ce97b 100644
--- a/dlls/riched20/clipboard.c
+++ b/dlls/riched20/clipboard.c
@@ -375,7 +375,7 @@ static DWORD CALLBACK ME_AppendToHGLOBAL(DWORD_PTR dwCookie, LPBYTE lpBuff, LONG
return 0;
}
-static HGLOBAL get_rtf_text(ME_TextEditor *editor, const CHARRANGE *lpchrg)
+static HGLOBAL get_rtf_text(ME_TextEditor *editor, const ME_Cursor *start, int nChars)
{
EDITSTREAM es;
ME_GlobalDestStruct gds;
@@ -384,7 +384,7 @@ static HGLOBAL get_rtf_text(ME_TextEditor *editor, const CHARRANGE *lpchrg)
gds.nLength = 0;
es.dwCookie = (DWORD_PTR)&gds;
es.pfnCallback = ME_AppendToHGLOBAL;
- ME_StreamOutRange(editor, SF_RTF, lpchrg->cpMin, lpchrg->cpMax, &es);
+ ME_StreamOutRange(editor, SF_RTF, start, nChars, &es);
GlobalReAlloc(gds.hData, gds.nLength+1, 0);
return gds.hData;
}
@@ -410,10 +410,7 @@ HRESULT ME_GetDataObject(ME_TextEditor *editor, const ME_Cursor *start,
obj->fmtetc = GlobalAlloc(GMEM_ZEROINIT, obj->fmtetc_cnt*sizeof(FORMATETC));
InitFormatEtc(obj->fmtetc[0], CF_UNICODETEXT, TYMED_HGLOBAL);
if(editor->mode & TM_RICHTEXT) {
- CHARRANGE chrg;
- chrg.cpMin = ME_GetCursorOfs(start);
- chrg.cpMax = chrg.cpMin + nChars;
- obj->rtf = get_rtf_text(editor, &chrg);
+ obj->rtf = get_rtf_text(editor, start, nChars);
InitFormatEtc(obj->fmtetc[1], cfRTF, TYMED_HGLOBAL);
}
diff --git a/dlls/riched20/editor.h b/dlls/riched20/editor.h
index 0457239..9b9ab4e 100644
--- a/dlls/riched20/editor.h
+++ b/dlls/riched20/editor.h
@@ -329,7 +329,7 @@ BOOL ME_Redo(ME_TextEditor *editor);
void ME_EmptyUndoStack(ME_TextEditor *editor);
/* writer.c */
-LRESULT ME_StreamOutRange(ME_TextEditor *editor, DWORD dwFormat, int nStart, int nTo, EDITSTREAM *stream);
+LRESULT ME_StreamOutRange(ME_TextEditor *editor, DWORD dwFormat, const ME_Cursor *start, int nChars, EDITSTREAM *stream);
LRESULT ME_StreamOut(ME_TextEditor *editor, DWORD dwFormat, EDITSTREAM *stream);
/* clipboard.c */
diff --git a/dlls/riched20/writer.c b/dlls/riched20/writer.c
index a41fe42..107fadf 100644
--- a/dlls/riched20/writer.c
+++ b/dlls/riched20/writer.c
@@ -762,23 +762,23 @@ ME_StreamOutRTFText(ME_OutStream *pStream, const WCHAR *text, LONG nChars)
}
-static BOOL
-ME_StreamOutRTF(ME_TextEditor *editor, ME_OutStream *pStream, int nStart, int nChars, int dwFormat)
+static BOOL ME_StreamOutRTF(ME_TextEditor *editor, ME_OutStream *pStream,
+ const ME_Cursor *start, int nChars, int dwFormat)
{
- ME_DisplayItem *p, *pEnd, *pPara;
- int nOffset, nEndLen;
+ ME_Cursor cursor = *start;
+ ME_DisplayItem *prev_para = cursor.pPara;
+ ME_Cursor endCur = cursor;
- ME_RunOfsFromCharOfs(editor, nStart, &pPara, &p, &nOffset);
- ME_RunOfsFromCharOfs(editor, nStart+nChars, NULL, &pEnd, &nEndLen);
+ ME_MoveCursorChars(editor, &endCur, nChars);
if (!ME_StreamOutRTFHeader(pStream, dwFormat))
return FALSE;
- if (!ME_StreamOutRTFFontAndColorTbl(pStream, p, pEnd))
+ if (!ME_StreamOutRTFFontAndColorTbl(pStream, cursor.pRun, endCur.pRun))
return FALSE;
-
+
/* TODO: stylesheet table */
-
+
/* FIXME: maybe emit something smarter for the generator? */
if (!ME_StreamOutPrint(pStream, "{\\*\\generator Wine Riched20 2.0.????;}"))
return FALSE;
@@ -791,138 +791,129 @@ ME_StreamOutRTF(ME_TextEditor *editor, ME_OutStream *pStream, int nStart, int nC
/* TODO: section formatting properties */
- if (!ME_StreamOutRTFParaProps(editor, pStream, pPara))
+ if (!ME_StreamOutRTFParaProps(editor, pStream, cursor.pPara))
return FALSE;
- while(1)
- {
- switch(p->type)
+ do {
+ if (cursor.pPara != prev_para)
{
- case diParagraph:
- if (!editor->bEmulateVersion10) { /* v4.1 */
- if (p->member.para.nFlags & MEPF_ROWSTART) {
- pStream->nNestingLevel++;
- if (pStream->nNestingLevel == 1) {
- if (!ME_StreamOutRTFTableProps(editor, pStream, p))
- return FALSE;
- }
- } else if (p->member.para.nFlags & MEPF_ROWEND) {
- pStream->nNestingLevel--;
- if (pStream->nNestingLevel >= 1) {
- if (!ME_StreamOutPrint(pStream, "{\\*\\nesttableprops"))
- return FALSE;
- if (!ME_StreamOutRTFTableProps(editor, pStream, p))
- return FALSE;
- if (!ME_StreamOutPrint(pStream, "\\nestrow}{\\nonesttables\\par}\r\n"))
- return FALSE;
- } else {
- if (!ME_StreamOutPrint(pStream, "\\row \r\n"))
- return FALSE;
- }
- } else if (!ME_StreamOutRTFParaProps(editor, pStream, p)) {
- return FALSE;
- }
- } else { /* v1.0 - 3.0 */
- if (p->member.para.pFmt->dwMask & PFM_TABLE &&
- p->member.para.pFmt->wEffects & PFE_TABLE)
- {
- if (!ME_StreamOutRTFTableProps(editor, pStream, p))
+ prev_para = cursor.pPara;
+ if (!editor->bEmulateVersion10) { /* v4.1 */
+ if (cursor.pPara->member.para.nFlags & MEPF_ROWSTART) {
+ pStream->nNestingLevel++;
+ if (pStream->nNestingLevel == 1) {
+ if (!ME_StreamOutRTFTableProps(editor, pStream, cursor.pPara))
return FALSE;
}
- if (!ME_StreamOutRTFParaProps(editor, pStream, p))
- return FALSE;
- }
- pPara = p;
- break;
- case diRun:
- if (p == pEnd && !nEndLen)
- break;
- TRACE("flags %xh\n", p->member.run.nFlags);
- /* TODO: emit embedded objects */
- if (pPara->member.para.nFlags & (MEPF_ROWSTART|MEPF_ROWEND))
- break;
- if (p->member.run.nFlags & MERF_GRAPHICS) {
- FIXME("embedded objects are not handled\n");
- } else if (p->member.run.nFlags & MERF_TAB) {
- if (editor->bEmulateVersion10 && /* v1.0 - 3.0 */
- pPara->member.para.pFmt->dwMask & PFM_TABLE &&
- pPara->member.para.pFmt->wEffects & PFE_TABLE)
- {
- if (!ME_StreamOutPrint(pStream, "\\cell "))
+ } else if (cursor.pPara->member.para.nFlags & MEPF_ROWEND) {
+ pStream->nNestingLevel--;
+ if (pStream->nNestingLevel >= 1) {
+ if (!ME_StreamOutPrint(pStream, "{\\*\\nesttableprops"))
return FALSE;
- } else {
- if (!ME_StreamOutPrint(pStream, "\\tab "))
+ if (!ME_StreamOutRTFTableProps(editor, pStream, cursor.pPara))
return FALSE;
- }
- } else if (p->member.run.nFlags & MERF_ENDCELL) {
- if (pStream->nNestingLevel > 1) {
- if (!ME_StreamOutPrint(pStream, "\\nestcell "))
+ if (!ME_StreamOutPrint(pStream, "\\nestrow}{\\nonesttables\\par}\r\n"))
return FALSE;
} else {
- if (!ME_StreamOutPrint(pStream, "\\cell "))
- return FALSE;
- }
- nChars--;
- } else if (p->member.run.nFlags & MERF_ENDPARA) {
- if (pPara->member.para.pFmt->dwMask & PFM_TABLE &&
- pPara->member.para.pFmt->wEffects & PFE_TABLE &&
- !(pPara->member.para.nFlags & (MEPF_ROWSTART|MEPF_ROWEND|MEPF_CELL)))
- {
if (!ME_StreamOutPrint(pStream, "\\row \r\n"))
return FALSE;
- } else {
- if (!ME_StreamOutPrint(pStream, "\r\n\\par"))
- return FALSE;
}
- /* Skip as many characters as required by current line break */
- nChars = max(0, nChars - p->member.run.strText->nLen);
- } else if (p->member.run.nFlags & MERF_ENDROW) {
- if (!ME_StreamOutPrint(pStream, "\\line \r\n"))
- return FALSE;
- nChars--;
- } else {
- int nEnd;
-
- if (!ME_StreamOutPrint(pStream, "{"))
- return FALSE;
- TRACE("style %p\n", p->member.run.style);
- if (!ME_StreamOutRTFCharProps(pStream, &p->member.run.style->fmt))
- return FALSE;
-
- nEnd = (p == pEnd) ? nEndLen : p->member.run.strText->nLen;
- if (!ME_StreamOutRTFText(pStream, p->member.run.strText->szData + nOffset, nEnd - nOffset))
- return FALSE;
- nOffset = 0;
- if (!ME_StreamOutPrint(pStream, "}"))
+ } else if (!ME_StreamOutRTFParaProps(editor, pStream, cursor.pPara)) {
+ return FALSE;
+ }
+ } else { /* v1.0 - 3.0 */
+ if (cursor.pPara->member.para.pFmt->dwMask & PFM_TABLE &&
+ cursor.pPara->member.para.pFmt->wEffects & PFE_TABLE)
+ {
+ if (!ME_StreamOutRTFTableProps(editor, pStream, cursor.pPara))
return FALSE;
}
- break;
- default: /* we missed the last item */
- assert(0);
+ if (!ME_StreamOutRTFParaProps(editor, pStream, cursor.pPara))
+ return FALSE;
+ }
}
- if (p == pEnd)
+
+ if (cursor.pRun == endCur.pRun && !endCur.nOffset)
break;
- p = ME_FindItemFwd(p, diRunOrParagraphOrEnd);
- }
+ TRACE("flags %xh\n", cursor.pRun->member.run.nFlags);
+ /* TODO: emit embedded objects */
+ if (cursor.pPara->member.para.nFlags & (MEPF_ROWSTART|MEPF_ROWEND))
+ break;
+ if (cursor.pRun->member.run.nFlags & MERF_GRAPHICS) {
+ FIXME("embedded objects are not handled\n");
+ } else if (cursor.pRun->member.run.nFlags & MERF_TAB) {
+ if (editor->bEmulateVersion10 && /* v1.0 - 3.0 */
+ cursor.pPara->member.para.pFmt->dwMask & PFM_TABLE &&
+ cursor.pPara->member.para.pFmt->wEffects & PFE_TABLE)
+ {
+ if (!ME_StreamOutPrint(pStream, "\\cell "))
+ return FALSE;
+ } else {
+ if (!ME_StreamOutPrint(pStream, "\\tab "))
+ return FALSE;
+ }
+ } else if (cursor.pRun->member.run.nFlags & MERF_ENDCELL) {
+ if (pStream->nNestingLevel > 1) {
+ if (!ME_StreamOutPrint(pStream, "\\nestcell "))
+ return FALSE;
+ } else {
+ if (!ME_StreamOutPrint(pStream, "\\cell "))
+ return FALSE;
+ }
+ nChars--;
+ } else if (cursor.pRun->member.run.nFlags & MERF_ENDPARA) {
+ if (cursor.pPara->member.para.pFmt->dwMask & PFM_TABLE &&
+ cursor.pPara->member.para.pFmt->wEffects & PFE_TABLE &&
+ !(cursor.pPara->member.para.nFlags & (MEPF_ROWSTART|MEPF_ROWEND|MEPF_CELL)))
+ {
+ if (!ME_StreamOutPrint(pStream, "\\row \r\n"))
+ return FALSE;
+ } else {
+ if (!ME_StreamOutPrint(pStream, "\r\n\\par"))
+ return FALSE;
+ }
+ /* Skip as many characters as required by current line break */
+ nChars = max(0, nChars - cursor.pRun->member.run.strText->nLen);
+ } else if (cursor.pRun->member.run.nFlags & MERF_ENDROW) {
+ if (!ME_StreamOutPrint(pStream, "\\line \r\n"))
+ return FALSE;
+ nChars--;
+ } else {
+ int nEnd;
+
+ if (!ME_StreamOutPrint(pStream, "{"))
+ return FALSE;
+ TRACE("style %p\n", cursor.pRun->member.run.style);
+ if (!ME_StreamOutRTFCharProps(pStream, &cursor.pRun->member.run.style->fmt))
+ return FALSE;
+
+ nEnd = (cursor.pRun == endCur.pRun) ? endCur.nOffset : cursor.pRun->member.run.strText->nLen;
+ if (!ME_StreamOutRTFText(pStream, cursor.pRun->member.run.strText->szData + cursor.nOffset,
+ nEnd - cursor.nOffset))
+ return FALSE;
+ cursor.nOffset = 0;
+ if (!ME_StreamOutPrint(pStream, "}"))
+ return FALSE;
+ }
+ } while (cursor.pRun != endCur.pRun && ME_NextRun(&cursor.pPara, &cursor.pRun));
+
if (!ME_StreamOutMove(pStream, "}\0", 2))
return FALSE;
return TRUE;
}
-static BOOL
-ME_StreamOutText(ME_TextEditor *editor, ME_OutStream *pStream, int nStart, int nChars, DWORD dwFormat)
+static BOOL ME_StreamOutText(ME_TextEditor *editor, ME_OutStream *pStream,
+ const ME_Cursor *start, int nChars, DWORD dwFormat)
{
- ME_DisplayItem *item;
+ ME_Cursor cursor = *start;
int nLen;
UINT nCodePage = CP_ACP;
char *buffer = NULL;
int nBufLen = 0;
BOOL success = TRUE;
- ME_RunOfsFromCharOfs(editor, nStart, NULL, &item, &nStart);
-
- if (!item)
+ if (!cursor.pRun)
return FALSE;
if (dwFormat & SF_USECODEPAGE)
@@ -930,10 +921,10 @@ ME_StreamOutText(ME_TextEditor *editor, ME_OutStream *pStream, int nStart, int n
/* TODO: Handle SF_TEXTIZED */
- while (success && nChars && item) {
- nLen = min(nChars, item->member.run.strText->nLen - nStart);
+ while (success && nChars && cursor.pRun) {
+ nLen = min(nChars, cursor.pRun->member.run.strText->nLen - cursor.nOffset);
- if (!editor->bEmulateVersion10 && item->member.run.nFlags & MERF_ENDPARA)
+ if (!editor->bEmulateVersion10 && cursor.pRun->member.run.nFlags & MERF_ENDPARA)
{
static const WCHAR szEOL[2] = { '\r', '\n' };
@@ -944,27 +935,27 @@ ME_StreamOutText(ME_TextEditor *editor, ME_OutStream *pStream, int nStart, int n
success = ME_StreamOutMove(pStream, "\r\n", 2);
} else {
if (dwFormat & SF_UNICODE)
- success = ME_StreamOutMove(pStream, (const char *)(item->member.run.strText->szData + nStart),
+ success = ME_StreamOutMove(pStream, (const char *)(cursor.pRun->member.run.strText->szData + cursor.nOffset),
sizeof(WCHAR) * nLen);
else {
int nSize;
- nSize = WideCharToMultiByte(nCodePage, 0, item->member.run.strText->szData + nStart,
+ nSize = WideCharToMultiByte(nCodePage, 0, cursor.pRun->member.run.strText->szData + cursor.nOffset,
nLen, NULL, 0, NULL, NULL);
if (nSize > nBufLen) {
FREE_OBJ(buffer);
buffer = ALLOC_N_OBJ(char, nSize);
nBufLen = nSize;
}
- WideCharToMultiByte(nCodePage, 0, item->member.run.strText->szData + nStart,
+ WideCharToMultiByte(nCodePage, 0, cursor.pRun->member.run.strText->szData + cursor.nOffset,
nLen, buffer, nSize, NULL, NULL);
success = ME_StreamOutMove(pStream, buffer, nSize);
}
}
nChars -= nLen;
- nStart = 0;
- item = ME_FindItemFwd(item, diRun);
+ cursor.nOffset = 0;
+ cursor.pRun = ME_FindItemFwd(cursor.pRun, diRun);
}
FREE_OBJ(buffer);
@@ -972,24 +963,16 @@ ME_StreamOutText(ME_TextEditor *editor, ME_OutStream *pStream, int nStart, int n
}
-LRESULT
-ME_StreamOutRange(ME_TextEditor *editor, DWORD dwFormat, int nStart, int nTo, EDITSTREAM *stream)
+LRESULT ME_StreamOutRange(ME_TextEditor *editor, DWORD dwFormat,
+ const ME_Cursor *start,
+ int nChars, EDITSTREAM *stream)
{
ME_OutStream *pStream = ME_StreamOutInit(editor, stream);
- if (nTo == -1)
- {
- nTo = ME_GetTextLength(editor);
- /* Generate an end-of-paragraph at the end of SCF_ALL RTF output */
- if (dwFormat & SF_RTF)
- nTo++;
- }
- TRACE("from %d to %d\n", nStart, nTo);
-
if (dwFormat & SF_RTF)
- ME_StreamOutRTF(editor, pStream, nStart, nTo - nStart, dwFormat);
+ ME_StreamOutRTF(editor, pStream, start, nChars, dwFormat);
else if (dwFormat & SF_TEXT || dwFormat & SF_TEXTIZED)
- ME_StreamOutText(editor, pStream, nStart, nTo - nStart, dwFormat);
+ ME_StreamOutText(editor, pStream, start, nChars, dwFormat);
if (!pStream->stream->dwError)
ME_StreamOutFlush(pStream);
return ME_StreamOutFree(pStream);
@@ -998,13 +981,19 @@ ME_StreamOutRange(ME_TextEditor *editor, DWORD dwFormat, int nStart, int nTo, ED
LRESULT
ME_StreamOut(ME_TextEditor *editor, DWORD dwFormat, EDITSTREAM *stream)
{
- int nStart, nTo;
+ ME_Cursor start;
+ int nChars;
- if (dwFormat & SFF_SELECTION)
- ME_GetSelectionOfs(editor, &nStart, &nTo);
- else {
- nStart = 0;
- nTo = -1;
+ if (dwFormat & SFF_SELECTION) {
+ int nStart, nTo;
+ start = editor->pCursors[ME_GetSelectionOfs(editor, &nStart, &nTo)];
+ nChars = nTo - nStart;
+ } else {
+ ME_SetCursorToStart(editor, &start);
+ nChars = ME_GetTextLength(editor);
+ /* Generate an end-of-paragraph at the end of SCF_ALL RTF output */
+ if (dwFormat & SF_RTF)
+ nChars++;
}
- return ME_StreamOutRange(editor, dwFormat, nStart, nTo, stream);
+ return ME_StreamOutRange(editor, dwFormat, &start, nChars, stream);
}
More information about the wine-patches
mailing list