Commit cfc89142 authored by Huw Davies's avatar Huw Davies Committed by Alexandre Julliard

riched20: Rewrite the picture destination parser to handle embedded groups.

Since almost every line of ME_RTFReadPictGroup() changed, I took the opportunity to re-format it. Signed-off-by: 's avatarHuw Davies <huw@codeweavers.com> Signed-off-by: 's avatarAlexandre Julliard <julliard@winehq.org>
parent 899207b6
......@@ -1236,136 +1236,161 @@ static BOOL ME_RTFInsertOleObject(RTF_Info *info, HENHMETAFILE hemf, HBITMAP hbm
return ret;
}
static void ME_RTFReadPictGroup(RTF_Info *info)
static DWORD read_hex_data( RTF_Info *info, BYTE **out )
{
SIZEL sz;
BYTE* buffer = NULL;
unsigned bufsz, bufidx;
BOOL flip;
DWORD read = 0, size = 1024;
BYTE *buf = HeapAlloc( GetProcessHeap(), 0, size );
BYTE val;
METAFILEPICT mfp;
HENHMETAFILE hemf;
HBITMAP hbmp;
enum gfxkind {gfx_unknown = 0, gfx_enhmetafile, gfx_metafile, gfx_dib} gfx = gfx_unknown;
BOOL flip;
RTFGetToken (info);
if (info->rtfClass == rtfEOF)
return;
mfp.mm = MM_TEXT;
/* fetch picture type */
if (RTFCheckMM (info, rtfPictAttr, rtfWinMetafile))
*out = NULL;
if (!buf) return 0;
if (info->rtfClass != rtfText)
{
mfp.mm = info->rtfParam;
gfx = gfx_metafile;
ERR("Called with incorrect token\n");
return 0;
}
else if (RTFCheckMM (info, rtfPictAttr, rtfDevIndBitmap))
val = info->rtfMajor;
for (flip = TRUE;; flip = !flip)
{
if (info->rtfParam != 0) FIXME("dibitmap should be 0 (%d)\n", info->rtfParam);
gfx = gfx_dib;
RTFGetToken( info );
if (info->rtfClass == rtfEOF)
{
HeapFree( GetProcessHeap(), 0, buf );
return 0;
}
else if (RTFCheckMM (info, rtfPictAttr, rtfEmfBlip))
if (info->rtfClass != rtfText) break;
if (flip)
{
gfx = gfx_enhmetafile;
if (read >= size)
{
size *= 2;
buf = HeapReAlloc( GetProcessHeap(), 0, buf, size );
if (!buf) return 0;
}
buf[read++] = RTFCharToHex(val) * 16 + RTFCharToHex(info->rtfMajor);
}
else
{
FIXME("%d %d\n", info->rtfMajor, info->rtfMinor);
goto skip_group;
val = info->rtfMajor;
}
if (flip) FIXME("wrong hex string\n");
*out = buf;
return read;
}
static void ME_RTFReadPictGroup(RTF_Info *info)
{
SIZEL sz;
BYTE *buffer = NULL;
DWORD size = 0;
METAFILEPICT mfp;
HENHMETAFILE hemf;
HBITMAP hbmp;
enum gfxkind {gfx_unknown = 0, gfx_enhmetafile, gfx_metafile, gfx_dib} gfx = gfx_unknown;
int level = 1;
mfp.mm = MM_TEXT;
sz.cx = sz.cy = 0;
/* fetch picture attributes */
for (;;)
{
RTFGetToken (info);
if (info->rtfClass == rtfEOF)
return;
RTFGetToken( info );
if (info->rtfClass == rtfText)
break;
if (!RTFCheckCM (info, rtfControl, rtfPictAttr))
{
ERR("Expected picture attribute (%d %d)\n",
info->rtfClass, info->rtfMajor);
goto skip_group;
if (level == 1)
{
if (!buffer)
size = read_hex_data( info, &buffer );
}
else if (RTFCheckMM (info, rtfPictAttr, rtfPicWid))
else
{
if (gfx == gfx_metafile) mfp.xExt = info->rtfParam;
RTFSkipGroup( info );
}
else if (RTFCheckMM (info, rtfPictAttr, rtfPicHt))
} /* We potentially have a new token so fall through. */
if (info->rtfClass == rtfEOF) return;
if (RTFCheckCM( info, rtfGroup, rtfEndGroup ))
{
if (gfx == gfx_metafile) mfp.yExt = info->rtfParam;
if (--level == 0) break;
continue;
}
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);
if (RTFCheckCM( info, rtfGroup, rtfBeginGroup ))
{
level++;
continue;
}
/* fetch picture data */
bufsz = 1024;
bufidx = 0;
buffer = HeapAlloc(GetProcessHeap(), 0, bufsz);
val = info->rtfMajor;
for (flip = TRUE;; flip = !flip)
if (!RTFCheckCM( info, rtfControl, rtfPictAttr ))
{
RTFGetToken (info);
if (info->rtfClass == rtfEOF)
RTFRouteToken( info );
if (RTFCheckCM( info, rtfGroup, rtfEndGroup ))
level--;
continue;
}
if (RTFCheckMM( info, rtfPictAttr, rtfWinMetafile ))
{
HeapFree(GetProcessHeap(), 0, buffer);
return; /* Warn ?? */
mfp.mm = info->rtfParam;
gfx = gfx_metafile;
}
if (RTFCheckCM(info, rtfGroup, rtfEndGroup))
break;
if (info->rtfClass != rtfText) goto skip_group;
if (flip)
else if (RTFCheckMM( info, rtfPictAttr, rtfDevIndBitmap ))
{
if (bufidx >= bufsz &&
!(buffer = HeapReAlloc(GetProcessHeap(), 0, buffer, bufsz += 1024)))
goto skip_group;
buffer[bufidx++] = RTFCharToHex(val) * 16 + RTFCharToHex(info->rtfMajor);
if (info->rtfParam != 0) FIXME("dibitmap should be 0 (%d)\n", info->rtfParam);
gfx = gfx_dib;
}
else if (RTFCheckMM( info, rtfPictAttr, rtfEmfBlip ))
gfx = gfx_enhmetafile;
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
val = info->rtfMajor;
FIXME("Non supported attribute: %d %d %d\n", info->rtfClass, info->rtfMajor, info->rtfMinor);
}
if (flip) FIXME("wrong hex string\n");
if (buffer)
{
switch (gfx)
{
case gfx_enhmetafile:
if ((hemf = SetEnhMetaFileBits(bufidx, buffer)))
ME_RTFInsertOleObject(info, hemf, NULL, &sz);
if ((hemf = SetEnhMetaFileBits( size, buffer )))
ME_RTFInsertOleObject( info, hemf, NULL, &sz );
break;
case gfx_metafile:
if ((hemf = SetWinMetaFileBits(bufidx, buffer, NULL, &mfp)))
ME_RTFInsertOleObject(info, hemf, NULL, &sz);
if ((hemf = SetWinMetaFileBits( size, buffer, NULL, &mfp )))
ME_RTFInsertOleObject( info, hemf, NULL, &sz );
break;
case gfx_dib:
{
BITMAPINFO* bi = (BITMAPINFO*)buffer;
BITMAPINFO *bi = (BITMAPINFO*)buffer;
HDC hdc = GetDC(0);
unsigned nc = bi->bmiHeader.biClrUsed;
/* not quite right, especially for bitfields type of compression */
if (!nc && bi->bmiHeader.biBitCount <= 8)
nc = 1 << bi->bmiHeader.biBitCount;
if ((hbmp = CreateDIBitmap(hdc, &bi->bmiHeader,
if ((hbmp = CreateDIBitmap( hdc, &bi->bmiHeader,
CBM_INIT, (char*)(bi + 1) + nc * sizeof(RGBQUAD),
bi, DIB_RGB_COLORS)))
ME_RTFInsertOleObject(info, NULL, hbmp, &sz);
ReleaseDC(0, hdc);
}
bi, DIB_RGB_COLORS)) )
ME_RTFInsertOleObject( info, NULL, hbmp, &sz );
ReleaseDC( 0, hdc );
break;
}
default:
break;
}
HeapFree(GetProcessHeap(), 0, buffer);
RTFRouteToken (info); /* feed "}" back to router */
}
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 */
}
/* for now, lookup the \result part and use it, whatever the object */
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment