[RICHED20] Sync with Wine Staging 1.9.16. CORE-11866
authorAmine Khaldi <amine.khaldi@reactos.org>
Thu, 18 Aug 2016 10:40:37 +0000 (10:40 +0000)
committerAmine Khaldi <amine.khaldi@reactos.org>
Thu, 18 Aug 2016 10:40:37 +0000 (10:40 +0000)
svn path=/trunk/; revision=72305

reactos/dll/win32/riched20/caret.c
reactos/dll/win32/riched20/clipboard.c
reactos/dll/win32/riched20/editor.c
reactos/dll/win32/riched20/editor.h
reactos/dll/win32/riched20/list.c
reactos/dll/win32/riched20/paint.c
reactos/dll/win32/riched20/para.c
reactos/dll/win32/riched20/richole.c
reactos/dll/win32/riched20/writer.c
reactos/media/doc/README.WINE

index 177f303..170363a 100644 (file)
@@ -331,7 +331,7 @@ BOOL ME_InternalDeleteText(ME_TextEditor *editor, ME_Cursor *start,
     {
       /* We aren't deleting anything in this run, so we will go back to the
        * last run we are deleting text in. */
-      ME_PrevRun(&c.pPara, &c.pRun);
+      ME_PrevRun(&c.pPara, &c.pRun, TRUE);
       c.nOffset = c.pRun->member.run.len;
     }
     run = &c.pRun->member.run;
@@ -1245,7 +1245,7 @@ ME_MoveCursorLines(ME_TextEditor *editor, ME_Cursor *pCursor, int nRelOfs)
   int x = ME_GetXForArrow(editor, pCursor);
 
   if (editor->bCaretAtEnd && !pCursor->nOffset)
-    if (!ME_PrevRun(&pOldPara, &pRun))
+    if (!ME_PrevRun(&pOldPara, &pRun, TRUE))
       return;
 
   if (nRelOfs == -1)
index 250a233..c7d850a 100644 (file)
@@ -157,7 +157,8 @@ static const IEnumFORMATETCVtbl VT_EnumFormatImpl = {
     EnumFormatImpl_Clone
 };
 
-static HRESULT EnumFormatImpl_Create(const FORMATETC *fmtetc, UINT fmtetc_cnt, IEnumFORMATETC **lplpformatetc)
+static HRESULT EnumFormatImpl_Create(const FORMATETC *fmtetc, UINT fmtetc_cnt,
+                                     IEnumFORMATETC **formatetc)
 {
     EnumFormatImpl *ret;
     TRACE("\n");
@@ -169,7 +170,7 @@ static HRESULT EnumFormatImpl_Create(const FORMATETC *fmtetc, UINT fmtetc_cnt, I
     ret->fmtetc_cnt = fmtetc_cnt;
     ret->fmtetc = GlobalAlloc(GMEM_ZEROINIT, fmtetc_cnt*sizeof(FORMATETC));
     memcpy(ret->fmtetc, fmtetc, fmtetc_cnt*sizeof(FORMATETC));
-    *lplpformatetc = (LPENUMFORMATETC)ret;
+    *formatetc = &ret->IEnumFORMATETC_iface;
     return S_OK;
 }
 
@@ -399,8 +400,8 @@ static HGLOBAL get_rtf_text(ME_TextEditor *editor, const ME_Cursor *start, int n
     return gds.hData;
 }
 
-HRESULT ME_GetDataObject(ME_TextEditor *editor, const ME_Cursor *start,
-                         int nChars, LPDATAOBJECT *lplpdataobj)
+HRESULT ME_GetDataObject(ME_TextEditor *editor, const ME_Cursor *start, int nChars,
+                         IDataObject **dataobj)
 {
     DataObjectImpl *obj;
     TRACE("(%p,%d,%d)\n", editor, ME_GetCursorOfs(start), nChars);
@@ -424,6 +425,6 @@ HRESULT ME_GetDataObject(ME_TextEditor *editor, const ME_Cursor *start,
         InitFormatEtc(obj->fmtetc[1], cfRTF, TYMED_HGLOBAL);
     }
 
-    *lplpdataobj = (LPDATAOBJECT)obj;
+    *dataobj = &obj->IDataObject_iface;
     return S_OK;
 }
index 648c3ef..e90dcb8 100644 (file)
@@ -1860,7 +1860,7 @@ ME_FindText(ME_TextEditor *editor, DWORD flags, const CHARRANGE *chrg, const WCH
       cursor.nOffset++;
       if (cursor.nOffset == cursor.pRun->member.run.len)
       {
-        ME_NextRun(&cursor.pPara, &cursor.pRun);
+        ME_NextRun(&cursor.pPara, &cursor.pRun, TRUE);
         cursor.nOffset = 0;
       }
     }
@@ -1886,7 +1886,7 @@ ME_FindText(ME_TextEditor *editor, DWORD flags, const CHARRANGE *chrg, const WCH
 
       if (nCurEnd == 0)
       {
-        ME_PrevRun(&pCurPara, &pCurItem);
+        ME_PrevRun(&pCurPara, &pCurItem, TRUE);
         nCurEnd = pCurItem->member.run.len;
       }
 
@@ -1935,7 +1935,7 @@ ME_FindText(ME_TextEditor *editor, DWORD flags, const CHARRANGE *chrg, const WCH
         }
         if (nCurEnd - nMatched == 0)
         {
-          ME_PrevRun(&pCurPara, &pCurItem);
+          ME_PrevRun(&pCurPara, &pCurItem, TRUE);
           /* Don't care about pCurItem becoming NULL here; it's already taken
            * care of in the exterior loop condition */
           nCurEnd = pCurItem->member.run.len + nMatched;
@@ -1949,7 +1949,7 @@ ME_FindText(ME_TextEditor *editor, DWORD flags, const CHARRANGE *chrg, const WCH
       cursor.nOffset--;
       if (cursor.nOffset < 0)
       {
-        ME_PrevRun(&cursor.pPara, &cursor.pRun);
+        ME_PrevRun(&cursor.pPara, &cursor.pRun, TRUE);
         cursor.nOffset = cursor.pRun->member.run.len;
       }
     }
@@ -2624,6 +2624,11 @@ static int ME_CalculateClickCount(ME_TextEditor *editor, UINT msg, WPARAM wParam
     return clickNum;
 }
 
+static BOOL is_link( ME_Run *run )
+{
+    return (run->style->fmt.dwMask & CFM_LINK) && (run->style->fmt.dwEffects & CFE_LINK);
+}
+
 static BOOL ME_SetCursor(ME_TextEditor *editor)
 {
   ME_Cursor cursor;
@@ -2689,8 +2694,7 @@ static BOOL ME_SetCursor(ME_TextEditor *editor)
       ME_Run *run;
 
       run = &cursor.pRun->member.run;
-      if (run->style->fmt.dwMask & CFM_LINK &&
-          run->style->fmt.dwEffects & CFE_LINK)
+      if (is_link( run ))
       {
           ITextHost_TxSetCursor(editor->texthost,
                                 LoadCursorW(NULL, (WCHAR*)IDC_HAND),
@@ -3125,8 +3129,7 @@ static void ME_LinkNotify(ME_TextEditor *editor, UINT msg, WPARAM wParam, LPARAM
   ME_CharFromPos(editor, x, y, &cursor, &isExact);
   if (!isExact) return;
 
-  if (cursor.pRun->member.run.style->fmt.dwMask & CFM_LINK &&
-      cursor.pRun->member.run.style->fmt.dwEffects & CFE_LINK)
+  if (is_link( &cursor.pRun->member.run ))
   { /* The clicked run has CFE_LINK set */
     ME_DisplayItem *di;
 
@@ -3140,21 +3143,15 @@ static void ME_LinkNotify(ME_TextEditor *editor, UINT msg, WPARAM wParam, LPARAM
 
     /* find the first contiguous run with CFE_LINK set */
     info.chrg.cpMin = ME_GetCursorOfs(&cursor);
-    for (di = cursor.pRun->prev;
-         di && di->type == diRun && (di->member.run.style->fmt.dwMask & CFM_LINK) && (di->member.run.style->fmt.dwEffects & CFE_LINK);
-         di = di->prev)
-    {
-      info.chrg.cpMin -= di->member.run.len;
-    }
+    di = cursor.pRun;
+    while (ME_PrevRun( NULL, &di, FALSE ) && is_link( &di->member.run ))
+        info.chrg.cpMin -= di->member.run.len;
 
     /* find the last contiguous run with CFE_LINK set */
     info.chrg.cpMax = ME_GetCursorOfs(&cursor) + cursor.pRun->member.run.len;
-    for (di = cursor.pRun->next;
-         di && di->type == diRun && (di->member.run.style->fmt.dwMask & CFM_LINK) && (di->member.run.style->fmt.dwEffects & CFE_LINK);
-         di = di->next)
-    {
-      info.chrg.cpMax += di->member.run.len;
-    }
+    di = cursor.pRun;
+    while (ME_NextRun( NULL, &di, FALSE ) && is_link( &di->member.run ))
+        info.chrg.cpMax += di->member.run.len;
 
     ITextHost_TxNotify(editor->texthost, info.nmhdr.code, &info);
   }
@@ -3453,14 +3450,15 @@ LRESULT ME_HandleMessage(ME_TextEditor *editor, UINT msg, WPARAM wParam,
         ME_RewrapRepaint(editor);
       }
 
+      if ((changedSettings & settings & ES_NOHIDESEL) && !editor->bHaveFocus)
+          ME_InvalidateSelection( editor );
+
       if (changedSettings & settings & ECO_VERTICAL)
         FIXME("ECO_VERTICAL not implemented yet!\n");
       if (changedSettings & settings & ECO_AUTOHSCROLL)
         FIXME("ECO_AUTOHSCROLL not implemented yet!\n");
       if (changedSettings & settings & ECO_AUTOVSCROLL)
         FIXME("ECO_AUTOVSCROLL not implemented yet!\n");
-      if (changedSettings & settings & ECO_NOHIDESEL)
-        FIXME("ECO_NOHIDESEL not implemented yet!\n");
       if (changedSettings & settings & ECO_WANTRETURN)
         FIXME("ECO_WANTRETURN not implemented yet!\n");
       if (changedSettings & settings & ECO_AUTOWORDSELECTION)
@@ -4257,6 +4255,8 @@ LRESULT ME_HandleMessage(ME_TextEditor *editor, UINT msg, WPARAM wParam,
     editor->bHaveFocus = TRUE;
     ME_ShowCaret(editor);
     ME_SendOldNotify(editor, EN_SETFOCUS);
+    if (!editor->bHideSelection && !(editor->styleFlags & ES_NOHIDESEL))
+        ME_InvalidateSelection( editor );
     return 0;
   case WM_KILLFOCUS:
     ME_CommitUndo(editor); /* End coalesced undos for typed characters */
@@ -4264,6 +4264,8 @@ LRESULT ME_HandleMessage(ME_TextEditor *editor, UINT msg, WPARAM wParam,
     editor->wheel_remain = 0;
     ME_HideCaret(editor);
     ME_SendOldNotify(editor, EN_KILLFOCUS);
+    if (!editor->bHideSelection && !(editor->styleFlags & ES_NOHIDESEL))
+        ME_InvalidateSelection( editor );
     return 0;
   case WM_COMMAND:
     TRACE("editor wnd command = %d\n", LOWORD(wParam));
@@ -5002,10 +5004,24 @@ LRESULT WINAPI REExtendedRegisterClass(void)
   return result;
 }
 
-static BOOL isurlspecial(WCHAR c)
+static int wchar_comp( const void *key, const void *elem )
 {
-  static const WCHAR special_chars[] = {'.','/','%','@','*','|','\\','+','#',0};
-  return strchrW( special_chars, c ) != NULL;
+    return *(const WCHAR *)key - *(const WCHAR *)elem;
+}
+
+/* neutral characters end the url if the next non-neutral character is a space character,
+   otherwise they are included in the url. */
+static BOOL isurlneutral( WCHAR c )
+{
+    /* NB this list is sorted */
+    static const WCHAR neutral_chars[] = {'!','\"','\'','(',')',',','-','.',':',';','<','>','?','[',']','{','}'};
+
+    /* Some shortcuts */
+    if (isalnum( c )) return FALSE;
+    if (c > neutral_chars[sizeof(neutral_chars) / sizeof(neutral_chars[0]) - 1]) return FALSE;
+
+    return !!bsearch( &c, neutral_chars, sizeof(neutral_chars) / sizeof(neutral_chars[0]),
+                      sizeof(c), wchar_comp );
 }
 
 /**
@@ -5021,87 +5037,90 @@ static BOOL ME_FindNextURLCandidate(ME_TextEditor *editor,
                                     ME_Cursor *candidate_min,
                                     ME_Cursor *candidate_max)
 {
-  ME_Cursor cursor = *start;
-  BOOL foundColon = FALSE;
-  BOOL candidateStarted = FALSE;
-  WCHAR lastAcceptedChar = '\0';
+  ME_Cursor cursor = *start, neutral_end, space_end;
+  BOOL candidateStarted = FALSE, quoted = FALSE;
+  WCHAR c;
 
   while (nChars > 0)
   {
-    WCHAR *strStart = get_text( &cursor.pRun->member.run, 0 );
-    WCHAR *str = strStart + cursor.nOffset;
-    int nLen = cursor.pRun->member.run.len - cursor.nOffset;
-    nChars -= nLen;
+    WCHAR *str = get_text( &cursor.pRun->member.run, 0 );
+    int run_len = cursor.pRun->member.run.len;
+
+    nChars -= run_len - cursor.nOffset;
 
-    if (~cursor.pRun->member.run.nFlags & MERF_ENDPARA)
+    /* Find start of candidate */
+    if (!candidateStarted)
     {
-      /* Find start of candidate */
-      if (!candidateStarted)
+      while (cursor.nOffset < run_len)
       {
-        while (nLen)
+        c = str[cursor.nOffset];
+        if (!isspaceW( c ) && !isurlneutral( c ))
         {
-          nLen--;
-          if (isalnumW(*str) || isurlspecial(*str))
-          {
-            cursor.nOffset = str - strStart;
-            *candidate_min = cursor;
-            candidateStarted = TRUE;
-            lastAcceptedChar = *str++;
-            break;
-          }
-          str++;
+          *candidate_min = cursor;
+          candidateStarted = TRUE;
+          neutral_end.pPara = NULL;
+          space_end.pPara = NULL;
+          cursor.nOffset++;
+          break;
         }
+        quoted = (c == '<');
+        cursor.nOffset++;
       }
+    }
 
-      /* Find end of candidate */
-      if (candidateStarted) {
-        while (nLen)
+    /* Find end of candidate */
+    if (candidateStarted)
+    {
+      while (cursor.nOffset < run_len)
+      {
+        c = str[cursor.nOffset];
+        if (isspaceW( c ))
         {
-          nLen--;
-          if (*str == ':' && !foundColon) {
-            foundColon = TRUE;
-          } else if (!isalnumW(*str) && !isurlspecial(*str)) {
-            cursor.nOffset = str - strStart;
-            if (lastAcceptedChar == ':')
-              ME_MoveCursorChars(editor, &cursor, -1);
-            *candidate_max = cursor;
-            return TRUE;
+          if (quoted && c != '\r')
+          {
+            if (!space_end.pPara)
+            {
+              if (neutral_end.pPara)
+                space_end = neutral_end;
+              else
+                space_end = cursor;
+            }
           }
-          lastAcceptedChar = *str++;
+          else
+            goto done;
         }
-      }
-    } else {
-      /* End of paragraph: skip it if before candidate span, or terminates
-         current active span */
-      if (candidateStarted) {
-        if (lastAcceptedChar == ':')
-          ME_MoveCursorChars(editor, &cursor, -1);
-        *candidate_max = cursor;
-        return TRUE;
-      }
-    }
+        else if (isurlneutral( c ))
+        {
+          if (quoted && c == '>')
+          {
+            neutral_end.pPara = NULL;
+            space_end.pPara = NULL;
+            goto done;
+          }
+          if (!neutral_end.pPara)
+            neutral_end = cursor;
+        }
+        else
+          neutral_end.pPara = NULL;
 
-    /* Reaching this point means no span was found, so get next span */
-    if (!ME_NextRun(&cursor.pPara, &cursor.pRun)) {
-      if (candidateStarted) {
-        /* There are no further runs, so take end of text as end of candidate */
-        cursor.nOffset = str - strStart;
-        if (lastAcceptedChar == ':')
-          ME_MoveCursorChars(editor, &cursor, -1);
-        *candidate_max = cursor;
-        return TRUE;
+        cursor.nOffset++;
       }
-      *candidate_max = *candidate_min = cursor;
-      return FALSE;
     }
+
     cursor.nOffset = 0;
+    if (!ME_NextRun(&cursor.pPara, &cursor.pRun, TRUE))
+      goto done;
   }
 
-  if (candidateStarted) {
-    /* There are no further runs, so take end of text as end of candidate */
-    if (lastAcceptedChar == ':')
-      ME_MoveCursorChars(editor, &cursor, -1);
-    *candidate_max = cursor;
+done:
+  if (candidateStarted)
+  {
+    if (space_end.pPara)
+      *candidate_max = space_end;
+    else if (neutral_end.pPara)
+      *candidate_max = neutral_end;
+    else
+      *candidate_max = cursor;
     return TRUE;
   }
   *candidate_max = *candidate_min = cursor;
index 0c95cd3..1ea6ea6 100644 (file)
@@ -123,8 +123,8 @@ void ME_CharFormatFromLogFont(HDC hDC, const LOGFONTW *lf, CHARFORMAT2W *fmt) DE
 /* list.c */
 void ME_InsertBefore(ME_DisplayItem *diWhere, ME_DisplayItem *diWhat) DECLSPEC_HIDDEN;
 void ME_Remove(ME_DisplayItem *diWhere) DECLSPEC_HIDDEN;
-BOOL ME_NextRun(ME_DisplayItem **para, ME_DisplayItem **run) DECLSPEC_HIDDEN;
-BOOL ME_PrevRun(ME_DisplayItem **para, ME_DisplayItem **run) DECLSPEC_HIDDEN;
+BOOL ME_NextRun(ME_DisplayItem **para, ME_DisplayItem **run, BOOL all_para) DECLSPEC_HIDDEN;
+BOOL ME_PrevRun(ME_DisplayItem **para, ME_DisplayItem **run, BOOL all_para) DECLSPEC_HIDDEN;
 ME_DisplayItem *ME_FindItemBack(ME_DisplayItem *di, ME_DIType nTypeOrClass) DECLSPEC_HIDDEN;
 ME_DisplayItem *ME_FindItemFwd(ME_DisplayItem *di, ME_DIType nTypeOrClass) DECLSPEC_HIDDEN;
 ME_DisplayItem *ME_FindItemBackOrHere(ME_DisplayItem *di, ME_DIType nTypeOrClass) DECLSPEC_HIDDEN;
index c57e526..ce21c59 100644 (file)
@@ -63,16 +63,18 @@ static BOOL ME_DITypesEqual(ME_DIType type, ME_DIType nTypeOrClass)
   }
 }
 
-/* Modifies run pointer to point to the next run, and modify the
- * paragraph pointer if moving into the next paragraph.
+/* Modifies run pointer to point to the next run.
+ * If all_para is FALSE constrain the search to the current para,
+ * otherwise modify the paragraph pointer if moving into the next paragraph.
  *
  * Returns TRUE if next run is found, otherwise returns FALSE. */
-BOOL ME_NextRun(ME_DisplayItem **para, ME_DisplayItem **run)
+BOOL ME_NextRun(ME_DisplayItem **para, ME_DisplayItem **run, BOOL all_para)
 {
   ME_DisplayItem *p = (*run)->next;
   while (p->type != diTextEnd)
   {
     if (p->type == diParagraph) {
+      if (!all_para) return FALSE;
       *para = p;
     } else if (p->type == diRun) {
       *run = p;
@@ -83,16 +85,18 @@ BOOL ME_NextRun(ME_DisplayItem **para, ME_DisplayItem **run)
   return FALSE;
 }
 
-/* Modifies run pointer to point to the previous run, and modify the
- * paragraph pointer if moving into the previous paragraph.
+/* Modifies run pointer to point to the previous run.
+ * If all_para is FALSE constrain the search to the current para,
+ * otherwise modify the paragraph pointer if moving into the previous paragraph.
  *
  * Returns TRUE if previous run is found, otherwise returns FALSE. */
-BOOL ME_PrevRun(ME_DisplayItem **para, ME_DisplayItem **run)
+BOOL ME_PrevRun(ME_DisplayItem **para, ME_DisplayItem **run, BOOL all_para)
 {
   ME_DisplayItem *p = (*run)->prev;
   while (p->type != diTextStart)
   {
     if (p->type == diParagraph) {
+      if (!all_para) return FALSE;
       if (p->member.para.prev_para->type == diParagraph)
         *para = p->member.para.prev_para;
     } else if (p->type == diRun) {
index 8580539..42434b9 100644 (file)
@@ -261,7 +261,8 @@ static void draw_space( ME_Context *c, ME_Run *run, int x, int y,
 
     SetRect( &rect, x, ymin, x + run->nWidth, ymin + cy );
 
-    if (c->editor->bHideSelection) selected = FALSE;
+    if (c->editor->bHideSelection || (!c->editor->bHaveFocus &&
+                !(c->editor->styleFlags & ES_NOHIDESEL))) selected = FALSE;
     if (c->editor->bEmulateVersion10)
     {
         old_style_selected = selected;
@@ -355,7 +356,8 @@ static void ME_DrawTextWithStyle(ME_Context *c, ME_Run *run, int x, int y,
   HGDIOBJ hOldFont;
   int yOffset = 0;
   BOOL selected = (nSelFrom < run->len && nSelTo >= 0
-                   && nSelFrom < nSelTo && !c->editor->bHideSelection);
+                   && nSelFrom < nSelTo && !c->editor->bHideSelection &&
+                   (c->editor->bHaveFocus || (c->editor->styleFlags & ES_NOHIDESEL)));
   BOOL old_style_selected = FALSE;
   RECT sel_rect;
   HRGN clip = NULL, sel_rgn = NULL;
index 6721698..c762cf0 100644 (file)
@@ -364,7 +364,7 @@ ME_DisplayItem *ME_JoinParagraphs(ME_TextEditor *editor, ME_DisplayItem *tp,
   endCur.pRun = ME_FindItemFwd(pNext, diRun);
   endCur.nOffset = 0;
   startCur = endCur;
-  ME_PrevRun(&startCur.pPara, &startCur.pRun);
+  ME_PrevRun(&startCur.pPara, &startCur.pRun, TRUE);
   ME_SetCharFormat(editor, &startCur, &endCur, &fmt);
 
   if (!editor->bEmulateVersion10) { /* v4.1 */
index 784b85f..e38009d 100644 (file)
@@ -1597,7 +1597,7 @@ static HRESULT WINAPI ITextRange_fnGetIDsOfNames(ITextRange *me, REFIID riid, LP
     ITypeInfo *ti;
     HRESULT hr;
 
-    TRACE("(%p)->(%p,%p,%u,%d,%p)\n", This, riid, rgszNames, cNames, lcid,
+    TRACE("(%p)->(%s, %p, %u, %d, %p)\n", This, debugstr_guid(riid), rgszNames, cNames, lcid,
             rgDispId);
 
     hr = get_typeinfo(ITextRange_tid, &ti);
@@ -1615,8 +1615,8 @@ static HRESULT WINAPI ITextRange_fnInvoke(ITextRange *me, DISPID dispIdMember, R
     ITypeInfo *ti;
     HRESULT hr;
 
-    TRACE("(%p)->(%d,%p,%d,%u,%p,%p,%p,%p)\n", This, dispIdMember, riid, lcid,
-            wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
+    TRACE("(%p)->(%d, %s, %d, %u, %p, %p, %p, %p)\n", This, dispIdMember, debugstr_guid(riid),
+            lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
 
     hr = get_typeinfo(ITextRange_tid, &ti);
     if (SUCCEEDED(hr))
@@ -1970,7 +1970,7 @@ static HRESULT range_Collapse(LONG bStart, LONG *start, LONG *end)
   if (*end == *start)
       return S_FALSE;
 
-  if (bStart == tomEnd || bStart == tomFalse)
+  if (bStart == tomEnd)
       *start = *end;
   else
       *end = *start;
@@ -2618,8 +2618,8 @@ static HRESULT WINAPI TextFont_GetIDsOfNames(ITextFont *iface, REFIID riid,
     ITypeInfo *ti;
     HRESULT hr;
 
-    TRACE("(%p)->(%p,%p,%u,%d,%p)\n", This, riid, rgszNames, cNames, lcid,
-            rgDispId);
+    TRACE("(%p)->(%s, %p, %u, %d, %p)\n", This, debugstr_guid(riid),
+            rgszNames, cNames, lcid, rgDispId);
 
     hr = get_typeinfo(ITextFont_tid, &ti);
     if (SUCCEEDED(hr))
@@ -2642,8 +2642,8 @@ static HRESULT WINAPI TextFont_Invoke(
     ITypeInfo *ti;
     HRESULT hr;
 
-    TRACE("(%p)->(%d,%p,%d,%u,%p,%p,%p,%p)\n", This, dispIdMember, riid, lcid,
-            wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
+    TRACE("(%p)->(%d, %s, %d, %u, %p, %p, %p, %p)\n", This, dispIdMember, debugstr_guid(riid),
+            lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
 
     hr = get_typeinfo(ITextFont_tid, &ti);
     if (SUCCEEDED(hr))
@@ -3430,8 +3430,8 @@ static HRESULT WINAPI TextPara_GetIDsOfNames(ITextPara *iface, REFIID riid,
     ITypeInfo *ti;
     HRESULT hr;
 
-    TRACE("(%p)->(%p,%p,%u,%d,%p)\n", This, riid, rgszNames, cNames, lcid,
-            rgDispId);
+    TRACE("(%p)->(%s, %p, %u, %d, %p)\n", This, debugstr_guid(riid), rgszNames,
+            cNames, lcid, rgDispId);
 
     hr = get_typeinfo(ITextPara_tid, &ti);
     if (SUCCEEDED(hr))
@@ -3454,8 +3454,9 @@ static HRESULT WINAPI TextPara_Invoke(
     ITypeInfo *ti;
     HRESULT hr;
 
-    TRACE("(%p)->(%d,%p,%d,%u,%p,%p,%p,%p)\n", This, dispIdMember, riid, lcid,
-            wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
+    TRACE("(%p)->(%d, %s, %d, %u, %p, %p, %p, %p)\n", This, dispIdMember,
+            debugstr_guid(riid), lcid, wFlags, pDispParams, pVarResult,
+            pExcepInfo, puArgErr);
 
     hr = get_typeinfo(ITextPara_tid, &ti);
     if (SUCCEEDED(hr))
@@ -4125,8 +4126,8 @@ ITextDocument_fnGetIDsOfNames(ITextDocument* me, REFIID riid,
     ITypeInfo *ti;
     HRESULT hr;
 
-    TRACE("(%p)->(%p,%p,%u,%d,%p)\n", This, riid, rgszNames, cNames, lcid,
-            rgDispId);
+    TRACE("(%p)->(%s, %p, %u, %d, %p)\n", This, debugstr_guid(riid),
+            rgszNames, cNames, lcid, rgDispId);
 
     hr = get_typeinfo(ITextDocument_tid, &ti);
     if (SUCCEEDED(hr))
@@ -4143,8 +4144,9 @@ ITextDocument_fnInvoke(ITextDocument* me, DISPID dispIdMember,
     ITypeInfo *ti;
     HRESULT hr;
 
-    TRACE("(%p)->(%d,%p,%d,%u,%p,%p,%p,%p)\n", This, dispIdMember, riid, lcid,
-            wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
+    TRACE("(%p)->(%d, %s, %d, %u, %p, %p, %p, %p)\n", This, dispIdMember,
+            debugstr_guid(riid), lcid, wFlags, pDispParams, pVarResult,
+            pExcepInfo, puArgErr);
 
     hr = get_typeinfo(ITextDocument_tid, &ti);
     if (SUCCEEDED(hr))
@@ -4445,7 +4447,7 @@ static HRESULT WINAPI ITextSelection_fnGetIDsOfNames(ITextSelection *me, REFIID
     ITypeInfo *ti;
     HRESULT hr;
 
-    TRACE("(%p)->(%p,%p,%u,%d,%p)\n", This, riid, rgszNames, cNames, lcid,
+    TRACE("(%p)->(%s, %p, %u, %d, %p)\n", This, debugstr_guid(riid), rgszNames, cNames, lcid,
             rgDispId);
 
     hr = get_typeinfo(ITextSelection_tid, &ti);
@@ -4469,7 +4471,7 @@ static HRESULT WINAPI ITextSelection_fnInvoke(
     ITypeInfo *ti;
     HRESULT hr;
 
-    TRACE("(%p)->(%d,%p,%d,%u,%p,%p,%p,%p)\n", This, dispIdMember, riid, lcid,
+    TRACE("(%p)->(%d, %s, %d, %u, %p, %p, %p, %p)\n", This, dispIdMember, debugstr_guid(riid), lcid,
             wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
 
     hr = get_typeinfo(ITextSelection_tid, &ti);
index f38ea30..96b8a40 100644 (file)
@@ -112,6 +112,32 @@ ME_StreamOutPrint(ME_OutStream *pStream, const char *format, ...)
   return ME_StreamOutMove(pStream, string, len);
 }
 
+#define HEX_BYTES_PER_LINE 40
+
+static BOOL
+ME_StreamOutHexData(ME_OutStream *stream, const BYTE *data, UINT len)
+{
+
+    char line[HEX_BYTES_PER_LINE * 2 + 1];
+    UINT size, i;
+    static const char hex[] = "0123456789abcdef";
+
+    while (len)
+    {
+        size = min( len, HEX_BYTES_PER_LINE );
+        for (i = 0; i < size; i++)
+        {
+            line[i * 2] = hex[(*data >> 4) & 0xf];
+            line[i * 2 + 1] = hex[*data & 0xf];
+            data++;
+        }
+        line[size * 2] = '\n';
+        if (!ME_StreamOutMove( stream, line, size * 2 + 1 ))
+            return FALSE;
+        len -= size;
+    }
+    return TRUE;
+}
 
 static BOOL
 ME_StreamOutRTFHeader(ME_OutStream *pStream, int dwFormat)
@@ -780,6 +806,69 @@ ME_StreamOutRTFText(ME_OutStream *pStream, const WCHAR *text, LONG nChars)
   return ME_StreamOutMove(pStream, buffer, pos);
 }
 
+static BOOL stream_out_graphics( ME_TextEditor *editor, ME_OutStream *stream,
+                                 ME_Run *run )
+{
+    IDataObject *data;
+    HRESULT hr;
+    FORMATETC fmt = { CF_ENHMETAFILE, NULL, DVASPECT_CONTENT, -1, TYMED_ENHMF };
+    STGMEDIUM med = { TYMED_NULL };
+    BOOL ret = FALSE;
+    ENHMETAHEADER *emf_bits = NULL;
+    UINT size;
+    SIZE goal, pic;
+    ME_Context c;
+
+    hr = IOleObject_QueryInterface( run->ole_obj->poleobj, &IID_IDataObject, (void **)&data );
+    if (FAILED(hr)) return FALSE;
+
+    ME_InitContext( &c, editor, ITextHost_TxGetDC( editor->texthost ) );
+    hr = IDataObject_QueryGetData( data, &fmt );
+    if (hr != S_OK) goto done;
+
+    hr = IDataObject_GetData( data, &fmt, &med );
+    if (FAILED(hr)) goto done;
+    if (med.tymed != TYMED_ENHMF) goto done;
+
+    size = GetEnhMetaFileBits( med.u.hEnhMetaFile, 0, NULL );
+    if (size < FIELD_OFFSET(ENHMETAHEADER, cbPixelFormat)) goto done;
+
+    emf_bits = HeapAlloc( GetProcessHeap(), 0, size );
+    if (!emf_bits) goto done;
+
+    size = GetEnhMetaFileBits( med.u.hEnhMetaFile, size, (BYTE *)emf_bits );
+    if (size < FIELD_OFFSET(ENHMETAHEADER, cbPixelFormat)) goto done;
+
+    /* size_in_pixels = (frame_size / 100) * szlDevice / szlMillimeters
+       pic = size_in_pixels * 2540 / dpi */
+    pic.cx = MulDiv( emf_bits->rclFrame.right - emf_bits->rclFrame.left, emf_bits->szlDevice.cx * 254,
+                     emf_bits->szlMillimeters.cx * c.dpi.cx * 10 );
+    pic.cy = MulDiv( emf_bits->rclFrame.bottom - emf_bits->rclFrame.top, emf_bits->szlDevice.cy * 254,
+                     emf_bits->szlMillimeters.cy * c.dpi.cy * 10 );
+
+    /* convert goal size to twips */
+    goal.cx = MulDiv( run->ole_obj->sizel.cx, 144, 254 );
+    goal.cy = MulDiv( run->ole_obj->sizel.cy, 144, 254 );
+
+    if (!ME_StreamOutPrint( stream, "{\\*\\shppict{\\pict\\emfblip\\picw%d\\pich%d\\picwgoal%d\\pichgoal%d\n",
+                            pic.cx, pic.cy, goal.cx, goal.cy ))
+        goto done;
+
+    if (!ME_StreamOutHexData( stream, (BYTE *)emf_bits, size ))
+        goto done;
+
+    if (!ME_StreamOutPrint( stream, "}}\n" ))
+        goto done;
+
+    ret = TRUE;
+
+done:
+    ME_DestroyContext( &c );
+    HeapFree( GetProcessHeap(), 0, emf_bits );
+    ReleaseStgMedium( &med );
+    IDataObject_Release( data );
+    return ret;
+}
 
 static BOOL ME_StreamOutRTF(ME_TextEditor *editor, ME_OutStream *pStream,
                             const ME_Cursor *start, int nChars, int dwFormat)
@@ -831,7 +920,8 @@ static BOOL ME_StreamOutRTF(ME_TextEditor *editor, ME_OutStream *pStream,
     if (cursor.pPara->member.para.nFlags & (MEPF_ROWSTART|MEPF_ROWEND))
       continue;
     if (cursor.pRun->member.run.nFlags & MERF_GRAPHICS) {
-      FIXME("embedded objects are not handled\n");
+      if (!stream_out_graphics(editor, pStream, &cursor.pRun->member.run))
+        return FALSE;
     } else if (cursor.pRun->member.run.nFlags & MERF_TAB) {
       if (editor->bEmulateVersion10 && /* v1.0 - 3.0 */
           cursor.pPara->member.para.pFmt->dwMask & PFM_TABLE &&
@@ -886,7 +976,7 @@ static BOOL ME_StreamOutRTF(ME_TextEditor *editor, ME_OutStream *pStream,
       if (!ME_StreamOutPrint(pStream, "}"))
         return FALSE;
     }
-  } while (cursor.pRun != endCur.pRun && ME_NextRun(&cursor.pPara, &cursor.pRun));
+  } while (cursor.pRun != endCur.pRun && ME_NextRun(&cursor.pPara, &cursor.pRun, TRUE));
 
   if (!ME_StreamOutMove(pStream, "}\0", 2))
     return FALSE;
index 4f8cf85..57a81cd 100644 (file)
@@ -161,7 +161,7 @@ reactos/dll/win32/qmgrprxy            # Synced to WineStaging-1.9.11
 reactos/dll/win32/query               # Synced to WineStaging-1.9.11
 reactos/dll/win32/rasapi32            # Synced to WineStaging-1.9.11
 reactos/dll/win32/resutils            # Synced to WineStaging-1.9.11
-reactos/dll/win32/riched20            # Synced to WineStaging-1.9.11
+reactos/dll/win32/riched20            # Synced to WineStaging-1.9.16
 reactos/dll/win32/riched32            # Synced to WineStaging-1.9.11
 reactos/dll/win32/rpcrt4              # Synced to WineStaging-1.9.11
 reactos/dll/win32/rsabase             # Synced to WineStaging-1.9.11