Commit 54b53b60 authored by Dylan Smith's avatar Dylan Smith Committed by Alexandre Julliard

richedit: Use ME_Cursor instead of offsets for stream out functions.

parent bd470428
...@@ -375,7 +375,7 @@ static DWORD CALLBACK ME_AppendToHGLOBAL(DWORD_PTR dwCookie, LPBYTE lpBuff, LONG ...@@ -375,7 +375,7 @@ static DWORD CALLBACK ME_AppendToHGLOBAL(DWORD_PTR dwCookie, LPBYTE lpBuff, LONG
return 0; 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; EDITSTREAM es;
ME_GlobalDestStruct gds; ME_GlobalDestStruct gds;
...@@ -384,7 +384,7 @@ static HGLOBAL get_rtf_text(ME_TextEditor *editor, const CHARRANGE *lpchrg) ...@@ -384,7 +384,7 @@ static HGLOBAL get_rtf_text(ME_TextEditor *editor, const CHARRANGE *lpchrg)
gds.nLength = 0; gds.nLength = 0;
es.dwCookie = (DWORD_PTR)&gds; es.dwCookie = (DWORD_PTR)&gds;
es.pfnCallback = ME_AppendToHGLOBAL; 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); GlobalReAlloc(gds.hData, gds.nLength+1, 0);
return gds.hData; return gds.hData;
} }
...@@ -410,10 +410,7 @@ HRESULT ME_GetDataObject(ME_TextEditor *editor, const ME_Cursor *start, ...@@ -410,10 +410,7 @@ HRESULT ME_GetDataObject(ME_TextEditor *editor, const ME_Cursor *start,
obj->fmtetc = GlobalAlloc(GMEM_ZEROINIT, obj->fmtetc_cnt*sizeof(FORMATETC)); obj->fmtetc = GlobalAlloc(GMEM_ZEROINIT, obj->fmtetc_cnt*sizeof(FORMATETC));
InitFormatEtc(obj->fmtetc[0], CF_UNICODETEXT, TYMED_HGLOBAL); InitFormatEtc(obj->fmtetc[0], CF_UNICODETEXT, TYMED_HGLOBAL);
if(editor->mode & TM_RICHTEXT) { if(editor->mode & TM_RICHTEXT) {
CHARRANGE chrg; obj->rtf = get_rtf_text(editor, start, nChars);
chrg.cpMin = ME_GetCursorOfs(start);
chrg.cpMax = chrg.cpMin + nChars;
obj->rtf = get_rtf_text(editor, &chrg);
InitFormatEtc(obj->fmtetc[1], cfRTF, TYMED_HGLOBAL); InitFormatEtc(obj->fmtetc[1], cfRTF, TYMED_HGLOBAL);
} }
......
...@@ -329,7 +329,7 @@ BOOL ME_Redo(ME_TextEditor *editor); ...@@ -329,7 +329,7 @@ BOOL ME_Redo(ME_TextEditor *editor);
void ME_EmptyUndoStack(ME_TextEditor *editor); void ME_EmptyUndoStack(ME_TextEditor *editor);
/* writer.c */ /* 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); LRESULT ME_StreamOut(ME_TextEditor *editor, DWORD dwFormat, EDITSTREAM *stream);
/* clipboard.c */ /* clipboard.c */
......
...@@ -762,23 +762,23 @@ ME_StreamOutRTFText(ME_OutStream *pStream, const WCHAR *text, LONG nChars) ...@@ -762,23 +762,23 @@ ME_StreamOutRTFText(ME_OutStream *pStream, const WCHAR *text, LONG nChars)
} }
static BOOL static BOOL ME_StreamOutRTF(ME_TextEditor *editor, ME_OutStream *pStream,
ME_StreamOutRTF(ME_TextEditor *editor, ME_OutStream *pStream, int nStart, int nChars, int dwFormat) const ME_Cursor *start, int nChars, int dwFormat)
{ {
ME_DisplayItem *p, *pEnd, *pPara; ME_Cursor cursor = *start;
int nOffset, nEndLen; ME_DisplayItem *prev_para = cursor.pPara;
ME_Cursor endCur = cursor;
ME_RunOfsFromCharOfs(editor, nStart, &pPara, &p, &nOffset); ME_MoveCursorChars(editor, &endCur, nChars);
ME_RunOfsFromCharOfs(editor, nStart+nChars, NULL, &pEnd, &nEndLen);
if (!ME_StreamOutRTFHeader(pStream, dwFormat)) if (!ME_StreamOutRTFHeader(pStream, dwFormat))
return FALSE; return FALSE;
if (!ME_StreamOutRTFFontAndColorTbl(pStream, p, pEnd)) if (!ME_StreamOutRTFFontAndColorTbl(pStream, cursor.pRun, endCur.pRun))
return FALSE; return FALSE;
/* TODO: stylesheet table */ /* TODO: stylesheet table */
/* FIXME: maybe emit something smarter for the generator? */ /* FIXME: maybe emit something smarter for the generator? */
if (!ME_StreamOutPrint(pStream, "{\\*\\generator Wine Riched20 2.0.????;}")) if (!ME_StreamOutPrint(pStream, "{\\*\\generator Wine Riched20 2.0.????;}"))
return FALSE; return FALSE;
...@@ -791,138 +791,129 @@ ME_StreamOutRTF(ME_TextEditor *editor, ME_OutStream *pStream, int nStart, int nC ...@@ -791,138 +791,129 @@ ME_StreamOutRTF(ME_TextEditor *editor, ME_OutStream *pStream, int nStart, int nC
/* TODO: section formatting properties */ /* TODO: section formatting properties */
if (!ME_StreamOutRTFParaProps(editor, pStream, pPara)) if (!ME_StreamOutRTFParaProps(editor, pStream, cursor.pPara))
return FALSE; return FALSE;
while(1) do {
{ if (cursor.pPara != prev_para)
switch(p->type)
{ {
case diParagraph: prev_para = cursor.pPara;
if (!editor->bEmulateVersion10) { /* v4.1 */ if (!editor->bEmulateVersion10) { /* v4.1 */
if (p->member.para.nFlags & MEPF_ROWSTART) { if (cursor.pPara->member.para.nFlags & MEPF_ROWSTART) {
pStream->nNestingLevel++; pStream->nNestingLevel++;
if (pStream->nNestingLevel == 1) { if (pStream->nNestingLevel == 1) {
if (!ME_StreamOutRTFTableProps(editor, pStream, p)) if (!ME_StreamOutRTFTableProps(editor, pStream, cursor.pPara))
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))
return FALSE; return FALSE;
} }
if (!ME_StreamOutRTFParaProps(editor, pStream, p)) } else if (cursor.pPara->member.para.nFlags & MEPF_ROWEND) {
return FALSE; pStream->nNestingLevel--;
} if (pStream->nNestingLevel >= 1) {
pPara = p; if (!ME_StreamOutPrint(pStream, "{\\*\\nesttableprops"))
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 "))
return FALSE; return FALSE;
} else { if (!ME_StreamOutRTFTableProps(editor, pStream, cursor.pPara))
if (!ME_StreamOutPrint(pStream, "\\tab "))
return FALSE; return FALSE;
} if (!ME_StreamOutPrint(pStream, "\\nestrow}{\\nonesttables\\par}\r\n"))
} else if (p->member.run.nFlags & MERF_ENDCELL) {
if (pStream->nNestingLevel > 1) {
if (!ME_StreamOutPrint(pStream, "\\nestcell "))
return FALSE; return FALSE;
} else { } 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")) if (!ME_StreamOutPrint(pStream, "\\row \r\n"))
return FALSE; return FALSE;
} else {
if (!ME_StreamOutPrint(pStream, "\r\n\\par"))
return FALSE;
} }
/* Skip as many characters as required by current line break */ } else if (!ME_StreamOutRTFParaProps(editor, pStream, cursor.pPara)) {
nChars = max(0, nChars - p->member.run.strText->nLen); return FALSE;
} else if (p->member.run.nFlags & MERF_ENDROW) { }
if (!ME_StreamOutPrint(pStream, "\\line \r\n")) } else { /* v1.0 - 3.0 */
return FALSE; if (cursor.pPara->member.para.pFmt->dwMask & PFM_TABLE &&
nChars--; cursor.pPara->member.para.pFmt->wEffects & PFE_TABLE)
} else { {
int nEnd; if (!ME_StreamOutRTFTableProps(editor, pStream, cursor.pPara))
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, "}"))
return FALSE; return FALSE;
} }
break; if (!ME_StreamOutRTFParaProps(editor, pStream, cursor.pPara))
default: /* we missed the last item */ return FALSE;
assert(0); }
} }
if (p == pEnd)
if (cursor.pRun == endCur.pRun && !endCur.nOffset)
break; 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)) if (!ME_StreamOutMove(pStream, "}\0", 2))
return FALSE; return FALSE;
return TRUE; return TRUE;
} }
static BOOL static BOOL ME_StreamOutText(ME_TextEditor *editor, ME_OutStream *pStream,
ME_StreamOutText(ME_TextEditor *editor, ME_OutStream *pStream, int nStart, int nChars, DWORD dwFormat) const ME_Cursor *start, int nChars, DWORD dwFormat)
{ {
ME_DisplayItem *item; ME_Cursor cursor = *start;
int nLen; int nLen;
UINT nCodePage = CP_ACP; UINT nCodePage = CP_ACP;
char *buffer = NULL; char *buffer = NULL;
int nBufLen = 0; int nBufLen = 0;
BOOL success = TRUE; BOOL success = TRUE;
ME_RunOfsFromCharOfs(editor, nStart, NULL, &item, &nStart); if (!cursor.pRun)
if (!item)
return FALSE; return FALSE;
if (dwFormat & SF_USECODEPAGE) if (dwFormat & SF_USECODEPAGE)
...@@ -930,10 +921,10 @@ ME_StreamOutText(ME_TextEditor *editor, ME_OutStream *pStream, int nStart, int n ...@@ -930,10 +921,10 @@ ME_StreamOutText(ME_TextEditor *editor, ME_OutStream *pStream, int nStart, int n
/* TODO: Handle SF_TEXTIZED */ /* TODO: Handle SF_TEXTIZED */
while (success && nChars && item) { while (success && nChars && cursor.pRun) {
nLen = min(nChars, item->member.run.strText->nLen - nStart); 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' }; static const WCHAR szEOL[2] = { '\r', '\n' };
...@@ -944,27 +935,27 @@ ME_StreamOutText(ME_TextEditor *editor, ME_OutStream *pStream, int nStart, int n ...@@ -944,27 +935,27 @@ ME_StreamOutText(ME_TextEditor *editor, ME_OutStream *pStream, int nStart, int n
success = ME_StreamOutMove(pStream, "\r\n", 2); success = ME_StreamOutMove(pStream, "\r\n", 2);
} else { } else {
if (dwFormat & SF_UNICODE) 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); sizeof(WCHAR) * nLen);
else { else {
int nSize; 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); nLen, NULL, 0, NULL, NULL);
if (nSize > nBufLen) { if (nSize > nBufLen) {
FREE_OBJ(buffer); FREE_OBJ(buffer);
buffer = ALLOC_N_OBJ(char, nSize); buffer = ALLOC_N_OBJ(char, nSize);
nBufLen = 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); nLen, buffer, nSize, NULL, NULL);
success = ME_StreamOutMove(pStream, buffer, nSize); success = ME_StreamOutMove(pStream, buffer, nSize);
} }
} }
nChars -= nLen; nChars -= nLen;
nStart = 0; cursor.nOffset = 0;
item = ME_FindItemFwd(item, diRun); cursor.pRun = ME_FindItemFwd(cursor.pRun, diRun);
} }
FREE_OBJ(buffer); FREE_OBJ(buffer);
...@@ -972,24 +963,16 @@ ME_StreamOutText(ME_TextEditor *editor, ME_OutStream *pStream, int nStart, int n ...@@ -972,24 +963,16 @@ ME_StreamOutText(ME_TextEditor *editor, ME_OutStream *pStream, int nStart, int n
} }
LRESULT LRESULT ME_StreamOutRange(ME_TextEditor *editor, DWORD dwFormat,
ME_StreamOutRange(ME_TextEditor *editor, DWORD dwFormat, int nStart, int nTo, EDITSTREAM *stream) const ME_Cursor *start,
int nChars, EDITSTREAM *stream)
{ {
ME_OutStream *pStream = ME_StreamOutInit(editor, 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) 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) 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) if (!pStream->stream->dwError)
ME_StreamOutFlush(pStream); ME_StreamOutFlush(pStream);
return ME_StreamOutFree(pStream); return ME_StreamOutFree(pStream);
...@@ -998,13 +981,19 @@ ME_StreamOutRange(ME_TextEditor *editor, DWORD dwFormat, int nStart, int nTo, ED ...@@ -998,13 +981,19 @@ ME_StreamOutRange(ME_TextEditor *editor, DWORD dwFormat, int nStart, int nTo, ED
LRESULT LRESULT
ME_StreamOut(ME_TextEditor *editor, DWORD dwFormat, EDITSTREAM *stream) ME_StreamOut(ME_TextEditor *editor, DWORD dwFormat, EDITSTREAM *stream)
{ {
int nStart, nTo; ME_Cursor start;
int nChars;
if (dwFormat & SFF_SELECTION) if (dwFormat & SFF_SELECTION) {
ME_GetSelectionOfs(editor, &nStart, &nTo); int nStart, nTo;
else { start = editor->pCursors[ME_GetSelectionOfs(editor, &nStart, &nTo)];
nStart = 0; nChars = nTo - nStart;
nTo = -1; } 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);
} }
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