[RICHED20]

- Sync riched20 with Wine-1.1.41.

svn path=/trunk/; revision=46328
This commit is contained in:
Aleksey Bragin 2010-03-21 22:44:26 +00:00
parent 11604ef89b
commit 79a14dac68
20 changed files with 1431 additions and 1246 deletions

View file

@ -24,27 +24,55 @@
WINE_DEFAULT_DEBUG_CHANNEL(richedit);
static BOOL
ME_MoveCursorChars(ME_TextEditor *editor, ME_Cursor *pCursor, int nRelOfs);
void ME_GetSelection(ME_TextEditor *editor, int *from, int *to)
void ME_SetCursorToStart(ME_TextEditor *editor, ME_Cursor *cursor)
{
*from = ME_GetCursorOfs(editor, 0);
*to = ME_GetCursorOfs(editor, 1);
cursor->pPara = editor->pBuffer->pFirst->member.para.next_para;
cursor->pRun = ME_FindItemFwd(cursor->pPara, diRun);
cursor->nOffset = 0;
}
static void ME_SetCursorToEnd(ME_TextEditor *editor, ME_Cursor *cursor)
{
cursor->pPara = editor->pBuffer->pLast->member.para.prev_para;
cursor->pRun = ME_FindItemBack(editor->pBuffer->pLast, diRun);
cursor->nOffset = 0;
}
int ME_GetSelectionOfs(ME_TextEditor *editor, int *from, int *to)
{
*from = ME_GetCursorOfs(&editor->pCursors[0]);
*to = ME_GetCursorOfs(&editor->pCursors[1]);
if (*from > *to)
{
int tmp = *from;
*from = *to;
*to = tmp;
*to = tmp;
return 1;
}
return 0;
}
int ME_GetSelection(ME_TextEditor *editor, ME_Cursor **from, ME_Cursor **to)
{
if (ME_GetCursorOfs(&editor->pCursors[0]) < ME_GetCursorOfs(&editor->pCursors[1]))
{
*from = &editor->pCursors[0];
*to = &editor->pCursors[1];
return 0;
} else {
*from = &editor->pCursors[1];
*to = &editor->pCursors[0];
return 1;
}
}
int ME_GetTextLength(ME_TextEditor *editor)
{
ME_DisplayItem *pLast = editor->pBuffer->pLast;
return ME_CharOfsFromRunOfs(editor, pLast->member.para.prev_para,
ME_FindItemBack(pLast, diRun), 0);
ME_Cursor cursor;
ME_SetCursorToEnd(editor, &cursor);
return ME_GetCursorOfs(&cursor);
}
@ -63,8 +91,10 @@ int ME_GetTextLengthEx(ME_TextEditor *editor, const GETTEXTLENGTHEX *how)
&& (how->flags & GTL_USECRLF)
&& !editor->bEmulateVersion10) /* Ignore GTL_USECRLF flag in 1.0 emulation */
length += editor->nParagraphs - 1;
if (how->flags & GTL_NUMBYTES)
if (how->flags & GTL_NUMBYTES ||
(how->flags & GTL_PRECISE && /* GTL_PRECISE seems to imply GTL_NUMBYTES */
!(how->flags & GTL_NUMCHARS))) /* unless GTL_NUMCHARS is given */
{
CPINFO cpinfo;
@ -95,12 +125,8 @@ int ME_SetSelection(ME_TextEditor *editor, int from, int to)
/* select all */
if (from == 0 && to == -1)
{
editor->pCursors[1].pPara = editor->pBuffer->pFirst->member.para.next_para;
editor->pCursors[1].pRun = ME_FindItemFwd(editor->pCursors[1].pPara, diRun);
editor->pCursors[1].nOffset = 0;
editor->pCursors[0].pPara = editor->pBuffer->pLast->member.para.prev_para;
editor->pCursors[0].pRun = ME_FindItemBack(editor->pBuffer->pLast, diRun);
editor->pCursors[0].nOffset = 0;
ME_SetCursorToStart(editor, &editor->pCursors[1]);
ME_SetCursorToEnd(editor, &editor->pCursors[0]);
ME_InvalidateSelection(editor);
ME_ClearTempStyle(editor);
return len + 1;
@ -119,7 +145,7 @@ int ME_SetSelection(ME_TextEditor *editor, int from, int to)
if (from < 0)
{
int start, end;
ME_GetSelection(editor, &start, &end);
ME_GetSelectionOfs(editor, &start, &end);
editor->pCursors[1] = editor->pCursors[0];
ME_Repaint(editor);
ME_ClearTempStyle(editor);
@ -148,9 +174,7 @@ int ME_SetSelection(ME_TextEditor *editor, int from, int to)
if (selectionEnd)
{
editor->pCursors[0].pPara = editor->pBuffer->pLast->member.para.prev_para;
editor->pCursors[0].pRun = ME_FindItemBack(editor->pBuffer->pLast, diRun);
editor->pCursors[0].nOffset = 0;
ME_SetCursorToEnd(editor, &editor->pCursors[0]);
editor->pCursors[1] = editor->pCursors[0];
ME_InvalidateSelection(editor);
ME_ClearTempStyle(editor);
@ -158,7 +182,8 @@ int ME_SetSelection(ME_TextEditor *editor, int from, int to)
}
ME_CursorFromCharOfs(editor, from, &editor->pCursors[1]);
ME_CursorFromCharOfs(editor, to, &editor->pCursors[0]);
editor->pCursors[0] = editor->pCursors[1];
ME_MoveCursorChars(editor, &editor->pCursors[0], to - from);
/* 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;
@ -258,23 +283,22 @@ void ME_HideCaret(ME_TextEditor *ed)
}
}
BOOL ME_InternalDeleteText(ME_TextEditor *editor, int nOfs, int nChars,
BOOL bForce)
BOOL ME_InternalDeleteText(ME_TextEditor *editor, ME_Cursor *start,
int nChars, BOOL bForce)
{
ME_Cursor c;
ME_Cursor c = *start;
int nOfs = ME_GetCursorOfs(start);
int shift = 0;
int totalChars = nChars;
ME_DisplayItem *start_para;
/* Prevent deletion past last end of paragraph run. */
nChars = min(nChars, ME_GetTextLength(editor) - nOfs);
ME_CursorFromCharOfs(editor, nOfs, &c);
start_para = c.pPara;
if (!bForce)
{
ME_ProtectPartialTableDeletion(editor, nOfs, &nChars);
ME_ProtectPartialTableDeletion(editor, &c, &nChars);
if (nChars == 0)
return FALSE;
}
@ -289,8 +313,7 @@ BOOL ME_InternalDeleteText(ME_TextEditor *editor, int nOfs, int nChars,
{
/* We aren't deleting anything in this run, so we will go back to the
* last run we are deleting text in. */
c.pRun = ME_FindItemBack(c.pRun, diRun);
c.pPara = ME_GetParagraph(c.pRun);
ME_PrevRun(&c.pPara, &c.pRun);
c.nOffset = c.pRun->member.run.strText->nLen;
}
run = &c.pRun->member.run;
@ -422,12 +445,12 @@ BOOL ME_InternalDeleteText(ME_TextEditor *editor, int nOfs, int nChars,
}
BOOL ME_DeleteTextAtCursor(ME_TextEditor *editor, int nCursor, int nChars)
{
{
assert(nCursor>=0 && nCursor<editor->nCursors);
/* text operations set modified state */
editor->nModifyStep = 1;
return ME_InternalDeleteText(editor, ME_GetCursorOfs(editor, nCursor), nChars,
FALSE);
return ME_InternalDeleteText(editor, &editor->pCursors[nCursor],
nChars, FALSE);
}
static ME_DisplayItem *
@ -459,7 +482,7 @@ void ME_InsertOLEFromCursor(ME_TextEditor *editor, const REOBJECT* reo, int nCur
MERF_GRAPHICS);
di->member.run.ole_obj = ALLOC_OBJ(*reo);
ME_CopyReObject(di->member.run.ole_obj, reo);
ME_SendSelChange(editor);
ME_ReleaseStyle(pStyle);
}
@ -475,7 +498,7 @@ void ME_InsertEndRowFromCursor(ME_TextEditor *editor, int nCursor)
di = ME_InternalInsertTextFromCursor(editor, nCursor, &space, 1, pStyle,
MERF_ENDROW);
ME_SendSelChange(editor);
ME_ReleaseStyle(pStyle);
}
@ -565,7 +588,7 @@ void ME_InsertTextFromCursor(ME_TextEditor *editor, int nCursor,
/* ME_SplitParagraph increases style refcount */
tp = ME_SplitParagraph(editor, p->pRun, p->pRun->member.run.style, eol_str, 0);
p->pRun = ME_FindItemFwd(tp, diRun);
p->pPara = ME_GetParagraph(p->pRun);
p->pPara = tp;
end_run = ME_FindItemBack(tp, diRun);
ME_ReleaseStyle(end_run->member.run.style);
end_run->member.run.style = tmp_style;
@ -577,77 +600,85 @@ void ME_InsertTextFromCursor(ME_TextEditor *editor, int nCursor,
}
}
static BOOL
ME_MoveCursorChars(ME_TextEditor *editor, ME_Cursor *pCursor, int nRelOfs)
/* Move the cursor nRelOfs characters (either forwards or backwards)
*
* returns the actual number of characters moved.
**/
int ME_MoveCursorChars(ME_TextEditor *editor, ME_Cursor *cursor, int nRelOfs)
{
ME_DisplayItem *pRun = pCursor->pRun;
if (nRelOfs == -1)
cursor->nOffset += nRelOfs;
if (cursor->nOffset < 0)
{
if (!pCursor->nOffset)
cursor->nOffset += cursor->pRun->member.run.nCharOfs;
if (cursor->nOffset >= 0)
{
ME_DisplayItem *pPara = pCursor->pPara;
/* new offset in the same paragraph */
do {
pRun = ME_FindItemBack(pRun, diRunOrParagraph);
assert(pRun);
switch (pRun->type)
{
case diRun:
break;
case diParagraph:
pPara = pRun;
if (pPara->member.para.prev_para->type == diTextStart)
return FALSE;
pRun = ME_FindItemBack(pPara, diRunOrParagraph);
pPara = pPara->member.para.prev_para;
/* every paragraph ought to have at least one run */
assert(pRun && pRun->type == diRun);
assert(pRun->member.run.nFlags & MERF_ENDPARA);
break;
default:
assert(pRun->type != diRun && pRun->type != diParagraph);
return FALSE;
}
} while (RUN_IS_HIDDEN(&pRun->member.run) ||
pRun->member.run.nFlags & MERF_HIDDEN);
pCursor->pPara = pPara;
pCursor->pRun = pRun;
if (pRun->member.run.nFlags & MERF_ENDPARA)
pCursor->nOffset = 0;
else
pCursor->nOffset = pRun->member.run.strText->nLen;
cursor->pRun = ME_FindItemBack(cursor->pRun, diRun);
} while (cursor->nOffset < cursor->pRun->member.run.nCharOfs);
cursor->nOffset -= cursor->pRun->member.run.nCharOfs;
return nRelOfs;
}
if (pCursor->nOffset)
pCursor->nOffset = pCursor->nOffset + nRelOfs;
return TRUE;
}
else
{
if (!(pRun->member.run.nFlags & MERF_ENDPARA))
cursor->nOffset += cursor->pPara->member.para.nCharOfs;
if (cursor->nOffset <= 0)
{
int new_ofs = pCursor->nOffset + nRelOfs;
if (new_ofs < pRun->member.run.strText->nLen)
{
pCursor->nOffset = new_ofs;
return TRUE;
}
/* moved to the start of the text */
nRelOfs -= cursor->nOffset;
ME_SetCursorToStart(editor, cursor);
return nRelOfs;
}
/* new offset in a previous paragraph */
do {
pRun = ME_FindItemFwd(pRun, diRun);
} while (pRun && (RUN_IS_HIDDEN(&pRun->member.run) ||
pRun->member.run.nFlags & MERF_HIDDEN));
if (pRun)
{
pCursor->pPara = ME_GetParagraph(pRun);
pCursor->pRun = pRun;
pCursor->nOffset = 0;
return TRUE;
cursor->pPara = cursor->pPara->member.para.prev_para;
} while (cursor->nOffset < cursor->pPara->member.para.nCharOfs);
cursor->nOffset -= cursor->pPara->member.para.nCharOfs;
cursor->pRun = ME_FindItemBack(cursor->pPara->member.para.next_para, diRun);
while (cursor->nOffset < cursor->pRun->member.run.nCharOfs) {
cursor->pRun = ME_FindItemBack(cursor->pRun, diRun);
}
}
return FALSE;
cursor->nOffset -= cursor->pRun->member.run.nCharOfs;
} else if (cursor->nOffset >= cursor->pRun->member.run.strText->nLen) {
ME_DisplayItem *next_para;
int new_offset;
new_offset = ME_GetCursorOfs(cursor);
next_para = cursor->pPara->member.para.next_para;
if (new_offset < next_para->member.para.nCharOfs)
{
/* new offset in the same paragraph */
do {
cursor->nOffset -= cursor->pRun->member.run.strText->nLen;
cursor->pRun = ME_FindItemFwd(cursor->pRun, diRun);
} while (cursor->nOffset >= cursor->pRun->member.run.strText->nLen);
return nRelOfs;
}
if (new_offset >= ME_GetTextLength(editor))
{
/* new offset at the end of the text */
ME_SetCursorToEnd(editor, cursor);
nRelOfs -= new_offset - ME_GetTextLength(editor);
return nRelOfs;
}
/* new offset in a following paragraph */
do {
cursor->pPara = next_para;
next_para = next_para->member.para.next_para;
} while (new_offset >= next_para->member.para.nCharOfs);
cursor->nOffset = new_offset - cursor->pPara->member.para.nCharOfs;
cursor->pRun = ME_FindItemFwd(cursor->pPara, diRun);
while (cursor->nOffset >= cursor->pRun->member.run.strText->nLen)
{
cursor->nOffset -= cursor->pRun->member.run.strText->nLen;
cursor->pRun = ME_FindItemFwd(cursor->pRun, diRun);
}
} /* else new offset is in the same run */
return nRelOfs;
}
@ -655,8 +686,9 @@ static BOOL
ME_MoveCursorWords(ME_TextEditor *editor, ME_Cursor *cursor, int nRelOfs)
{
ME_DisplayItem *pRun = cursor->pRun, *pOtherRun;
ME_DisplayItem *pPara = cursor->pPara;
int nOffset = cursor->nOffset;
if (nRelOfs == -1)
{
/* Backward movement */
@ -684,14 +716,16 @@ ME_MoveCursorWords(ME_TextEditor *editor, ME_Cursor *cursor, int nRelOfs)
{
if (cursor->pRun == pRun && cursor->nOffset == 0)
{
pPara = pOtherRun;
/* Skip empty start of table row paragraph */
if (pOtherRun->member.para.prev_para->member.para.nFlags & MEPF_ROWSTART)
pOtherRun = pOtherRun->member.para.prev_para;
if (pPara->member.para.prev_para->member.para.nFlags & MEPF_ROWSTART)
pPara = pPara->member.para.prev_para;
/* Paragraph breaks are treated as separate words */
if (pOtherRun->member.para.prev_para->type == diTextStart)
if (pPara->member.para.prev_para->type == diTextStart)
return FALSE;
pRun = ME_FindItemBack(pOtherRun, diRun);
pRun = ME_FindItemBack(pPara, diRun);
pPara = pPara->member.para.prev_para;
}
break;
}
@ -723,8 +757,10 @@ ME_MoveCursorWords(ME_TextEditor *editor, ME_Cursor *cursor, int nRelOfs)
{
if (pOtherRun->member.para.nFlags & MEPF_ROWSTART)
pOtherRun = pOtherRun->member.para.next_para;
if (cursor->pRun == pRun)
pRun = ME_FindItemFwd(pOtherRun, diRun);
if (cursor->pRun == pRun) {
pPara = pOtherRun;
pRun = ME_FindItemFwd(pPara, diRun);
}
nOffset = 0;
break;
}
@ -737,7 +773,7 @@ ME_MoveCursorWords(ME_TextEditor *editor, ME_Cursor *cursor, int nRelOfs)
}
}
}
cursor->pPara = ME_GetParagraph(pRun);
cursor->pPara = pPara;
cursor->pRun = pRun;
cursor->nOffset = nOffset;
return TRUE;
@ -793,12 +829,8 @@ ME_SelectByType(ME_TextEditor *editor, ME_SelectionType selectionType)
case stDocument:
/* Select everything with cursor anchored from the start of the text */
editor->nSelectionType = stDocument;
editor->pCursors[1].pPara = editor->pBuffer->pFirst->member.para.next_para;
editor->pCursors[1].pRun = ME_FindItemFwd(editor->pCursors[1].pPara, diRun);
editor->pCursors[1].nOffset = 0;
editor->pCursors[0].pPara = editor->pBuffer->pLast->member.para.prev_para;
editor->pCursors[0].pRun = ME_FindItemBack(editor->pBuffer->pLast, diRun);
editor->pCursors[0].nOffset = 0;
ME_SetCursorToStart(editor, &editor->pCursors[1]);
ME_SetCursorToEnd(editor, &editor->pCursors[0]);
break;
default: assert(0);
}
@ -807,11 +839,10 @@ ME_SelectByType(ME_TextEditor *editor, ME_SelectionType selectionType)
editor->pCursors[3] = editor->pCursors[1];
}
int ME_GetCursorOfs(ME_TextEditor *editor, int nCursor)
int ME_GetCursorOfs(const ME_Cursor *cursor)
{
ME_Cursor *pCursor = &editor->pCursors[nCursor];
return pCursor->pPara->member.para.nCharOfs
+ pCursor->pRun->member.run.nCharOfs + pCursor->nOffset;
return cursor->pPara->member.para.nCharOfs
+ cursor->pRun->member.run.nCharOfs + cursor->nOffset;
}
/* Helper function for ME_FindPixelPos to find paragraph within tables */
@ -862,9 +893,9 @@ static BOOL ME_ReturnFoundPos(ME_TextEditor *editor, ME_DisplayItem *found,
rx = 0;
result->pRun = found;
result->nOffset = ME_CharFromPointCursor(editor, rx, &found->member.run);
if (editor->pCursors[0].nOffset == found->member.run.strText->nLen && rx)
if (result->nOffset == found->member.run.strText->nLen && rx)
{
result->pRun = ME_FindItemFwd(editor->pCursors[0].pRun, diRun);
result->pRun = ME_FindItemFwd(result->pRun, diRun);
result->nOffset = 0;
}
result->pPara = ME_GetParagraph(result->pRun);
@ -975,30 +1006,32 @@ static BOOL ME_FindPixelPos(ME_TextEditor *editor, int x, int y,
}
/* Returns the character offset closest to the pixel position
/* Sets the cursor to the position closest to the pixel position
*
* x & y are pixel positions in client coordinates.
*
* isExact will be set to TRUE if the run is directly under the pixel
* position, FALSE if it not, unless isExact is set to NULL.
*
* return FALSE if outside client area and the cursor is not set,
* otherwise TRUE is returned.
*/
int ME_CharFromPos(ME_TextEditor *editor, int x, int y, BOOL *isExact)
BOOL ME_CharFromPos(ME_TextEditor *editor, int x, int y,
ME_Cursor *cursor, BOOL *isExact)
{
ME_Cursor cursor;
RECT rc;
BOOL bResult;
ITextHost_TxGetClientRect(editor->texthost, &rc);
if (x < 0 || y < 0 || x >= rc.right || y >= rc.bottom) {
if (isExact) *isExact = FALSE;
return -1;
return FALSE;
}
x += editor->horz_si.nPos;
y += editor->vert_si.nPos;
bResult = ME_FindPixelPos(editor, x, y, &cursor, NULL);
bResult = ME_FindPixelPos(editor, x, y, cursor, NULL);
if (isExact) *isExact = bResult;
return cursor.pPara->member.para.nCharOfs
+ cursor.pRun->member.run.nCharOfs + cursor.nOffset;
return TRUE;
}
@ -1019,9 +1052,9 @@ static void ME_ExtendAnchorSelection(ME_TextEditor *editor)
int curOfs, anchorStartOfs, anchorEndOfs;
if (editor->nSelectionType == stPosition || editor->nSelectionType == stDocument)
return;
curOfs = ME_GetCursorOfs(editor, 0);
anchorStartOfs = ME_GetCursorOfs(editor, 3);
anchorEndOfs = ME_GetCursorOfs(editor, 2);
curOfs = ME_GetCursorOfs(&editor->pCursors[0]);
anchorStartOfs = ME_GetCursorOfs(&editor->pCursors[3]);
anchorEndOfs = ME_GetCursorOfs(&editor->pCursors[2]);
tmp_cursor = editor->pCursors[0];
editor->pCursors[0] = editor->pCursors[2];
@ -1231,14 +1264,14 @@ static void
ME_MoveCursorLines(ME_TextEditor *editor, ME_Cursor *pCursor, int nRelOfs)
{
ME_DisplayItem *pRun = pCursor->pRun;
ME_DisplayItem *pItem, *pOldPara, *pNewPara;
ME_DisplayItem *pOldPara = pCursor->pPara;
ME_DisplayItem *pItem, *pNewPara;
int x = ME_GetXForArrow(editor, pCursor);
if (editor->bCaretAtEnd && !pCursor->nOffset)
pRun = ME_FindItemBack(pRun, diRun);
if (!pRun)
return;
pOldPara = ME_GetParagraph(pRun);
if (!ME_PrevRun(&pOldPara, &pRun))
return;
if (nRelOfs == -1)
{
/* start of this row */
@ -1313,9 +1346,7 @@ static void ME_ArrowPageUp(ME_TextEditor *editor, ME_Cursor *pCursor)
if (editor->vert_si.nPos < p->member.row.nHeight)
{
pCursor->pPara = editor->pBuffer->pFirst->member.para.next_para;
pCursor->pRun = ME_FindItemFwd(pCursor->pPara, diRun);
pCursor->nOffset = 0;
ME_SetCursorToStart(editor, pCursor);
editor->bCaretAtEnd = FALSE;
/* Native clears seems to clear this x value on page up at the top
* of the text, but not on page down at the end of the text.
@ -1380,9 +1411,7 @@ static void ME_ArrowPageDown(ME_TextEditor *editor, ME_Cursor *pCursor)
if (editor->vert_si.nPos >= y - editor->sizeWindow.cy)
{
pCursor->pPara = editor->pBuffer->pLast->member.para.prev_para;
pCursor->pRun = ME_FindItemBack(editor->pBuffer->pLast, diRun);
pCursor->nOffset = 0;
ME_SetCursorToEnd(editor, pCursor);
editor->bCaretAtEnd = FALSE;
} else {
ME_DisplayItem *pRun = pCursor->pRun;
@ -1451,9 +1480,7 @@ static void ME_ArrowHome(ME_TextEditor *editor, ME_Cursor *pCursor)
static void ME_ArrowCtrlHome(ME_TextEditor *editor, ME_Cursor *pCursor)
{
pCursor->pPara = editor->pBuffer->pFirst->member.para.next_para;
pCursor->pRun = ME_FindItemFwd(pCursor->pPara, diRun);
pCursor->nOffset = 0;
ME_SetCursorToStart(editor, pCursor);
editor->bCaretAtEnd = FALSE;
}
@ -1484,33 +1511,21 @@ static void ME_ArrowEnd(ME_TextEditor *editor, ME_Cursor *pCursor)
static void ME_ArrowCtrlEnd(ME_TextEditor *editor, ME_Cursor *pCursor)
{
pCursor->pPara = editor->pBuffer->pLast->member.para.prev_para;
pCursor->pRun = ME_FindItemBack(editor->pBuffer->pLast, diRun);
assert(pCursor->pRun->member.run.nFlags & MERF_ENDPARA);
pCursor->nOffset = 0;
ME_SetCursorToEnd(editor, pCursor);
editor->bCaretAtEnd = FALSE;
}
BOOL ME_IsSelection(ME_TextEditor *editor)
{
return memcmp(&editor->pCursors[0], &editor->pCursors[1], sizeof(ME_Cursor))!=0;
}
static int ME_GetSelCursor(ME_TextEditor *editor, int dir)
{
int cdir = ME_GetCursorOfs(editor, 0) - ME_GetCursorOfs(editor, 1);
if (cdir*dir>0)
return 0;
else
return 1;
return editor->pCursors[0].pRun != editor->pCursors[1].pRun ||
editor->pCursors[0].nOffset != editor->pCursors[1].nOffset;
}
void ME_DeleteSelection(ME_TextEditor *editor)
{
int from, to;
ME_GetSelection(editor, &from, &to);
ME_DeleteTextAtCursor(editor, ME_GetSelCursor(editor,-1), to-from);
int nStartCursor = ME_GetSelectionOfs(editor, &from, &to);
ME_DeleteTextAtCursor(editor, nStartCursor, to - from);
}
ME_Style *ME_GetSelectionInsertStyle(ME_TextEditor *editor)
@ -1525,12 +1540,14 @@ void ME_SendSelChange(ME_TextEditor *editor)
if (!(editor->nEventMask & ENM_SELCHANGE))
return;
sc.nmhdr.hwndFrom = NULL;
sc.nmhdr.idFrom = 0;
sc.nmhdr.code = EN_SELCHANGE;
ME_GetSelection(editor, &sc.chrg.cpMin, &sc.chrg.cpMax);
ME_GetSelectionOfs(editor, &sc.chrg.cpMin, &sc.chrg.cpMax);
sc.seltyp = SEL_EMPTY;
if (sc.chrg.cpMin != sc.chrg.cpMax)
sc.seltyp |= SEL_TEXT;
if (sc.chrg.cpMin < sc.chrg.cpMax+1) /* wth were RICHEDIT authors thinking ? */
if (sc.chrg.cpMin < sc.chrg.cpMax+1) /* what were RICHEDIT authors thinking ? */
sc.seltyp |= SEL_MULTICHAR;
TRACE("cpMin=%d cpMax=%d seltyp=%d (%s %s)\n",
sc.chrg.cpMin, sc.chrg.cpMax, sc.seltyp,

View file

@ -326,18 +326,23 @@ static const IDataObjectVtbl VT_DataObjectImpl =
DataObjectImpl_EnumDAdvise
};
static HGLOBAL get_unicode_text(ME_TextEditor *editor, const CHARRANGE *lpchrg)
static HGLOBAL get_unicode_text(ME_TextEditor *editor, const ME_Cursor *start, int nChars)
{
int pars, len;
int pars = 0;
WCHAR *data;
HANDLE ret;
ME_DisplayItem *para;
int nEnd = ME_GetCursorOfs(start) + nChars;
pars = ME_CountParagraphsBetween(editor, lpchrg->cpMin, lpchrg->cpMax);
len = lpchrg->cpMax-lpchrg->cpMin;
ret = GlobalAlloc(GMEM_MOVEABLE, sizeof(WCHAR)*(len+pars+1));
/* count paragraphs in range */
para = start->pPara;
while((para = para->member.para.next_para) &&
para->member.para.nCharOfs <= nEnd)
pars++;
ret = GlobalAlloc(GMEM_MOVEABLE, sizeof(WCHAR) * (nChars + pars + 1));
data = GlobalLock(ret);
len = ME_GetTextW(editor, data, lpchrg->cpMin, len, TRUE);
data[len] = 0;
ME_GetTextW(editor, data, nChars + pars, start, nChars, TRUE);
GlobalUnlock(ret);
return ret;
}
@ -370,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;
@ -379,15 +384,16 @@ 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;
}
HRESULT ME_GetDataObject(ME_TextEditor *editor, const CHARRANGE *lpchrg, LPDATAOBJECT *lplpdataobj)
HRESULT ME_GetDataObject(ME_TextEditor *editor, const ME_Cursor *start,
int nChars, LPDATAOBJECT *lplpdataobj)
{
DataObjectImpl *obj;
TRACE("(%p,%d,%d)\n", editor, lpchrg->cpMin, lpchrg->cpMax);
TRACE("(%p,%d,%d)\n", editor, ME_GetCursorOfs(start), nChars);
obj = heap_alloc(sizeof(DataObjectImpl));
if(cfRTF == 0)
@ -395,7 +401,7 @@ HRESULT ME_GetDataObject(ME_TextEditor *editor, const CHARRANGE *lpchrg, LPDATAO
obj->lpVtbl = &VT_DataObjectImpl;
obj->ref = 1;
obj->unicode = get_unicode_text(editor, lpchrg);
obj->unicode = get_unicode_text(editor, start, nChars);
obj->rtf = NULL;
obj->fmtetc_cnt = 1;
@ -404,7 +410,7 @@ HRESULT ME_GetDataObject(ME_TextEditor *editor, const CHARRANGE *lpchrg, LPDATAO
obj->fmtetc = GlobalAlloc(GMEM_ZEROINIT, obj->fmtetc_cnt*sizeof(FORMATETC));
InitFormatEtc(obj->fmtetc[0], CF_UNICODETEXT, TYMED_HGLOBAL);
if(editor->mode & TM_RICHTEXT) {
obj->rtf = get_rtf_text(editor, lpchrg);
obj->rtf = get_rtf_text(editor, start, nChars);
InitFormatEtc(obj->fmtetc[1], cfRTF, TYMED_HGLOBAL);
}

File diff suppressed because it is too large Load diff

View file

@ -77,6 +77,8 @@ void ME_CharFormatFromLogFont(HDC hDC, const LOGFONTW *lf, CHARFORMAT2W *fmt); /
/* list.c */
void ME_InsertBefore(ME_DisplayItem *diWhere, ME_DisplayItem *diWhat);
void ME_Remove(ME_DisplayItem *diWhere);
BOOL ME_NextRun(ME_DisplayItem **para, ME_DisplayItem **run);
BOOL ME_PrevRun(ME_DisplayItem **para, ME_DisplayItem **run);
ME_DisplayItem *ME_FindItemBack(ME_DisplayItem *di, ME_DIType nTypeOrClass);
ME_DisplayItem *ME_FindItemFwd(ME_DisplayItem *di, ME_DIType nTypeOrClass);
ME_DisplayItem *ME_FindItemBackOrHere(ME_DisplayItem *di, ME_DIType nTypeOrClass);
@ -95,7 +97,6 @@ ME_String *ME_VSplitString(ME_String *orig, int nVPos);
int ME_IsWhitespaces(const ME_String *s);
int ME_IsSplitable(const ME_String *s);
int ME_FindNonWhitespaceV(const ME_String *s, int nVChar);
int ME_FindWhitespaceV(ME_String *s, int nVChar);
int ME_CallWordBreakProc(ME_TextEditor *editor, ME_String *str, INT start, INT code);
void ME_StrDeleteV(ME_String *s, int nVChar, int nChars);
/* smart helpers for A<->W conversions, they reserve/free memory and call MultiByte<->WideChar functions */
@ -120,14 +121,11 @@ int ME_ReverseFindWhitespaceV(const ME_String *s, int nVChar);
/* row.c */
ME_DisplayItem *ME_RowStart(ME_DisplayItem *item);
/* ME_DisplayItem *ME_RowEnd(ME_DisplayItem *item); */
void ME_RenumberParagraphs(ME_DisplayItem *item); /* TODO */
ME_DisplayItem *ME_FindRowWithNumber(ME_TextEditor *editor, int nRow);
int ME_RowNumberFromCharOfs(ME_TextEditor *editor, int nOfs);
/* run.c */
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);
@ -136,49 +134,49 @@ int ME_CharFromPoint(ME_Context *c, int cx, ME_Run *run);
/* this one accounts for 1/2 char tolerance */
int ME_CharFromPointCursor(ME_TextEditor *editor, int cx, ME_Run *run);
int ME_PointFromChar(ME_TextEditor *editor, ME_Run *pRun, int nOffset);
int ME_GetLastSplittablePlace(ME_Context *c, ME_Run *run);
int ME_CanJoinRuns(const ME_Run *run1, const ME_Run *run2);
void ME_JoinRuns(ME_TextEditor *editor, ME_DisplayItem *p);
ME_DisplayItem *ME_SplitRun(ME_WrapContext *wc, ME_DisplayItem *item, int nChar);
ME_DisplayItem *ME_SplitRunSimple(ME_TextEditor *editor, ME_DisplayItem *item, int nChar);
int ME_FindSplitPoint(ME_Context *c, POINT *pt, ME_Run *run, int desperate);
void ME_UpdateRunFlags(ME_TextEditor *editor, ME_Run *run);
ME_DisplayItem *ME_SplitFurther(ME_TextEditor *editor, ME_DisplayItem *run);
void ME_CalcRunExtent(ME_Context *c, const ME_Paragraph *para, int startx, ME_Run *run);
SIZE ME_GetRunSize(ME_Context *c, const ME_Paragraph *para, ME_Run *run, int nLen, int startx);
void ME_CursorFromCharOfs(ME_TextEditor *editor, int nCharOfs, ME_Cursor *pCursor);
void ME_RunOfsFromCharOfs(ME_TextEditor *editor, int nCharOfs, ME_DisplayItem **ppPara, ME_DisplayItem **ppRun, int *pOfs);
int ME_CharOfsFromRunOfs(ME_TextEditor *editor, const ME_DisplayItem *pPara, const ME_DisplayItem *pRun, int nOfs);
void ME_SkipAndPropagateCharOffset(ME_DisplayItem *p, int shift);
void ME_SetCharFormat(ME_TextEditor *editor, int nFrom, int nLen, CHARFORMAT2W *pFmt);
void ME_SetCharFormat(ME_TextEditor *editor, ME_Cursor *start, ME_Cursor *end, CHARFORMAT2W *pFmt);
void ME_SetSelectionCharFormat(ME_TextEditor *editor, CHARFORMAT2W *pFmt);
void ME_GetCharFormat(ME_TextEditor *editor, int nFrom, int nLen, CHARFORMAT2W *pFmt);
void ME_GetCharFormat(ME_TextEditor *editor, const ME_Cursor *from,
const ME_Cursor *to, CHARFORMAT2W *pFmt);
void ME_GetSelectionCharFormat(ME_TextEditor *editor, CHARFORMAT2W *pFmt);
void ME_GetDefaultCharFormat(ME_TextEditor *editor, CHARFORMAT2W *pFmt);
void ME_SetDefaultCharFormat(ME_TextEditor *editor, CHARFORMAT2W *mod);
/* caret.c */
void ME_SetCursorToStart(ME_TextEditor *editor, ME_Cursor *cursor);
int ME_SetSelection(ME_TextEditor *editor, int from, int to);
void ME_HideCaret(ME_TextEditor *ed);
void ME_ShowCaret(ME_TextEditor *ed);
void ME_MoveCaret(ME_TextEditor *ed);
int ME_CharFromPos(ME_TextEditor *editor, int x, int y, BOOL *isExact);
BOOL ME_CharFromPos(ME_TextEditor *editor, int x, int y, ME_Cursor *cursor, BOOL *isExact);
void ME_LButtonDown(ME_TextEditor *editor, int x, int y, int clickNum);
void ME_MouseMove(ME_TextEditor *editor, int x, int y);
BOOL ME_DeleteTextAtCursor(ME_TextEditor *editor, int nCursor, int nChars);
void ME_InsertTextFromCursor(ME_TextEditor *editor, int nCursor,
const WCHAR *str, int len, ME_Style *style);
void ME_InsertEndRowFromCursor(ME_TextEditor *editor, int nCursor);
int ME_MoveCursorChars(ME_TextEditor *editor, ME_Cursor *cursor, int nRelOfs);
BOOL ME_ArrowKey(ME_TextEditor *ed, int nVKey, BOOL extend, BOOL ctrl);
int ME_GetCursorOfs(ME_TextEditor *editor, int nCursor);
void ME_GetSelection(ME_TextEditor *editor, int *from, int *to);
int ME_CountParagraphsBetween(ME_TextEditor *editor, int from, int to);
int ME_GetCursorOfs(const ME_Cursor *cursor);
int ME_GetSelectionOfs(ME_TextEditor *editor, int *from, int *to);
int ME_GetSelection(ME_TextEditor *editor, ME_Cursor **from, ME_Cursor **to);
BOOL ME_IsSelection(ME_TextEditor *editor);
void ME_DeleteSelection(ME_TextEditor *editor);
void ME_SendSelChange(ME_TextEditor *editor);
void ME_InsertOLEFromCursor(ME_TextEditor *editor, const REOBJECT* reo, int nCursor);
BOOL ME_InternalDeleteText(ME_TextEditor *editor, int nOfs, int nChars, BOOL bForce);
BOOL ME_InternalDeleteText(ME_TextEditor *editor, ME_Cursor *start, int nChars, BOOL bForce);
int ME_GetTextLength(ME_TextEditor *editor);
int ME_GetTextLengthEx(ME_TextEditor *editor, const GETTEXTLENGTHEX *how);
ME_Style *ME_GetSelectionInsertStyle(ME_TextEditor *editor);
@ -231,8 +229,7 @@ void ME_ScrollRight(ME_TextEditor *editor, int cx);
void ME_UpdateScrollBar(ME_TextEditor *editor);
/* other functions in paint.c */
int ME_GetParaBorderWidth(ME_TextEditor *editor, int);
int ME_GetParaLineSpace(ME_Context *c, ME_Paragraph*);
int ME_GetParaBorderWidth(ME_Context *c, int flags);
/* richole.c */
LRESULT CreateIRichEditOle(ME_TextEditor *editor, LPVOID *);
@ -246,14 +243,14 @@ ME_TextEditor *ME_MakeEditor(ITextHost *texthost, BOOL bEmulateVersion10);
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);
int ME_GetTextW(ME_TextEditor *editor, WCHAR *buffer, int buflen,
const ME_Cursor *start, int srcChars, BOOL bCRLF);
void ME_RTFCharAttrHook(struct _RTF_Info *info);
void ME_RTFParAttrHook(struct _RTF_Info *info);
void ME_RTFTblAttrHook(struct _RTF_Info *info);
void ME_RTFSpecialCharHook(struct _RTF_Info *info);
void ME_StreamInFill(ME_InStream *stream);
extern int me_debug;
extern void DoWrap(ME_TextEditor *editor);
/* table.c */
BOOL ME_IsInTable(ME_DisplayItem *pItem);
@ -265,7 +262,7 @@ ME_DisplayItem *ME_InsertTableRowEndFromCursor(ME_TextEditor *editor);
ME_DisplayItem *ME_GetTableRowEnd(ME_DisplayItem *para);
ME_DisplayItem *ME_GetTableRowStart(ME_DisplayItem *para);
void ME_CheckTablesForCorruption(ME_TextEditor *editor);
void ME_ProtectPartialTableDeletion(ME_TextEditor *editor, int nOfs,int *nChars);
void ME_ProtectPartialTableDeletion(ME_TextEditor *editor, ME_Cursor *c, int *nChars);
ME_DisplayItem* ME_AppendTableRow(ME_TextEditor *editor, ME_DisplayItem *table_row);
void ME_TabPressedInTable(ME_TextEditor *editor, BOOL bSelectedRow);
void ME_MoveCursorFromTableRowStartParagraph(ME_TextEditor *editor);
@ -273,7 +270,7 @@ struct RTFTable *ME_MakeTableDef(ME_TextEditor *editor);
void ME_InitTableDef(ME_TextEditor *editor, struct RTFTable *tableDef);
/* txthost.c */
ITextHost *ME_CreateTextHost(HWND hwnd, BOOL bEmulateVersion10);
ITextHost *ME_CreateTextHost(HWND hwnd, CREATESTRUCTW *cs, BOOL bEmulateVersion10);
#ifdef __i386__ /* Use wrappers to perform thiscall on i386 */
#define TXTHOST_VTABLE(This) (&itextHostStdcallVtbl)
#else /* __i386__ */
@ -330,8 +327,8 @@ 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 */
HRESULT ME_GetDataObject(ME_TextEditor *editor, const CHARRANGE *lpchrg, LPDATAOBJECT *lplpdataobj);
HRESULT ME_GetDataObject(ME_TextEditor *editor, const ME_Cursor *start, int nChars, LPDATAOBJECT *lplpdataobj);

View file

@ -29,6 +29,7 @@
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
#define COBJMACROS
#define NONAMELESSUNION
@ -50,7 +51,7 @@
#include "wine/debug.h"
#ifdef __i386__
extern struct ITextHostVtbl itextHostStdcallVtbl;
extern const struct ITextHostVtbl itextHostStdcallVtbl;
#endif /* __i386__ */
typedef struct tagME_String
@ -325,7 +326,7 @@ typedef struct tagME_FontCacheItem
typedef struct tagME_TextEditor
{
HWND hWnd;
HWND hWnd, hwndParent;
ITextHost *texthost;
BOOL bEmulateVersion10;
ME_TextBuffer *pBuffer;
@ -369,6 +370,7 @@ typedef struct tagME_TextEditor
BOOL AutoURLDetect_bEnable;
WCHAR cPasswordMask;
BOOL bHaveFocus;
BOOL bDialogMode; /* Indicates that we are inside a dialog window */
/*for IME */
int imeStartIndex;
DWORD selofs; /* The size of the selection bar on the left side of control */

View file

@ -44,22 +44,63 @@ void ME_Remove(ME_DisplayItem *diWhere)
static BOOL ME_DITypesEqual(ME_DIType type, ME_DIType nTypeOrClass)
{
if (type==nTypeOrClass)
return TRUE;
if (nTypeOrClass==diRunOrParagraph && (type==diRun || type==diParagraph))
return TRUE;
if (nTypeOrClass==diRunOrStartRow && (type==diRun || type==diStartRow))
return TRUE;
if (nTypeOrClass==diParagraphOrEnd && (type==diTextEnd || type==diParagraph))
return TRUE;
if (nTypeOrClass==diStartRowOrParagraph && (type==diStartRow || type==diParagraph))
return TRUE;
if (nTypeOrClass==diStartRowOrParagraphOrEnd
&& (type==diStartRow || type==diParagraph || type==diTextEnd))
return TRUE;
if (nTypeOrClass==diRunOrParagraphOrEnd
&& (type==diRun || type==diParagraph || type==diTextEnd))
return TRUE;
switch (nTypeOrClass)
{
case diRunOrParagraph:
return type == diRun || type == diParagraph;
case diRunOrStartRow:
return type == diRun || type == diStartRow;
case diParagraphOrEnd:
return type == diTextEnd || type == diParagraph;
case diStartRowOrParagraph:
return type == diStartRow || type == diParagraph;
case diStartRowOrParagraphOrEnd:
return type == diStartRow || type == diParagraph || type == diTextEnd;
case diRunOrParagraphOrEnd:
return type == diRun || type == diParagraph || type == diTextEnd;
default:
return type == nTypeOrClass;
}
}
/* Modifies run pointer to point to the next run, and modify the
* paragraph pointer if moving into the next paragraph.
*
* Returns TRUE if next run is found, otherwise returns FALSE. */
BOOL ME_NextRun(ME_DisplayItem **para, ME_DisplayItem **run)
{
ME_DisplayItem *p = (*run)->next;
while (p->type != diTextEnd)
{
if (p->type == diParagraph) {
*para = p;
} else if (p->type == diRun) {
*run = p;
return TRUE;
}
p = p->next;
}
return FALSE;
}
/* Modifies run pointer to point to the previous run, and modify the
* paragraph pointer if moving into the previous paragraph.
*
* Returns TRUE if previous run is found, otherwise returns FALSE. */
BOOL ME_PrevRun(ME_DisplayItem **para, ME_DisplayItem **run)
{
ME_DisplayItem *p = (*run)->prev;
while (p->type != diTextStart)
{
if (p->type == diParagraph) {
if (p->member.para.prev_para->type == diParagraph)
*para = p->member.para.prev_para;
} else if (p->type == diRun) {
*run = p;
return TRUE;
}
p = p->prev;
}
return FALSE;
}

View file

@ -413,7 +413,7 @@ static void ME_DrawRun(ME_Context *c, int x, int y, ME_DisplayItem *rundi, ME_Pa
return;
start = ME_FindItemBack(rundi, diStartRow);
ME_GetSelection(c->editor, &nSelFrom, &nSelTo);
ME_GetSelectionOfs(c->editor, &nSelFrom, &nSelTo);
/* Draw selected end-of-paragraph mark */
if (run->nFlags & MERF_ENDPARA)
@ -461,19 +461,21 @@ static void ME_DrawRun(ME_Context *c, int x, int y, ME_DisplayItem *rundi, ME_Pa
}
}
static const struct {unsigned width_num : 4, width_den : 4, pen_style : 4, dble : 1;} border_details[] = {
/* none */ {0, 1, PS_SOLID, FALSE},
/* 3/4 */ {3, 4, PS_SOLID, FALSE},
/* 1 1/2 */ {3, 2, PS_SOLID, FALSE},
/* 2 1/4 */ {9, 4, PS_SOLID, FALSE},
/* 3 */ {3, 1, PS_SOLID, FALSE},
/* 4 1/2 */ {9, 2, PS_SOLID, FALSE},
/* 6 */ {6, 1, PS_SOLID, FALSE},
/* 3/4 double */ {3, 4, PS_SOLID, TRUE},
/* 1 1/2 double */ {3, 2, PS_SOLID, TRUE},
/* 2 1/4 double */ {9, 4, PS_SOLID, TRUE},
/* 3/4 gray */ {3, 4, PS_DOT /* FIXME */, FALSE},
/* 1 1/2 dashed */ {3, 2, PS_DASH, FALSE},
/* The documented widths are in points (72 dpi), but converting them to
* 96 dpi (standard display resolution) avoids dealing with fractions. */
static const struct {unsigned width : 8, pen_style : 4, dble : 1;} border_details[] = {
/* none */ {0, PS_SOLID, FALSE},
/* 3/4 */ {1, PS_SOLID, FALSE},
/* 1 1/2 */ {2, PS_SOLID, FALSE},
/* 2 1/4 */ {3, PS_SOLID, FALSE},
/* 3 */ {4, PS_SOLID, FALSE},
/* 4 1/2 */ {6, PS_SOLID, FALSE},
/* 6 */ {8, PS_SOLID, FALSE},
/* 3/4 double */ {1, PS_SOLID, TRUE},
/* 1 1/2 double */ {2, PS_SOLID, TRUE},
/* 2 1/4 double */ {3, PS_SOLID, TRUE},
/* 3/4 gray */ {1, PS_DOT /* FIXME */, FALSE},
/* 1 1/2 dashed */ {2, PS_DASH, FALSE},
};
static const COLORREF pen_colors[16] = {
@ -487,25 +489,20 @@ static const COLORREF pen_colors[16] = {
/* Dark gray */ RGB(0x80, 0x80, 0x80), /* Light gray */ RGB(0xc0, 0xc0, 0xc0),
};
static int ME_GetBorderPenWidth(ME_TextEditor* editor, int idx)
static int ME_GetBorderPenWidth(ME_Context* c, int idx)
{
int width;
int width = border_details[idx].width;
if (c->dpi.cx != 96)
width = MulDiv(width, c->dpi.cx, 96);
if (c->editor->nZoomNumerator != 0)
width = MulDiv(width, c->editor->nZoomNumerator, c->editor->nZoomDenominator);
if (editor->nZoomNumerator == 0)
{
width = border_details[idx].width_num + border_details[idx].width_den / 2;
width /= border_details[idx].width_den;
}
else
{
width = border_details[idx].width_num * editor->nZoomNumerator;
width += border_details[idx].width_den * editor->nZoomNumerator / 2;
width /= border_details[idx].width_den * editor->nZoomDenominator;
}
return width;
}
int ME_GetParaBorderWidth(ME_TextEditor* editor, int flags)
int ME_GetParaBorderWidth(ME_Context* c, int flags)
{
int idx = (flags >> 8) & 0xF;
int width;
@ -515,34 +512,11 @@ int ME_GetParaBorderWidth(ME_TextEditor* editor, int flags)
FIXME("Unsupported border value %d\n", idx);
return 0;
}
width = ME_GetBorderPenWidth(editor, idx);
width = ME_GetBorderPenWidth(c, idx);
if (border_details[idx].dble) width = width * 2 + 1;
return width;
}
int ME_GetParaLineSpace(ME_Context* c, ME_Paragraph* para)
{
int sp = 0, ls = 0;
if (!(para->pFmt->dwMask & PFM_LINESPACING)) return 0;
/* FIXME: how to compute simply the line space in ls ??? */
/* FIXME: does line spacing include the line itself ??? */
switch (para->pFmt->bLineSpacingRule)
{
case 0: sp = ls; break;
case 1: sp = (3 * ls) / 2; break;
case 2: sp = 2 * ls; break;
case 3: sp = ME_twips2pointsY(c, para->pFmt->dyLineSpacing); if (sp < ls) sp = ls; break;
case 4: sp = ME_twips2pointsY(c, para->pFmt->dyLineSpacing); break;
case 5: sp = para->pFmt->dyLineSpacing / 20; break;
default: FIXME("Unsupported spacing rule value %d\n", para->pFmt->bLineSpacingRule);
}
if (c->editor->nZoomNumerator == 0)
return sp;
else
return sp * c->editor->nZoomNumerator / c->editor->nZoomDenominator;
}
static void ME_DrawParaDecoration(ME_Context* c, ME_Paragraph* para, int y, RECT* bounds)
{
int idx, border_width, top_border, bottom_border;
@ -588,7 +562,7 @@ static void ME_DrawParaDecoration(ME_Context* c, ME_Paragraph* para, int y, RECT
*/
if (para->pFmt->wBorders & 0x00B0)
FIXME("Unsupported border flags %x\n", para->pFmt->wBorders);
border_width = ME_GetParaBorderWidth(c->editor, para->pFmt->wBorders);
border_width = ME_GetParaBorderWidth(c, para->pFmt->wBorders);
if (para->pFmt->wBorders & 4) top_border = border_width;
if (para->pFmt->wBorders & 8) bottom_border = border_width;
}
@ -630,7 +604,7 @@ static void ME_DrawParaDecoration(ME_Context* c, ME_Paragraph* para, int y, RECT
rightEdge = c->pt.x + max(c->editor->sizeWindow.cx,
c->editor->nTotalWidth);
pen_width = ME_GetBorderPenWidth(c->editor, idx);
pen_width = ME_GetBorderPenWidth(c, idx);
pen = CreatePen(border_details[idx].pen_style, pen_width, pencr);
oldpen = SelectObject(c->hDC, pen);
MoveToEx(c->hDC, 0, 0, &pt);
@ -1036,17 +1010,21 @@ void ME_ScrollAbs(ME_TextEditor *editor, int x, int y)
if (editor->horz_si.nPos != x) {
x = min(x, editor->horz_si.nMax);
x = max(x, editor->horz_si.nMin);
ITextHost_TxSetScrollPos(editor->texthost, SB_HORZ, x, TRUE);
scrollX = editor->horz_si.nPos - x;
editor->horz_si.nPos = x;
if (editor->horz_si.nMax > 0xFFFF) /* scale to 16-bit value */
x = MulDiv(x, 0xFFFF, editor->horz_si.nMax);
ITextHost_TxSetScrollPos(editor->texthost, SB_HORZ, x, TRUE);
}
if (editor->vert_si.nPos != y) {
y = min(y, editor->vert_si.nMax - (int)editor->vert_si.nPage);
y = max(y, editor->vert_si.nMin);
ITextHost_TxSetScrollPos(editor->texthost, SB_VERT, y, TRUE);
scrollY = editor->vert_si.nPos - y;
editor->vert_si.nPos = y;
if (editor->vert_si.nMax > 0xFFFF) /* scale to 16-bit value */
y = MulDiv(y, 0xFFFF, editor->vert_si.nMax);
ITextHost_TxSetScrollPos(editor->texthost, SB_VERT, y, TRUE);
}
if (abs(scrollX) > editor->sizeWindow.cx ||
@ -1061,22 +1039,28 @@ void ME_ScrollAbs(ME_TextEditor *editor, int x, int y)
if (editor->hWnd)
{
LONG winStyle = GetWindowLongW(editor->hWnd, GWL_STYLE);
bScrollBarIsVisible = (winStyle & WS_HSCROLL) != 0;
bScrollBarWillBeVisible = (editor->nTotalWidth > editor->sizeWindow.cx
&& (editor->styleFlags & WS_HSCROLL))
|| (editor->styleFlags & ES_DISABLENOSCROLL);
if (bScrollBarIsVisible != bScrollBarWillBeVisible)
ITextHost_TxShowScrollBar(editor->texthost, SB_HORZ,
bScrollBarWillBeVisible);
if (editor->styleFlags & WS_HSCROLL)
{
bScrollBarIsVisible = (winStyle & WS_HSCROLL) != 0;
bScrollBarWillBeVisible = (editor->nTotalWidth > editor->sizeWindow.cx
&& (editor->styleFlags & WS_HSCROLL))
|| (editor->styleFlags & ES_DISABLENOSCROLL);
if (bScrollBarIsVisible != bScrollBarWillBeVisible)
ITextHost_TxShowScrollBar(editor->texthost, SB_HORZ,
bScrollBarWillBeVisible);
}
bScrollBarIsVisible = (winStyle & WS_VSCROLL) != 0;
bScrollBarWillBeVisible = (editor->nTotalLength > editor->sizeWindow.cy
&& (editor->styleFlags & WS_VSCROLL)
&& (editor->styleFlags & ES_MULTILINE))
|| (editor->styleFlags & ES_DISABLENOSCROLL);
if (bScrollBarIsVisible != bScrollBarWillBeVisible)
ITextHost_TxShowScrollBar(editor->texthost, SB_VERT,
bScrollBarWillBeVisible);
if (editor->styleFlags & WS_VSCROLL)
{
bScrollBarIsVisible = (winStyle & WS_VSCROLL) != 0;
bScrollBarWillBeVisible = (editor->nTotalLength > editor->sizeWindow.cy
&& (editor->styleFlags & WS_VSCROLL)
&& (editor->styleFlags & ES_MULTILINE))
|| (editor->styleFlags & ES_DISABLENOSCROLL);
if (bScrollBarIsVisible != bScrollBarWillBeVisible)
ITextHost_TxShowScrollBar(editor->texthost, SB_VERT,
bScrollBarWillBeVisible);
}
}
ME_UpdateScrollBar(editor);
}
@ -1136,6 +1120,7 @@ void ME_UpdateScrollBar(ME_TextEditor *editor)
si.cbSize = sizeof(si);
si.fMask = SIF_PAGE | SIF_RANGE | SIF_POS;
si.nMin = 0;
if (editor->styleFlags & ES_DISABLENOSCROLL)
si.fMask |= SIF_DISABLENOSCROLL;
@ -1150,20 +1135,25 @@ void ME_UpdateScrollBar(ME_TextEditor *editor)
return;
}
si.nMin = 0;
si.nMax = editor->nTotalWidth;
si.nPos = editor->horz_si.nPos;
si.nPage = editor->sizeWindow.cx;
if (si.nMin != editor->horz_si.nMin ||
si.nMax != editor->horz_si.nMax ||
if (si.nMax != editor->horz_si.nMax ||
si.nPage != editor->horz_si.nPage)
{
TRACE("min=%d max=%d page=%d\n", si.nMin, si.nMax, si.nPage);
editor->horz_si.nMin = si.nMin;
editor->horz_si.nMax = si.nMax;
editor->horz_si.nPage = si.nPage;
if (bScrollBarWillBeVisible || bScrollBarWasVisible) {
if ((bScrollBarWillBeVisible || bScrollBarWasVisible) &&
editor->styleFlags & WS_HSCROLL)
{
if (si.nMax > 0xFFFF)
{
/* Native scales the scrollbar info to 16-bit external values. */
si.nPos = MulDiv(si.nPos, 0xFFFF, si.nMax);
si.nMax = 0xFFFF;
}
if (editor->hWnd) {
SetScrollInfo(editor->hWnd, SB_HORZ, &si, TRUE);
} else {
@ -1175,14 +1165,17 @@ void ME_UpdateScrollBar(ME_TextEditor *editor)
}
}
if (si.fMask & SIF_DISABLENOSCROLL) {
bScrollBarWillBeVisible = TRUE;
} else if (!(editor->styleFlags & WS_HSCROLL)) {
bScrollBarWillBeVisible = FALSE;
}
if (editor->styleFlags & WS_HSCROLL)
{
if (si.fMask & SIF_DISABLENOSCROLL) {
bScrollBarWillBeVisible = TRUE;
} else if (!(editor->styleFlags & WS_HSCROLL)) {
bScrollBarWillBeVisible = FALSE;
}
if (bScrollBarWasVisible != bScrollBarWillBeVisible)
ITextHost_TxShowScrollBar(editor->texthost, SB_HORZ, bScrollBarWillBeVisible);
if (bScrollBarWasVisible != bScrollBarWillBeVisible)
ITextHost_TxShowScrollBar(editor->texthost, SB_HORZ, bScrollBarWillBeVisible);
}
/* Update vertical scrollbar */
bScrollBarWasVisible = editor->vert_si.nMax > editor->vert_si.nPage;
@ -1201,15 +1194,21 @@ void ME_UpdateScrollBar(ME_TextEditor *editor)
si.nPos = editor->vert_si.nPos;
si.nPage = editor->sizeWindow.cy;
if (si.nMin != editor->vert_si.nMin ||
si.nMax != editor->vert_si.nMax ||
if (si.nMax != editor->vert_si.nMax ||
si.nPage != editor->vert_si.nPage)
{
TRACE("min=%d max=%d page=%d\n", si.nMin, si.nMax, si.nPage);
editor->vert_si.nMin = si.nMin;
editor->vert_si.nMax = si.nMax;
editor->vert_si.nPage = si.nPage;
if (bScrollBarWillBeVisible || bScrollBarWasVisible) {
if ((bScrollBarWillBeVisible || bScrollBarWasVisible) &&
editor->styleFlags & WS_VSCROLL)
{
if (si.nMax > 0xFFFF)
{
/* Native scales the scrollbar info to 16-bit external values. */
si.nPos = MulDiv(si.nPos, 0xFFFF, si.nMax);
si.nMax = 0xFFFF;
}
if (editor->hWnd) {
SetScrollInfo(editor->hWnd, SB_VERT, &si, TRUE);
} else {
@ -1221,15 +1220,18 @@ void ME_UpdateScrollBar(ME_TextEditor *editor)
}
}
if (si.fMask & SIF_DISABLENOSCROLL) {
bScrollBarWillBeVisible = TRUE;
} else if (!(editor->styleFlags & WS_VSCROLL)) {
bScrollBarWillBeVisible = FALSE;
}
if (editor->styleFlags & WS_VSCROLL)
{
if (si.fMask & SIF_DISABLENOSCROLL) {
bScrollBarWillBeVisible = TRUE;
} else if (!(editor->styleFlags & WS_VSCROLL)) {
bScrollBarWillBeVisible = FALSE;
}
if (bScrollBarWasVisible != bScrollBarWillBeVisible)
ITextHost_TxShowScrollBar(editor->texthost, SB_VERT,
bScrollBarWillBeVisible);
if (bScrollBarWasVisible != bScrollBarWillBeVisible)
ITextHost_TxShowScrollBar(editor->texthost, SB_VERT,
bScrollBarWillBeVisible);
}
}
void ME_EnsureVisible(ME_TextEditor *editor, ME_Cursor *pCursor)
@ -1242,11 +1244,24 @@ void ME_EnsureVisible(ME_TextEditor *editor, ME_Cursor *pCursor)
assert(pRow);
assert(pPara);
x = pRun->pt.x + ME_PointFromChar(editor, pRun, pCursor->nOffset);
if (x > editor->horz_si.nPos + editor->sizeWindow.cx)
x = x + 1 - editor->sizeWindow.cx;
else if (x > editor->horz_si.nPos)
if (editor->styleFlags & ES_AUTOHSCROLL)
{
x = pRun->pt.x + ME_PointFromChar(editor, pRun, pCursor->nOffset);
if (x > editor->horz_si.nPos + editor->sizeWindow.cx)
x = x + 1 - editor->sizeWindow.cx;
else if (x > editor->horz_si.nPos)
x = editor->horz_si.nPos;
if (~editor->styleFlags & ES_AUTOVSCROLL)
{
ME_HScrollAbs(editor, x);
return;
}
} else {
if (~editor->styleFlags & ES_AUTOVSCROLL)
return;
x = editor->horz_si.nPos;
}
y = pPara->member.para.pt.y + pRow->member.row.pt.y;
yheight = pRow->member.row.nHeight;
@ -1267,7 +1282,7 @@ ME_InvalidateSelection(ME_TextEditor *editor)
int nStart, nEnd;
int len = ME_GetTextLength(editor);
ME_GetSelection(editor, &nStart, &nEnd);
ME_GetSelectionOfs(editor, &nStart, &nEnd);
/* if both old and new selection are 0-char (= caret only), then
there's no (inverted) area to be repainted, neither old nor new */
if (nStart == nEnd && editor->nLastSelStart == editor->nLastSelEnd)
@ -1300,7 +1315,7 @@ ME_InvalidateSelection(ME_TextEditor *editor)
ME_InvalidateMarkedParagraphs(editor);
/* remember the last invalidated position */
ME_GetSelection(editor, &editor->nLastSelStart, &editor->nLastSelEnd);
ME_GetSelectionOfs(editor, &editor->nLastSelStart, &editor->nLastSelEnd);
ME_GetSelectionParas(editor, &editor->pLastSelStartPara, &editor->pLastSelEndPara);
assert(editor->pLastSelStartPara->type == diParagraph);
assert(editor->pLastSelEndPara->type == diParagraph);

View file

@ -335,6 +335,8 @@ ME_DisplayItem *ME_JoinParagraphs(ME_TextEditor *editor, ME_DisplayItem *tp,
int i, shift;
ME_UndoItem *undo = NULL;
int end_len;
CHARFORMAT2W fmt;
ME_Cursor startCur, endCur;
assert(tp->type == diParagraph);
assert(tp->member.para.next_para);
@ -351,12 +353,15 @@ ME_DisplayItem *ME_JoinParagraphs(ME_TextEditor *editor, ME_DisplayItem *tp,
end_len = pRun->member.run.strText->nLen;
{
/* null char format operation to store the original char format for the ENDPARA run */
CHARFORMAT2W fmt;
ME_InitCharFormat2W(&fmt);
ME_SetCharFormat(editor, pNext->member.para.nCharOfs - end_len, end_len, &fmt);
}
/* null char format operation to store the original char format for the ENDPARA run */
ME_InitCharFormat2W(&fmt);
endCur.pPara = pNext;
endCur.pRun = ME_FindItemFwd(pNext, diRun);
endCur.nOffset = 0;
startCur = endCur;
ME_PrevRun(&startCur.pPara, &startCur.pRun);
ME_SetCharFormat(editor, &startCur, &endCur, &fmt);
undo = ME_AddUndoItem(editor, diUndoSplitParagraph, pNext);
if (undo)
{

View file

@ -442,7 +442,11 @@ static void RTFUngetToken(RTF_Info *info)
* increment the value to compensate for it being decremented
* twice due to the RTFUngetToken. */
if(RTFCheckCM (info, rtfGroup, rtfEndGroup))
{
info->stack[info->stackTop].style = info->style;
ME_AddRefStyle(info->style);
info->stackTop++;
}
}
@ -783,7 +787,6 @@ static void ReadFontTbl(RTF_Info *info)
RTFFont *fp = NULL;
char buf[rtfBufSiz], *bp;
int old = -1;
const char *fn = "ReadFontTbl";
for (;;)
{
@ -799,19 +802,19 @@ static void ReadFontTbl(RTF_Info *info)
else if (RTFCheckCM (info, rtfGroup, rtfBeginGroup))
old = 0; /* brace */
else /* can't tell! */
ERR ( "%s: Cannot determine format\n", fn);
ERR ("cannot determine format\n");
}
if (old == 0) /* need to find "{" here */
{
if (!RTFCheckCM (info, rtfGroup, rtfBeginGroup))
ERR ( "%s: missing \"{\"\n", fn);
ERR ("missing \"{\"\n");
RTFGetToken (info); /* yes, skip to next token */
if (info->rtfClass == rtfEOF)
break;
}
fp = New (RTFFont);
if (fp == NULL) {
ERR ( "%s: cannot allocate font entry\n", fn);
ERR ("cannot allocate font entry\n");
break;
}
@ -837,8 +840,8 @@ static void ReadFontTbl(RTF_Info *info)
{
default:
/* ignore token but announce it */
WARN ("%s: unknown token \"%s\"\n",
fn, info->rtfTextBuf);
WARN ("unknown token \"%s\"\n",
info->rtfTextBuf);
break;
case rtfFontFamily:
fp->rtfFFamily = info->rtfMinor;
@ -899,7 +902,7 @@ static void ReadFontTbl(RTF_Info *info)
*bp = '\0';
fp->rtfFName = RTFStrSave (buf);
if (fp->rtfFName == NULL)
ERR ( "%s: cannot allocate font name\n", fn);
ERR ("cannot allocate font name\n");
/* already have next token; don't read one */
/* at bottom of loop */
continue;
@ -907,8 +910,7 @@ static void ReadFontTbl(RTF_Info *info)
else
{
/* ignore token but announce it */
WARN ( "%s: unknown token \"%s\"\n",
fn,info->rtfTextBuf);
WARN ("unknown token \"%s\"\n", info->rtfTextBuf);
}
RTFGetToken (info);
if (info->rtfClass == rtfEOF)
@ -920,7 +922,7 @@ static void ReadFontTbl(RTF_Info *info)
{
RTFGetToken (info);
if (!RTFCheckCM (info, rtfGroup, rtfEndGroup))
ERR ( "%s: missing \"}\"\n", fn);
ERR ("missing \"}\"\n");
if (info->rtfClass == rtfEOF)
break;
}
@ -934,7 +936,7 @@ static void ReadFontTbl(RTF_Info *info)
}
}
if (!fp || (fp->rtfFNum == -1))
ERR( "%s: missing font number\n", fn);
ERR("missing font number\n");
/*
* Could check other pieces of structure here, too, I suppose.
*/
@ -963,7 +965,6 @@ static void ReadColorTbl(RTF_Info *info)
{
RTFColor *cp;
int cnum = 0;
const char *fn = "ReadColorTbl";
int group_level = 1;
for (;;)
@ -986,27 +987,30 @@ static void ReadColorTbl(RTF_Info *info)
cp = New (RTFColor);
if (cp == NULL) {
ERR ( "%s: cannot allocate color entry\n", fn);
ERR ("cannot allocate color entry\n");
break;
}
cp->rtfCNum = cnum++;
cp->rtfCRed = cp->rtfCGreen = cp->rtfCBlue = -1;
cp->rtfNextColor = info->colorList;
info->colorList = cp;
while (RTFCheckCM (info, rtfControl, rtfColorName))
{
switch (info->rtfMinor)
{
case rtfRed: cp->rtfCRed = info->rtfParam; break;
case rtfGreen: cp->rtfCGreen = info->rtfParam; break;
case rtfBlue: cp->rtfCBlue = info->rtfParam; break;
}
RTFGetToken (info);
if (!RTFCheckCM (info, rtfControl, rtfColorName))
cp->rtfCRed = cp->rtfCGreen = cp->rtfCBlue = -1;
else {
cp->rtfCRed = cp->rtfCGreen = cp->rtfCBlue = 0;
do {
switch (info->rtfMinor)
{
case rtfRed: cp->rtfCRed = info->rtfParam & 0xFF; break;
case rtfGreen: cp->rtfCGreen = info->rtfParam & 0xFF; break;
case rtfBlue: cp->rtfCBlue = info->rtfParam & 0xFF; break;
}
RTFGetToken (info);
} while (RTFCheckCM (info, rtfControl, rtfColorName));
}
if (info->rtfClass == rtfEOF)
break;
if (!RTFCheckCM (info, rtfText, ';'))
ERR ("%s: malformed entry\n", fn);
ERR ("malformed entry\n");
}
RTFRouteToken (info); /* feed "}" back to router */
}
@ -1022,7 +1026,6 @@ static void ReadStyleSheet(RTF_Info *info)
RTFStyle *sp;
RTFStyleElt *sep, *sepLast;
char buf[rtfBufSiz], *bp;
const char *fn = "ReadStyleSheet";
int real_style;
for (;;)
@ -1034,7 +1037,7 @@ static void ReadStyleSheet(RTF_Info *info)
break;
sp = New (RTFStyle);
if (sp == NULL) {
ERR ( "%s: cannot allocate stylesheet entry\n", fn);
ERR ("cannot allocate stylesheet entry\n");
break;
}
sp->rtfSName = NULL;
@ -1048,7 +1051,7 @@ static void ReadStyleSheet(RTF_Info *info)
sp->rtfExpanding = 0;
info->styleList = sp;
if (!RTFCheckCM (info, rtfGroup, rtfBeginGroup))
ERR ( "%s: missing \"{\"\n", fn);
ERR ("missing \"{\"\n");
real_style = TRUE;
for (;;)
{
@ -1060,7 +1063,7 @@ static void ReadStyleSheet(RTF_Info *info)
{
if (RTFCheckMM (info, rtfSpecialChar, rtfOptDest)) {
RTFGetToken(info);
ERR( "%s: skipping optional destination\n", fn);
ERR("skipping optional destination\n");
RTFSkipGroup(info);
info->rtfClass = rtfGroup;
info->rtfMajor = rtfEndGroup;
@ -1102,14 +1105,17 @@ static void ReadStyleSheet(RTF_Info *info)
}
sep = New (RTFStyleElt);
if (sep == NULL)
ERR ( "%s: cannot allocate style element\n", fn);
{
ERR ("cannot allocate style element\n");
break;
}
sep->rtfSEClass = info->rtfClass;
sep->rtfSEMajor = info->rtfMajor;
sep->rtfSEMinor = info->rtfMinor;
sep->rtfSEParam = info->rtfParam;
sep->rtfSEText = RTFStrSave (info->rtfTextBuf);
if (sep->rtfSEText == NULL)
ERR ( "%s: cannot allocate style element text\n", fn);
ERR ("cannot allocate style element text\n");
if (sepLast == NULL)
sp->rtfSSEList = sep; /* first element */
else /* add to end */
@ -1123,7 +1129,7 @@ static void ReadStyleSheet(RTF_Info *info)
* This passes over "{\*\keycode ... }, among
* other things. A temporary (perhaps) hack.
*/
ERR( "%s: skipping begin\n", fn);
ERR("skipping begin\n");
RTFSkipGroup (info);
continue;
}
@ -1144,19 +1150,18 @@ static void ReadStyleSheet(RTF_Info *info)
*bp = '\0';
sp->rtfSName = RTFStrSave (buf);
if (sp->rtfSName == NULL)
ERR ( "%s: cannot allocate style name\n", fn);
ERR ("cannot allocate style name\n");
}
else /* unrecognized */
{
/* ignore token but announce it */
WARN ( "%s: unknown token \"%s\"\n",
fn, info->rtfTextBuf);
WARN ("unknown token \"%s\"\n", info->rtfTextBuf);
}
}
if (real_style) {
RTFGetToken (info);
if (!RTFCheckCM (info, rtfGroup, rtfEndGroup))
ERR ( "%s: missing \"}\"\n", fn);
ERR ("missing \"}\"\n");
/*
* Check over the style structure. A name is a must.
* If no style number was specified, check whether it's the
@ -1168,12 +1173,12 @@ static void ReadStyleSheet(RTF_Info *info)
* Some German RTF writers use "Standard" instead of "Normal".
*/
if (sp->rtfSName == NULL)
ERR ( "%s: missing style name\n", fn);
ERR ("missing style name\n");
if (sp->rtfSNum < 0)
{
if (strncmp (buf, "Normal", 6) != 0
&& strncmp (buf, "Standard", 8) != 0)
ERR ( "%s: missing style number\n", fn);
ERR ("missing style number\n");
sp->rtfSNum = rtfNormalStyleNum;
}
if (sp->rtfSNextPar == -1) /* if \snext not given, */

View file

@ -315,16 +315,21 @@ IRichEditOle_fnGetClipboardData(IRichEditOle *me, CHARRANGE *lpchrg,
DWORD reco, LPDATAOBJECT *lplpdataobj)
{
IRichEditOleImpl *This = impl_from_IRichEditOle(me);
CHARRANGE tmpchrg;
ME_Cursor start;
int nChars;
TRACE("(%p,%p,%d)\n",This, lpchrg, reco);
if(!lplpdataobj)
return E_INVALIDARG;
if(!lpchrg) {
ME_GetSelection(This->editor, &tmpchrg.cpMin, &tmpchrg.cpMax);
lpchrg = &tmpchrg;
int nFrom, nTo, nStartCur = ME_GetSelectionOfs(This->editor, &nFrom, &nTo);
start = This->editor->pCursors[nStartCur];
nChars = nTo - nFrom;
} else {
ME_CursorFromCharOfs(This->editor, lpchrg->cpMin, &start);
nChars = lpchrg->cpMax - lpchrg->cpMin;
}
return ME_GetDataObject(This->editor, lpchrg, lplpdataobj);
return ME_GetDataObject(This->editor, &start, nChars, lplpdataobj);
}
static LONG WINAPI IRichEditOle_fnGetLinkCount(IRichEditOle *me)
@ -383,11 +388,10 @@ IRichEditOle_fnInsertObject(IRichEditOle *me, REOBJECT *reo)
TRACE("(%p,%p)\n", This, reo);
if (reo->cbStruct < sizeof(*reo)) return STG_E_INVALIDPARAMETER;
if (reo->poleobj) IOleObject_AddRef(reo->poleobj);
if (reo->pstg) IStorage_AddRef(reo->pstg);
if (reo->polesite) IOleClientSite_AddRef(reo->polesite);
ME_InsertOLEFromCursor(This->editor, reo, 0);
ME_CommitUndo(This->editor);
ME_UpdateRepaint(This->editor);
return S_OK;
}
@ -1725,6 +1729,11 @@ void ME_GetOLEObjectSize(ME_Context *c, ME_Run *run, SIZE *pSize)
if (run->ole_obj->sizel.cx != 0 || run->ole_obj->sizel.cy != 0)
{
convert_sizel(c, &run->ole_obj->sizel, pSize);
if (c->editor->nZoomNumerator != 0)
{
pSize->cx = MulDiv(pSize->cx, c->editor->nZoomNumerator, c->editor->nZoomDenominator);
pSize->cy = MulDiv(pSize->cy, c->editor->nZoomNumerator, c->editor->nZoomDenominator);
}
return;
}
@ -1815,53 +1824,45 @@ void ME_DrawOLE(ME_Context *c, int x, int y, ME_Run *run,
GetObjectW(stgm.u.hBitmap, sizeof(dibsect), &dibsect);
hMemDC = CreateCompatibleDC(c->hDC);
SelectObject(hMemDC, stgm.u.hBitmap);
if (!has_size && c->editor->nZoomNumerator == 0)
if (has_size)
{
sz.cx = dibsect.dsBm.bmWidth;
sz.cy = dibsect.dsBm.bmHeight;
BitBlt(c->hDC, x, y - dibsect.dsBm.bmHeight,
convert_sizel(c, &run->ole_obj->sizel, &sz);
} else {
sz.cx = MulDiv(dibsect.dsBm.bmWidth, c->dpi.cx, 96);
sz.cy = MulDiv(dibsect.dsBm.bmHeight, c->dpi.cy, 96);
}
if (c->editor->nZoomNumerator != 0)
{
sz.cx = MulDiv(sz.cx, c->editor->nZoomNumerator, c->editor->nZoomDenominator);
sz.cy = MulDiv(sz.cy, c->editor->nZoomNumerator, c->editor->nZoomDenominator);
}
if (sz.cx == dibsect.dsBm.bmWidth && sz.cy == dibsect.dsBm.bmHeight)
{
BitBlt(c->hDC, x, y - sz.cy,
dibsect.dsBm.bmWidth, dibsect.dsBm.bmHeight,
hMemDC, 0, 0, SRCCOPY);
}
else
{
if (has_size)
{
convert_sizel(c, &run->ole_obj->sizel, &sz);
}
else
{
sz.cx = MulDiv(dibsect.dsBm.bmWidth,
c->editor->nZoomNumerator, c->editor->nZoomDenominator);
sz.cy = MulDiv(dibsect.dsBm.bmHeight,
c->editor->nZoomNumerator, c->editor->nZoomDenominator);
}
} else {
StretchBlt(c->hDC, x, y - sz.cy, sz.cx, sz.cy,
hMemDC, 0, 0, dibsect.dsBm.bmWidth, dibsect.dsBm.bmHeight, SRCCOPY);
hMemDC, 0, 0, dibsect.dsBm.bmWidth,
dibsect.dsBm.bmHeight, SRCCOPY);
}
if (!stgm.pUnkForRelease) DeleteObject(stgm.u.hBitmap);
break;
case TYMED_ENHMF:
GetEnhMetaFileHeader(stgm.u.hEnhMetaFile, sizeof(emh), &emh);
if (!has_size && c->editor->nZoomNumerator == 0)
if (has_size)
{
sz.cy = emh.rclBounds.bottom - emh.rclBounds.top;
sz.cx = emh.rclBounds.right - emh.rclBounds.left;
convert_sizel(c, &run->ole_obj->sizel, &sz);
} else {
sz.cy = MulDiv(emh.rclBounds.bottom - emh.rclBounds.top, c->dpi.cx, 96);
sz.cx = MulDiv(emh.rclBounds.right - emh.rclBounds.left, c->dpi.cy, 96);
}
else
if (c->editor->nZoomNumerator != 0)
{
if (has_size)
{
convert_sizel(c, &run->ole_obj->sizel, &sz);
}
else
{
sz.cy = MulDiv(emh.rclBounds.bottom - emh.rclBounds.top,
c->editor->nZoomNumerator, c->editor->nZoomDenominator);
sz.cx = MulDiv(emh.rclBounds.right - emh.rclBounds.left,
c->editor->nZoomNumerator, c->editor->nZoomDenominator);
}
sz.cx = MulDiv(sz.cx, c->editor->nZoomNumerator, c->editor->nZoomDenominator);
sz.cy = MulDiv(sz.cy, c->editor->nZoomNumerator, c->editor->nZoomDenominator);
}
{
RECT rc;

View file

@ -1095,7 +1095,7 @@ typedef void (*RTFFuncPtr) (RTF_Info *); /* generic function pointer */
/* RTF parser stack element */
struct tagRTFState {
CHARFORMAT2W fmt;
ME_Style *style;
int codePage;
int unicodeLength;
};

View file

@ -347,27 +347,6 @@ ME_DisplayItem *ME_MakeRun(ME_Style *s, ME_String *strData, int nFlags)
return item;
}
/******************************************************************************
* ME_InsertRun
*
* Inserts a run at a given character position (offset).
*/
ME_DisplayItem *ME_InsertRun(ME_TextEditor *editor, int nCharOfs, ME_DisplayItem *pItem)
{
ME_Cursor tmp;
ME_DisplayItem *pDI;
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_InsertRunAtCursor
*
@ -571,9 +550,14 @@ int ME_CharFromPointCursor(ME_TextEditor *editor, int cx, ME_Run *run)
static void ME_GetTextExtent(ME_Context *c, LPCWSTR szText, int nChars, ME_Style *s, SIZE *size)
{
HGDIOBJ hOldFont;
hOldFont = ME_SelectStyleFont(c, s);
GetTextExtentPoint32W(c->hDC, szText, nChars, size);
ME_UnselectStyleFont(c, s, hOldFont);
if (c->hDC) {
hOldFont = ME_SelectStyleFont(c, s);
GetTextExtentPoint32W(c->hDC, szText, nChars, size);
ME_UnselectStyleFont(c, s, hOldFont);
} else {
size->cx = 0;
size->cy = 0;
}
}
/******************************************************************************
@ -726,15 +710,13 @@ void ME_CalcRunExtent(ME_Context *c, const ME_Paragraph *para, int startx, ME_Ru
/******************************************************************************
* ME_SetSelectionCharFormat
*
*
* Applies a style change, either to a current selection, or to insert cursor
* (ie. the style next typed characters will use).
*/
*/
void ME_SetSelectionCharFormat(ME_TextEditor *editor, CHARFORMAT2W *pFmt)
{
int nFrom, nTo;
ME_GetSelection(editor, &nFrom, &nTo);
if (nFrom == nTo)
if (!ME_IsSelection(editor))
{
ME_Style *s;
if (!editor->pBuffer->pCharStyle)
@ -742,57 +724,85 @@ void ME_SetSelectionCharFormat(ME_TextEditor *editor, CHARFORMAT2W *pFmt)
s = ME_ApplyStyle(editor->pBuffer->pCharStyle, pFmt);
ME_ReleaseStyle(editor->pBuffer->pCharStyle);
editor->pBuffer->pCharStyle = s;
} else {
ME_Cursor *from, *to;
ME_GetSelection(editor, &from, &to);
ME_SetCharFormat(editor, from, to, pFmt);
}
else
ME_SetCharFormat(editor, nFrom, nTo-nFrom, pFmt);
}
/******************************************************************************
* ME_SetCharFormat
*
*
* Applies a style change to the specified part of the text
*/
void ME_SetCharFormat(ME_TextEditor *editor, int nOfs, int nChars, CHARFORMAT2W *pFmt)
*
* The start and end cursors specify the part of the text. These cursors will
* be updated to stay valid, but this function may invalidate other
* non-selection cursors. The end cursor may be NULL to specify all the text
* following the start cursor.
*
* If no text is selected, then nothing is done.
*/
void ME_SetCharFormat(ME_TextEditor *editor, ME_Cursor *start, ME_Cursor *end, CHARFORMAT2W *pFmt)
{
ME_Cursor tmp, tmp2;
ME_DisplayItem *para;
ME_DisplayItem *run;
ME_DisplayItem *end_run = NULL;
ME_CursorFromCharOfs(editor, nOfs, &tmp);
if (tmp.nOffset)
tmp.pRun = ME_SplitRunSimple(editor, tmp.pRun, tmp.nOffset);
if (end && start->pRun == end->pRun && start->nOffset == end->nOffset)
return;
ME_CursorFromCharOfs(editor, nOfs+nChars, &tmp2);
if (tmp2.nOffset)
tmp2.pRun = ME_SplitRunSimple(editor, tmp2.pRun, tmp2.nOffset);
if (start->nOffset)
{
/* SplitRunSimple may or may not update the cursors, depending on whether they
* are selection cursors, but we need to make sure they are valid. */
ME_DisplayItem *split_run = start->pRun;
int split_offset = start->nOffset;
start->pRun = ME_SplitRunSimple(editor, split_run, split_offset);
start->nOffset = 0;
if (end && end->pRun == split_run)
{
end->pRun = start->pRun;
end->nOffset -= split_offset;
}
}
para = tmp.pPara;
if (end && end->nOffset)
{
end_run = end->pRun = ME_SplitRunSimple(editor, end->pRun, end->nOffset);
end->nOffset = 0;
} else if (end) {
end_run = end->pRun;
}
run = start->pRun;
para = start->pPara;
para->member.para.nFlags |= MEPF_REWRAP;
while(tmp.pRun != tmp2.pRun)
while(run != end_run)
{
ME_UndoItem *undo = NULL;
ME_Style *new_style = ME_ApplyStyle(tmp.pRun->member.run.style, pFmt);
ME_Style *new_style = ME_ApplyStyle(run->member.run.style, pFmt);
/* ME_DumpStyle(new_style); */
undo = ME_AddUndoItem(editor, diUndoSetCharFormat, NULL);
if (undo) {
undo->nStart = tmp.pRun->member.run.nCharOfs+para->member.para.nCharOfs;
undo->nLen = tmp.pRun->member.run.strText->nLen;
undo->di.member.ustyle = tmp.pRun->member.run.style;
undo->nStart = run->member.run.nCharOfs+para->member.para.nCharOfs;
undo->nLen = run->member.run.strText->nLen;
undo->di.member.ustyle = run->member.run.style;
/* we'd have to addref undo...ustyle and release tmp...style
but they'd cancel each other out so we can do nothing instead */
}
else
ME_ReleaseStyle(tmp.pRun->member.run.style);
tmp.pRun->member.run.style = new_style;
tmp.pRun = ME_FindItemFwd(tmp.pRun, diRunOrParagraph);
if (tmp.pRun->type == diParagraph)
ME_ReleaseStyle(run->member.run.style);
run->member.run.style = new_style;
run = ME_FindItemFwd(run, diRunOrParagraph);
if (run && run->type == diParagraph)
{
para = tmp.pRun;
tmp.pRun = ME_FindItemFwd(tmp.pRun, diRun);
if (tmp.pRun != tmp2.pRun)
para = run;
run = ME_FindItemFwd(run, diRun);
if (run != end_run)
para->member.para.nFlags |= MEPF_REWRAP;
}
assert(tmp.pRun);
}
}
@ -842,20 +852,20 @@ void ME_GetDefaultCharFormat(ME_TextEditor *editor, CHARFORMAT2W *pFmt)
/******************************************************************************
* ME_GetSelectionCharFormat
*
*
* If selection exists, it returns all style elements that are set consistently
* in the whole selection. If not, it just returns the current style.
*/
* in the whole selection. If not, it just returns the current style.
*/
void ME_GetSelectionCharFormat(ME_TextEditor *editor, CHARFORMAT2W *pFmt)
{
int nFrom, nTo;
ME_GetSelection(editor, &nFrom, &nTo);
if (nFrom == nTo && editor->pBuffer->pCharStyle)
ME_Cursor *from, *to;
if (!ME_IsSelection(editor) && editor->pBuffer->pCharStyle)
{
ME_CopyCharFormat(pFmt, &editor->pBuffer->pCharStyle->fmt);
return;
}
ME_GetCharFormat(editor, nFrom, nTo, pFmt);
ME_GetSelection(editor, &from, &to);
ME_GetCharFormat(editor, from, to, pFmt);
}
/******************************************************************************
@ -864,16 +874,17 @@ void ME_GetSelectionCharFormat(ME_TextEditor *editor, CHARFORMAT2W *pFmt)
* Returns the style consisting of those attributes which are consistently set
* in the whole character range.
*/
void ME_GetCharFormat(ME_TextEditor *editor, int nFrom, int nTo, CHARFORMAT2W *pFmt)
void ME_GetCharFormat(ME_TextEditor *editor, const ME_Cursor *from,
const ME_Cursor *to, CHARFORMAT2W *pFmt)
{
ME_DisplayItem *run, *run_end;
int nOffset, nOffset2;
CHARFORMAT2W tmp;
ME_RunOfsFromCharOfs(editor, nFrom, NULL, &run, &nOffset);
if (nFrom == nTo) /* special case - if selection is empty, take previous char's formatting */
run = from->pRun;
/* special case - if selection is empty, take previous char's formatting */
if (from->pRun == to->pRun && from->nOffset == to->nOffset)
{
if (!nOffset)
if (!from->nOffset)
{
ME_DisplayItem *tmp_run = ME_FindItemBack(run, diRunOrParagraph);
if (tmp_run->type == diRun) {
@ -884,10 +895,10 @@ void ME_GetCharFormat(ME_TextEditor *editor, int nFrom, int nTo, CHARFORMAT2W *p
ME_GetRunCharFormat(editor, run, pFmt);
return;
}
if (nTo>nFrom) /* selection consists of chars from nFrom up to nTo-1 */
nTo--;
ME_RunOfsFromCharOfs(editor, nTo, NULL, &run_end, &nOffset2);
run_end = to->pRun;
if (!to->nOffset)
run_end = ME_FindItemBack(run_end, diRun);
ME_GetRunCharFormat(editor, run, pFmt);

View file

@ -156,6 +156,7 @@ ME_Style *ME_MakeStyle(CHARFORMAT2W *style) {
s->hFont = NULL;
s->tm.tmAscent = -1;
all_refs++;
TRACE_(richedit_style)("ME_MakeStyle %p, total refs=%d\n", s, all_refs);
return s;
}
@ -449,6 +450,7 @@ void ME_AddRefStyle(ME_Style *s)
assert(s->nRefs>0); /* style with 0 references isn't supposed to exist */
s->nRefs++;
all_refs++;
TRACE_(richedit_style)("ME_AddRefStyle %p, new refs=%d, total refs=%d\n", s, s->nRefs, all_refs);
}
void ME_ReleaseStyle(ME_Style *s)
@ -465,16 +467,15 @@ void ME_ReleaseStyle(ME_Style *s)
ME_DestroyStyle(s);
}
ME_Style *ME_GetInsertStyle(ME_TextEditor *editor, int nCursor) {
ME_Style *ME_GetInsertStyle(ME_TextEditor *editor, int nCursor)
{
if (ME_IsSelection(editor))
{
ME_Cursor c;
int from, to;
ME_Cursor *from, *to;
ME_GetSelection(editor, &from, &to);
ME_CursorFromCharOfs(editor, from, &c);
ME_AddRefStyle(c.pRun->member.run.style);
return c.pRun->member.run.style;
ME_AddRefStyle(from->pRun->member.run.style);
return from->pRun->member.run.style;
}
if (editor->pBuffer->pCharStyle) {
ME_AddRefStyle(editor->pBuffer->pCharStyle);

View file

@ -70,6 +70,7 @@ static ME_DisplayItem* ME_InsertEndParaFromCursor(ME_TextEditor *editor,
}
tp = ME_SplitParagraph(editor, cursor->pRun, pStyle, eol_str, paraFlags);
ME_ReleaseStyle(pStyle);
cursor->pPara = tp;
cursor->pRun = ME_FindItemFwd(tp, diRun);
return tp;
@ -95,6 +96,7 @@ ME_DisplayItem* ME_InsertTableRowStartAtParagraph(ME_TextEditor *editor,
editor->pCursors[0].nOffset = 0;
editor->pCursors[1] = editor->pCursors[0];
startRowPara = ME_InsertTableRowStartFromCursor(editor);
savedCursor.pPara = ME_GetParagraph(savedCursor.pRun);
editor->pCursors[0] = savedCursor;
editor->pCursors[1] = editor->pCursors[0];
@ -121,8 +123,8 @@ ME_DisplayItem* ME_InsertTableRowStartAtParagraph(ME_TextEditor *editor,
ME_DisplayItem* ME_InsertTableCellFromCursor(ME_TextEditor *editor)
{
ME_DisplayItem *para;
WCHAR cr = '\r';
ME_String *eol_str = ME_MakeStringN(&cr, 1);
WCHAR tab = '\t';
ME_String *eol_str = ME_MakeStringN(&tab, 1);
para = ME_InsertEndParaFromCursor(editor, 0, eol_str, MEPF_CELL);
return para;
}
@ -273,13 +275,14 @@ BOOL ME_IsInTable(ME_DisplayItem *pItem)
}
/* Table rows should either be deleted completely or not at all. */
void ME_ProtectPartialTableDeletion(ME_TextEditor *editor, int nOfs,int *nChars)
void ME_ProtectPartialTableDeletion(ME_TextEditor *editor, ME_Cursor *c, int *nChars)
{
ME_Cursor c, c2;
ME_DisplayItem *this_para, *end_para;
ME_CursorFromCharOfs(editor, nOfs, &c);
this_para = c.pPara;
ME_CursorFromCharOfs(editor, nOfs + *nChars, &c2);
int nOfs = ME_GetCursorOfs(c);
ME_Cursor c2 = *c;
ME_DisplayItem *this_para = c->pPara;
ME_DisplayItem *end_para;
ME_MoveCursorChars(editor, &c2, *nChars);
end_para = c2.pPara;
if (c2.pRun->member.run.nFlags & MERF_ENDPARA) {
/* End offset might be in the middle of the end paragraph run.
@ -355,27 +358,32 @@ void ME_ProtectPartialTableDeletion(ME_TextEditor *editor, int nOfs,int *nChars)
this_para->member.para.pFmt->dwMask & PFM_TABLE &&
this_para->member.para.pFmt->wEffects & PFE_TABLE)
{
pRun = c.pRun;
pRun = c->pRun;
/* Find the next tab or end paragraph to use as a delete boundary */
while (!(pRun->member.run.nFlags & (MERF_TAB|MERF_ENDPARA)))
pRun = ME_FindItemFwd(pRun, diRun);
nCharsToBoundary = pRun->member.run.nCharOfs
- c.pRun->member.run.nCharOfs
- c.nOffset;
- c->pRun->member.run.nCharOfs
- c->nOffset;
*nChars = min(*nChars, nCharsToBoundary);
} else if (end_para->member.para.pFmt->dwMask & PFM_TABLE &&
end_para->member.para.pFmt->wEffects & PFE_TABLE)
{
/* The deletion starts from before the row, so don't join it with
* previous non-empty paragraphs. */
ME_DisplayItem *curPara;
pRun = NULL;
if (nOfs > this_para->member.para.nCharOfs)
if (nOfs > this_para->member.para.nCharOfs) {
pRun = ME_FindItemBack(end_para, diRun);
if (!pRun)
curPara = end_para->member.para.prev_para;
}
if (!pRun) {
pRun = ME_FindItemFwd(end_para, diRun);
curPara = end_para;
}
if (pRun)
{
nCharsToBoundary = ME_GetParagraph(pRun)->member.para.nCharOfs
nCharsToBoundary = curPara->member.para.nCharOfs
+ pRun->member.run.nCharOfs
- nOfs;
if (nCharsToBoundary >= 0)
@ -549,8 +557,8 @@ void ME_TabPressedInTable(ME_TextEditor *editor, BOOL bSelectedRow)
ME_InvalidateSelection(editor);
{
int from, to;
from = ME_GetCursorOfs(editor, 0);
to = ME_GetCursorOfs(editor, 1);
from = ME_GetCursorOfs(&editor->pCursors[0]);
to = ME_GetCursorOfs(&editor->pCursors[1]);
if (from <= to)
{
fromCursor = editor->pCursors[0];

View file

@ -42,9 +42,9 @@ typedef struct ITextHostImpl {
BOOL bEmulateVersion10;
} ITextHostImpl;
static ITextHostVtbl textHostVtbl;
static const ITextHostVtbl textHostVtbl;
ITextHost *ME_CreateTextHost(HWND hwnd, BOOL bEmulateVersion10)
ITextHost *ME_CreateTextHost(HWND hwnd, CREATESTRUCTW *cs, BOOL bEmulateVersion10)
{
ITextHostImpl *texthost;
texthost = CoTaskMemAlloc(sizeof(*texthost));
@ -59,7 +59,9 @@ ITextHost *ME_CreateTextHost(HWND hwnd, BOOL bEmulateVersion10)
editor = ME_MakeEditor((ITextHost*)texthost, bEmulateVersion10);
editor->exStyleFlags = GetWindowLongW(hwnd, GWL_EXSTYLE);
editor->styleFlags |= GetWindowLongW(hwnd, GWL_STYLE) & ES_WANTRETURN;
editor->hWnd = hwnd; /* FIXME: Remove editor's dependence on hWnd */
editor->hwndParent = cs->hwndParent;
SetWindowLongPtrW(hwnd, 0, (LONG_PTR)editor);
}
@ -448,9 +450,13 @@ HRESULT WINAPI ITextHostImpl_TxNotify(ITextHost *iface,
void *pv)
{
ITextHostImpl *This = (ITextHostImpl *)iface;
ME_TextEditor *editor = (ME_TextEditor*)GetWindowLongPtrW(This->hWnd, 0);
HWND hwnd = This->hWnd;
HWND parent = GetParent(hwnd);
UINT id = GetWindowLongW(hwnd, GWLP_ID);
UINT id;
if (!editor || !editor->hwndParent) return S_OK;
id = GetWindowLongW(hwnd, GWLP_ID);
switch (iNotify)
{
@ -471,13 +477,13 @@ HRESULT WINAPI ITextHostImpl_TxNotify(ITextHost *iface,
info->hwndFrom = hwnd;
info->idFrom = id;
info->code = iNotify;
SendMessageW(parent, WM_NOTIFY, id, (LPARAM)info);
SendMessageW(editor->hwndParent, WM_NOTIFY, id, (LPARAM)info);
break;
}
case EN_UPDATE:
/* Only sent when the window is visible. */
if (!IsWindowVisible(This->hWnd))
if (!IsWindowVisible(hwnd))
break;
/* Fall through */
case EN_CHANGE:
@ -487,7 +493,7 @@ HRESULT WINAPI ITextHostImpl_TxNotify(ITextHost *iface,
case EN_MAXTEXT:
case EN_SETFOCUS:
case EN_VSCROLL:
SendMessageW(parent, WM_COMMAND, MAKEWPARAM(id, iNotify), (LPARAM)hwnd);
SendMessageW(editor->hwndParent, WM_COMMAND, MAKEWPARAM(id, iNotify), (LPARAM)hwnd);
break;
case EN_MSGFILTER:
@ -528,159 +534,114 @@ HRESULT WINAPI ITextHostImpl_TxGetSelectionBarWidth(ITextHost *iface,
#ifdef __i386__ /* thiscall functions are i386-specific */
#define THISCALL(func) __thiscall_ ## func
#define DEFINE_THISCALL_WRAPPER(func) \
#define DEFINE_THISCALL_WRAPPER(func,args) \
extern typeof(func) THISCALL(func); \
__ASM_GLOBAL_FUNC(__thiscall_ ## func, \
__ASM_STDCALL_FUNC(__thiscall_ ## func, args, \
"popl %eax\n\t" \
"pushl %ecx\n\t" \
"pushl %eax\n\t" \
"jmp " __ASM_NAME(#func) )
"jmp " __ASM_NAME(#func) __ASM_STDCALL(args) )
#else /* __i386__ */
#define THISCALL(func) func
#define DEFINE_THISCALL_WRAPPER(func) /* nothing */
#define DEFINE_THISCALL_WRAPPER(func,args) /* nothing */
#endif /* __i386__ */
DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxGetDC);
DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxReleaseDC);
DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxShowScrollBar);
DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxEnableScrollBar);
DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxSetScrollRange);
DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxSetScrollPos);
DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxInvalidateRect);
DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxViewChange);
DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxCreateCaret);
DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxShowCaret);
DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxSetCaretPos);
DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxSetTimer);
DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxKillTimer);
DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxScrollWindowEx);
DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxSetCapture);
DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxSetFocus);
DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxSetCursor);
DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxScreenToClient);
DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxClientToScreen);
DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxActivate);
DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxDeactivate);
DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxGetClientRect);
DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxGetViewInset);
DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxGetCharFormat);
DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxGetParaFormat);
DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxGetSysColor);
DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxGetBackStyle);
DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxGetMaxLength);
DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxGetScrollBars);
DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxGetPasswordChar);
DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxGetAcceleratorPos);
DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxGetExtent);
DEFINE_THISCALL_WRAPPER(ITextHostImpl_OnTxCharFormatChange);
DEFINE_THISCALL_WRAPPER(ITextHostImpl_OnTxParaFormatChange);
DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxGetPropertyBits);
DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxNotify);
DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxImmGetContext);
DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxImmReleaseContext);
DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxGetSelectionBarWidth);
static ITextHostVtbl textHostVtbl = {
ITextHostImpl_QueryInterface,
ITextHostImpl_AddRef,
ITextHostImpl_Release,
THISCALL(ITextHostImpl_TxGetDC),
THISCALL(ITextHostImpl_TxReleaseDC),
THISCALL(ITextHostImpl_TxShowScrollBar),
THISCALL(ITextHostImpl_TxEnableScrollBar),
THISCALL(ITextHostImpl_TxSetScrollRange),
THISCALL(ITextHostImpl_TxSetScrollPos),
THISCALL(ITextHostImpl_TxInvalidateRect),
THISCALL(ITextHostImpl_TxViewChange),
THISCALL(ITextHostImpl_TxCreateCaret),
THISCALL(ITextHostImpl_TxShowCaret),
THISCALL(ITextHostImpl_TxSetCaretPos),
THISCALL(ITextHostImpl_TxSetTimer),
THISCALL(ITextHostImpl_TxKillTimer),
THISCALL(ITextHostImpl_TxScrollWindowEx),
THISCALL(ITextHostImpl_TxSetCapture),
THISCALL(ITextHostImpl_TxSetFocus),
THISCALL(ITextHostImpl_TxSetCursor),
THISCALL(ITextHostImpl_TxScreenToClient),
THISCALL(ITextHostImpl_TxClientToScreen),
THISCALL(ITextHostImpl_TxActivate),
THISCALL(ITextHostImpl_TxDeactivate),
THISCALL(ITextHostImpl_TxGetClientRect),
THISCALL(ITextHostImpl_TxGetViewInset),
THISCALL(ITextHostImpl_TxGetCharFormat),
THISCALL(ITextHostImpl_TxGetParaFormat),
THISCALL(ITextHostImpl_TxGetSysColor),
THISCALL(ITextHostImpl_TxGetBackStyle),
THISCALL(ITextHostImpl_TxGetMaxLength),
THISCALL(ITextHostImpl_TxGetScrollBars),
THISCALL(ITextHostImpl_TxGetPasswordChar),
THISCALL(ITextHostImpl_TxGetAcceleratorPos),
THISCALL(ITextHostImpl_TxGetExtent),
THISCALL(ITextHostImpl_OnTxCharFormatChange),
THISCALL(ITextHostImpl_OnTxParaFormatChange),
THISCALL(ITextHostImpl_TxGetPropertyBits),
THISCALL(ITextHostImpl_TxNotify),
THISCALL(ITextHostImpl_TxImmGetContext),
THISCALL(ITextHostImpl_TxImmReleaseContext),
THISCALL(ITextHostImpl_TxGetSelectionBarWidth),
};
DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxGetDC,4)
DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxReleaseDC,8)
DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxShowScrollBar,12)
DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxEnableScrollBar,12)
DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxSetScrollRange,20)
DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxSetScrollPos,16)
DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxInvalidateRect,12)
DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxViewChange,8)
DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxCreateCaret,16)
DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxShowCaret,8)
DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxSetCaretPos,12)
DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxSetTimer,12)
DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxKillTimer,8)
DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxScrollWindowEx,32)
DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxSetCapture,8)
DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxSetFocus,4)
DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxSetCursor,12)
DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxScreenToClient,8)
DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxClientToScreen,8)
DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxActivate,8)
DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxDeactivate,8)
DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxGetClientRect,8)
DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxGetViewInset,8)
DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxGetCharFormat,8)
DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxGetParaFormat,8)
DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxGetSysColor,8)
DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxGetBackStyle,8)
DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxGetMaxLength,8)
DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxGetScrollBars,8)
DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxGetPasswordChar,8)
DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxGetAcceleratorPos,8)
DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxGetExtent,8)
DEFINE_THISCALL_WRAPPER(ITextHostImpl_OnTxCharFormatChange,8)
DEFINE_THISCALL_WRAPPER(ITextHostImpl_OnTxParaFormatChange,8)
DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxGetPropertyBits,12)
DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxNotify,12)
DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxImmGetContext,4)
DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxImmReleaseContext,8)
DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxGetSelectionBarWidth,8)
#ifdef __i386__ /* thiscall functions are i386-specific */
#define STDCALL(func) __stdcall_ ## func
#define DEFINE_STDCALL_WRAPPER(num,func) \
#define DEFINE_STDCALL_WRAPPER(num,func,args) \
extern typeof(func) __stdcall_ ## func; \
__ASM_GLOBAL_FUNC(__stdcall_ ## func, \
__ASM_STDCALL_FUNC(__stdcall_ ## func, args, \
"popl %eax\n\t" \
"popl %ecx\n\t" \
"pushl %eax\n\t" \
"movl (%ecx), %eax\n\t" \
"jmp *(4*(" #num "))(%eax)" )
DEFINE_STDCALL_WRAPPER(3,ITextHostImpl_TxGetDC);
DEFINE_STDCALL_WRAPPER(4,ITextHostImpl_TxReleaseDC);
DEFINE_STDCALL_WRAPPER(5,ITextHostImpl_TxShowScrollBar);
DEFINE_STDCALL_WRAPPER(6,ITextHostImpl_TxEnableScrollBar);
DEFINE_STDCALL_WRAPPER(7,ITextHostImpl_TxSetScrollRange);
DEFINE_STDCALL_WRAPPER(8,ITextHostImpl_TxSetScrollPos);
DEFINE_STDCALL_WRAPPER(9,ITextHostImpl_TxInvalidateRect);
DEFINE_STDCALL_WRAPPER(10,ITextHostImpl_TxViewChange);
DEFINE_STDCALL_WRAPPER(11,ITextHostImpl_TxCreateCaret);
DEFINE_STDCALL_WRAPPER(12,ITextHostImpl_TxShowCaret);
DEFINE_STDCALL_WRAPPER(13,ITextHostImpl_TxSetCaretPos);
DEFINE_STDCALL_WRAPPER(14,ITextHostImpl_TxSetTimer);
DEFINE_STDCALL_WRAPPER(15,ITextHostImpl_TxKillTimer);
DEFINE_STDCALL_WRAPPER(16,ITextHostImpl_TxScrollWindowEx);
DEFINE_STDCALL_WRAPPER(17,ITextHostImpl_TxSetCapture);
DEFINE_STDCALL_WRAPPER(18,ITextHostImpl_TxSetFocus);
DEFINE_STDCALL_WRAPPER(19,ITextHostImpl_TxSetCursor);
DEFINE_STDCALL_WRAPPER(20,ITextHostImpl_TxScreenToClient);
DEFINE_STDCALL_WRAPPER(21,ITextHostImpl_TxClientToScreen);
DEFINE_STDCALL_WRAPPER(22,ITextHostImpl_TxActivate);
DEFINE_STDCALL_WRAPPER(23,ITextHostImpl_TxDeactivate);
DEFINE_STDCALL_WRAPPER(24,ITextHostImpl_TxGetClientRect);
DEFINE_STDCALL_WRAPPER(25,ITextHostImpl_TxGetViewInset);
DEFINE_STDCALL_WRAPPER(26,ITextHostImpl_TxGetCharFormat);
DEFINE_STDCALL_WRAPPER(27,ITextHostImpl_TxGetParaFormat);
DEFINE_STDCALL_WRAPPER(28,ITextHostImpl_TxGetSysColor);
DEFINE_STDCALL_WRAPPER(29,ITextHostImpl_TxGetBackStyle);
DEFINE_STDCALL_WRAPPER(30,ITextHostImpl_TxGetMaxLength);
DEFINE_STDCALL_WRAPPER(31,ITextHostImpl_TxGetScrollBars);
DEFINE_STDCALL_WRAPPER(32,ITextHostImpl_TxGetPasswordChar);
DEFINE_STDCALL_WRAPPER(33,ITextHostImpl_TxGetAcceleratorPos);
DEFINE_STDCALL_WRAPPER(34,ITextHostImpl_TxGetExtent);
DEFINE_STDCALL_WRAPPER(35,ITextHostImpl_OnTxCharFormatChange);
DEFINE_STDCALL_WRAPPER(36,ITextHostImpl_OnTxParaFormatChange);
DEFINE_STDCALL_WRAPPER(37,ITextHostImpl_TxGetPropertyBits);
DEFINE_STDCALL_WRAPPER(38,ITextHostImpl_TxNotify);
DEFINE_STDCALL_WRAPPER(39,ITextHostImpl_TxImmGetContext);
DEFINE_STDCALL_WRAPPER(40,ITextHostImpl_TxImmReleaseContext);
DEFINE_STDCALL_WRAPPER(41,ITextHostImpl_TxGetSelectionBarWidth);
DEFINE_STDCALL_WRAPPER(3,ITextHostImpl_TxGetDC,4)
DEFINE_STDCALL_WRAPPER(4,ITextHostImpl_TxReleaseDC,8)
DEFINE_STDCALL_WRAPPER(5,ITextHostImpl_TxShowScrollBar,12)
DEFINE_STDCALL_WRAPPER(6,ITextHostImpl_TxEnableScrollBar,12)
DEFINE_STDCALL_WRAPPER(7,ITextHostImpl_TxSetScrollRange,20)
DEFINE_STDCALL_WRAPPER(8,ITextHostImpl_TxSetScrollPos,16)
DEFINE_STDCALL_WRAPPER(9,ITextHostImpl_TxInvalidateRect,12)
DEFINE_STDCALL_WRAPPER(10,ITextHostImpl_TxViewChange,8)
DEFINE_STDCALL_WRAPPER(11,ITextHostImpl_TxCreateCaret,16)
DEFINE_STDCALL_WRAPPER(12,ITextHostImpl_TxShowCaret,8)
DEFINE_STDCALL_WRAPPER(13,ITextHostImpl_TxSetCaretPos,12)
DEFINE_STDCALL_WRAPPER(14,ITextHostImpl_TxSetTimer,12)
DEFINE_STDCALL_WRAPPER(15,ITextHostImpl_TxKillTimer,8)
DEFINE_STDCALL_WRAPPER(16,ITextHostImpl_TxScrollWindowEx,32)
DEFINE_STDCALL_WRAPPER(17,ITextHostImpl_TxSetCapture,8)
DEFINE_STDCALL_WRAPPER(18,ITextHostImpl_TxSetFocus,4)
DEFINE_STDCALL_WRAPPER(19,ITextHostImpl_TxSetCursor,12)
DEFINE_STDCALL_WRAPPER(20,ITextHostImpl_TxScreenToClient,8)
DEFINE_STDCALL_WRAPPER(21,ITextHostImpl_TxClientToScreen,8)
DEFINE_STDCALL_WRAPPER(22,ITextHostImpl_TxActivate,8)
DEFINE_STDCALL_WRAPPER(23,ITextHostImpl_TxDeactivate,8)
DEFINE_STDCALL_WRAPPER(24,ITextHostImpl_TxGetClientRect,8)
DEFINE_STDCALL_WRAPPER(25,ITextHostImpl_TxGetViewInset,8)
DEFINE_STDCALL_WRAPPER(26,ITextHostImpl_TxGetCharFormat,8)
DEFINE_STDCALL_WRAPPER(27,ITextHostImpl_TxGetParaFormat,8)
DEFINE_STDCALL_WRAPPER(28,ITextHostImpl_TxGetSysColor,8)
DEFINE_STDCALL_WRAPPER(29,ITextHostImpl_TxGetBackStyle,8)
DEFINE_STDCALL_WRAPPER(30,ITextHostImpl_TxGetMaxLength,8)
DEFINE_STDCALL_WRAPPER(31,ITextHostImpl_TxGetScrollBars,8)
DEFINE_STDCALL_WRAPPER(32,ITextHostImpl_TxGetPasswordChar,8)
DEFINE_STDCALL_WRAPPER(33,ITextHostImpl_TxGetAcceleratorPos,8)
DEFINE_STDCALL_WRAPPER(34,ITextHostImpl_TxGetExtent,8)
DEFINE_STDCALL_WRAPPER(35,ITextHostImpl_OnTxCharFormatChange,8)
DEFINE_STDCALL_WRAPPER(36,ITextHostImpl_OnTxParaFormatChange,8)
DEFINE_STDCALL_WRAPPER(37,ITextHostImpl_TxGetPropertyBits,12)
DEFINE_STDCALL_WRAPPER(38,ITextHostImpl_TxNotify,12)
DEFINE_STDCALL_WRAPPER(39,ITextHostImpl_TxImmGetContext,4)
DEFINE_STDCALL_WRAPPER(40,ITextHostImpl_TxImmReleaseContext,8)
DEFINE_STDCALL_WRAPPER(41,ITextHostImpl_TxGetSelectionBarWidth,8)
ITextHostVtbl itextHostStdcallVtbl = {
const ITextHostVtbl itextHostStdcallVtbl = {
NULL,
NULL,
NULL,
@ -726,3 +687,48 @@ ITextHostVtbl itextHostStdcallVtbl = {
};
#endif /* __i386__ */
static const ITextHostVtbl textHostVtbl = {
ITextHostImpl_QueryInterface,
ITextHostImpl_AddRef,
ITextHostImpl_Release,
THISCALL(ITextHostImpl_TxGetDC),
THISCALL(ITextHostImpl_TxReleaseDC),
THISCALL(ITextHostImpl_TxShowScrollBar),
THISCALL(ITextHostImpl_TxEnableScrollBar),
THISCALL(ITextHostImpl_TxSetScrollRange),
THISCALL(ITextHostImpl_TxSetScrollPos),
THISCALL(ITextHostImpl_TxInvalidateRect),
THISCALL(ITextHostImpl_TxViewChange),
THISCALL(ITextHostImpl_TxCreateCaret),
THISCALL(ITextHostImpl_TxShowCaret),
THISCALL(ITextHostImpl_TxSetCaretPos),
THISCALL(ITextHostImpl_TxSetTimer),
THISCALL(ITextHostImpl_TxKillTimer),
THISCALL(ITextHostImpl_TxScrollWindowEx),
THISCALL(ITextHostImpl_TxSetCapture),
THISCALL(ITextHostImpl_TxSetFocus),
THISCALL(ITextHostImpl_TxSetCursor),
THISCALL(ITextHostImpl_TxScreenToClient),
THISCALL(ITextHostImpl_TxClientToScreen),
THISCALL(ITextHostImpl_TxActivate),
THISCALL(ITextHostImpl_TxDeactivate),
THISCALL(ITextHostImpl_TxGetClientRect),
THISCALL(ITextHostImpl_TxGetViewInset),
THISCALL(ITextHostImpl_TxGetCharFormat),
THISCALL(ITextHostImpl_TxGetParaFormat),
THISCALL(ITextHostImpl_TxGetSysColor),
THISCALL(ITextHostImpl_TxGetBackStyle),
THISCALL(ITextHostImpl_TxGetMaxLength),
THISCALL(ITextHostImpl_TxGetScrollBars),
THISCALL(ITextHostImpl_TxGetPasswordChar),
THISCALL(ITextHostImpl_TxGetAcceleratorPos),
THISCALL(ITextHostImpl_TxGetExtent),
THISCALL(ITextHostImpl_OnTxCharFormatChange),
THISCALL(ITextHostImpl_OnTxParaFormatChange),
THISCALL(ITextHostImpl_TxGetPropertyBits),
THISCALL(ITextHostImpl_TxNotify),
THISCALL(ITextHostImpl_TxImmGetContext),
THISCALL(ITextHostImpl_TxImmReleaseContext),
THISCALL(ITextHostImpl_TxGetSelectionBarWidth),
};

View file

@ -37,17 +37,17 @@
#ifdef __i386__ /* thiscall functions are i386-specific */
#define THISCALL(func) __thiscall_ ## func
#define DEFINE_THISCALL_WRAPPER(func) \
#define DEFINE_THISCALL_WRAPPER(func,args) \
extern typeof(func) THISCALL(func); \
__ASM_GLOBAL_FUNC(__thiscall_ ## func, \
__ASM_STDCALL_FUNC(__thiscall_ ## func, args, \
"popl %eax\n\t" \
"pushl %ecx\n\t" \
"pushl %eax\n\t" \
"jmp " __ASM_NAME(#func) )
"jmp " __ASM_NAME(#func) __ASM_STDCALL(args) )
#else /* __i386__ */
#define THISCALL(func) func
#define DEFINE_THISCALL_WRAPPER(func) /* nothing */
#define DEFINE_THISCALL_WRAPPER(func,args) /* nothing */
#endif /* __i386__ */
@ -87,6 +87,8 @@ HRESULT WINAPI CreateTextServices(IUnknown * pUnkOuter,
ITextImpl->pMyHost = pITextHost;
ITextImpl->lpVtbl = &textservices_Vtbl;
ITextImpl->editor = ME_MakeEditor(pITextHost, FALSE);
ITextImpl->editor->exStyleFlags = 0;
ITextImpl->editor->rcFormat = (RECT){0,0,0,0};
ME_HandleMessage(ITextImpl->editor, WM_CREATE, 0, 0, TRUE, &hres);
if (pUnkOuter)
@ -292,12 +294,14 @@ HRESULT WINAPI fnTextSrv_TxGetText(ITextServices *iface,
length = ME_GetTextLength(This->editor);
if (length)
{
ME_Cursor start;
BSTR bstr;
bstr = SysAllocStringByteLen(NULL, length * sizeof(WCHAR));
if (bstr == NULL)
return E_OUTOFMEMORY;
ME_GetTextW(This->editor, bstr , 0, length, FALSE);
ME_CursorFromCharOfs(This->editor, 0, &start);
ME_GetTextW(This->editor, bstr, length, &start, INT_MAX, FALSE);
*pbstrText = bstr;
} else {
*pbstrText = NULL;
@ -310,9 +314,11 @@ HRESULT WINAPI fnTextSrv_TxSetText(ITextServices *iface,
LPCWSTR pszText)
{
ICOM_THIS_MULTI(ITextServicesImpl, lpVtbl, iface);
ME_Cursor cursor;
ME_InternalDeleteText(This->editor, 0, ME_GetTextLength(This->editor),
FALSE);
ME_SetCursorToStart(This->editor, &cursor);
ME_InternalDeleteText(This->editor, &cursor,
ME_GetTextLength(This->editor), FALSE);
ME_InsertTextFromCursor(This->editor, 0, pszText, -1,
This->editor->pBuffer->pDefaultStyle);
ME_SetSelection(This->editor, 0, 0);
@ -387,24 +393,24 @@ HRESULT WINAPI fnTextSrv_TxGetCachedSize(ITextServices *iface,
return E_NOTIMPL;
}
DEFINE_THISCALL_WRAPPER(fnTextSrv_TxSendMessage)
DEFINE_THISCALL_WRAPPER(fnTextSrv_TxDraw)
DEFINE_THISCALL_WRAPPER(fnTextSrv_TxGetHScroll)
DEFINE_THISCALL_WRAPPER(fnTextSrv_TxGetVScroll)
DEFINE_THISCALL_WRAPPER(fnTextSrv_OnTxSetCursor)
DEFINE_THISCALL_WRAPPER(fnTextSrv_TxQueryHitPoint)
DEFINE_THISCALL_WRAPPER(fnTextSrv_OnTxInplaceActivate)
DEFINE_THISCALL_WRAPPER(fnTextSrv_OnTxInplaceDeactivate)
DEFINE_THISCALL_WRAPPER(fnTextSrv_OnTxUIActivate)
DEFINE_THISCALL_WRAPPER(fnTextSrv_OnTxUIDeactivate)
DEFINE_THISCALL_WRAPPER(fnTextSrv_TxGetText)
DEFINE_THISCALL_WRAPPER(fnTextSrv_TxSetText)
DEFINE_THISCALL_WRAPPER(fnTextSrv_TxGetCurrentTargetX)
DEFINE_THISCALL_WRAPPER(fnTextSrv_TxGetBaseLinePos)
DEFINE_THISCALL_WRAPPER(fnTextSrv_TxGetNaturalSize)
DEFINE_THISCALL_WRAPPER(fnTextSrv_TxGetDropTarget)
DEFINE_THISCALL_WRAPPER(fnTextSrv_OnTxPropertyBitsChange)
DEFINE_THISCALL_WRAPPER(fnTextSrv_TxGetCachedSize)
DEFINE_THISCALL_WRAPPER(fnTextSrv_TxSendMessage,20)
DEFINE_THISCALL_WRAPPER(fnTextSrv_TxDraw,52)
DEFINE_THISCALL_WRAPPER(fnTextSrv_TxGetHScroll,24)
DEFINE_THISCALL_WRAPPER(fnTextSrv_TxGetVScroll,24)
DEFINE_THISCALL_WRAPPER(fnTextSrv_OnTxSetCursor,40)
DEFINE_THISCALL_WRAPPER(fnTextSrv_TxQueryHitPoint,44)
DEFINE_THISCALL_WRAPPER(fnTextSrv_OnTxInplaceActivate,8)
DEFINE_THISCALL_WRAPPER(fnTextSrv_OnTxInplaceDeactivate,4)
DEFINE_THISCALL_WRAPPER(fnTextSrv_OnTxUIActivate,4)
DEFINE_THISCALL_WRAPPER(fnTextSrv_OnTxUIDeactivate,4)
DEFINE_THISCALL_WRAPPER(fnTextSrv_TxGetText,8)
DEFINE_THISCALL_WRAPPER(fnTextSrv_TxSetText,8)
DEFINE_THISCALL_WRAPPER(fnTextSrv_TxGetCurrentTargetX,8)
DEFINE_THISCALL_WRAPPER(fnTextSrv_TxGetBaseLinePos,8)
DEFINE_THISCALL_WRAPPER(fnTextSrv_TxGetNaturalSize,36)
DEFINE_THISCALL_WRAPPER(fnTextSrv_TxGetDropTarget,8)
DEFINE_THISCALL_WRAPPER(fnTextSrv_OnTxPropertyBitsChange,12)
DEFINE_THISCALL_WRAPPER(fnTextSrv_TxGetCachedSize,12)
static const ITextServicesVtbl textservices_Vtbl =
{

View file

@ -298,17 +298,28 @@ static void ME_PlayUndoItem(ME_TextEditor *editor, ME_DisplayItem *pItem)
}
case diUndoSetCharFormat:
{
ME_SetCharFormat(editor, pUItem->nStart, pUItem->nLen, &pItem->member.ustyle->fmt);
ME_Cursor start, end;
ME_CursorFromCharOfs(editor, pUItem->nStart, &start);
end = start;
ME_MoveCursorChars(editor, &end, pUItem->nLen);
ME_SetCharFormat(editor, &start, &end, &pItem->member.ustyle->fmt);
break;
}
case diUndoInsertRun:
{
ME_InsertRun(editor, pItem->member.run.nCharOfs, pItem);
ME_Cursor tmp;
ME_CursorFromCharOfs(editor, pItem->member.run.nCharOfs, &tmp);
ME_InsertRunAtCursor(editor, &tmp, pItem->member.run.style,
pItem->member.run.strText->szData,
pItem->member.run.strText->nLen,
pItem->member.run.nFlags);
break;
}
case diUndoDeleteRun:
{
ME_InternalDeleteText(editor, pUItem->nStart, pUItem->nLen, TRUE);
ME_Cursor tmp;
ME_CursorFromCharOfs(editor, pUItem->nStart, &tmp);
ME_InternalDeleteText(editor, &tmp, pUItem->nLen, TRUE);
break;
}
case diUndoJoinParagraphs:

View file

@ -456,6 +456,29 @@ static ME_DisplayItem *ME_WrapHandleRun(ME_WrapContext *wc, ME_DisplayItem *p)
return p->next;
}
static int ME_GetParaLineSpace(ME_Context* c, ME_Paragraph* para)
{
int sp = 0, ls = 0;
if (!(para->pFmt->dwMask & PFM_LINESPACING)) return 0;
/* FIXME: how to compute simply the line space in ls ??? */
/* FIXME: does line spacing include the line itself ??? */
switch (para->pFmt->bLineSpacingRule)
{
case 0: sp = ls; break;
case 1: sp = (3 * ls) / 2; break;
case 2: sp = 2 * ls; break;
case 3: sp = ME_twips2pointsY(c, para->pFmt->dyLineSpacing); if (sp < ls) sp = ls; break;
case 4: sp = ME_twips2pointsY(c, para->pFmt->dyLineSpacing); break;
case 5: sp = para->pFmt->dyLineSpacing / 20; break;
default: FIXME("Unsupported spacing rule value %d\n", para->pFmt->bLineSpacingRule);
}
if (c->editor->nZoomNumerator == 0)
return sp;
else
return sp * c->editor->nZoomNumerator / c->editor->nZoomDenominator;
}
static void ME_PrepareParagraphForWrapping(ME_Context *c, ME_DisplayItem *tp);
static void ME_WrapTextParagraph(ME_Context *c, ME_DisplayItem *tp) {
@ -499,7 +522,7 @@ static void ME_WrapTextParagraph(ME_Context *c, ME_DisplayItem *tp) {
if (!(pFmt->dwMask & PFM_TABLE && pFmt->wEffects & PFE_TABLE) &&
pFmt->dwMask & PFM_BORDER)
{
border = ME_GetParaBorderWidth(c->editor, tp->member.para.pFmt->wBorders);
border = ME_GetParaBorderWidth(c, tp->member.para.pFmt->wBorders);
if (pFmt->wBorders & 1) {
wc.nFirstMargin += border;
wc.nLeftMargin += border;
@ -580,7 +603,6 @@ BOOL ME_WrapMarkedParagraphs(ME_TextEditor *editor)
ME_DisplayItem *item;
ME_Context c;
BOOL bModified = FALSE;
int yStart = -1;
int totalWidth = 0;
ME_InitContext(&c, editor, ITextHost_TxGetDC(editor->texthost));
@ -598,11 +620,7 @@ BOOL ME_WrapMarkedParagraphs(ME_TextEditor *editor)
ME_WrapTextParagraph(&c, item);
if (bRedraw)
{
item->member.para.nFlags |= MEPF_REPAINT;
if (yStart == -1)
yStart = c.pt.y;
}
bModified = bModified | bRedraw;
@ -776,6 +794,8 @@ ME_SendRequestResize(ME_TextEditor *editor, BOOL force)
{
REQRESIZE info;
info.nmhdr.hwndFrom = NULL;
info.nmhdr.idFrom = 0;
info.nmhdr.code = EN_REQUESTRESIZE;
info.rc = rc;
info.rc.right = editor->nTotalWidth;

View file

@ -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, ME_GetParagraph(p)))
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;
if (!ME_StreamOutRTFTableProps(editor, pStream, cursor.pPara))
return FALSE;
if (!ME_StreamOutPrint(pStream, "\\nestrow}{\\nonesttables\\par}\r\n"))
return FALSE;
} else {
if (!ME_StreamOutPrint(pStream, "\\tab "))
return FALSE;
}
} else if (p->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 (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_GetSelection(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);
}

View file

@ -22,7 +22,7 @@ When porting a new DLL from Wine to ReactOS, please do the following steps
The following build tools are shared with Wine.
reactos/tools/unicode # Synced to Wine-20081105 (~Wine-1.1.7)
reactos/tools/widl # Synced to Wine-1_1_39
reactos/tools/widl # Synced to Wine-1_1_41
reactos/tools/winebuild # Synced to Wine-1_1_13
reactos/tools/wmc # Synced to Wine-20081105 (~Wine-1.1.7)
reactos/tools/wpp # Synced to Wine-20081105 (~Wine-1.1.7)
@ -137,7 +137,7 @@ reactos/dll/win32/pstorec # Autosync
reactos/dll/win32/query # Autosync
reactos/dll/win32/rasapi32 # Autosync
reactos/dll/win32/resutils # Autosync
reactos/dll/win32/riched20 # Autosync ??
reactos/dll/win32/riched20 # Autosync
reactos/dll/win32/riched32 # Autosync
reactos/dll/win32/rpcrt4 # Synced to Wine-0_9_55
reactos/dll/win32/rsabase # Autosync