winhelp: improved metafile support

Kirill K. Smirnov lich at math.spbu.ru
Mon Oct 16 12:02:23 CDT 2006


ChangeLog:
  Improved metafile support

-------------- next part --------------
diff --git a/programs/winhelp/hlpfile.c b/programs/winhelp/hlpfile.c
index 2e64270..04e5645 100644
--- a/programs/winhelp/hlpfile.c
+++ b/programs/winhelp/hlpfile.c
@@ -654,16 +654,17 @@ static BOOL     HLPFILE_LoadMetaFile(BYT
     unsigned long       size, csize;
     unsigned long       off, hsoff;
     BYTE*               bits;
-    METAFILEPICT        mfp;
+    LPMETAFILEPICT      lpmfp;
 
     WINE_TRACE("Loading metafile\n");
 
     ptr = beg + 2; /* for type and pack */
 
-    mfp.mm = fetch_ushort(&ptr); /* mapping mode */
+    lpmfp = &paragraph->u.gfx.u.mfp;
+    lpmfp->mm = fetch_ushort(&ptr); /* mapping mode */
 
-    mfp.xExt = GET_USHORT(ptr, 0);
-    mfp.yExt = GET_USHORT(ptr, 2);
+    lpmfp->xExt = GET_USHORT(ptr, 0);
+    lpmfp->yExt = GET_USHORT(ptr, 2);
     ptr += 4;
 
     size = fetch_ulong(&ptr); /* decompressed size */
@@ -674,25 +675,20 @@ static BOOL     HLPFILE_LoadMetaFile(BYT
     ptr += 8;
 
     WINE_TRACE("sz=%lu csz=%lu (%d,%d) offs=%lu/%u,%lu\n",
-               size, csize, mfp.xExt, mfp.yExt, off, ptr - beg, hsoff);
+               size, csize, lpmfp->xExt, lpmfp->yExt, off, ptr - beg, hsoff);
 
     bits = HLPFILE_DecompressGfx(beg + off, csize, size, pack);
     if (!bits) return FALSE;
 
     paragraph->cookie = para_metafile;
 
-    mfp.hMF = NULL;
+    lpmfp->hMF = SetMetaFileBitsEx(size, bits);
 
-    paragraph->u.gfx.u.mf.hMetaFile = SetMetaFileBitsEx(size, bits);
-
-    if (!paragraph->u.gfx.u.mf.hMetaFile)
+    if (!lpmfp->hMF)
         WINE_FIXME("Couldn't load metafile\n");
 
     if (bits != beg + off) HeapFree(GetProcessHeap(), 0, bits);
 
-    paragraph->u.gfx.u.mf.mfSize.cx = mfp.xExt;
-    paragraph->u.gfx.u.mf.mfSize.cy = mfp.yExt;
-
     return TRUE;
 }
 
@@ -1930,7 +1926,7 @@ static void HLPFILE_DeleteParagraph(HLPF
         next = paragraph->next;
 
         if (paragraph->cookie == para_metafile)
-            DeleteMetaFile(paragraph->u.gfx.u.mf.hMetaFile);
+            DeleteMetaFile(paragraph->u.gfx.u.mfp.hMF);
 
         HLPFILE_FreeLink(paragraph->link);
 
diff --git a/programs/winhelp/hlpfile.h b/programs/winhelp/hlpfile.h
index 0818ca1..2f3ffed 100644
--- a/programs/winhelp/hlpfile.h
+++ b/programs/winhelp/hlpfile.h
@@ -69,11 +69,7 @@ typedef struct tagHlpFileParagraph
                 {
                     HBITMAP             hBitmap;
                 } bmp;
-                struct
-                {
-                    HMETAFILE           hMetaFile;
-                    SIZE                mfSize;
-                } mf;
+                METAFILEPICT            mfp;
             } u;
         } gfx; /* for bitmaps and metafiles */
     } u;
diff --git a/programs/winhelp/winhelp.c b/programs/winhelp/winhelp.c
index 9cf7993..40921a9 100644
--- a/programs/winhelp/winhelp.c
+++ b/programs/winhelp/winhelp.c
@@ -1049,11 +1049,35 @@ static LRESULT CALLBACK WINHELP_TextWndP
                     break;
                 case hlp_line_part_metafile:
                     {
-                        POINT   pt;
+                        HDC hMemDC;
+                        HBITMAP hBitmap;
+                        SIZE sz;
+                        RECT rc;
 
-                        SetViewportOrgEx(hDc, part->rect.left, part->rect.top - scroll_pos, &pt);
-                        PlayMetaFile(hDc, part->u.metafile.hMetaFile);
-                        SetViewportOrgEx(hDc, pt.x, pt.y, NULL);
+                        sz.cx = part->rect.right - part->rect.left;
+                        sz.cy = part->rect.bottom - part->rect.top;
+                        hMemDC = CreateCompatibleDC(hDc);
+                        hBitmap = CreateCompatibleBitmap(hDc, sz.cx, sz.cy);
+                        SelectObject(hMemDC, hBitmap);
+                        SelectObject(hMemDC, win->hBrush);
+                        rc.left = 0;
+                        rc.top = 0;
+                        rc.right = sz.cx;
+                        rc.bottom = sz.cy;
+                        FillRect(hMemDC, &rc, win->hBrush);
+                        SetMapMode(hMemDC, part->u.metafile.mm);
+                        SetWindowExtEx(hMemDC, sz.cx, sz.cy, 0);
+                        SetViewportExtEx(hMemDC, sz.cx, sz.cy, 0);
+                        SetWindowOrgEx(hMemDC, 0, 0, 0);
+                        SetViewportOrgEx(hMemDC, 0, 0, 0);
+                        PlayMetaFile(hMemDC, part->u.metafile.hMetaFile);
+                        SetMapMode(hMemDC, MM_TEXT);
+                        SetWindowOrgEx(hMemDC, 0, 0, 0);
+                        SetViewportOrgEx(hMemDC, 0, 0, 0);
+                        BitBlt(hDc, part->rect.left, part->rect.top - scroll_pos,
+                               sz.cx, sz.cy, hMemDC, 0, 0, SRCCOPY);
+                        DeleteDC(hMemDC);
+                        DeleteObject(hBitmap);
                     }
                     break;
                 }
@@ -1576,8 +1600,23 @@ static BOOL WINHELP_SplitLines(HWND hWnd
                     gfxSize.cx = dibs.dsBm.bmWidth;
                     gfxSize.cy = dibs.dsBm.bmHeight;
                 }
-                else gfxSize = p->u.gfx.u.mf.mfSize;
-                    
+                else
+                {
+                    LPMETAFILEPICT lpmfp = &p->u.gfx.u.mfp;
+                    if (lpmfp->mm == MM_ANISOTROPIC || lpmfp->mm == MM_ISOTROPIC)
+                    {
+                        gfxSize.cx = MulDiv(lpmfp->xExt, GetDeviceCaps(hDc, HORZRES),
+                                            100*GetDeviceCaps(hDc, HORZSIZE));
+                        gfxSize.cy = MulDiv(lpmfp->yExt, GetDeviceCaps(hDc, VERTRES),
+                                            100*GetDeviceCaps(hDc, VERTSIZE));
+                    }
+                    else
+                    {
+                        gfxSize.cx = lpmfp->xExt;
+                        gfxSize.cy = lpmfp->yExt;
+                    }
+                }
+
                 free_width = rect.right - ((part && *line) ? (*line)->rect.right : rect.left) - space.cx;
                 if (free_width <= 0)
                 {
@@ -1599,7 +1638,8 @@ static BOOL WINHELP_SplitLines(HWND hWnd
                 else
                 {
                     ref_part->cookie = hlp_line_part_metafile;
-                    ref_part->u.metafile.hMetaFile = p->u.gfx.u.mf.hMetaFile;
+                    ref_part->u.metafile.hMetaFile = p->u.gfx.u.mfp.hMF;
+                    ref_part->u.metafile.mm = p->u.gfx.u.mfp.mm;
                 }
             }
             break;
diff --git a/programs/winhelp/winhelp.h b/programs/winhelp/winhelp.h
index b7227bf..7b10019 100644
--- a/programs/winhelp/winhelp.h
+++ b/programs/winhelp/winhelp.h
@@ -62,6 +62,7 @@ typedef struct tagHelpLinePart
         struct
         {
             HMETAFILE   hMetaFile;
+            INT         mm;
         } metafile;
     } u;
     HLPFILE_LINK*       link;


More information about the wine-patches mailing list