Module: wine Branch: master Commit: cfc891420096c8e999ee5b955d57b20742b768c7 URL: http://source.winehq.org/git/wine.git/?a=commit;h=cfc891420096c8e999ee5b955d...
Author: Huw Davies huw@codeweavers.com Date: Wed Oct 28 12:49:55 2015 +0000
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
---
dlls/riched20/editor.c | 265 +++++++++++++++++++++++++++---------------------- 1 file changed, 145 insertions(+), 120 deletions(-)
diff --git a/dlls/riched20/editor.c b/dlls/riched20/editor.c index ae4a3ab..31d134f 100644 --- a/dlls/riched20/editor.c +++ b/dlls/riched20/editor.c @@ -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; - BYTE val; - METAFILEPICT mfp; - HENHMETAFILE hemf; - HBITMAP hbmp; - enum gfxkind {gfx_unknown = 0, gfx_enhmetafile, gfx_metafile, gfx_dib} gfx = gfx_unknown; - - RTFGetToken (info); - if (info->rtfClass == rtfEOF) - return; - mfp.mm = MM_TEXT; - /* fetch picture type */ - if (RTFCheckMM (info, rtfPictAttr, rtfWinMetafile)) - { - mfp.mm = info->rtfParam; - gfx = gfx_metafile; - } - else if (RTFCheckMM (info, rtfPictAttr, rtfDevIndBitmap)) - { - 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 - { - 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)) - { - if (gfx == gfx_metafile) mfp.xExt = info->rtfParam; - } - else if (RTFCheckMM (info, rtfPictAttr, rtfPicHt)) + 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) { - if (gfx == gfx_metafile) mfp.yExt = info->rtfParam; + ERR("Called with incorrect token\n"); + return 0; } - 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) + + val = info->rtfMajor; + for (flip = TRUE;; flip = !flip) { - HeapFree(GetProcessHeap(), 0, buffer); - return; /* Warn ?? */ + 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 (RTFCheckCM(info, rtfGroup, rtfEndGroup)) - break; - if (info->rtfClass != rtfText) goto skip_group; - if (flip) + 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; + + for (;;) { - if (bufidx >= bufsz && - !(buffer = HeapReAlloc(GetProcessHeap(), 0, buffer, bufsz += 1024))) - goto skip_group; - buffer[bufidx++] = RTFCharToHex(val) * 16 + RTFCharToHex(info->rtfMajor); + 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 )) + { + mfp.mm = info->rtfParam; + gfx = gfx_metafile; + } + else if (RTFCheckMM( info, rtfPictAttr, rtfDevIndBitmap )) + { + 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 + FIXME("Non supported attribute: %d %d %d\n", info->rtfClass, info->rtfMajor, info->rtfMinor); } - else - val = info->rtfMajor; - } - if (flip) FIXME("wrong hex string\n");
- switch (gfx) - { - case gfx_enhmetafile: - if ((hemf = SetEnhMetaFileBits(bufidx, buffer))) - ME_RTFInsertOleObject(info, hemf, NULL, &sz); - break; - case gfx_metafile: - if ((hemf = SetWinMetaFileBits(bufidx, buffer, NULL, &mfp))) - ME_RTFInsertOleObject(info, hemf, NULL, &sz); - break; - case gfx_dib: + if (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, - CBM_INIT, (char*)(bi + 1) + nc * sizeof(RGBQUAD), - bi, DIB_RGB_COLORS))) - ME_RTFInsertOleObject(info, NULL, hbmp, &sz); - ReleaseDC(0, hdc); + switch (gfx) + { + case gfx_enhmetafile: + if ((hemf = SetEnhMetaFileBits( size, buffer ))) + ME_RTFInsertOleObject( info, hemf, NULL, &sz ); + break; + case gfx_metafile: + if ((hemf = SetWinMetaFileBits( size, buffer, NULL, &mfp ))) + ME_RTFInsertOleObject( info, hemf, NULL, &sz ); + break; + case gfx_dib: + { + 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, + CBM_INIT, (char*)(bi + 1) + nc * sizeof(RGBQUAD), + bi, DIB_RGB_COLORS)) ) + ME_RTFInsertOleObject( info, NULL, hbmp, &sz ); + ReleaseDC( 0, hdc ); + break; + } + default: + break; + } } - break; - default: - break; - } - 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 */ + HeapFree( GetProcessHeap(), 0, buffer ); + RTFRouteToken( info ); /* feed "}" back to router */ + return; }
/* for now, lookup the \result part and use it, whatever the object */