Sync to Wine-20050725:

Phil Krylov <phil@newstar.rinet.ru>
- Added some useful TRACEs.
- Allow NULL parameter for WM_SETTEXT in RichEdit.
- Implemented EM_LINELENGTH RichEdit message.
- Fixed EM_LINEINDEX handler and added EM_LINEFROMCHAR handler.
- Implemented EM_EXLINEFROMCHAR, EM_LINEINDEX, EM_FINDTEXT,
  EM_FINDTEXTW, EM_FINDTEXTEX, and EM_FINDTEXTEXW messages.
- Fixed a comment about EM_STREAMIN.
- Implemented EM_GETLINECOUNT RichEdit message.
- Fixed EM_GETCHARFORMAT for selection containing a single character.
- Fixed an off-by-one error in EM_GETLINECOUNT handler.
- Fixed an off-by-one error in EM_STREAMOUT handler for non-Unicode
  plain text output.
- Fixed another couple of EM_STREAMOUT bugs.
- Removed junk from UTF-8 RTF output.
- Added emulation of RichEdit 1.0 behaviour when the 1.0 window class is
  being used. This emulation (introduced in M$ RichEdit 3.0) counts
  paragraph endings as 2 characters (CR+LF) instead of 1 (CR).
- Added EM_GETZOOM and EM_SETZOOM RichEdit message handlers.
- Added some missing but useful items to the TODO list.
Felix Nawothnig <felix.nawothnig@t-online.de>
- Check structure size and fix return values in EM_GETCHARFORMAT.
Aric Stewart <aric@codeweavers.com>
- Implementation for EM_GETTEXTEX.
Daniel Remenak <dtremenak@gmail.com>
- Basic handling of EM_SETTEXTEX.
Stefan Huehner <stefan@huehner.org>
- Make functions static to fix -Wmissing-declarations warnings.
- Change some char* to const char* to fix warnigns.
- Make some function static.
- Fix -Wmissing-declarations warnings.

svn path=/trunk/; revision=17335
This commit is contained in:
Gé van Geldorp 2005-08-12 17:41:40 +00:00
parent e97f6fb328
commit 6dd32969d0
12 changed files with 613 additions and 100 deletions

View file

@ -192,6 +192,8 @@ void ME_InternalDeleteText(ME_TextEditor *editor, int nOfs,
/* ME_SkipAndPropagateCharOffset(p->pRun, shift); */ /* ME_SkipAndPropagateCharOffset(p->pRun, shift); */
ME_CheckCharOffsets(editor); ME_CheckCharOffsets(editor);
nChars--; nChars--;
if (editor->bEmulateVersion10 && nChars)
nChars--;
continue; continue;
} }
else else
@ -413,7 +415,7 @@ void ME_InsertTextFromCursor(ME_TextEditor *editor, int nCursor,
} }
} }
BOOL ME_ArrowLeft(ME_TextEditor *editor, ME_Cursor *p) static BOOL ME_ArrowLeft(ME_TextEditor *editor, ME_Cursor *p)
{ {
if (p->nOffset) { if (p->nOffset) {
p->nOffset = ME_StrRelPos2(p->pRun->member.run.strText, p->nOffset, -1); p->nOffset = ME_StrRelPos2(p->pRun->member.run.strText, p->nOffset, -1);
@ -453,21 +455,26 @@ BOOL ME_ArrowLeft(ME_TextEditor *editor, ME_Cursor *p)
return FALSE; return FALSE;
} }
BOOL ME_ArrowRight(ME_TextEditor *editor, ME_Cursor *p) static BOOL ME_ArrowRight(ME_TextEditor *editor, ME_Cursor *p)
{ {
int new_ofs = ME_StrRelPos2(p->pRun->member.run.strText, p->nOffset, 1); ME_DisplayItem *pRun;
if (new_ofs<p->pRun->member.run.strText->nLen) {
p->nOffset = new_ofs; if (!(p->pRun->member.run.nFlags & MERF_ENDPARA))
}
else
{ {
ME_DisplayItem *pRun = ME_FindItemFwd(p->pRun, diRun); int new_ofs = ME_StrRelPos2(p->pRun->member.run.strText, p->nOffset, 1);
if (pRun) {
p->pRun = pRun; if (new_ofs<p->pRun->member.run.strText->nLen)
assert(p->pRun->type == diRun); {
p->nOffset = 0; p->nOffset = new_ofs;
return TRUE;
} }
} }
pRun = ME_FindItemFwd(p->pRun, diRun);
if (pRun) {
p->pRun = pRun;
assert(p->pRun->type == diRun);
p->nOffset = 0;
}
return TRUE; return TRUE;
} }
@ -698,7 +705,7 @@ static int ME_GetXForArrow(ME_TextEditor *editor, ME_Cursor *pCursor)
return x; return x;
} }
void ME_ArrowUp(ME_TextEditor *editor, ME_Cursor *pCursor) static void ME_ArrowUp(ME_TextEditor *editor, ME_Cursor *pCursor)
{ {
ME_DisplayItem *pRun = pCursor->pRun; ME_DisplayItem *pRun = pCursor->pRun;
ME_DisplayItem *pItem, *pItem2; ME_DisplayItem *pItem, *pItem2;
@ -725,7 +732,7 @@ void ME_ArrowUp(ME_TextEditor *editor, ME_Cursor *pCursor)
pCursor->pRun = ME_FindRunInRow(editor, pItem2, x, &pCursor->nOffset, &editor->bCaretAtEnd); pCursor->pRun = ME_FindRunInRow(editor, pItem2, x, &pCursor->nOffset, &editor->bCaretAtEnd);
} }
void ME_ArrowDown(ME_TextEditor *editor, ME_Cursor *pCursor) static void ME_ArrowDown(ME_TextEditor *editor, ME_Cursor *pCursor)
{ {
ME_DisplayItem *pRun = pCursor->pRun; ME_DisplayItem *pRun = pCursor->pRun;
ME_DisplayItem *pItem; ME_DisplayItem *pItem;
@ -749,7 +756,7 @@ void ME_ArrowDown(ME_TextEditor *editor, ME_Cursor *pCursor)
assert(pCursor->pRun->type == diRun); assert(pCursor->pRun->type == diRun);
} }
void ME_ArrowPageUp(ME_TextEditor *editor, ME_Cursor *pCursor) static void ME_ArrowPageUp(ME_TextEditor *editor, ME_Cursor *pCursor)
{ {
ME_DisplayItem *pRun = pCursor->pRun; ME_DisplayItem *pRun = pCursor->pRun;
ME_DisplayItem *pLast, *p; ME_DisplayItem *pLast, *p;
@ -804,7 +811,7 @@ void ME_ArrowPageUp(ME_TextEditor *editor, ME_Cursor *pCursor)
In such a situation, clicking the scrollbar restores its position back to the In such a situation, clicking the scrollbar restores its position back to the
normal range (ie. sets it to (doclength-screenheight)). */ normal range (ie. sets it to (doclength-screenheight)). */
void ME_ArrowPageDown(ME_TextEditor *editor, ME_Cursor *pCursor) static void ME_ArrowPageDown(ME_TextEditor *editor, ME_Cursor *pCursor)
{ {
ME_DisplayItem *pRun = pCursor->pRun; ME_DisplayItem *pRun = pCursor->pRun;
ME_DisplayItem *pLast, *p; ME_DisplayItem *pLast, *p;
@ -852,7 +859,7 @@ void ME_ArrowPageDown(ME_TextEditor *editor, ME_Cursor *pCursor)
assert(pCursor->pRun->type == diRun); assert(pCursor->pRun->type == diRun);
} }
void ME_ArrowHome(ME_TextEditor *editor, ME_Cursor *pCursor) static void ME_ArrowHome(ME_TextEditor *editor, ME_Cursor *pCursor)
{ {
ME_DisplayItem *pRow = ME_FindItemBack(pCursor->pRun, diStartRow); ME_DisplayItem *pRow = ME_FindItemBack(pCursor->pRun, diStartRow);
if (pRow) { if (pRow) {
@ -871,7 +878,7 @@ void ME_ArrowHome(ME_TextEditor *editor, ME_Cursor *pCursor)
editor->bCaretAtEnd = FALSE; editor->bCaretAtEnd = FALSE;
} }
void ME_ArrowCtrlHome(ME_TextEditor *editor, ME_Cursor *pCursor) static void ME_ArrowCtrlHome(ME_TextEditor *editor, ME_Cursor *pCursor)
{ {
ME_DisplayItem *pRow = ME_FindItemBack(pCursor->pRun, diTextStart); ME_DisplayItem *pRow = ME_FindItemBack(pCursor->pRun, diTextStart);
if (pRow) { if (pRow) {
@ -883,7 +890,7 @@ void ME_ArrowCtrlHome(ME_TextEditor *editor, ME_Cursor *pCursor)
} }
} }
void ME_ArrowEnd(ME_TextEditor *editor, ME_Cursor *pCursor) static void ME_ArrowEnd(ME_TextEditor *editor, ME_Cursor *pCursor)
{ {
ME_DisplayItem *pRow; ME_DisplayItem *pRow;
@ -907,7 +914,7 @@ void ME_ArrowEnd(ME_TextEditor *editor, ME_Cursor *pCursor)
editor->bCaretAtEnd = FALSE; editor->bCaretAtEnd = FALSE;
} }
void ME_ArrowCtrlEnd(ME_TextEditor *editor, ME_Cursor *pCursor) static void ME_ArrowCtrlEnd(ME_TextEditor *editor, ME_Cursor *pCursor)
{ {
ME_DisplayItem *p = ME_FindItemFwd(pCursor->pRun, diTextEnd); ME_DisplayItem *p = ME_FindItemFwd(pCursor->pRun, diTextEnd);
assert(p); assert(p);
@ -924,7 +931,7 @@ BOOL ME_IsSelection(ME_TextEditor *editor)
return memcmp(&editor->pCursors[0], &editor->pCursors[1], sizeof(ME_Cursor))!=0; return memcmp(&editor->pCursors[0], &editor->pCursors[1], sizeof(ME_Cursor))!=0;
} }
int ME_GetSelCursor(ME_TextEditor *editor, int dir) static int ME_GetSelCursor(ME_TextEditor *editor, int dir)
{ {
int cdir = ME_GetCursorOfs(editor, 0) - ME_GetCursorOfs(editor, 1); int cdir = ME_GetCursorOfs(editor, 0) - ME_GetCursorOfs(editor, 1);
@ -934,7 +941,7 @@ int ME_GetSelCursor(ME_TextEditor *editor, int dir)
return 1; return 1;
} }
BOOL ME_CancelSelection(ME_TextEditor *editor, int dir) static BOOL ME_CancelSelection(ME_TextEditor *editor, int dir)
{ {
int cdir; int cdir;
@ -979,7 +986,7 @@ BOOL ME_UpdateSelection(ME_TextEditor *editor, ME_Cursor *pTempCursor)
return TRUE; return TRUE;
} }
void ME_RepaintSelection(ME_TextEditor *editor, ME_Cursor *pTempCursor) static void ME_RepaintSelection(ME_TextEditor *editor, ME_Cursor *pTempCursor)
{ {
if (ME_UpdateSelection(editor, pTempCursor)) { if (ME_UpdateSelection(editor, pTempCursor)) {
ME_EnsureVisible(editor, editor->pCursors[0].pRun); ME_EnsureVisible(editor, editor->pCursors[0].pRun);

View file

@ -31,10 +31,10 @@
+ EM_EMPTYUNDOBUFFER + EM_EMPTYUNDOBUFFER
+ EM_EXGETSEL + EM_EXGETSEL
- EM_EXLIMITTEXT - EM_EXLIMITTEXT
- EM_EXLINEFROMCHAR + EM_EXLINEFROMCHAR
+ EM_EXSETSEL + EM_EXSETSEL
- EM_FINDTEXT + EM_FINDTEXT (only FR_DOWN flag implemented)
- EM_FINDTEXTEX + EM_FINDTEXTEX (only FR_DOWN flag implemented)
- EM_FINDWORDBREAK - EM_FINDWORDBREAK
- EM_FMTLINES - EM_FMTLINES
- EM_FORMATRANGE - EM_FORMATRANGE
@ -51,7 +51,7 @@
- EM_GETLANGOPTIONS 2.0 - EM_GETLANGOPTIONS 2.0
- EM_GETLIMITTEXT - EM_GETLIMITTEXT
- EM_GETLINE - EM_GETLINE
- EM_GETLINECOUNT returns number of rows, not of paragraphs + EM_GETLINECOUNT returns number of rows, not of paragraphs
+ EM_GETMODIFY + EM_GETMODIFY
- EM_GETOLEINTERFACE - EM_GETOLEINTERFACE
- EM_GETOPTIONS - EM_GETOPTIONS
@ -73,12 +73,12 @@
- EM_GETWORDBREAKPROC - EM_GETWORDBREAKPROC
- EM_GETWORDBREAKPROCEX - EM_GETWORDBREAKPROCEX
- EM_GETWORDWRAPMODE 1.0asian - EM_GETWORDWRAPMODE 1.0asian
- EM_SETZOOM 3.0 + EM_GETZOOM 3.0
- EM_HIDESELECTION - EM_HIDESELECTION
- EM_LIMITTEXT - EM_LIMITTEXT
- EM_LINEFROMCHAR + EM_LINEFROMCHAR
- EM_LINEINDEX + EM_LINEINDEX
- EM_LINELENGTH + EM_LINELENGTH
+ EM_LINESCROLL + EM_LINESCROLL
- EM_PASTESPECIAL - EM_PASTESPECIAL
- EM_POSFROMCHARS - EM_POSFROMCHARS
@ -112,17 +112,17 @@
- EM_SETSCROLLPOS 3.0 - EM_SETSCROLLPOS 3.0
- EM_SETTABSTOPS 3.0 - EM_SETTABSTOPS 3.0
- EM_SETTARGETDEVICE - EM_SETTARGETDEVICE
- EM_SETTEXTEX 3.0 + EM_SETTEXTEX 3.0 (unicode only, no rich text insertion handling, proper style?)
- EM_SETTEXTMODE 2.0 - EM_SETTEXTMODE 2.0
- EM_SETTYPOGRAPHYOPTIONS 3.0 - EM_SETTYPOGRAPHYOPTIONS 3.0
- EM_SETUNDOLIMIT 2.0 - EM_SETUNDOLIMIT 2.0
- EM_SETWORDBREAKPROC - EM_SETWORDBREAKPROC
- EM_SETWORDBREAKPROCEX - EM_SETWORDBREAKPROCEX
- EM_SETWORDWRAPMODE 1.0asian - EM_SETWORDWRAPMODE 1.0asian
- EM_SETZOOM 3.0 + EM_SETZOOM 3.0
- EM_SHOWSCROLLBAR 2.0 - EM_SHOWSCROLLBAR 2.0
- EM_STOPGROUPTYPING 2.0 - EM_STOPGROUPTYPING 2.0
+ EM_STREAMIN (can't fall back to text when the RTF isn't really RTF) + EM_STREAMIN
+ EM_STREAMOUT + EM_STREAMOUT
+ EM_UNDO + EM_UNDO
+ WM_CHAR + WM_CHAR
@ -205,6 +205,9 @@
* - when should EN_SELCHANGE be sent after text change ? (before/after EN_UPDATE?) * - when should EN_SELCHANGE be sent after text change ? (before/after EN_UPDATE?)
* - WM_SETTEXT may use wrong style (but I'm 80% sure it's OK) * - WM_SETTEXT may use wrong style (but I'm 80% sure it's OK)
* - EM_GETCHARFORMAT with SCF_SELECTION may not behave 100% like in original (but very close) * - EM_GETCHARFORMAT with SCF_SELECTION may not behave 100% like in original (but very close)
* - full justification
* - hyphenation
* - tables
* *
* Bugs that are probably fixed, but not so easy to verify: * Bugs that are probably fixed, but not so easy to verify:
* - EN_UPDATE/EN_CHANGE are handled very incorrectly (should be OK now) * - EN_UPDATE/EN_CHANGE are handled very incorrectly (should be OK now)
@ -218,6 +221,7 @@
*/ */
#include "editor.h" #include "editor.h"
#include "commdlg.h"
#include "ole2.h" #include "ole2.h"
#include "richole.h" #include "richole.h"
#include "winreg.h" #include "winreg.h"
@ -231,7 +235,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(richedit);
int me_debug = 0; int me_debug = 0;
HANDLE me_heap = NULL; HANDLE me_heap = NULL;
ME_TextBuffer *ME_MakeText(void) { static ME_TextBuffer *ME_MakeText(void) {
ME_TextBuffer *buf = ALLOC_OBJ(ME_TextBuffer); ME_TextBuffer *buf = ALLOC_OBJ(ME_TextBuffer);
@ -295,7 +299,7 @@ static LRESULT ME_StreamInText(ME_TextEditor *editor, DWORD dwFormat, ME_InStrea
return 0; return 0;
} }
void ME_RTFCharAttrHook(RTF_Info *info) static void ME_RTFCharAttrHook(RTF_Info *info)
{ {
CHARFORMAT2W fmt; CHARFORMAT2W fmt;
fmt.cbSize = sizeof(fmt); fmt.cbSize = sizeof(fmt);
@ -394,7 +398,7 @@ void ME_RTFCharAttrHook(RTF_Info *info)
/* FIXME this function doesn't get any information about context of the RTF tag, which is very bad, /* FIXME this function doesn't get any information about context of the RTF tag, which is very bad,
the same tags mean different things in different contexts */ the same tags mean different things in different contexts */
void ME_RTFParAttrHook(RTF_Info *info) static void ME_RTFParAttrHook(RTF_Info *info)
{ {
PARAFORMAT2 fmt; PARAFORMAT2 fmt;
fmt.cbSize = sizeof(fmt); fmt.cbSize = sizeof(fmt);
@ -459,7 +463,7 @@ void ME_RTFParAttrHook(RTF_Info *info)
} }
} }
void ME_RTFReadHook(RTF_Info *info) { static void ME_RTFReadHook(RTF_Info *info) {
switch(info->rtfClass) switch(info->rtfClass)
{ {
case rtfGroup: case rtfGroup:
@ -651,11 +655,75 @@ ME_FindItemAtOffset(ME_TextEditor *editor, ME_DIType nItemType, int nOffset, int
} }
static int
ME_FindText(ME_TextEditor *editor, DWORD flags, CHARRANGE *chrg, WCHAR *text, CHARRANGE *chrgText)
{
int nStart = chrg->cpMin;
int nLen = lstrlenW(text);
ME_DisplayItem *item = ME_FindItemAtOffset(editor, diRun, nStart, &nStart);
ME_DisplayItem *para;
if (!item)
return -1;
if (!nLen)
{
if (chrgText)
chrgText->cpMin = chrgText->cpMax = chrg->cpMin;
return chrg->cpMin;
}
if (!(flags & FR_DOWN))
FIXME("Backward search not implemented\n");
if (!(flags & FR_MATCHCASE))
FIXME("Case-insensitive search not implemented\n");
if (flags & ~(FR_DOWN | FR_MATCHCASE))
FIXME("Flags 0x%08lx not implemented\n", flags & ~(FR_DOWN | FR_MATCHCASE));
para = ME_GetParagraph(item);
while (item && para->member.para.nCharOfs + item->member.run.nCharOfs + nStart + nLen < chrg->cpMax)
{
ME_DisplayItem *pCurItem = item;
int nCurStart = nStart;
int nMatched = 0;
while (pCurItem->member.run.strText->szData[nCurStart + nMatched] == text[nMatched])
{
nMatched++;
if (nMatched == nLen)
{
nStart += para->member.para.nCharOfs + item->member.run.nCharOfs;
if (chrgText)
{
chrgText->cpMin = nStart;
chrgText->cpMax = nStart + nLen;
}
return nStart;
}
if (nCurStart + nMatched == ME_StrLen(pCurItem->member.run.strText))
{
pCurItem = ME_FindItemFwd(pCurItem, diRun);
nCurStart = -nMatched;
}
}
nStart++;
if (nStart == ME_StrLen(item->member.run.strText))
{
item = ME_FindItemFwd(item, diRun);
para = ME_GetParagraph(item);
nStart = 0;
}
}
return -1;
}
ME_TextEditor *ME_MakeEditor(HWND hWnd) { ME_TextEditor *ME_MakeEditor(HWND hWnd) {
ME_TextEditor *ed = ALLOC_OBJ(ME_TextEditor); ME_TextEditor *ed = ALLOC_OBJ(ME_TextEditor);
HDC hDC; HDC hDC;
int i; int i;
ed->hWnd = hWnd; ed->hWnd = hWnd;
ed->bEmulateVersion10 = FALSE;
ed->pBuffer = ME_MakeText(); ed->pBuffer = ME_MakeText();
hDC = GetDC(hWnd); hDC = GetDC(hWnd);
ME_MakeFirstParagraph(hDC, ed->pBuffer); ME_MakeFirstParagraph(hDC, ed->pBuffer);
@ -679,6 +747,7 @@ ME_TextEditor *ME_MakeEditor(HWND hWnd) {
ed->nParagraphs = 1; ed->nParagraphs = 1;
ed->nLastSelStart = ed->nLastSelEnd = 0; ed->nLastSelStart = ed->nLastSelEnd = 0;
ed->nScrollPosY = 0; ed->nScrollPosY = 0;
ed->nZoomNumerator = ed->nZoomDenominator = 0;
for (i=0; i<HFONT_CACHE_SIZE; i++) for (i=0; i<HFONT_CACHE_SIZE; i++)
{ {
ed->pFontCache[i].nRefs = 0; ed->pFontCache[i].nRefs = 0;
@ -753,6 +822,7 @@ static DWORD CALLBACK ME_ReadFromHGLOBALRTF(DWORD_PTR dwCookie, LPBYTE lpBuff, L
return 0; return 0;
} }
void ME_DestroyEditor(ME_TextEditor *editor) void ME_DestroyEditor(ME_TextEditor *editor)
{ {
ME_DisplayItem *pFirst = editor->pBuffer->pFirst; ME_DisplayItem *pFirst = editor->pBuffer->pFirst;
@ -808,6 +878,140 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
FIXME(#e ": stub\n"); \ FIXME(#e ": stub\n"); \
return DefWindowProcW(hWnd, msg, wParam, lParam); return DefWindowProcW(hWnd, msg, wParam, lParam);
static const char * const edit_messages[] = {
"EM_GETSEL",
"EM_SETSEL",
"EM_GETRECT",
"EM_SETRECT",
"EM_SETRECTNP",
"EM_SCROLL",
"EM_LINESCROLL",
"EM_SCROLLCARET",
"EM_GETMODIFY",
"EM_SETMODIFY",
"EM_GETLINECOUNT",
"EM_LINEINDEX",
"EM_SETHANDLE",
"EM_GETHANDLE",
"EM_GETTHUMB",
"EM_UNKNOWN_BF",
"EM_UNKNOWN_C0",
"EM_LINELENGTH",
"EM_REPLACESEL",
"EM_UNKNOWN_C3",
"EM_GETLINE",
"EM_LIMITTEXT",
"EM_CANUNDO",
"EM_UNDO",
"EM_FMTLINES",
"EM_LINEFROMCHAR",
"EM_UNKNOWN_CA",
"EM_SETTABSTOPS",
"EM_SETPASSWORDCHAR",
"EM_EMPTYUNDOBUFFER",
"EM_GETFIRSTVISIBLELINE",
"EM_SETREADONLY",
"EM_SETWORDBREAKPROC",
"EM_GETWORDBREAKPROC",
"EM_GETPASSWORDCHAR",
"EM_SETMARGINS",
"EM_GETMARGINS",
"EM_GETLIMITTEXT",
"EM_POSFROMCHAR",
"EM_CHARFROMPOS"
};
static const char * const richedit_messages[] = {
"EM_CANPASTE",
"EM_DISPLAYBAND",
"EM_EXGETSEL",
"EM_EXLIMITTEXT",
"EM_EXLINEFROMCHAR",
"EM_EXSETSEL",
"EM_FINDTEXT",
"EM_FORMATRANGE",
"EM_GETCHARFORMAT",
"EM_GETEVENTMASK",
"EM_GETOLEINTERFACE",
"EM_GETPARAFORMAT",
"EM_GETSELTEXT",
"EM_HIDESELECTION",
"EM_PASTESPECIAL",
"EM_REQUESTRESIZE",
"EM_SELECTIONTYPE",
"EM_SETBKGNDCOLOR",
"EM_SETCHARFORMAT",
"EM_SETEVENTMASK",
"EM_SETOLECALLBACK",
"EM_SETPARAFORMAT",
"EM_SETTARGETDEVICE",
"EM_STREAMIN",
"EM_STREAMOUT",
"EM_GETTEXTRANGE",
"EM_FINDWORDBREAK",
"EM_SETOPTIONS",
"EM_GETOPTIONS",
"EM_FINDTEXTEX",
"EM_GETWORDBREAKPROCEX",
"EM_SETWORDBREAKPROCEX",
"EM_SETUNDOLIMIT",
"EM_UNKNOWN_USER_83",
"EM_REDO",
"EM_CANREDO",
"EM_GETUNDONAME",
"EM_GETREDONAME",
"EM_STOPGROUPTYPING",
"EM_SETTEXTMODE",
"EM_GETTEXTMODE",
"EM_AUTOURLDETECT",
"EM_GETAUTOURLDETECT",
"EM_SETPALETTE",
"EM_GETTEXTEX",
"EM_GETTEXTLENGTHEX",
"EM_SHOWSCROLLBAR",
"EM_SETTEXTEX",
"EM_UNKNOWN_USER_98",
"EM_UNKNOWN_USER_99",
"EM_SETPUNCTUATION",
"EM_GETPUNCTUATION",
"EM_SETWORDWRAPMODE",
"EM_GETWORDWRAPMODE",
"EM_SETIMECOLOR",
"EM_GETIMECOLOR",
"EM_SETIMEOPTIONS",
"EM_GETIMEOPTIONS",
"EM_CONVPOSITION",
"EM_UNKNOWN_USER_109",
"EM_UNKNOWN_USER_110",
"EM_UNKNOWN_USER_111",
"EM_UNKNOWN_USER_112",
"EM_UNKNOWN_USER_113",
"EM_UNKNOWN_USER_114",
"EM_UNKNOWN_USER_115",
"EM_UNKNOWN_USER_116",
"EM_UNKNOWN_USER_117",
"EM_UNKNOWN_USER_118",
"EM_UNKNOWN_USER_119",
"EM_SETLANGOPTIONS",
"EM_GETLANGOPTIONS",
"EM_GETIMECOMPMODE",
"EM_FINDTEXTW",
"EM_FINDTEXTEXW",
"EM_RECONVERSION",
"EM_SETIMEMODEBIAS",
"EM_GETIMEMODEBIAS"
};
static const char *
get_msg_name(UINT msg)
{
if (msg >= EM_GETSEL && msg <= EM_SETLIMITTEXT)
return edit_messages[msg - EM_GETSEL];
if (msg >= EM_CANPASTE && msg <= EM_GETIMEMODEBIAS)
return richedit_messages[msg - EM_CANPASTE];
return "";
}
/****************************************************************** /******************************************************************
* RichEditANSIWndProc (RICHED20.10) * RichEditANSIWndProc (RICHED20.10)
*/ */
@ -816,16 +1020,15 @@ LRESULT WINAPI RichEditANSIWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lP
PAINTSTRUCT ps; PAINTSTRUCT ps;
SCROLLINFO si; SCROLLINFO si;
ME_TextEditor *editor = (ME_TextEditor *)GetWindowLongW(hWnd, 0); ME_TextEditor *editor = (ME_TextEditor *)GetWindowLongW(hWnd, 0);
TRACE("msg %d %08x %08lx\n", msg, wParam, lParam);
TRACE("msg %d (%s) %08x %08lx\n", msg, get_msg_name(msg), wParam, lParam);
switch(msg) { switch(msg) {
UNSUPPORTED_MSG(EM_AUTOURLDETECT) UNSUPPORTED_MSG(EM_AUTOURLDETECT)
UNSUPPORTED_MSG(EM_CHARFROMPOS) UNSUPPORTED_MSG(EM_CHARFROMPOS)
UNSUPPORTED_MSG(EM_DISPLAYBAND) UNSUPPORTED_MSG(EM_DISPLAYBAND)
UNSUPPORTED_MSG(EM_EXLIMITTEXT) UNSUPPORTED_MSG(EM_EXLIMITTEXT)
UNSUPPORTED_MSG(EM_EXLINEFROMCHAR)
UNSUPPORTED_MSG(EM_FINDTEXT)
UNSUPPORTED_MSG(EM_FINDTEXTEX)
UNSUPPORTED_MSG(EM_FINDWORDBREAK) UNSUPPORTED_MSG(EM_FINDWORDBREAK)
UNSUPPORTED_MSG(EM_FMTLINES) UNSUPPORTED_MSG(EM_FMTLINES)
UNSUPPORTED_MSG(EM_FORMATRANGE) UNSUPPORTED_MSG(EM_FORMATRANGE)
@ -838,25 +1041,19 @@ LRESULT WINAPI RichEditANSIWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lP
UNSUPPORTED_MSG(EM_GETLANGOPTIONS) UNSUPPORTED_MSG(EM_GETLANGOPTIONS)
UNSUPPORTED_MSG(EM_GETLIMITTEXT) UNSUPPORTED_MSG(EM_GETLIMITTEXT)
UNSUPPORTED_MSG(EM_GETLINE) UNSUPPORTED_MSG(EM_GETLINE)
UNSUPPORTED_MSG(EM_GETLINECOUNT)
/* UNSUPPORTED_MSG(EM_GETOLEINTERFACE) separate stub */ /* UNSUPPORTED_MSG(EM_GETOLEINTERFACE) separate stub */
UNSUPPORTED_MSG(EM_GETOPTIONS) UNSUPPORTED_MSG(EM_GETOPTIONS)
UNSUPPORTED_MSG(EM_GETPASSWORDCHAR) UNSUPPORTED_MSG(EM_GETPASSWORDCHAR)
UNSUPPORTED_MSG(EM_GETRECT) UNSUPPORTED_MSG(EM_GETRECT)
UNSUPPORTED_MSG(EM_GETREDONAME) UNSUPPORTED_MSG(EM_GETREDONAME)
UNSUPPORTED_MSG(EM_GETSCROLLPOS) UNSUPPORTED_MSG(EM_GETSCROLLPOS)
UNSUPPORTED_MSG(EM_GETTEXTEX)
UNSUPPORTED_MSG(EM_GETTEXTMODE) UNSUPPORTED_MSG(EM_GETTEXTMODE)
UNSUPPORTED_MSG(EM_GETTYPOGRAPHYOPTIONS) UNSUPPORTED_MSG(EM_GETTYPOGRAPHYOPTIONS)
UNSUPPORTED_MSG(EM_GETUNDONAME) UNSUPPORTED_MSG(EM_GETUNDONAME)
UNSUPPORTED_MSG(EM_GETWORDBREAKPROC) UNSUPPORTED_MSG(EM_GETWORDBREAKPROC)
UNSUPPORTED_MSG(EM_GETWORDBREAKPROCEX) UNSUPPORTED_MSG(EM_GETWORDBREAKPROCEX)
UNSUPPORTED_MSG(EM_GETZOOM)
UNSUPPORTED_MSG(EM_HIDESELECTION) UNSUPPORTED_MSG(EM_HIDESELECTION)
UNSUPPORTED_MSG(EM_LIMITTEXT) /* also known as EM_SETLIMITTEXT */ UNSUPPORTED_MSG(EM_LIMITTEXT) /* also known as EM_SETLIMITTEXT */
UNSUPPORTED_MSG(EM_LINEFROMCHAR)
UNSUPPORTED_MSG(EM_LINEINDEX)
UNSUPPORTED_MSG(EM_LINELENGTH)
UNSUPPORTED_MSG(EM_PASTESPECIAL) UNSUPPORTED_MSG(EM_PASTESPECIAL)
/* UNSUPPORTED_MSG(EM_POSFROMCHARS) missing in Wine headers */ /* UNSUPPORTED_MSG(EM_POSFROMCHARS) missing in Wine headers */
UNSUPPORTED_MSG(EM_REQUESTRESIZE) UNSUPPORTED_MSG(EM_REQUESTRESIZE)
@ -876,14 +1073,12 @@ LRESULT WINAPI RichEditANSIWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lP
UNSUPPORTED_MSG(EM_SETSCROLLPOS) UNSUPPORTED_MSG(EM_SETSCROLLPOS)
UNSUPPORTED_MSG(EM_SETTABSTOPS) UNSUPPORTED_MSG(EM_SETTABSTOPS)
UNSUPPORTED_MSG(EM_SETTARGETDEVICE) UNSUPPORTED_MSG(EM_SETTARGETDEVICE)
UNSUPPORTED_MSG(EM_SETTEXTEX)
UNSUPPORTED_MSG(EM_SETTEXTMODE) UNSUPPORTED_MSG(EM_SETTEXTMODE)
UNSUPPORTED_MSG(EM_SETTYPOGRAPHYOPTIONS) UNSUPPORTED_MSG(EM_SETTYPOGRAPHYOPTIONS)
UNSUPPORTED_MSG(EM_SETUNDOLIMIT) UNSUPPORTED_MSG(EM_SETUNDOLIMIT)
UNSUPPORTED_MSG(EM_SETWORDBREAKPROC) UNSUPPORTED_MSG(EM_SETWORDBREAKPROC)
UNSUPPORTED_MSG(EM_SETWORDBREAKPROCEX) UNSUPPORTED_MSG(EM_SETWORDBREAKPROCEX)
UNSUPPORTED_MSG(EM_SHOWSCROLLBAR) UNSUPPORTED_MSG(EM_SHOWSCROLLBAR)
UNSUPPORTED_MSG(EM_SETZOOM)
UNSUPPORTED_MSG(WM_SETFONT) UNSUPPORTED_MSG(WM_SETFONT)
UNSUPPORTED_MSG(WM_STYLECHANGING) UNSUPPORTED_MSG(WM_STYLECHANGING)
UNSUPPORTED_MSG(WM_STYLECHANGED) UNSUPPORTED_MSG(WM_STYLECHANGED)
@ -905,6 +1100,7 @@ LRESULT WINAPI RichEditANSIWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lP
case WM_NCCREATE: case WM_NCCREATE:
{ {
CREATESTRUCTW *pcs = (CREATESTRUCTW *)lParam; CREATESTRUCTW *pcs = (CREATESTRUCTW *)lParam;
TRACE("WM_NCCREATE: style 0x%08lx\n", pcs->style);
editor = ME_MakeEditor(hWnd); editor = ME_MakeEditor(hWnd);
SetWindowLongW(hWnd, 0, (long)editor); SetWindowLongW(hWnd, 0, (long)editor);
pcs = 0; /* ignore */ pcs = 0; /* ignore */
@ -928,6 +1124,7 @@ LRESULT WINAPI RichEditANSIWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lP
{ {
CHARRANGE *pRange = (CHARRANGE *)lParam; CHARRANGE *pRange = (CHARRANGE *)lParam;
ME_GetSelection(editor, (int *)&pRange->cpMin, (int *)&pRange->cpMax); ME_GetSelection(editor, (int *)&pRange->cpMin, (int *)&pRange->cpMax);
TRACE("EM_EXGETSEL = (%ld,%ld)\n", pRange->cpMin, pRange->cpMax);
return 0; return 0;
} }
case EM_CANUNDO: case EM_CANUNDO:
@ -950,12 +1147,44 @@ LRESULT WINAPI RichEditANSIWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lP
case EM_EXSETSEL: case EM_EXSETSEL:
{ {
CHARRANGE *pRange = (CHARRANGE *)lParam; CHARRANGE *pRange = (CHARRANGE *)lParam;
TRACE("EM_EXSETSEL (%ld,%ld)\n", pRange->cpMin, pRange->cpMax);
ME_SetSelection(editor, pRange->cpMin, pRange->cpMax); ME_SetSelection(editor, pRange->cpMin, pRange->cpMax);
/* FIXME optimize */ /* FIXME optimize */
ME_Repaint(editor); ME_Repaint(editor);
ME_SendSelChange(editor); ME_SendSelChange(editor);
return 0; return 0;
} }
case EM_SETTEXTEX:
{
LPWSTR wszText = (LPWSTR)lParam;
SETTEXTEX *pStruct = (SETTEXTEX *)wParam;
size_t len = lstrlenW(wszText);
int from, to;
ME_Style *style;
TRACE("EM_SETTEXEX - %s, flags %d, cp %d\n", debugstr_w(wszText), (int)pStruct->flags, pStruct->codepage);
if (pStruct->codepage != 1200) {
FIXME("EM_SETTEXTEX only supports unicode right now!\n");
return 0;
}
/* FIXME: this should support RTF strings too, according to MSDN */
if (pStruct->flags & ST_SELECTION) {
ME_GetSelection(editor, &from, &to);
style = ME_GetSelectionInsertStyle(editor);
ME_InternalDeleteText(editor, from, to - from);
ME_InsertTextFromCursor(editor, 0, wszText, len, style);
ME_ReleaseStyle(style);
}
else {
ME_InternalDeleteText(editor, 0, ME_GetTextLength(editor));
ME_InsertTextFromCursor(editor, 0, wszText, -1, editor->pBuffer->pDefaultStyle);
len = 1;
}
ME_CommitUndo(editor);
if (!(pStruct->flags & ST_KEEPUNDO))
ME_EmptyUndoStack(editor);
ME_UpdateRepaint(editor);
return len;
}
case EM_SETBKGNDCOLOR: case EM_SETBKGNDCOLOR:
{ {
LRESULT lColor = ME_GetBackColor(editor); LRESULT lColor = ME_GetBackColor(editor);
@ -1002,7 +1231,7 @@ LRESULT WINAPI RichEditANSIWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lP
if (!wParam) if (!wParam)
ME_SetDefaultCharFormat(editor, p); ME_SetDefaultCharFormat(editor, p);
else if (wParam == (SCF_WORD | SCF_SELECTION)) else if (wParam == (SCF_WORD | SCF_SELECTION))
FIXME("word selection not supported\n"); FIXME("EM_SETCHARFORMAT: word selection not supported\n");
else if (wParam == SCF_ALL) else if (wParam == SCF_ALL)
ME_SetCharFormat(editor, 0, ME_GetTextLength(editor), p); ME_SetCharFormat(editor, 0, ME_GetTextLength(editor), p);
else { else {
@ -1018,14 +1247,19 @@ LRESULT WINAPI RichEditANSIWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lP
} }
case EM_GETCHARFORMAT: case EM_GETCHARFORMAT:
{ {
CHARFORMAT2W tmp; CHARFORMAT2W tmp, *dst = (CHARFORMAT2W *)lParam;
if (dst->cbSize != sizeof(CHARFORMATA) &&
dst->cbSize != sizeof(CHARFORMATW) &&
dst->cbSize != sizeof(CHARFORMAT2A) &&
dst->cbSize != sizeof(CHARFORMAT2W))
return 0;
tmp.cbSize = sizeof(tmp); tmp.cbSize = sizeof(tmp);
if (!wParam) if (!wParam)
ME_GetDefaultCharFormat(editor, &tmp); ME_GetDefaultCharFormat(editor, &tmp);
else else
ME_GetSelectionCharFormat(editor, &tmp); ME_GetSelectionCharFormat(editor, &tmp);
ME_CopyToCFAny((CHARFORMAT2W *)lParam, &tmp); ME_CopyToCFAny(dst, &tmp);
return 0; return tmp.dwMask;
} }
case EM_SETPARAFORMAT: case EM_SETPARAFORMAT:
ME_SetSelectionParaFormat(editor, (PARAFORMAT2 *)lParam); ME_SetSelectionParaFormat(editor, (PARAFORMAT2 *)lParam);
@ -1087,12 +1321,21 @@ LRESULT WINAPI RichEditANSIWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lP
} }
case WM_SETTEXT: case WM_SETTEXT:
{ {
LPWSTR wszText = ME_ToUnicode(hWnd, (void *)lParam);
TRACE("WM_SETTEXT - %s\n", (char *)(wszText)); /* debugstr_w() */
ME_InternalDeleteText(editor, 0, ME_GetTextLength(editor)); ME_InternalDeleteText(editor, 0, ME_GetTextLength(editor));
/* uses default style! */ if (lParam)
ME_InsertTextFromCursor(editor, 0, wszText, -1, editor->pBuffer->pDefaultStyle); {
ME_EndToUnicode(hWnd, wszText); LPWSTR wszText = ME_ToUnicode(hWnd, (void *)lParam);
TRACE("WM_SETTEXT lParam==%lx\n",lParam);
TRACE("WM_SETTEXT - %s\n", debugstr_w(wszText)); /* debugstr_w() */
if (lstrlenW(wszText) > 0)
{
/* uses default style! */
ME_InsertTextFromCursor(editor, 0, wszText, -1, editor->pBuffer->pDefaultStyle);
}
ME_EndToUnicode(hWnd, wszText);
}
else
TRACE("WM_SETTEXT - NULL\n");
ME_CommitUndo(editor); ME_CommitUndo(editor);
ME_EmptyUndoStack(editor); ME_EmptyUndoStack(editor);
ME_UpdateRepaint(editor); ME_UpdateRepaint(editor);
@ -1184,6 +1427,29 @@ LRESULT WINAPI RichEditANSIWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lP
tr.lpstrText = (WCHAR *)lParam; tr.lpstrText = (WCHAR *)lParam;
return RichEditANSIWndProc(hWnd, EM_GETTEXTRANGE, 0, (LPARAM)&tr); return RichEditANSIWndProc(hWnd, EM_GETTEXTRANGE, 0, (LPARAM)&tr);
} }
case EM_GETTEXTEX:
{
GETTEXTEX *ex = (GETTEXTEX*)wParam;
if (ex->flags != 0)
FIXME("Unhandled EM_GETTEXTEX flags 0x%lx\n",ex->flags);
if (IsWindowUnicode(hWnd))
return ME_GetTextW(editor, (LPWSTR)lParam, 0, ex->cb, FALSE);
else
{
LPWSTR buffer = HeapAlloc(GetProcessHeap(),0,ex->cb*sizeof(WCHAR));
DWORD buflen = ex->cb;
LRESULT rc;
DWORD flags = 0;
buflen = ME_GetTextW(editor, buffer, 0, buflen, FALSE);
rc = WideCharToMultiByte(ex->codepage, flags, buffer, buflen, (LPSTR)lParam, ex->cb, ex->lpDefaultChar, ex->lpUsedDefaultChar);
HeapFree(GetProcessHeap(),0,buffer);
return rc;
}
}
case EM_GETSELTEXT: case EM_GETSELTEXT:
{ {
int from, to; int from, to;
@ -1213,6 +1479,114 @@ LRESULT WINAPI RichEditANSIWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lP
} }
return ME_GetTextW(editor, rng->lpstrText, rng->chrg.cpMin, rng->chrg.cpMax-rng->chrg.cpMin, FALSE); return ME_GetTextW(editor, rng->lpstrText, rng->chrg.cpMin, rng->chrg.cpMax-rng->chrg.cpMin, FALSE);
} }
case EM_GETLINECOUNT:
{
ME_DisplayItem *item = editor->pBuffer->pFirst->next;
int nRows = 0;
while (item != editor->pBuffer->pLast)
{
assert(item->type == diParagraph);
nRows += item->member.para.nRows;
item = item->member.para.next_para;
}
TRACE("EM_GETLINECOUNT: nRows==%d\n", nRows);
return max(1, nRows);
}
case EM_LINEFROMCHAR:
{
if (wParam == -1)
return ME_RowNumberFromCharOfs(editor, ME_GetCursorOfs(editor, 1));
else
return ME_RowNumberFromCharOfs(editor, wParam);
}
case EM_EXLINEFROMCHAR:
{
return ME_RowNumberFromCharOfs(editor, lParam);
}
case EM_LINEINDEX:
{
ME_DisplayItem *item, *para;
int nCharOfs;
if (wParam == -1)
item = ME_FindItemBack(editor->pCursors[0].pRun, diStartRow);
else
item = ME_FindRowWithNumber(editor, wParam);
if (!item)
return -1;
para = ME_GetParagraph(item);
item = ME_FindItemFwd(item, diRun);
nCharOfs = para->member.para.nCharOfs + item->member.run.nCharOfs;
TRACE("EM_LINEINDEX: nCharOfs==%d\n", nCharOfs);
return nCharOfs;
}
case EM_LINELENGTH:
{
ME_DisplayItem *item, *item_end;
int nChars = 0;
if (wParam > ME_GetTextLength(editor))
return 0;
if (wParam == -1)
{
FIXME("EM_LINELENGTH: returning number of unselected characters on lines with selection unsupported.\n");
return 0;
}
item = ME_FindItemAtOffset(editor, diRun, wParam, NULL);
item = ME_RowStart(item);
item_end = ME_RowEnd(item);
if (!item_end)
{
/* Empty buffer, no runs */
nChars = 0;
}
else
{
nChars = ME_CharOfsFromRunOfs(editor, item_end, ME_StrLen(item_end->member.run.strText));
nChars -= ME_CharOfsFromRunOfs(editor, item, 0);
}
TRACE("EM_LINELENGTH(%d)==%d\n",wParam, nChars);
return nChars;
}
case EM_FINDTEXT:
{
FINDTEXTA *ft = (FINDTEXTA *)lParam;
int nChars = MultiByteToWideChar(CP_ACP, 0, ft->lpstrText, -1, NULL, 0);
WCHAR *tmp;
if ((tmp = ALLOC_N_OBJ(WCHAR, nChars)) != NULL)
MultiByteToWideChar(CP_ACP, 0, ft->lpstrText, -1, tmp, nChars);
return ME_FindText(editor, wParam, &ft->chrg, tmp, NULL);
}
case EM_FINDTEXTEX:
{
FINDTEXTEXA *ex = (FINDTEXTEXA *)lParam;
int nChars = MultiByteToWideChar(CP_ACP, 0, ex->lpstrText, -1, NULL, 0);
WCHAR *tmp;
if ((tmp = ALLOC_N_OBJ(WCHAR, nChars)) != NULL)
MultiByteToWideChar(CP_ACP, 0, ex->lpstrText, -1, tmp, nChars);
return ME_FindText(editor, wParam, &ex->chrg, tmp, &ex->chrgText);
}
case EM_FINDTEXTW:
{
FINDTEXTW *ft = (FINDTEXTW *)lParam;
return ME_FindText(editor, wParam, &ft->chrg, ft->lpstrText, NULL);
}
case EM_FINDTEXTEXW:
{
FINDTEXTEXW *ex = (FINDTEXTEXW *)lParam;
return ME_FindText(editor, wParam, &ex->chrg, ex->lpstrText, &ex->chrgText);
}
case EM_GETZOOM:
if (!wParam || !lParam)
return FALSE;
*(int *)wParam = editor->nZoomNumerator;
*(int *)lParam = editor->nZoomDenominator;
return TRUE;
case EM_SETZOOM:
return ME_SetZoom(editor, wParam, lParam);
case WM_CREATE: case WM_CREATE:
ME_CommitUndo(editor); ME_CommitUndo(editor);
ME_WrapMarkedParagraphs(editor); ME_WrapMarkedParagraphs(editor);
@ -1369,10 +1743,7 @@ LRESULT WINAPI RichEditANSIWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lP
} }
case WM_SIZE: case WM_SIZE:
{ {
ME_MarkAllForWrapping(editor); ME_RewrapRepaint(editor);
ME_WrapMarkedParagraphs(editor);
ME_UpdateScrollBar(editor);
ME_Repaint(editor);
return DefWindowProcW(hWnd, msg, wParam, lParam); return DefWindowProcW(hWnd, msg, wParam, lParam);
} }
case EM_GETOLEINTERFACE: case EM_GETOLEINTERFACE:
@ -1388,13 +1759,24 @@ LRESULT WINAPI RichEditANSIWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lP
return 0L; return 0L;
} }
/****************************************************************** /******************************************************************
* RichEdit10ANSIWndProc (RICHED20.9) * RichEdit10ANSIWndProc (RICHED20.9)
*/ */
LRESULT WINAPI RichEdit10ANSIWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) LRESULT WINAPI RichEdit10ANSIWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{ {
LRESULT result;
/* FIXME: this is NOT the same as 2.0 version */ /* FIXME: this is NOT the same as 2.0 version */
return RichEditANSIWndProc(hWnd, msg, wParam, lParam); result = RichEditANSIWndProc(hWnd, msg, wParam, lParam);
if (msg == WM_NCCREATE)
{
ME_TextEditor *editor = (ME_TextEditor *)GetWindowLongW(hWnd, 0);
editor->bEmulateVersion10 = TRUE;
editor->pBuffer->pLast->member.para.nCharOfs = 2;
}
return result;
} }
void ME_SendOldNotify(ME_TextEditor *editor, int nCode) void ME_SendOldNotify(ME_TextEditor *editor, int nCode)

View file

@ -100,6 +100,8 @@ ME_DisplayItem *ME_FindRowStart(ME_Context *c, ME_DisplayItem *run, int nRelPos)
ME_DisplayItem *ME_RowStart(ME_DisplayItem *item); ME_DisplayItem *ME_RowStart(ME_DisplayItem *item);
ME_DisplayItem *ME_RowEnd(ME_DisplayItem *item); ME_DisplayItem *ME_RowEnd(ME_DisplayItem *item);
void ME_RenumberParagraphs(ME_DisplayItem *item); /* TODO */ 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 */ /* run.c */
ME_DisplayItem *ME_MakeRun(ME_Style *s, ME_String *strData, int nFlags); ME_DisplayItem *ME_MakeRun(ME_Style *s, ME_String *strData, int nFlags);
@ -189,6 +191,7 @@ void ME_MarkAllForWrapping(ME_TextEditor *editor);
/* paint.c */ /* paint.c */
void ME_PaintContent(ME_TextEditor *editor, HDC hDC, BOOL bOnlyNew, RECT *rcUpdate); void ME_PaintContent(ME_TextEditor *editor, HDC hDC, BOOL bOnlyNew, RECT *rcUpdate);
void ME_Repaint(ME_TextEditor *editor); void ME_Repaint(ME_TextEditor *editor);
void ME_RewrapRepaint(ME_TextEditor *editor);
void ME_UpdateRepaint(ME_TextEditor *editor); void ME_UpdateRepaint(ME_TextEditor *editor);
void ME_DrawParagraph(ME_Context *c, ME_DisplayItem *paragraph); void ME_DrawParagraph(ME_Context *c, ME_DisplayItem *paragraph);
void ME_UpdateScrollBar(ME_TextEditor *editor); void ME_UpdateScrollBar(ME_TextEditor *editor);
@ -196,6 +199,7 @@ int ME_GetYScrollPos(ME_TextEditor *editor);
void ME_EnsureVisible(ME_TextEditor *editor, ME_DisplayItem *pRun); void ME_EnsureVisible(ME_TextEditor *editor, ME_DisplayItem *pRun);
COLORREF ME_GetBackColor(ME_TextEditor *editor); COLORREF ME_GetBackColor(ME_TextEditor *editor);
void ME_Scroll(ME_TextEditor *editor, int cx, int cy); void ME_Scroll(ME_TextEditor *editor, int cx, int cy);
BOOL ME_SetZoom(ME_TextEditor *editor, int numerator, int denominator);
/* richole.c */ /* richole.c */
extern LRESULT CreateIRichEditOle(LPVOID *); extern LRESULT CreateIRichEditOle(LPVOID *);

View file

@ -147,6 +147,7 @@ typedef struct tagME_Paragraph
int nFlags; int nFlags;
int nYPos, nHeight; int nYPos, nHeight;
int nLastPaintYPos, nLastPaintHeight; int nLastPaintYPos, nLastPaintHeight;
int nRows;
struct tagME_DisplayItem *prev_para, *next_para, *document; struct tagME_DisplayItem *prev_para, *next_para, *document;
} ME_Paragraph; } ME_Paragraph;
@ -246,6 +247,7 @@ typedef struct tagME_FontCacheItem
typedef struct tagME_TextEditor typedef struct tagME_TextEditor
{ {
HWND hWnd; HWND hWnd;
BOOL bEmulateVersion10;
BOOL bCaretShown; BOOL bCaretShown;
ME_TextBuffer *pBuffer; ME_TextBuffer *pBuffer;
ME_Cursor *pCursors; ME_Cursor *pCursors;
@ -267,6 +269,7 @@ typedef struct tagME_TextEditor
ME_OutStream *pStream; ME_OutStream *pStream;
BOOL bScrollX, bScrollY; BOOL bScrollX, bScrollY;
int nScrollPosY; int nScrollPosY;
int nZoomNumerator, nZoomDenominator;
} ME_TextEditor; } ME_TextEditor;
typedef struct tagME_Context typedef struct tagME_Context

View file

@ -94,7 +94,7 @@ void ME_PaintContent(ME_TextEditor *editor, HDC hDC, BOOL bOnlyNew, RECT *rcUpda
ME_DestroyContext(&c); ME_DestroyContext(&c);
} }
void ME_MarkParagraphRange(ME_TextEditor *editor, ME_DisplayItem *p1, static void ME_MarkParagraphRange(ME_TextEditor *editor, ME_DisplayItem *p1,
ME_DisplayItem *p2, int nFlags) ME_DisplayItem *p2, int nFlags)
{ {
ME_DisplayItem *p3; ME_DisplayItem *p3;
@ -113,7 +113,7 @@ void ME_MarkParagraphRange(ME_TextEditor *editor, ME_DisplayItem *p1,
} while (p1 != p2); } while (p1 != p2);
} }
void ME_MarkOffsetRange(ME_TextEditor *editor, int from, int to, int nFlags) static void ME_MarkOffsetRange(ME_TextEditor *editor, int from, int to, int nFlags)
{ {
ME_Cursor c1, c2; ME_Cursor c1, c2;
ME_CursorFromCharOfs(editor, from, &c1); ME_CursorFromCharOfs(editor, from, &c1);
@ -122,7 +122,7 @@ void ME_MarkOffsetRange(ME_TextEditor *editor, int from, int to, int nFlags)
ME_MarkParagraphRange(editor, ME_GetParagraph(c1.pRun), ME_GetParagraph(c2.pRun), nFlags); ME_MarkParagraphRange(editor, ME_GetParagraph(c1.pRun), ME_GetParagraph(c2.pRun), nFlags);
} }
void ME_MarkSelectionForRepaint(ME_TextEditor *editor) static void ME_MarkSelectionForRepaint(ME_TextEditor *editor)
{ {
int from, to, from2, to2, end; int from, to, from2, to2, end;
@ -173,7 +173,18 @@ void ME_UpdateRepaint(ME_TextEditor *editor)
ME_SendSelChange(editor); ME_SendSelChange(editor);
} }
void ME_DrawTextWithStyle(ME_Context *c, int x, int y, LPCWSTR szText, int nChars,
void
ME_RewrapRepaint(ME_TextEditor *editor)
{
ME_MarkAllForWrapping(editor);
ME_WrapMarkedParagraphs(editor);
ME_UpdateScrollBar(editor);
ME_Repaint(editor);
}
static void ME_DrawTextWithStyle(ME_Context *c, int x, int y, LPCWSTR szText, int nChars,
ME_Style *s, int *width, int nSelFrom, int nSelTo, int ymin, int cy) { ME_Style *s, int *width, int nSelFrom, int nSelTo, int ymin, int cy) {
HDC hDC = c->hDC; HDC hDC = c->hDC;
HGDIOBJ hOldFont; HGDIOBJ hOldFont;
@ -193,7 +204,17 @@ void ME_DrawTextWithStyle(ME_Context *c, int x, int y, LPCWSTR szText, int nChar
if (s->fmt.dwEffects & CFE_SUBSCRIPT) yTwipsOffset = -s->fmt.yHeight/12; if (s->fmt.dwEffects & CFE_SUBSCRIPT) yTwipsOffset = -s->fmt.yHeight/12;
} }
if (yTwipsOffset) if (yTwipsOffset)
yOffset = yTwipsOffset*GetDeviceCaps(hDC, LOGPIXELSY)/1440; {
int numerator = 1;
int denominator = 1;
if (c->editor->nZoomNumerator)
{
numerator = c->editor->nZoomNumerator;
denominator = c->editor->nZoomDenominator;
}
yOffset = yTwipsOffset * GetDeviceCaps(hDC, LOGPIXELSY) * numerator / denominator / 1440;
}
ExtTextOutW(hDC, x, y-yOffset, 0, NULL, szText, nChars, NULL); ExtTextOutW(hDC, x, y-yOffset, 0, NULL, szText, nChars, NULL);
if (width) { if (width) {
SIZE sz; SIZE sz;
@ -214,7 +235,7 @@ void ME_DrawTextWithStyle(ME_Context *c, int x, int y, LPCWSTR szText, int nChar
ME_UnselectStyleFont(c->editor, hDC, s, hOldFont); ME_UnselectStyleFont(c->editor, hDC, s, hOldFont);
} }
void ME_DebugWrite(HDC hDC, POINT *pt, WCHAR *szText) { static void ME_DebugWrite(HDC hDC, POINT *pt, WCHAR *szText) {
int align = SetTextAlign(hDC, TA_LEFT|TA_TOP); int align = SetTextAlign(hDC, TA_LEFT|TA_TOP);
HGDIOBJ hFont = SelectObject(hDC, GetStockObject(DEFAULT_GUI_FONT)); HGDIOBJ hFont = SelectObject(hDC, GetStockObject(DEFAULT_GUI_FONT));
COLORREF color = SetTextColor(hDC, RGB(128,128,128)); COLORREF color = SetTextColor(hDC, RGB(128,128,128));
@ -252,7 +273,7 @@ void ME_DrawGraphics(ME_Context *c, int x, int y, ME_Run *run,
} }
} }
void ME_DrawRun(ME_Context *c, int x, int y, ME_DisplayItem *rundi, ME_Paragraph *para) { static void ME_DrawRun(ME_Context *c, int x, int y, ME_DisplayItem *rundi, ME_Paragraph *para) {
ME_Run *run = &rundi->member.run; ME_Run *run = &rundi->member.run;
int runofs = run->nCharOfs+para->nCharOfs; int runofs = run->nCharOfs+para->nCharOfs;
@ -484,3 +505,25 @@ void ME_EnsureVisible(ME_TextEditor *editor, ME_DisplayItem *pRun)
UpdateWindow(hWnd); UpdateWindow(hWnd);
} }
} }
BOOL
ME_SetZoom(ME_TextEditor *editor, int numerator, int denominator)
{
/* TODO: Zoom images and objects */
if (numerator != 0)
{
if (denominator == 0)
return FALSE;
if (1.0 / 64.0 > (float)numerator / (float)denominator
|| (float)numerator / (float)denominator > 64.0)
return FALSE;
}
editor->nZoomNumerator = numerator;
editor->nZoomDenominator = denominator;
ME_RewrapRepaint(editor);
return TRUE;
}

View file

@ -101,6 +101,7 @@ ME_DisplayItem *ME_SplitParagraph(ME_TextEditor *editor, ME_DisplayItem *run, ME
ME_UndoItem *undo = NULL; ME_UndoItem *undo = NULL;
int ofs; int ofs;
ME_DisplayItem *pp; ME_DisplayItem *pp;
int end_len = (editor->bEmulateVersion10 ? 2 : 1);
assert(run->type == diRun); assert(run->type == diRun);
@ -122,7 +123,7 @@ ME_DisplayItem *ME_SplitParagraph(ME_TextEditor *editor, ME_DisplayItem *run, ME
pp = ME_FindItemFwd(pp, diRunOrParagraphOrEnd); pp = ME_FindItemFwd(pp, diRunOrParagraphOrEnd);
} }
new_para->member.para.nCharOfs = ME_GetParagraph(run)->member.para.nCharOfs+ofs; new_para->member.para.nCharOfs = ME_GetParagraph(run)->member.para.nCharOfs+ofs;
new_para->member.para.nCharOfs += 1; new_para->member.para.nCharOfs += end_len;
new_para->member.para.nFlags = MEPF_REWRAP; /* FIXME copy flags (if applicable) */ new_para->member.para.nFlags = MEPF_REWRAP; /* FIXME copy flags (if applicable) */
/* FIXME initialize format style and call ME_SetParaFormat blah blah */ /* FIXME initialize format style and call ME_SetParaFormat blah blah */
@ -148,7 +149,7 @@ ME_DisplayItem *ME_SplitParagraph(ME_TextEditor *editor, ME_DisplayItem *run, ME
new_para->member.para.prev_para->member.para.nFlags |= MEPF_REWRAP; new_para->member.para.prev_para->member.para.nFlags |= MEPF_REWRAP;
/* we've added the end run, so we need to modify nCharOfs in the next paragraphs */ /* we've added the end run, so we need to modify nCharOfs in the next paragraphs */
ME_PropagateCharOffset(next_para, 1); ME_PropagateCharOffset(next_para, end_len);
editor->nParagraphs++; editor->nParagraphs++;
return new_para; return new_para;
@ -161,6 +162,7 @@ ME_DisplayItem *ME_JoinParagraphs(ME_TextEditor *editor, ME_DisplayItem *tp)
ME_DisplayItem *pNext, *pFirstRunInNext, *pRun, *pTmp; ME_DisplayItem *pNext, *pFirstRunInNext, *pRun, *pTmp;
int i, shift; int i, shift;
ME_UndoItem *undo = NULL; ME_UndoItem *undo = NULL;
int end_len = (editor->bEmulateVersion10 ? 2 : 1);
assert(tp->type == diParagraph); assert(tp->type == diParagraph);
assert(tp->member.para.next_para); assert(tp->member.para.next_para);
@ -172,17 +174,17 @@ ME_DisplayItem *ME_JoinParagraphs(ME_TextEditor *editor, ME_DisplayItem *tp)
/* null char format operation to store the original char format for the ENDPARA run */ /* null char format operation to store the original char format for the ENDPARA run */
CHARFORMAT2W fmt; CHARFORMAT2W fmt;
ME_InitCharFormat2W(&fmt); ME_InitCharFormat2W(&fmt);
ME_SetCharFormat(editor, pNext->member.para.nCharOfs-1, 1, &fmt); ME_SetCharFormat(editor, pNext->member.para.nCharOfs - end_len, end_len, &fmt);
} }
undo = ME_AddUndoItem(editor, diUndoSplitParagraph, NULL); undo = ME_AddUndoItem(editor, diUndoSplitParagraph, NULL);
if (undo) if (undo)
{ {
undo->nStart = pNext->member.para.nCharOfs-1; undo->nStart = pNext->member.para.nCharOfs - end_len;
assert(pNext->member.para.pFmt->cbSize == sizeof(PARAFORMAT2)); assert(pNext->member.para.pFmt->cbSize == sizeof(PARAFORMAT2));
CopyMemory(undo->di.member.para.pFmt, pNext->member.para.pFmt, sizeof(PARAFORMAT2)); CopyMemory(undo->di.member.para.pFmt, pNext->member.para.pFmt, sizeof(PARAFORMAT2));
} }
shift = pNext->member.para.nCharOfs - tp->member.para.nCharOfs - 1; shift = pNext->member.para.nCharOfs - tp->member.para.nCharOfs - end_len;
pRun = ME_FindItemBack(pNext, diRunOrParagraph); pRun = ME_FindItemBack(pNext, diRunOrParagraph);
pFirstRunInNext = ME_FindItemFwd(pNext, diRunOrParagraph); pFirstRunInNext = ME_FindItemFwd(pNext, diRunOrParagraph);
@ -218,7 +220,7 @@ ME_DisplayItem *ME_JoinParagraphs(ME_TextEditor *editor, ME_DisplayItem *tp)
ME_Remove(pNext); ME_Remove(pNext);
ME_DestroyDisplayItem(pNext); ME_DestroyDisplayItem(pNext);
ME_PropagateCharOffset(tp->member.para.next_para, -1); ME_PropagateCharOffset(tp->member.para.next_para, -end_len);
ME_CheckCharOffsets(editor); ME_CheckCharOffsets(editor);

View file

@ -82,3 +82,49 @@ ME_DisplayItem *ME_RowEnd(ME_DisplayItem *item) {
if (!item2) return NULL; if (!item2) return NULL;
return ME_FindItemBack(item, diRun); return ME_FindItemBack(item, diRun);
} }
ME_DisplayItem *
ME_FindRowWithNumber(ME_TextEditor *editor, int nRow)
{
ME_DisplayItem *item = ME_FindItemFwd(editor->pBuffer->pFirst, diParagraph);
int nCount = 0;
while (item && nCount + item->member.para.nRows <= nRow)
{
nCount += item->member.para.nRows;
item = ME_FindItemFwd(item, diParagraph);
}
if (!item)
return item;
for (item = ME_FindItemFwd(item, diStartRow); item && nCount < nRow; nCount++)
item = ME_FindItemFwd(item, diStartRow);
return item;
}
int
ME_RowNumberFromCharOfs(ME_TextEditor *editor, int nOfs)
{
ME_DisplayItem *item = editor->pBuffer->pFirst->next;
int nRow = 0;
while (item && item->member.para.next_para->member.para.nCharOfs <= nOfs)
{
nRow += item->member.para.nRows;
item = ME_FindItemFwd(item, diParagraph);
}
if (item)
{
nOfs -= item->member.para.nCharOfs;
item = ME_FindItemFwd(item, diRun);
while ((item = ME_FindItemFwd(item, diStartRowOrParagraph)) != NULL)
{
item = ME_FindItemFwd(item, diRun);
if (item->member.run.nCharOfs > nOfs)
break;
nRow++;
}
}
return nRow;
}

View file

@ -97,7 +97,10 @@ void ME_CheckCharOffsets(ME_TextEditor *editor)
p->member.run.nFlags, p->member.run.nFlags,
p->member.run.style->fmt.dwMask & p->member.run.style->fmt.dwEffects); p->member.run.style->fmt.dwMask & p->member.run.style->fmt.dwEffects);
assert(ofs == p->member.run.nCharOfs); assert(ofs == p->member.run.nCharOfs);
ofs += ME_StrLen(p->member.run.strText); if (p->member.run.nFlags & MERF_ENDPARA)
ofs += (editor->bEmulateVersion10 ? 2 : 1);
else
ofs += ME_StrLen(p->member.run.strText);
break; break;
default: default:
assert(0); assert(0);
@ -639,9 +642,6 @@ void ME_GetCharFormat(ME_TextEditor *editor, int nFrom, int nTo, CHARFORMAT2W *p
int nOffset, nOffset2; int nOffset, nOffset2;
CHARFORMAT2W tmp; CHARFORMAT2W tmp;
if (nTo>nFrom) /* selection consists of chars from nFrom up to nTo-1 */
nTo--;
ME_RunOfsFromCharOfs(editor, nFrom, &run, &nOffset); ME_RunOfsFromCharOfs(editor, nFrom, &run, &nOffset);
if (nFrom == nTo) /* special case - if selection is empty, take previous char's formatting */ if (nFrom == nTo) /* special case - if selection is empty, take previous char's formatting */
{ {
@ -656,6 +656,9 @@ void ME_GetCharFormat(ME_TextEditor *editor, int nFrom, int nTo, CHARFORMAT2W *p
ME_GetRunCharFormat(editor, run, pFmt); ME_GetRunCharFormat(editor, run, pFmt);
return; return;
} }
if (nTo>nFrom) /* selection consists of chars from nFrom up to nTo-1 */
nTo--;
ME_RunOfsFromCharOfs(editor, nTo, &run_end, &nOffset2); ME_RunOfsFromCharOfs(editor, nTo, &run_end, &nOffset2);
ME_GetRunCharFormat(editor, run, pFmt); ME_GetRunCharFormat(editor, run, pFmt);

View file

@ -249,14 +249,23 @@ void ME_DumpStyleToBuf(CHARFORMAT2W *pFmt, char buf[2048])
ME_DumpStyleEffect(&p, "Text protected:", pFmt, CFM_PROTECTED); ME_DumpStyleEffect(&p, "Text protected:", pFmt, CFM_PROTECTED);
} }
void ME_LogFontFromStyle(HDC hDC, LOGFONTW *lf, ME_Style *s)
static void
ME_LogFontFromStyle(HDC hDC, LOGFONTW *lf, ME_Style *s, int nZoomNumerator, int nZoomDenominator)
{ {
int rx, ry; int rx, ry;
rx = GetDeviceCaps(hDC, LOGPIXELSX); rx = GetDeviceCaps(hDC, LOGPIXELSX);
ry = GetDeviceCaps(hDC, LOGPIXELSY); ry = GetDeviceCaps(hDC, LOGPIXELSY);
ZeroMemory(lf, sizeof(LOGFONTW)); ZeroMemory(lf, sizeof(LOGFONTW));
lstrcpyW(lf->lfFaceName, s->fmt.szFaceName); lstrcpyW(lf->lfFaceName, s->fmt.szFaceName);
lf->lfHeight = -s->fmt.yHeight*ry/1440;
if (nZoomNumerator == 0)
{
nZoomNumerator = 1;
nZoomDenominator = 1;
}
lf->lfHeight = -s->fmt.yHeight*ry*nZoomNumerator/nZoomDenominator/1440;
lf->lfWeight = 400; lf->lfWeight = 400;
if (s->fmt.dwEffects & s->fmt.dwMask & CFM_BOLD) if (s->fmt.dwEffects & s->fmt.dwMask & CFM_BOLD)
lf->lfWeight = 700; lf->lfWeight = 700;
@ -294,7 +303,7 @@ HFONT ME_SelectStyleFont(ME_TextEditor *editor, HDC hDC, ME_Style *s)
assert(hDC); assert(hDC);
assert(s); assert(s);
ME_LogFontFromStyle(hDC, &lf, s); ME_LogFontFromStyle(hDC, &lf, s, editor->nZoomNumerator, editor->nZoomDenominator);
for (i=0; i<HFONT_CACHE_SIZE; i++) for (i=0; i<HFONT_CACHE_SIZE; i++)
editor->pFontCache[i].nAge++; editor->pFontCache[i].nAge++;

View file

@ -42,7 +42,7 @@ ME_DisplayItem *ME_MakeRow(int height, int baseline, int width)
return item; return item;
} }
void ME_BeginRow(ME_WrapContext *wc) static void ME_BeginRow(ME_WrapContext *wc)
{ {
wc->pRowStart = NULL; wc->pRowStart = NULL;
wc->bOverflown = FALSE; wc->bOverflown = FALSE;
@ -91,7 +91,7 @@ void ME_InsertRowStart(ME_WrapContext *wc, ME_DisplayItem *pEnd)
ME_BeginRow(wc); ME_BeginRow(wc);
} }
void ME_WrapEndParagraph(ME_WrapContext *wc, ME_DisplayItem *p) static void ME_WrapEndParagraph(ME_WrapContext *wc, ME_DisplayItem *p)
{ {
if (wc->pRowStart) if (wc->pRowStart)
ME_InsertRowStart(wc, p->next); ME_InsertRowStart(wc, p->next);
@ -111,7 +111,7 @@ void ME_WrapEndParagraph(ME_WrapContext *wc, ME_DisplayItem *p)
*/ */
} }
void ME_WrapSizeRun(ME_WrapContext *wc, ME_DisplayItem *p) static void ME_WrapSizeRun(ME_WrapContext *wc, ME_DisplayItem *p)
{ {
/* FIXME compose style (out of character and paragraph styles) here */ /* FIXME compose style (out of character and paragraph styles) here */
@ -120,7 +120,7 @@ void ME_WrapSizeRun(ME_WrapContext *wc, ME_DisplayItem *p)
ME_CalcRunExtent(wc->context, &ME_GetParagraph(p)->member.para, &p->member.run); ME_CalcRunExtent(wc->context, &ME_GetParagraph(p)->member.para, &p->member.run);
} }
ME_DisplayItem *ME_MaximizeSplit(ME_WrapContext *wc, ME_DisplayItem *p, int i) static ME_DisplayItem *ME_MaximizeSplit(ME_WrapContext *wc, ME_DisplayItem *p, int i)
{ {
ME_DisplayItem *pp, *piter = p; ME_DisplayItem *pp, *piter = p;
int j; int j;
@ -162,7 +162,7 @@ ME_DisplayItem *ME_MaximizeSplit(ME_WrapContext *wc, ME_DisplayItem *p, int i)
} }
} }
ME_DisplayItem *ME_SplitByBacktracking(ME_WrapContext *wc, ME_DisplayItem *p, int loc) static ME_DisplayItem *ME_SplitByBacktracking(ME_WrapContext *wc, ME_DisplayItem *p, int loc)
{ {
ME_DisplayItem *piter = p, *pp; ME_DisplayItem *piter = p, *pp;
int i, idesp, len; int i, idesp, len;
@ -242,7 +242,7 @@ ME_DisplayItem *ME_SplitByBacktracking(ME_WrapContext *wc, ME_DisplayItem *p, in
} }
} }
ME_DisplayItem *ME_WrapHandleRun(ME_WrapContext *wc, ME_DisplayItem *p) static ME_DisplayItem *ME_WrapHandleRun(ME_WrapContext *wc, ME_DisplayItem *p)
{ {
ME_DisplayItem *pp; ME_DisplayItem *pp;
ME_Run *run; ME_Run *run;
@ -375,12 +375,15 @@ void ME_WrapTextParagraph(ME_Context *c, ME_DisplayItem *tp) {
ME_WrapEndParagraph(&wc, p); ME_WrapEndParagraph(&wc, p);
tp->member.para.nFlags &= ~MEPF_REWRAP; tp->member.para.nFlags &= ~MEPF_REWRAP;
tp->member.para.nHeight = wc.pt.y; tp->member.para.nHeight = wc.pt.y;
tp->member.para.nRows = wc.nRow;
} }
void ME_PrepareParagraphForWrapping(ME_Context *c, ME_DisplayItem *tp) { void ME_PrepareParagraphForWrapping(ME_Context *c, ME_DisplayItem *tp) {
ME_DisplayItem *p; ME_DisplayItem *p;
/* remove all items that will be reinserted by paragraph wrapper anyway */ /* remove all items that will be reinserted by paragraph wrapper anyway */
tp->member.para.nRows = 0;
for (p = tp->next; p!=tp->member.para.next_para; p = p->next) { for (p = tp->next; p!=tp->member.para.next_para; p = p->next) {
switch(p->type) { switch(p->type) {
case diStartRow: case diStartRow:

View file

@ -33,6 +33,7 @@ ME_StreamOutInit(ME_TextEditor *editor, EDITSTREAM *stream)
{ {
editor->pStream = ALLOC_OBJ(ME_OutStream); editor->pStream = ALLOC_OBJ(ME_OutStream);
editor->pStream->stream = stream; editor->pStream->stream = stream;
editor->pStream->stream->dwError = 0;
editor->pStream->pos = 0; editor->pStream->pos = 0;
editor->pStream->written = 0; editor->pStream->written = 0;
editor->pStream->nFontTblLen = 0; editor->pStream->nFontTblLen = 0;
@ -108,7 +109,7 @@ ME_StreamOutMove(ME_TextEditor *editor, BYTE *buffer, int len)
static BOOL static BOOL
ME_StreamOutPrint(ME_TextEditor *editor, char *format, ...) ME_StreamOutPrint(ME_TextEditor *editor, const char *format, ...)
{ {
char string[STREAMOUT_BUFFER_SIZE]; /* This is going to be enough */ char string[STREAMOUT_BUFFER_SIZE]; /* This is going to be enough */
int len; int len;
@ -125,7 +126,7 @@ ME_StreamOutPrint(ME_TextEditor *editor, char *format, ...)
static BOOL static BOOL
ME_StreamOutRTFHeader(ME_TextEditor *editor, int dwFormat) ME_StreamOutRTFHeader(ME_TextEditor *editor, int dwFormat)
{ {
char *cCharSet = NULL; const char *cCharSet = NULL;
UINT nCodePage; UINT nCodePage;
LANGID language; LANGID language;
BOOL success; BOOL success;
@ -567,7 +568,7 @@ ME_StreamOutRTFText(ME_TextEditor *editor, WCHAR *text, LONG nChars)
{ {
char buffer[STREAMOUT_BUFFER_SIZE]; char buffer[STREAMOUT_BUFFER_SIZE];
int pos = 0; int pos = 0;
int fit, i; int fit, nBytes, i;
if (nChars == -1) if (nChars == -1)
nChars = lstrlenW(text); nChars = lstrlenW(text);
@ -577,18 +578,18 @@ ME_StreamOutRTFText(ME_TextEditor *editor, WCHAR *text, LONG nChars)
if (editor->pStream->nDefaultCodePage == CP_UTF8) { if (editor->pStream->nDefaultCodePage == CP_UTF8) {
/* 6 is the maximum character length in UTF-8 */ /* 6 is the maximum character length in UTF-8 */
fit = min(nChars, STREAMOUT_BUFFER_SIZE / 6); fit = min(nChars, STREAMOUT_BUFFER_SIZE / 6);
WideCharToMultiByte(CP_UTF8, 0, text, fit, buffer, STREAMOUT_BUFFER_SIZE, nBytes = WideCharToMultiByte(CP_UTF8, 0, text, fit, buffer,
NULL, NULL); STREAMOUT_BUFFER_SIZE, NULL, NULL);
nChars -= fit; nChars -= fit;
text += fit; text += fit;
for (i = 0; buffer[i]; i++) for (i = 0; i < nBytes; i++)
if (buffer[i] == '{' || buffer[i] == '}' || buffer[i] == '\\') { if (buffer[i] == '{' || buffer[i] == '}' || buffer[i] == '\\') {
if (!ME_StreamOutPrint(editor, "%.*s\\", i - pos, buffer + pos)) if (!ME_StreamOutPrint(editor, "%.*s\\", i - pos, buffer + pos))
return FALSE; return FALSE;
pos = i; pos = i;
} }
if (!pos) if (!pos)
if (!ME_StreamOutPrint(editor, "%s", buffer + pos)) if (!ME_StreamOutMove(editor, buffer + pos, nBytes - pos))
return FALSE; return FALSE;
pos = 0; pos = 0;
} else if (*text < 128) { } else if (*text < 128) {
@ -599,7 +600,6 @@ ME_StreamOutRTFText(ME_TextEditor *editor, WCHAR *text, LONG nChars)
} else { } else {
BOOL unknown = FALSE; BOOL unknown = FALSE;
BYTE letter[3]; BYTE letter[3];
int nBytes, i;
/* FIXME: In the MS docs for WideCharToMultiByte there is a big list of /* FIXME: In the MS docs for WideCharToMultiByte there is a big list of
* codepages including CP_SYMBOL for which the last parameter must be set * codepages including CP_SYMBOL for which the last parameter must be set
@ -759,11 +759,13 @@ ME_StreamOutText(ME_TextEditor *editor, int nStart, int nChars, DWORD dwFormat)
} }
WideCharToMultiByte(nCodePage, 0, item->member.run.strText->szData + nStart, WideCharToMultiByte(nCodePage, 0, item->member.run.strText->szData + nStart,
nLen, buffer, nSize, NULL, NULL); nLen, buffer, nSize, NULL, NULL);
success = ME_StreamOutMove(editor, buffer, nSize - 1); success = ME_StreamOutMove(editor, buffer, nSize);
} }
} }
nChars -= nLen; nChars -= nLen;
if (editor->bEmulateVersion10 && nChars && item->member.run.nFlags & MERF_ENDPARA)
nChars--;
nStart = 0; nStart = 0;
item = ME_FindItemFwd(item, diRun); item = ME_FindItemFwd(item, diRun);
} }
@ -791,7 +793,7 @@ ME_StreamOut(ME_TextEditor *editor, DWORD dwFormat, EDITSTREAM *stream)
nTo = ME_GetTextLength(editor); nTo = ME_GetTextLength(editor);
TRACE("from %d to %d\n", nStart, nTo); TRACE("from %d to %d\n", nStart, nTo);
if (dwFormat & SF_RTF || dwFormat & SF_RTFNOOBJS) if (dwFormat & SF_RTF)
ME_StreamOutRTF(editor, nStart, nTo - nStart, dwFormat); ME_StreamOutRTF(editor, nStart, nTo - nStart, dwFormat);
else if (dwFormat & SF_TEXT || dwFormat & SF_TEXTIZED) else if (dwFormat & SF_TEXT || dwFormat & SF_TEXTIZED)
ME_StreamOutText(editor, nStart, nTo - nStart, dwFormat); ME_StreamOutText(editor, nStart, nTo - nStart, dwFormat);

View file

@ -139,6 +139,9 @@ extern "C" {
#define SFF_PERSISTVIEWSCALE 0x2000 #define SFF_PERSISTVIEWSCALE 0x2000
#define SFF_PLAINRTF 0x4000 #define SFF_PLAINRTF 0x4000
#define SFF_SELECTION 0x8000 #define SFF_SELECTION 0x8000
#define ST_DEFAULT 0x00000000
#define ST_KEEPUNDO 0x00000001
#define ST_SELECTION 0x00000002
#define WB_CLASSIFY 3 #define WB_CLASSIFY 3
#define WB_MOVEWORDLEFT 4 #define WB_MOVEWORDLEFT 4
#define WB_MOVEWORDRIGHT 5 #define WB_MOVEWORDRIGHT 5
@ -225,6 +228,8 @@ extern "C" {
#define EM_FINDTEXTW (WM_USER + 123) #define EM_FINDTEXTW (WM_USER + 123)
#define EM_FINDTEXTEXW (WM_USER + 124) #define EM_FINDTEXTEXW (WM_USER + 124)
#define EM_RECONVERSION (WM_USER + 125) #define EM_RECONVERSION (WM_USER + 125)
#define EM_SETIMEMODEBIAS (WM_USER + 126)
#define EM_GETIMEMODEBIAS (WM_USER + 127)
#define EM_SETBIDIOPTIONS (WM_USER + 200) #define EM_SETBIDIOPTIONS (WM_USER + 200)
#define EM_GETBIDIOPTIONS (WM_USER + 201) #define EM_GETBIDIOPTIONS (WM_USER + 201)
#define EM_SETTYPOGRAPHYOPTIONS (WM_USER+202) #define EM_SETTYPOGRAPHYOPTIONS (WM_USER+202)
@ -510,6 +515,10 @@ typedef struct _gettextex {
LPCSTR lpDefaultChar; LPCSTR lpDefaultChar;
LPBOOL lpUsedDefaultChar; LPBOOL lpUsedDefaultChar;
} GETTEXTEX; } GETTEXTEX;
typedef struct _settextex {
DWORD flags;
UINT codepage;
} SETTEXTEX;
typedef LONG (*EDITWORDBREAKPROCEX)(char*,LONG,BYTE,INT); typedef LONG (*EDITWORDBREAKPROCEX)(char*,LONG,BYTE,INT);
/* Defines for EM_SETTYPOGRAPHYOPTIONS */ /* Defines for EM_SETTYPOGRAPHYOPTIONS */
#define TO_ADVANCEDTYPOGRAPHY 1 #define TO_ADVANCEDTYPOGRAPHY 1