mirror of
git://source.winehq.org/git/wine.git
synced 2024-11-05 18:01:34 +00:00
riched20: Added support for image reading from RTF stream.
This commit is contained in:
parent
1e62b0e3b0
commit
e5f91bab15
2 changed files with 162 additions and 1 deletions
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -1103,6 +1103,7 @@ struct _RTF_Info {
|
|||
RTFState stack[maxStack];
|
||||
int stackTop;
|
||||
BOOL styleChanged;
|
||||
LPRICHEDITOLE lpRichEditOle;
|
||||
};
|
||||
|
||||
|
||||
|
|
Loading…
Reference in a new issue