Sync to Wine-20050725:
authorGé van Geldorp <ge@gse.nl>
Fri, 12 Aug 2005 17:41:40 +0000 (17:41 +0000)
committerGé van Geldorp <ge@gse.nl>
Fri, 12 Aug 2005 17:41:40 +0000 (17:41 +0000)
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

12 files changed:
reactos/lib/riched20/caret.c
reactos/lib/riched20/editor.c
reactos/lib/riched20/editor.h
reactos/lib/riched20/editstr.h
reactos/lib/riched20/paint.c
reactos/lib/riched20/para.c
reactos/lib/riched20/row.c
reactos/lib/riched20/run.c
reactos/lib/riched20/style.c
reactos/lib/riched20/wrap.c
reactos/lib/riched20/writer.c
reactos/w32api/include/richedit.h

index 24b3758..f1c87db 100644 (file)
@@ -192,6 +192,8 @@ void ME_InternalDeleteText(ME_TextEditor *editor, int nOfs,
       /* ME_SkipAndPropagateCharOffset(p->pRun, shift); */
       ME_CheckCharOffsets(editor);
       nChars--;
       /* ME_SkipAndPropagateCharOffset(p->pRun, shift); */
       ME_CheckCharOffsets(editor);
       nChars--;
+      if (editor->bEmulateVersion10 && nChars)
+        nChars--;
       continue;
     }
     else
       continue;
     }
     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) {
     p->nOffset = ME_StrRelPos2(p->pRun->member.run.strText, p->nOffset, -1);
 {
   if (p->nOffset) {
     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);
-  if (new_ofs<p->pRun->member.run.strText->nLen) {
-    p->nOffset = new_ofs;
-  }
-  else
+  ME_DisplayItem *pRun;
+  
+  if (!(p->pRun->member.run.nFlags & MERF_ENDPARA))
   {
   {
-    ME_DisplayItem *pRun = ME_FindItemFwd(p->pRun, diRun);
-    if (pRun) {
-      p->pRun = pRun;
-      assert(p->pRun->type == diRun);
-      p->nOffset = 0;
+    int new_ofs = ME_StrRelPos2(p->pRun->member.run.strText, p->nOffset, 1);
+    
+    if (new_ofs<p->pRun->member.run.strText->nLen)
+    {
+      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 *pItem, *pItem2;
 {
   ME_DisplayItem *pRun = pCursor->pRun;
   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 *pItem;
 {
   ME_DisplayItem *pRun = pCursor->pRun;
   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 *pLast, *p;
 {
   ME_DisplayItem *pRun = pCursor->pRun;
   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
    normal range (ie. sets it to (doclength-screenheight)). */
 
    In such a situation, clicking the scrollbar restores its position back to the
    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 *pLast, *p;
 {
   ME_DisplayItem *pRun = pCursor->pRun;
   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);
   if (pRow) {
 {
   ME_DisplayItem *pRow = ME_FindItemBack(pCursor->pRun, diStartRow);
   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);
   if (pRow) {
 {
   ME_DisplayItem *pRow = ME_FindItemBack(pCursor->pRun, diTextStart);
   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);
   assert(p);
 {
   ME_DisplayItem *p = ME_FindItemFwd(pCursor->pRun, diTextEnd);
   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)) {
     ME_EnsureVisible(editor, editor->pCursors[0].pRun); 
 {
   if (ME_UpdateSelection(editor, pTempCursor)) {
     ME_EnsureVisible(editor, editor->pCursors[0].pRun); 
index 0e4d2b7..8339b12 100644 (file)
   + EM_EMPTYUNDOBUFFER
   + EM_EXGETSEL
   - EM_EXLIMITTEXT
   + EM_EMPTYUNDOBUFFER
   + EM_EXGETSEL
   - EM_EXLIMITTEXT
-  - EM_EXLINEFROMCHAR
+  + EM_EXLINEFROMCHAR
   + EM_EXSETSEL
   + EM_EXSETSEL
-  - EM_FINDTEXT
-  - EM_FINDTEXTEX
+  + EM_FINDTEXT (only FR_DOWN flag implemented)
+  + EM_FINDTEXTEX (only FR_DOWN flag implemented)
   - EM_FINDWORDBREAK
   - EM_FMTLINES
   - EM_FORMATRANGE
   - EM_FINDWORDBREAK
   - EM_FMTLINES
   - EM_FORMATRANGE
@@ -51,7 +51,7 @@
   - EM_GETLANGOPTIONS 2.0
   - EM_GETLIMITTEXT
   - EM_GETLINE        
   - EM_GETLANGOPTIONS 2.0
   - EM_GETLIMITTEXT
   - EM_GETLINE        
-  - EM_GETLINECOUNT   returns number of rows, not of paragraphs
+  + EM_GETLINECOUNT   returns number of rows, not of paragraphs
   + EM_GETMODIFY
   - EM_GETOLEINTERFACE
   - EM_GETOPTIONS
   + EM_GETMODIFY
   - EM_GETOLEINTERFACE
   - EM_GETOPTIONS
   - EM_GETWORDBREAKPROC
   - EM_GETWORDBREAKPROCEX
   - EM_GETWORDWRAPMODE 1.0asian
   - EM_GETWORDBREAKPROC
   - EM_GETWORDBREAKPROCEX
   - EM_GETWORDWRAPMODE 1.0asian
-  - EM_SETZOOM 3.0
+  + EM_GETZOOM 3.0
   - EM_HIDESELECTION
   - EM_LIMITTEXT
   - EM_HIDESELECTION
   - EM_LIMITTEXT
-  - EM_LINEFROMCHAR
-  - EM_LINEINDEX
-  - EM_LINELENGTH
+  + EM_LINEFROMCHAR
+  + EM_LINEINDEX
+  + EM_LINELENGTH
   + EM_LINESCROLL
   - EM_PASTESPECIAL
   - EM_POSFROMCHARS
   + EM_LINESCROLL
   - EM_PASTESPECIAL
   - EM_POSFROMCHARS
   - EM_SETSCROLLPOS 3.0
   - EM_SETTABSTOPS 3.0
   - EM_SETTARGETDEVICE
   - EM_SETSCROLLPOS 3.0
   - EM_SETTABSTOPS 3.0
   - EM_SETTARGETDEVICE
-  - EM_SETTEXTEX 3.0
+  + EM_SETTEXTEX 3.0 (unicode only, no rich text insertion handling, proper style?)
   - EM_SETTEXTMODE 2.0
   - EM_SETTYPOGRAPHYOPTIONS 3.0
   - EM_SETUNDOLIMIT 2.0
   - EM_SETWORDBREAKPROC
   - EM_SETWORDBREAKPROCEX
   - EM_SETWORDWRAPMODE 1.0asian
   - EM_SETTEXTMODE 2.0
   - EM_SETTYPOGRAPHYOPTIONS 3.0
   - EM_SETUNDOLIMIT 2.0
   - EM_SETWORDBREAKPROC
   - EM_SETWORDBREAKPROCEX
   - EM_SETWORDWRAPMODE 1.0asian
-  - EM_SETZOOM 3.0
+  + EM_SETZOOM 3.0
   - EM_SHOWSCROLLBAR 2.0
   - EM_STOPGROUPTYPING 2.0
   - EM_SHOWSCROLLBAR 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_UNDO
   + WM_CHAR
   + EM_STREAMOUT
   + EM_UNDO
   + WM_CHAR
  * - 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)
  * - EM_GETCHARFORMAT with SCF_SELECTION may not behave 100% like in original (but very close)
  * - 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)
  * - 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:
  * - EN_UPDATE/EN_CHANGE are handled very incorrectly (should be OK now)
  *
  * Bugs that are probably fixed, but not so easy to verify:
  * - EN_UPDATE/EN_CHANGE are handled very incorrectly (should be OK now)
  */
 
 #include "editor.h"
  */
 
 #include "editor.h"
+#include "commdlg.h"
 #include "ole2.h"
 #include "richole.h"
 #include "winreg.h"
 #include "ole2.h"
 #include "richole.h"
 #include "winreg.h"
@@ -231,7 +235,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(richedit);
 int me_debug = 0;
 HANDLE me_heap = NULL;
 
 int me_debug = 0;
 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;
   fmt.cbSize = sizeof(fmt);
 {
   CHARFORMAT2W 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,
    the same tags mean different things in different contexts */
 
 /* 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 */
-void ME_RTFParAttrHook(RTF_Info *info)
+static void ME_RTFParAttrHook(RTF_Info *info)
 {
   PARAFORMAT2 fmt;
   fmt.cbSize = sizeof(fmt);
 {
   PARAFORMAT2 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)
   {
     case rtfGroup:
   switch(info->rtfClass)
   {
     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 *ed = ALLOC_OBJ(ME_TextEditor);
   HDC hDC;
   int i;
   ed->hWnd = hWnd;
 ME_TextEditor *ME_MakeEditor(HWND hWnd) {
   ME_TextEditor *ed = ALLOC_OBJ(ME_TextEditor);
   HDC hDC;
   int i;
   ed->hWnd = hWnd;
+  ed->bEmulateVersion10 = FALSE;
   ed->pBuffer = ME_MakeText();
   hDC = GetDC(hWnd);
   ME_MakeFirstParagraph(hDC, ed->pBuffer);
   ed->pBuffer = ME_MakeText();
   hDC = GetDC(hWnd);
   ME_MakeFirstParagraph(hDC, ed->pBuffer);
@@ -679,6 +747,7 @@ ME_TextEditor *ME_MakeEditor(HWND hWnd) {
   ed->nParagraphs = 1;
   ed->nLastSelStart = ed->nLastSelEnd = 0;
   ed->nScrollPosY = 0;
   ed->nParagraphs = 1;
   ed->nLastSelStart = ed->nLastSelEnd = 0;
   ed->nScrollPosY = 0;
+  ed->nZoomNumerator = ed->nZoomDenominator = 0;
   for (i=0; i<HFONT_CACHE_SIZE; i++)
   {
     ed->pFontCache[i].nRefs = 0;
   for (i=0; i<HFONT_CACHE_SIZE; i++)
   {
     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)
 {
   ME_DisplayItem *pFirst = editor->pBuffer->pFirst;
 void ME_DestroyEditor(ME_TextEditor *editor)
 {
   ME_DisplayItem *pFirst = editor->pBuffer->pFirst;
@@ -808,6 +878,140 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
     FIXME(#e ": stub\n"); \
     return DefWindowProcW(hWnd, msg, wParam, lParam);
 
     FIXME(#e ": stub\n"); \
     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;
   SCROLLINFO si;
   ME_TextEditor *editor = (ME_TextEditor *)GetWindowLongW(hWnd, 0);
   PAINTSTRUCT ps;
   SCROLLINFO si;
   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) {
   
   UNSUPPORTED_MSG(EM_AUTOURLDETECT)
   UNSUPPORTED_MSG(EM_CHARFROMPOS)
   UNSUPPORTED_MSG(EM_DISPLAYBAND)
   UNSUPPORTED_MSG(EM_EXLIMITTEXT)
   switch(msg) {
   
   UNSUPPORTED_MSG(EM_AUTOURLDETECT)
   UNSUPPORTED_MSG(EM_CHARFROMPOS)
   UNSUPPORTED_MSG(EM_DISPLAYBAND)
   UNSUPPORTED_MSG(EM_EXLIMITTEXT)
-  UNSUPPORTED_MSG(EM_EXLINEFROMCHAR)
-  UNSUPPORTED_MSG(EM_FINDTEXT)
-  UNSUPPORTED_MSG(EM_FINDTEXTEX)
   UNSUPPORTED_MSG(EM_FINDWORDBREAK)
   UNSUPPORTED_MSG(EM_FMTLINES)
   UNSUPPORTED_MSG(EM_FORMATRANGE)
   UNSUPPORTED_MSG(EM_FINDWORDBREAK)
   UNSUPPORTED_MSG(EM_FMTLINES)
   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_GETLIMITTEXT)
   UNSUPPORTED_MSG(EM_GETLINE)
   UNSUPPORTED_MSG(EM_GETLANGOPTIONS)
   UNSUPPORTED_MSG(EM_GETLIMITTEXT)
   UNSUPPORTED_MSG(EM_GETLINE)
-  UNSUPPORTED_MSG(EM_GETLINECOUNT)
   /* UNSUPPORTED_MSG(EM_GETOLEINTERFACE) separate stub */
   UNSUPPORTED_MSG(EM_GETOPTIONS)
   UNSUPPORTED_MSG(EM_GETPASSWORDCHAR)
   UNSUPPORTED_MSG(EM_GETRECT)
   UNSUPPORTED_MSG(EM_GETREDONAME)
   UNSUPPORTED_MSG(EM_GETSCROLLPOS)
   /* UNSUPPORTED_MSG(EM_GETOLEINTERFACE) separate stub */
   UNSUPPORTED_MSG(EM_GETOPTIONS)
   UNSUPPORTED_MSG(EM_GETPASSWORDCHAR)
   UNSUPPORTED_MSG(EM_GETRECT)
   UNSUPPORTED_MSG(EM_GETREDONAME)
   UNSUPPORTED_MSG(EM_GETSCROLLPOS)
-  UNSUPPORTED_MSG(EM_GETTEXTEX)
   UNSUPPORTED_MSG(EM_GETTEXTMODE)
   UNSUPPORTED_MSG(EM_GETTYPOGRAPHYOPTIONS)
   UNSUPPORTED_MSG(EM_GETUNDONAME)
   UNSUPPORTED_MSG(EM_GETWORDBREAKPROC)
   UNSUPPORTED_MSG(EM_GETWORDBREAKPROCEX)
   UNSUPPORTED_MSG(EM_GETTEXTMODE)
   UNSUPPORTED_MSG(EM_GETTYPOGRAPHYOPTIONS)
   UNSUPPORTED_MSG(EM_GETUNDONAME)
   UNSUPPORTED_MSG(EM_GETWORDBREAKPROC)
   UNSUPPORTED_MSG(EM_GETWORDBREAKPROCEX)
-  UNSUPPORTED_MSG(EM_GETZOOM)
   UNSUPPORTED_MSG(EM_HIDESELECTION)
   UNSUPPORTED_MSG(EM_LIMITTEXT) /* also known as EM_SETLIMITTEXT */
   UNSUPPORTED_MSG(EM_HIDESELECTION)
   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_POSFROMCHARS) missing in Wine headers */
   UNSUPPORTED_MSG(EM_REQUESTRESIZE)
   UNSUPPORTED_MSG(EM_PASTESPECIAL)
 /*  UNSUPPORTED_MSG(EM_POSFROMCHARS) missing in Wine headers */
   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_SETTABSTOPS)
   UNSUPPORTED_MSG(EM_SETTARGETDEVICE)
   UNSUPPORTED_MSG(EM_SETSCROLLPOS)
   UNSUPPORTED_MSG(EM_SETTABSTOPS)
   UNSUPPORTED_MSG(EM_SETTARGETDEVICE)
-  UNSUPPORTED_MSG(EM_SETTEXTEX)
   UNSUPPORTED_MSG(EM_SETTEXTMODE)
   UNSUPPORTED_MSG(EM_SETTYPOGRAPHYOPTIONS)
   UNSUPPORTED_MSG(EM_SETUNDOLIMIT)
   UNSUPPORTED_MSG(EM_SETWORDBREAKPROC)
   UNSUPPORTED_MSG(EM_SETWORDBREAKPROCEX)
   UNSUPPORTED_MSG(EM_SHOWSCROLLBAR)
   UNSUPPORTED_MSG(EM_SETTEXTMODE)
   UNSUPPORTED_MSG(EM_SETTYPOGRAPHYOPTIONS)
   UNSUPPORTED_MSG(EM_SETUNDOLIMIT)
   UNSUPPORTED_MSG(EM_SETWORDBREAKPROC)
   UNSUPPORTED_MSG(EM_SETWORDBREAKPROCEX)
   UNSUPPORTED_MSG(EM_SHOWSCROLLBAR)
-  UNSUPPORTED_MSG(EM_SETZOOM)
   UNSUPPORTED_MSG(WM_SETFONT)
   UNSUPPORTED_MSG(WM_STYLECHANGING)
   UNSUPPORTED_MSG(WM_STYLECHANGED)
   UNSUPPORTED_MSG(WM_SETFONT)
   UNSUPPORTED_MSG(WM_STYLECHANGING)
   UNSUPPORTED_MSG(WM_STYLECHANGED)
@@ -905,6 +1100,7 @@ LRESULT WINAPI RichEditANSIWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lP
   case WM_NCCREATE:
   {
     CREATESTRUCTW *pcs = (CREATESTRUCTW *)lParam;
   case WM_NCCREATE:
   {
     CREATESTRUCTW *pcs = (CREATESTRUCTW *)lParam;
+    TRACE("WM_NCCREATE: style 0x%08lx\n", pcs->style);
     editor = ME_MakeEditor(hWnd);
     SetWindowLongW(hWnd, 0, (long)editor);
     pcs = 0; /* ignore */
     editor = ME_MakeEditor(hWnd);
     SetWindowLongW(hWnd, 0, (long)editor);
     pcs = 0; /* ignore */
@@ -928,6 +1124,7 @@ LRESULT WINAPI RichEditANSIWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lP
   {
     CHARRANGE *pRange = (CHARRANGE *)lParam;
     ME_GetSelection(editor, (int *)&pRange->cpMin, (int *)&pRange->cpMax);
   {
     CHARRANGE *pRange = (CHARRANGE *)lParam;
     ME_GetSelection(editor, (int *)&pRange->cpMin, (int *)&pRange->cpMax);
+    TRACE("EM_EXGETSEL = (%ld,%ld)\n", pRange->cpMin, pRange->cpMax);
     return 0;
   }
   case EM_CANUNDO:
     return 0;
   }
   case EM_CANUNDO:
@@ -950,12 +1147,44 @@ LRESULT WINAPI RichEditANSIWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lP
   case EM_EXSETSEL:
   {
     CHARRANGE *pRange = (CHARRANGE *)lParam;
   case EM_EXSETSEL:
   {
     CHARRANGE *pRange = (CHARRANGE *)lParam;
+    TRACE("EM_EXSETSEL (%ld,%ld)\n", pRange->cpMin, pRange->cpMax);
     ME_SetSelection(editor, pRange->cpMin, pRange->cpMax);
     /* FIXME optimize */
     ME_Repaint(editor);
     ME_SendSelChange(editor);
     return 0;
   }
     ME_SetSelection(editor, pRange->cpMin, pRange->cpMax);
     /* FIXME optimize */
     ME_Repaint(editor);
     ME_SendSelChange(editor);
     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:
   {
     LRESULT lColor = ME_GetBackColor(editor);
   case EM_SETBKGNDCOLOR:
   {
     LRESULT lColor = ME_GetBackColor(editor);
@@ -1002,7 +1231,7 @@ LRESULT WINAPI RichEditANSIWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lP
     if (!wParam)
       ME_SetDefaultCharFormat(editor, p);
     else if (wParam == (SCF_WORD | SCF_SELECTION))
     if (!wParam)
       ME_SetDefaultCharFormat(editor, p);
     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)
       ME_SetCharFormat(editor, 0, ME_GetTextLength(editor), p);
     else {
     else if (wParam == SCF_ALL)
       ME_SetCharFormat(editor, 0, ME_GetTextLength(editor), p);
     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);
     if (!wParam)
       ME_GetDefaultCharFormat(editor, &tmp);
     else
       ME_GetSelectionCharFormat(editor, &tmp);
     tmp.cbSize = sizeof(tmp);
     if (!wParam)
       ME_GetDefaultCharFormat(editor, &tmp);
     else
       ME_GetSelectionCharFormat(editor, &tmp);
-    ME_CopyToCFAny((CHARFORMAT2W *)lParam, &tmp);
-    return 0;
+    ME_CopyToCFAny(dst, &tmp);
+    return tmp.dwMask;
   }
   case EM_SETPARAFORMAT:
     ME_SetSelectionParaFormat(editor, (PARAFORMAT2 *)lParam);
   }
   case EM_SETPARAFORMAT:
     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! */
-    ME_InsertTextFromCursor(editor, 0, wszText, -1, editor->pBuffer->pDefaultStyle);
-    ME_EndToUnicode(hWnd, wszText);
+    if (lParam)
+    {
+      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_EmptyUndoStack(editor);
     ME_UpdateRepaint(editor);
     ME_CommitUndo(editor);
     ME_EmptyUndoStack(editor);
     ME_UpdateRepaint(editor);
@@ -1184,6 +1427,29 @@ LRESULT WINAPI RichEditANSIWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lP
     tr.lpstrText = (WCHAR *)lParam;
     return RichEditANSIWndProc(hWnd, EM_GETTEXTRANGE, 0, (LPARAM)&tr);
   }
     tr.lpstrText = (WCHAR *)lParam;
     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:
   {
     int from, to;
   case EM_GETSELTEXT:
   {
     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:
     ME_CommitUndo(editor);
     ME_WrapMarkedParagraphs(editor);
   case WM_CREATE:
     ME_CommitUndo(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_WrapMarkedParagraphs(editor);
-    ME_UpdateScrollBar(editor);
-    ME_Repaint(editor);
+    ME_RewrapRepaint(editor);
     return DefWindowProcW(hWnd, msg, wParam, lParam);
   }
   case EM_GETOLEINTERFACE:
     return DefWindowProcW(hWnd, msg, wParam, lParam);
   }
   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)
  */
 LRESULT WINAPI RichEdit10ANSIWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
 {
 /******************************************************************
  *        RichEdit10ANSIWndProc (RICHED20.9)
  */
 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)
index a0eab82..9f5f6bd 100644 (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_RowEnd(ME_DisplayItem *item);
 void ME_RenumberParagraphs(ME_DisplayItem *item); /* TODO */
 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);
 
 /* run.c */
 ME_DisplayItem *ME_MakeRun(ME_Style *s, ME_String *strData, int nFlags);
@@ -189,6 +191,7 @@ void ME_MarkAllForWrapping(ME_TextEditor *editor);
 /* paint.c */
 void ME_PaintContent(ME_TextEditor *editor, HDC hDC, BOOL bOnlyNew, RECT *rcUpdate);
 void ME_Repaint(ME_TextEditor *editor);
 /* paint.c */
 void ME_PaintContent(ME_TextEditor *editor, HDC hDC, BOOL bOnlyNew, RECT *rcUpdate);
 void ME_Repaint(ME_TextEditor *editor);
+void ME_RewrapRepaint(ME_TextEditor *editor);
 void ME_UpdateRepaint(ME_TextEditor *editor);
 void ME_DrawParagraph(ME_Context *c, ME_DisplayItem *paragraph);
 void ME_UpdateScrollBar(ME_TextEditor *editor);
 void ME_UpdateRepaint(ME_TextEditor *editor);
 void ME_DrawParagraph(ME_Context *c, ME_DisplayItem *paragraph);
 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);
 COLORREF ME_GetBackColor(ME_TextEditor *editor);
 void ME_Scroll(ME_TextEditor *editor, int cx, int cy);
 void ME_EnsureVisible(ME_TextEditor *editor, ME_DisplayItem *pRun);
 COLORREF ME_GetBackColor(ME_TextEditor *editor);
 void ME_Scroll(ME_TextEditor *editor, int cx, int cy);
+BOOL ME_SetZoom(ME_TextEditor *editor, int numerator, int denominator);
 
 /* richole.c */
 extern LRESULT CreateIRichEditOle(LPVOID *);
 
 /* richole.c */
 extern LRESULT CreateIRichEditOle(LPVOID *);
index 00329fb..b6df587 100644 (file)
@@ -147,6 +147,7 @@ typedef struct tagME_Paragraph
   int nFlags;
   int nYPos, nHeight;
   int nLastPaintYPos, nLastPaintHeight;
   int nFlags;
   int nYPos, nHeight;
   int nLastPaintYPos, nLastPaintHeight;
+  int nRows;
   struct tagME_DisplayItem *prev_para, *next_para, *document;
 } ME_Paragraph;
 
   struct tagME_DisplayItem *prev_para, *next_para, *document;
 } ME_Paragraph;
 
@@ -246,6 +247,7 @@ typedef struct tagME_FontCacheItem
 typedef struct tagME_TextEditor
 {
   HWND hWnd;
 typedef struct tagME_TextEditor
 {
   HWND hWnd;
+  BOOL bEmulateVersion10;
   BOOL bCaretShown;
   ME_TextBuffer *pBuffer;
   ME_Cursor *pCursors;
   BOOL bCaretShown;
   ME_TextBuffer *pBuffer;
   ME_Cursor *pCursors;
@@ -267,6 +269,7 @@ typedef struct tagME_TextEditor
   ME_OutStream *pStream;
   BOOL bScrollX, bScrollY;
   int nScrollPosY;
   ME_OutStream *pStream;
   BOOL bScrollX, bScrollY;
   int nScrollPosY;
+  int nZoomNumerator, nZoomDenominator;
 } ME_TextEditor;
 
 typedef struct tagME_Context
 } ME_TextEditor;
 
 typedef struct tagME_Context
index d02bd25..7b734af 100644 (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 *p3;  
                            ME_DisplayItem *p2, int nFlags)
 {
   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_CursorFromCharOfs(editor, from, &c1);
 {
   ME_Cursor c1, c2;
   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) {
   HDC hDC = c->hDC;
   HGDIOBJ hOldFont;
   ME_Style *s, int *width, int nSelFrom, int nSelTo, int ymin, int cy) {
   HDC hDC = c->hDC;
   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 (yTwipsOffset)
     if (s->fmt.dwEffects & CFE_SUBSCRIPT) yTwipsOffset = -s->fmt.yHeight/12;
   }
   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);
   if (width) {
     SIZE sz;
   ExtTextOutW(hDC, x, y-yOffset, 0, NULL, szText, nChars, NULL);
   if (width) {
     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);
   HGDIOBJ hFont = SelectObject(hDC, GetStockObject(DEFAULT_GUI_FONT));
   COLORREF color = SetTextColor(hDC, RGB(128,128,128));
   int align = SetTextAlign(hDC, TA_LEFT|TA_TOP);
   HGDIOBJ hFont = SelectObject(hDC, GetStockObject(DEFAULT_GUI_FONT));
   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;
   int runofs = run->nCharOfs+para->nCharOfs;
   
   ME_Run *run = &rundi->member.run;
   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;
+}
index 4b1947c..a6a548f 100644 (file)
@@ -101,6 +101,7 @@ ME_DisplayItem *ME_SplitParagraph(ME_TextEditor *editor, ME_DisplayItem *run, ME
   ME_UndoItem *undo = NULL;
   int ofs;
   ME_DisplayItem *pp;
   ME_UndoItem *undo = NULL;
   int ofs;
   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);
   }
   new_para->member.para.nCharOfs = ME_GetParagraph(run)->member.para.nCharOfs+ofs;
     pp = ME_FindItemFwd(pp, diRunOrParagraphOrEnd);
   }
   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) */
   /* FIXME initialize format style and call ME_SetParaFormat blah blah */
   
   new_para->member.para.nFlags = MEPF_REWRAP; /* FIXME copy flags (if applicable) */
   /* 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;
   
   /* we've added the end run, so we need to modify nCharOfs in the next paragraphs */
   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 */
-  ME_PropagateCharOffset(next_para, 1);
+  ME_PropagateCharOffset(next_para, end_len);
   editor->nParagraphs++;
   
   return new_para;
   editor->nParagraphs++;
   
   return new_para;
@@ -161,6 +162,7 @@ ME_DisplayItem *ME_JoinParagraphs(ME_TextEditor *editor, ME_DisplayItem *tp)
   ME_DisplayItem *pNext, *pFirstRunInNext, *pRun, *pTmp;
   int i, shift;
   ME_UndoItem *undo = NULL;
   ME_DisplayItem *pNext, *pFirstRunInNext, *pRun, *pTmp;
   int i, shift;
   ME_UndoItem *undo = NULL;
+  int end_len = (editor->bEmulateVersion10 ? 2 : 1);
 
   assert(tp->type == diParagraph);
   assert(tp->member.para.next_para);
 
   assert(tp->type == diParagraph);
   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 */
     CHARFORMAT2W fmt;
     ME_InitCharFormat2W(&fmt);
     /* 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-1, 1, &fmt);
+    ME_SetCharFormat(editor, pNext->member.para.nCharOfs - end_len, end_len, &fmt);
   }
   undo = ME_AddUndoItem(editor, diUndoSplitParagraph, NULL);
   if (undo)
   {
   }
   undo = ME_AddUndoItem(editor, diUndoSplitParagraph, NULL);
   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));
     CopyMemory(undo->di.member.para.pFmt, pNext->member.para.pFmt, sizeof(PARAFORMAT2));
   }
   
     assert(pNext->member.para.pFmt->cbSize == 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);
   pFirstRunInNext = ME_FindItemFwd(pNext, diRunOrParagraph);
   
   pRun = ME_FindItemBack(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_DestroyDisplayItem(pNext);
 
   ME_Remove(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);
   
index 1e4e208..b803ed2 100644 (file)
@@ -82,3 +82,49 @@ ME_DisplayItem *ME_RowEnd(ME_DisplayItem *item) {
   if (!item2) return NULL;
   return ME_FindItemBack(item, diRun);
 }
   if (!item2) return NULL;
   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;
+}
index 2c8edb2..eab7401 100644 (file)
@@ -97,7 +97,10 @@ void ME_CheckCharOffsets(ME_TextEditor *editor)
           p->member.run.nFlags,
           p->member.run.style->fmt.dwMask & p->member.run.style->fmt.dwEffects);
         assert(ofs == p->member.run.nCharOfs);
           p->member.run.nFlags,
           p->member.run.style->fmt.dwMask & p->member.run.style->fmt.dwEffects);
         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;
       default:
         assert(0);
         break;
       default:
         assert(0);
@@ -639,9 +642,6 @@ void ME_GetCharFormat(ME_TextEditor *editor, int nFrom, int nTo, CHARFORMAT2W *p
   int nOffset, nOffset2;
   CHARFORMAT2W tmp;
 
   int nOffset, nOffset2;
   CHARFORMAT2W tmp;
 
-  if (nTo>nFrom) /* selection consists of chars from nFrom up to nTo-1 */
-    nTo--;
-
   ME_RunOfsFromCharOfs(editor, nFrom, &run, &nOffset);
   if (nFrom == nTo) /* special case - if selection is empty, take previous char's formatting */
   {
   ME_RunOfsFromCharOfs(editor, nFrom, &run, &nOffset);
   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);
     return;
   }
     ME_GetRunCharFormat(editor, run, pFmt);
     return;
   }
+  
+  if (nTo>nFrom) /* selection consists of chars from nFrom up to nTo-1 */
+    nTo--;
   ME_RunOfsFromCharOfs(editor, nTo, &run_end, &nOffset2);
 
   ME_GetRunCharFormat(editor, run, pFmt);
   ME_RunOfsFromCharOfs(editor, nTo, &run_end, &nOffset2);
 
   ME_GetRunCharFormat(editor, run, pFmt);
index 3bc8b9e..3cc543a 100644 (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;
   rx = GetDeviceCaps(hDC, LOGPIXELSX);
   ry = GetDeviceCaps(hDC, LOGPIXELSY);
   ZeroMemory(lf, sizeof(LOGFONTW));
   lstrcpyW(lf->lfFaceName, s->fmt.szFaceName);
 {
   int rx, ry;
   rx = GetDeviceCaps(hDC, LOGPIXELSX);
   ry = GetDeviceCaps(hDC, LOGPIXELSY);
   ZeroMemory(lf, sizeof(LOGFONTW));
   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;
   if (s->fmt.dwEffects & s->fmt.dwMask & CFM_BOLD)
     lf->lfWeight = 700;
   lf->lfWeight = 400;
   if (s->fmt.dwEffects & s->fmt.dwMask & CFM_BOLD)
     lf->lfWeight = 700;
@@ -294,7 +303,7 @@ HFONT ME_SelectStyleFont(ME_TextEditor *editor, HDC hDC, ME_Style *s)
   assert(hDC);
   assert(s);
   
   assert(hDC);
   assert(s);
   
-  ME_LogFontFromStyle(hDC, &lf, s);
+  ME_LogFontFromStyle(hDC, &lf, s, editor->nZoomNumerator, editor->nZoomDenominator);
   
   for (i=0; i<HFONT_CACHE_SIZE; i++)
     editor->pFontCache[i].nAge++;
   
   for (i=0; i<HFONT_CACHE_SIZE; i++)
     editor->pFontCache[i].nAge++;
index d48da58..2da74a1 100644 (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->bOverflown = FALSE;
 {
   wc->pRowStart = NULL;
   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)
     ME_InsertRowStart(wc, p->next);
 {
   if (wc->pRowStart)
     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;
   int j;
 {
   ME_DisplayItem *pp, *piter = p;
   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;
   int i, idesp, len;
 {
   ME_DisplayItem *piter = p, *pp;
   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_Run *run;
 {
   ME_DisplayItem *pp;
   ME_Run *run;
@@ -375,12 +375,15 @@ void ME_WrapTextParagraph(ME_Context *c, ME_DisplayItem *tp) {
   ME_WrapEndParagraph(&wc, p);
   tp->member.para.nFlags &= ~MEPF_REWRAP;
   tp->member.para.nHeight = wc.pt.y;
   ME_WrapEndParagraph(&wc, p);
   tp->member.para.nFlags &= ~MEPF_REWRAP;
   tp->member.para.nHeight = wc.pt.y;
+  tp->member.para.nRows = wc.nRow;
 }
 
 
 void ME_PrepareParagraphForWrapping(ME_Context *c, ME_DisplayItem *tp) {
   ME_DisplayItem *p;
 }
 
 
 void ME_PrepareParagraphForWrapping(ME_Context *c, ME_DisplayItem *tp) {
   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) {
     switch(p->type) {
       case diStartRow:
   for (p = tp->next; p!=tp->member.para.next_para; p = p->next) {
     switch(p->type) {
       case diStartRow:
index 176c161..a6aba95 100644 (file)
@@ -33,6 +33,7 @@ ME_StreamOutInit(ME_TextEditor *editor, EDITSTREAM *stream)
 {
   editor->pStream = ALLOC_OBJ(ME_OutStream);
   editor->pStream->stream = stream;
 {
   editor->pStream = ALLOC_OBJ(ME_OutStream);
   editor->pStream->stream = stream;
+  editor->pStream->stream->dwError = 0;
   editor->pStream->pos = 0;
   editor->pStream->written = 0;
   editor->pStream->nFontTblLen = 0;
   editor->pStream->pos = 0;
   editor->pStream->written = 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 */
   int len;
 {
   char string[STREAMOUT_BUFFER_SIZE]; /* This is going to be enough */
   int len;
@@ -125,7 +126,7 @@ ME_StreamOutPrint(ME_TextEditor *editor, char *format, ...)
 static BOOL
 ME_StreamOutRTFHeader(ME_TextEditor *editor, int dwFormat)
 {
 static BOOL
 ME_StreamOutRTFHeader(ME_TextEditor *editor, int dwFormat)
 {
-  char *cCharSet = NULL;
+  const char *cCharSet = NULL;
   UINT nCodePage;
   LANGID language;
   BOOL success;
   UINT nCodePage;
   LANGID language;
   BOOL success;
@@ -567,7 +568,7 @@ ME_StreamOutRTFText(ME_TextEditor *editor, WCHAR *text, LONG nChars)
 {
   char buffer[STREAMOUT_BUFFER_SIZE];
   int pos = 0;
 {
   char buffer[STREAMOUT_BUFFER_SIZE];
   int pos = 0;
-  int fit, i;
+  int fit, nBytes, i;
 
   if (nChars == -1)
     nChars = lstrlenW(text);
 
   if (nChars == -1)
     nChars = lstrlenW(text);
@@ -577,18 +578,18 @@ ME_StreamOutRTFText(ME_TextEditor *editor, WCHAR *text, LONG nChars)
     if (editor->pStream->nDefaultCodePage == CP_UTF8) {
       /* 6 is the maximum character length in UTF-8 */
       fit = min(nChars, STREAMOUT_BUFFER_SIZE / 6);
     if (editor->pStream->nDefaultCodePage == CP_UTF8) {
       /* 6 is the maximum character length in UTF-8 */
       fit = min(nChars, STREAMOUT_BUFFER_SIZE / 6);
-      WideCharToMultiByte(CP_UTF8, 0, text, fit, buffer, STREAMOUT_BUFFER_SIZE,
-                          NULL, NULL);
+      nBytes = WideCharToMultiByte(CP_UTF8, 0, text, fit, buffer,
+                                   STREAMOUT_BUFFER_SIZE, NULL, NULL);
       nChars -= fit;
       text += fit;
       nChars -= fit;
       text += fit;
-      for (i = 0; buffer[i]; i++)
+      for (i = 0; i < nBytes; i++)
         if (buffer[i] == '{' || buffer[i] == '}' || buffer[i] == '\\') {
           if (!ME_StreamOutPrint(editor, "%.*s\\", i - pos, buffer + pos))
             return FALSE;
           pos = i;
         }
       if (!pos)
         if (buffer[i] == '{' || buffer[i] == '}' || buffer[i] == '\\') {
           if (!ME_StreamOutPrint(editor, "%.*s\\", i - pos, buffer + pos))
             return FALSE;
           pos = i;
         }
       if (!pos)
-        if (!ME_StreamOutPrint(editor, "%s", buffer + pos))
+        if (!ME_StreamOutMove(editor, buffer + pos, nBytes - pos))
           return FALSE;
       pos = 0;
     } else if (*text < 128) {
           return FALSE;
       pos = 0;
     } else if (*text < 128) {
@@ -599,7 +600,6 @@ ME_StreamOutRTFText(ME_TextEditor *editor, WCHAR *text, LONG nChars)
     } else {
       BOOL unknown = FALSE;
       BYTE letter[3];
     } else {
       BOOL unknown = FALSE;
       BYTE letter[3];
-      int nBytes, i;
       
       /* 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
       
       /* 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
@@ -759,11 +759,13 @@ ME_StreamOutText(ME_TextEditor *editor, int nStart, int nChars, DWORD dwFormat)
         }
         WideCharToMultiByte(nCodePage, 0, item->member.run.strText->szData + nStart,
                             nLen, buffer, nSize, NULL, NULL);
         }
         WideCharToMultiByte(nCodePage, 0, item->member.run.strText->szData + nStart,
                             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;
     item = ME_FindItemFwd(item, diRun);
   }
     nStart = 0;
     item = ME_FindItemFwd(item, diRun);
   }
@@ -791,7 +793,7 @@ ME_StreamOut(ME_TextEditor *editor, DWORD dwFormat, EDITSTREAM *stream)
     nTo = ME_GetTextLength(editor);
   TRACE("from %d to %d\n", nStart, nTo);
   
     nTo = ME_GetTextLength(editor);
   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);
   else if (dwFormat & SF_TEXT || dwFormat & SF_TEXTIZED)
     ME_StreamOutText(editor, nStart, nTo - nStart, dwFormat);
     ME_StreamOutRTF(editor, nStart, nTo - nStart, dwFormat);
   else if (dwFormat & SF_TEXT || dwFormat & SF_TEXTIZED)
     ME_StreamOutText(editor, nStart, nTo - nStart, dwFormat);
index 6d135a5..5a1a5fe 100644 (file)
@@ -139,6 +139,9 @@ extern "C" {
 #define SFF_PERSISTVIEWSCALE   0x2000
 #define SFF_PLAINRTF   0x4000
 #define SFF_SELECTION  0x8000
 #define SFF_PERSISTVIEWSCALE   0x2000
 #define SFF_PLAINRTF   0x4000
 #define SFF_SELECTION  0x8000
+#define ST_DEFAULT     0x00000000
+#define ST_KEEPUNDO    0x00000001
+#define ST_SELECTION   0x00000002
 #define WB_CLASSIFY    3
 #define WB_MOVEWORDLEFT        4
 #define WB_MOVEWORDRIGHT       5
 #define WB_CLASSIFY    3
 #define WB_MOVEWORDLEFT        4
 #define WB_MOVEWORDRIGHT       5
@@ -225,6 +228,8 @@ extern "C" {
 #define EM_FINDTEXTW   (WM_USER + 123)
 #define EM_FINDTEXTEXW (WM_USER + 124)
 #define EM_RECONVERSION        (WM_USER + 125)
 #define EM_FINDTEXTW   (WM_USER + 123)
 #define EM_FINDTEXTEXW (WM_USER + 124)
 #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_GETBIDIOPTIONS      (WM_USER + 201)
 #define EM_SETTYPOGRAPHYOPTIONS        (WM_USER+202)
 #define EM_SETBIDIOPTIONS      (WM_USER + 200)
 #define EM_GETBIDIOPTIONS      (WM_USER + 201)
 #define EM_SETTYPOGRAPHYOPTIONS        (WM_USER+202)
@@ -510,6 +515,10 @@ typedef struct _gettextex {
        LPCSTR lpDefaultChar;
        LPBOOL lpUsedDefaultChar;
 } GETTEXTEX;
        LPCSTR lpDefaultChar;
        LPBOOL lpUsedDefaultChar;
 } GETTEXTEX;
+typedef struct _settextex {
+    DWORD       flags;
+    UINT        codepage;
+} SETTEXTEX;
 typedef LONG (*EDITWORDBREAKPROCEX)(char*,LONG,BYTE,INT);
 /* Defines for EM_SETTYPOGRAPHYOPTIONS */
 #define        TO_ADVANCEDTYPOGRAPHY   1
 typedef LONG (*EDITWORDBREAKPROCEX)(char*,LONG,BYTE,INT);
 /* Defines for EM_SETTYPOGRAPHYOPTIONS */
 #define        TO_ADVANCEDTYPOGRAPHY   1