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

Alexandre Julliard julliard at wine.codeweavers.com
Wed Oct 28 10:16:15 CDT 2015


Module: wine
Branch: master
Commit: cfc891420096c8e999ee5b955d57b20742b768c7
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=cfc891420096c8e999ee5b955d57b20742b768c7

Author: Huw Davies <huw at 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 at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at 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 */




More information about the wine-cvs mailing list