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: Huw Davies <huw@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
899207b6c9
commit
cfc8914200
|
@ -1236,23 +1236,102 @@ static BOOL ME_RTFInsertOleObject(RTF_Info *info, HENHMETAFILE hemf, HBITMAP hbm
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static DWORD read_hex_data( RTF_Info *info, BYTE **out )
|
||||||
|
{
|
||||||
|
DWORD read = 0, size = 1024;
|
||||||
|
BYTE *buf = HeapAlloc( GetProcessHeap(), 0, size );
|
||||||
|
BYTE val;
|
||||||
|
BOOL flip;
|
||||||
|
|
||||||
|
*out = NULL;
|
||||||
|
if (!buf) return 0;
|
||||||
|
|
||||||
|
if (info->rtfClass != rtfText)
|
||||||
|
{
|
||||||
|
ERR("Called with incorrect token\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
val = info->rtfMajor;
|
||||||
|
for (flip = TRUE;; flip = !flip)
|
||||||
|
{
|
||||||
|
RTFGetToken( info );
|
||||||
|
if (info->rtfClass == rtfEOF)
|
||||||
|
{
|
||||||
|
HeapFree( GetProcessHeap(), 0, buf );
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if (info->rtfClass != rtfText) break;
|
||||||
|
if (flip)
|
||||||
|
{
|
||||||
|
if (read >= size)
|
||||||
|
{
|
||||||
|
size *= 2;
|
||||||
|
buf = HeapReAlloc( GetProcessHeap(), 0, buf, size );
|
||||||
|
if (!buf) return 0;
|
||||||
|
}
|
||||||
|
buf[read++] = RTFCharToHex(val) * 16 + RTFCharToHex(info->rtfMajor);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
val = info->rtfMajor;
|
||||||
|
}
|
||||||
|
if (flip) FIXME("wrong hex string\n");
|
||||||
|
|
||||||
|
*out = buf;
|
||||||
|
return read;
|
||||||
|
}
|
||||||
|
|
||||||
static void ME_RTFReadPictGroup(RTF_Info *info)
|
static void ME_RTFReadPictGroup(RTF_Info *info)
|
||||||
{
|
{
|
||||||
SIZEL sz;
|
SIZEL sz;
|
||||||
BYTE *buffer = NULL;
|
BYTE *buffer = NULL;
|
||||||
unsigned bufsz, bufidx;
|
DWORD size = 0;
|
||||||
BOOL flip;
|
|
||||||
BYTE val;
|
|
||||||
METAFILEPICT mfp;
|
METAFILEPICT mfp;
|
||||||
HENHMETAFILE hemf;
|
HENHMETAFILE hemf;
|
||||||
HBITMAP hbmp;
|
HBITMAP hbmp;
|
||||||
enum gfxkind {gfx_unknown = 0, gfx_enhmetafile, gfx_metafile, gfx_dib} gfx = gfx_unknown;
|
enum gfxkind {gfx_unknown = 0, gfx_enhmetafile, gfx_metafile, gfx_dib} gfx = gfx_unknown;
|
||||||
|
int level = 1;
|
||||||
|
|
||||||
RTFGetToken (info);
|
|
||||||
if (info->rtfClass == rtfEOF)
|
|
||||||
return;
|
|
||||||
mfp.mm = MM_TEXT;
|
mfp.mm = MM_TEXT;
|
||||||
/* fetch picture type */
|
sz.cx = sz.cy = 0;
|
||||||
|
|
||||||
|
for (;;)
|
||||||
|
{
|
||||||
|
RTFGetToken( info );
|
||||||
|
|
||||||
|
if (info->rtfClass == rtfText)
|
||||||
|
{
|
||||||
|
if (level == 1)
|
||||||
|
{
|
||||||
|
if (!buffer)
|
||||||
|
size = read_hex_data( info, &buffer );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
RTFSkipGroup( info );
|
||||||
|
}
|
||||||
|
} /* We potentially have a new token so fall through. */
|
||||||
|
|
||||||
|
if (info->rtfClass == rtfEOF) return;
|
||||||
|
|
||||||
|
if (RTFCheckCM( info, rtfGroup, rtfEndGroup ))
|
||||||
|
{
|
||||||
|
if (--level == 0) break;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (RTFCheckCM( info, rtfGroup, rtfBeginGroup ))
|
||||||
|
{
|
||||||
|
level++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (!RTFCheckCM( info, rtfControl, rtfPictAttr ))
|
||||||
|
{
|
||||||
|
RTFRouteToken( info );
|
||||||
|
if (RTFCheckCM( info, rtfGroup, rtfEndGroup ))
|
||||||
|
level--;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
if (RTFCheckMM( info, rtfPictAttr, rtfWinMetafile ))
|
if (RTFCheckMM( info, rtfPictAttr, rtfWinMetafile ))
|
||||||
{
|
{
|
||||||
mfp.mm = info->rtfParam;
|
mfp.mm = info->rtfParam;
|
||||||
|
@ -1264,37 +1343,11 @@ static void ME_RTFReadPictGroup(RTF_Info *info)
|
||||||
gfx = gfx_dib;
|
gfx = gfx_dib;
|
||||||
}
|
}
|
||||||
else if (RTFCheckMM( info, rtfPictAttr, rtfEmfBlip ))
|
else if (RTFCheckMM( info, rtfPictAttr, rtfEmfBlip ))
|
||||||
{
|
|
||||||
gfx = gfx_enhmetafile;
|
gfx = gfx_enhmetafile;
|
||||||
}
|
|
||||||
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 ))
|
else if (RTFCheckMM( info, rtfPictAttr, rtfPicWid ))
|
||||||
{
|
mfp.xExt = info->rtfParam;
|
||||||
if (gfx == gfx_metafile) mfp.xExt = info->rtfParam;
|
|
||||||
}
|
|
||||||
else if (RTFCheckMM( info, rtfPictAttr, rtfPicHt ))
|
else if (RTFCheckMM( info, rtfPictAttr, rtfPicHt ))
|
||||||
{
|
mfp.yExt = info->rtfParam;
|
||||||
if (gfx == gfx_metafile) mfp.yExt = info->rtfParam;
|
|
||||||
}
|
|
||||||
else if (RTFCheckMM( info, rtfPictAttr, rtfPicGoalWid ))
|
else if (RTFCheckMM( info, rtfPictAttr, rtfPicGoalWid ))
|
||||||
sz.cx = info->rtfParam;
|
sz.cx = info->rtfParam;
|
||||||
else if (RTFCheckMM( info, rtfPictAttr, rtfPicGoalHt ))
|
else if (RTFCheckMM( info, rtfPictAttr, rtfPicGoalHt ))
|
||||||
|
@ -1302,42 +1355,17 @@ static void ME_RTFReadPictGroup(RTF_Info *info)
|
||||||
else
|
else
|
||||||
FIXME("Non supported attribute: %d %d %d\n", info->rtfClass, info->rtfMajor, info->rtfMinor);
|
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 (buffer)
|
||||||
|
{
|
||||||
switch (gfx)
|
switch (gfx)
|
||||||
{
|
{
|
||||||
case gfx_enhmetafile:
|
case gfx_enhmetafile:
|
||||||
if ((hemf = SetEnhMetaFileBits(bufidx, buffer)))
|
if ((hemf = SetEnhMetaFileBits( size, buffer )))
|
||||||
ME_RTFInsertOleObject( info, hemf, NULL, &sz );
|
ME_RTFInsertOleObject( info, hemf, NULL, &sz );
|
||||||
break;
|
break;
|
||||||
case gfx_metafile:
|
case gfx_metafile:
|
||||||
if ((hemf = SetWinMetaFileBits(bufidx, buffer, NULL, &mfp)))
|
if ((hemf = SetWinMetaFileBits( size, buffer, NULL, &mfp )))
|
||||||
ME_RTFInsertOleObject( info, hemf, NULL, &sz );
|
ME_RTFInsertOleObject( info, hemf, NULL, &sz );
|
||||||
break;
|
break;
|
||||||
case gfx_dib:
|
case gfx_dib:
|
||||||
|
@ -1354,18 +1382,15 @@ static void ME_RTFReadPictGroup(RTF_Info *info)
|
||||||
bi, DIB_RGB_COLORS)) )
|
bi, DIB_RGB_COLORS)) )
|
||||||
ME_RTFInsertOleObject( info, NULL, hbmp, &sz );
|
ME_RTFInsertOleObject( info, NULL, hbmp, &sz );
|
||||||
ReleaseDC( 0, hdc );
|
ReleaseDC( 0, hdc );
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
HeapFree( GetProcessHeap(), 0, buffer );
|
HeapFree( GetProcessHeap(), 0, buffer );
|
||||||
RTFRouteToken( info ); /* feed "}" back to router */
|
RTFRouteToken( info ); /* feed "}" back to router */
|
||||||
return;
|
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 */
|
/* for now, lookup the \result part and use it, whatever the object */
|
||||||
|
|
Loading…
Reference in New Issue