Eric Pouech : riched20: Added support for image reading from RTF stream.
Alexandre Julliard
julliard at winehq.org
Tue Feb 5 06:33:13 CST 2008
Module: wine
Branch: master
Commit: e5f91bab15607a990f664a136f90a77b83a65aa6
URL: http://source.winehq.org/git/wine.git/?a=commit;h=e5f91bab15607a990f664a136f90a77b83a65aa6
Author: Eric Pouech <eric.pouech at orange.fr>
Date: Sun Jan 27 19:02:21 2008 +0100
riched20: Added support for image reading from RTF stream.
---
dlls/riched20/editor.c | 162 +++++++++++++++++++++++++++++++++++++++++++++++-
dlls/riched20/rtf.h | 1 +
2 files changed, 162 insertions(+), 1 deletions(-)
diff --git a/dlls/riched20/editor.c b/dlls/riched20/editor.c
index 2df5eb1..02d5ca8 100644
--- a/dlls/riched20/editor.c
+++ b/dlls/riched20/editor.c
@@ -692,6 +692,163 @@ static void ME_RTFTblAttrHook(RTF_Info *info)
}
}
+static BOOL ME_RTFInsertOleObject(RTF_Info *info, HENHMETAFILE h, const SIZEL* sz)
+{
+ LPOLEOBJECT lpObject = NULL;
+ LPSTORAGE lpStorage = NULL;
+ LPOLECLIENTSITE lpClientSite = NULL;
+ LPDATAOBJECT lpDataObject = NULL;
+ LPOLECACHE lpOleCache = NULL;
+ STGMEDIUM stgm;
+ FORMATETC fm;
+ CLSID clsid;
+ BOOL ret = FALSE;
+ DWORD conn;
+
+ stgm.tymed = TYMED_ENHMF;
+ stgm.u.hEnhMetaFile = h;
+ stgm.pUnkForRelease = NULL;
+
+ fm.cfFormat = CF_ENHMETAFILE;
+ fm.ptd = NULL;
+ fm.dwAspect = DVASPECT_CONTENT;
+ fm.lindex = -1;
+ fm.tymed = stgm.tymed;
+
+ if (!info->lpRichEditOle)
+ {
+ CreateIRichEditOle(info->editor, (VOID**)&info->lpRichEditOle);
+ }
+
+ if (OleCreateDefaultHandler(&CLSID_NULL, NULL, &IID_IOleObject, (void**)&lpObject) == S_OK &&
+#if 0
+ /* FIXME: enable it when rich-edit properly implements this method */
+ IRichEditOle_GetClientSite(info->lpRichEditOle, &lpClientSite) == S_OK &&
+ IOleObject_SetClientSite(lpObject, lpClientSite) == S_OK &&
+#endif
+ IOleObject_GetUserClassID(lpObject, &clsid) == S_OK &&
+ IOleObject_QueryInterface(lpObject, &IID_IOleCache, (void**)&lpOleCache) == S_OK &&
+ IOleCache_Cache(lpOleCache, &fm, 0, &conn) == S_OK &&
+ IOleObject_QueryInterface(lpObject, &IID_IDataObject, (void**)&lpDataObject) == S_OK &&
+ IDataObject_SetData(lpDataObject, &fm, &stgm, TRUE) == S_OK)
+ {
+ REOBJECT reobject;
+
+ reobject.cbStruct = sizeof(reobject);
+ reobject.cp = REO_CP_SELECTION;
+ reobject.clsid = clsid;
+ reobject.poleobj = lpObject;
+ reobject.pstg = lpStorage;
+ reobject.polesite = lpClientSite;
+ /* convert from twips to .01 mm */
+ reobject.sizel.cx = MulDiv(sz->cx, 254, 144);
+ reobject.sizel.cy = MulDiv(sz->cy, 254, 144);
+ reobject.dvaspect = DVASPECT_CONTENT;
+ reobject.dwFlags = 0; /* FIXME */
+ reobject.dwUser = 0;
+
+ /* FIXME: could be simpler */
+ ret = IRichEditOle_InsertObject(info->lpRichEditOle, &reobject) == S_OK;
+ }
+
+ if (lpObject) IOleObject_Release(lpObject);
+ if (lpClientSite) IOleClientSite_Release(lpClientSite);
+ if (lpStorage) IStorage_Release(lpStorage);
+ if (lpDataObject) IDataObject_Release(lpDataObject);
+ if (lpOleCache) IOleCache_Release(lpOleCache);
+
+ return ret;
+}
+
+static void ME_RTFReadPictGroup(RTF_Info *info)
+{
+ SIZEL sz;
+ BYTE* buffer = NULL;
+ unsigned bufsz, bufidx;
+ BOOL flip;
+ BYTE val;
+ METAFILEPICT mfp;
+ HENHMETAFILE hemf;
+
+ RTFGetToken (info);
+ if (info->rtfClass == rtfEOF)
+ return;
+ mfp.mm = MM_TEXT;
+ /* fetch picture type */
+ if (RTFCheckMM (info, rtfPictAttr, rtfWinMetafile))
+ {
+ mfp.mm = info->rtfParam;
+ }
+ else
+ {
+ FIXME("%d %d\n", info->rtfMajor, info->rtfMinor);
+ goto skip_group;
+ }
+ sz.cx = sz.cy = 0;
+ /* fetch picture attributes */
+ for (;;)
+ {
+ RTFGetToken (info);
+ if (info->rtfClass == rtfEOF)
+ return;
+ if (info->rtfClass == rtfText)
+ break;
+ if (!RTFCheckCM (info, rtfControl, rtfPictAttr))
+ {
+ ERR("Expected picture attribute (%d %d)\n",
+ info->rtfClass, info->rtfMajor);
+ goto skip_group;
+ }
+ else if (RTFCheckMM (info, rtfPictAttr, rtfPicWid))
+ mfp.xExt = info->rtfParam;
+ else if (RTFCheckMM (info, rtfPictAttr, rtfPicHt))
+ mfp.yExt = info->rtfParam;
+ else if (RTFCheckMM (info, rtfPictAttr, rtfPicGoalWid))
+ sz.cx = info->rtfParam;
+ else if (RTFCheckMM (info, rtfPictAttr, rtfPicGoalHt))
+ sz.cy = info->rtfParam;
+ else
+ FIXME("Non supported attribute: %d %d %d\n", info->rtfClass, info->rtfMajor, info->rtfMinor);
+ }
+ /* fetch picture data */
+ bufsz = 1024;
+ bufidx = 0;
+ buffer = HeapAlloc(GetProcessHeap(), 0, bufsz);
+ val = info->rtfMajor;
+ for (flip = TRUE;; flip = !flip)
+ {
+ RTFGetToken (info);
+ if (info->rtfClass == rtfEOF)
+ {
+ HeapFree(GetProcessHeap(), 0, buffer);
+ return; /* Warn ?? */
+ }
+ if (RTFCheckCM(info, rtfGroup, rtfEndGroup))
+ break;
+ if (info->rtfClass != rtfText) goto skip_group;
+ if (flip)
+ {
+ if (bufidx >= bufsz &&
+ !(buffer = HeapReAlloc(GetProcessHeap(), 0, buffer, bufsz += 1024)))
+ goto skip_group;
+ buffer[bufidx++] = RTFCharToHex(val) * 16 + RTFCharToHex(info->rtfMajor);
+ }
+ else
+ val = info->rtfMajor;
+ }
+ if (flip) FIXME("wrong hex string\n");
+
+ if ((hemf = SetWinMetaFileBits(bufidx, buffer, NULL, &mfp)))
+ ME_RTFInsertOleObject(info, hemf, &sz);
+ HeapFree(GetProcessHeap(), 0, buffer);
+ RTFRouteToken (info); /* feed "}" back to router */
+ return;
+skip_group:
+ HeapFree(GetProcessHeap(), 0, buffer);
+ RTFSkipGroup(info);
+ RTFRouteToken(info); /* feed "}" back to router */
+}
+
static void ME_RTFReadHook(RTF_Info *info) {
switch(info->rtfClass)
{
@@ -830,12 +987,15 @@ static LRESULT ME_StreamIn(ME_TextEditor *editor, DWORD format, EDITSTREAM *stre
WriterInit(&parser);
RTFInit(&parser);
RTFSetReadHook(&parser, ME_RTFReadHook);
+ RTFSetDestinationCallback(&parser, rtfPict, ME_RTFReadPictGroup);
BeginFile(&parser);
-
+
/* do the parsing */
RTFRead(&parser);
RTFFlushOutputBuffer(&parser);
RTFDestroy(&parser);
+ if (parser.lpRichEditOle)
+ IRichEditOle_Release(parser.lpRichEditOle);
style = parser.style;
}
diff --git a/dlls/riched20/rtf.h b/dlls/riched20/rtf.h
index 5a12515..3a9c235 100644
--- a/dlls/riched20/rtf.h
+++ b/dlls/riched20/rtf.h
@@ -1103,6 +1103,7 @@ struct _RTF_Info {
RTFState stack[maxStack];
int stackTop;
BOOL styleChanged;
+ LPRICHEDITOLE lpRichEditOle;
};
More information about the wine-cvs
mailing list