mirror of
https://github.com/reactos/reactos.git
synced 2025-04-27 17:10:22 +00:00
[RICHED20]
- Sync riched20 with Wine-1.1.41. svn path=/trunk/; revision=46328
This commit is contained in:
parent
11604ef89b
commit
79a14dac68
20 changed files with 1431 additions and 1246 deletions
|
@ -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,
|
||||
|
|
|
@ -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
|
@ -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);
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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, */
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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];
|
||||
|
|
|
@ -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),
|
||||
};
|
||||
|
|
|
@ -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 =
|
||||
{
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue