riched20: Add support for saving enhanced metafiles.

Signed-off-by: Huw Davies <huw@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Huw Davies 2016-06-07 11:18:23 +01:00 committed by Alexandre Julliard
parent 389c86c8c1
commit 8477dcf909
1 changed files with 93 additions and 1 deletions

View File

@ -21,6 +21,8 @@
#include "config.h"
#include "wine/port.h"
#define NONAMELESSUNION
#include "editor.h"
#include "rtf.h"
@ -115,6 +117,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)
@ -783,6 +811,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)
@ -834,7 +925,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 &&