[PATCH 1/2] winhlp32: fix table formatting

Jean-Christophe Cardot jeanchristophe.cardot at gmail.com
Mon Dec 21 13:59:58 CST 2015


Fixes https://bugs.winehq.org/show_bug.cgi?id=20977
Fixes https://bugs.winehq.org/show_bug.cgi?id=14288

Fix bugs in the handling of the hlp values in order to generate correct
rtf tables; Read the DPI from the registry (instead of hardcoded 72);
Use font scaling (depends on the version) to compute the rtf values
so that the columns width are correct and precise (compared with MS
winhlp32.exe); Add some comments and DEFINES tu make the code easier
to understand.
This is a first step into making wine's winhlp much better at handling
hlp files and - when time permits - mvp files.

Tested on Linux (Mageia 5)

Signed-off-by: Jean-Christophe Cardot <wine at cardot.net>
---
 programs/winhlp32/hlpfile.c | 361 ++++++++++++++++++++++++++++++--------------
 programs/winhlp32/hlpfile.h |  11 +-
 programs/winhlp32/winhelp.c |   2 +-
 3 files changed, 260 insertions(+), 114 deletions(-)

diff --git a/programs/winhlp32/hlpfile.c b/programs/winhlp32/hlpfile.c
index ab75b2a..e6e386a 100644
--- a/programs/winhlp32/hlpfile.c
+++ b/programs/winhlp32/hlpfile.c
@@ -28,10 +28,17 @@
 #include "winbase.h"
 #include "wingdi.h"
 #include "winuser.h"
+#include "winreg.h"
 #include "winhelp.h"
 
 #include "wine/debug.h"
 
+#define DEFDPI 96
+static const WCHAR logpixels_reg[] = 
{'S','y','s','t','e','m','\\','C','u','r','r','e','n','t','C','o','n','t','r','o','l','S','e','t','\\','H','a','r','d','w','a','r','e',' 
','P','r','o','f','i','l','e','s','\\','C','u','r','r','e','n','t','\\','S','o','f','t','w','a','r','e','\\','F','o','n','t','s',0};
+static const WCHAR logpixels[] = {'L','o','g','P','i','x','e','l','s',0};
+
+static INT screen_dpi;
+
 WINE_DEFAULT_DEBUG_CHANNEL(winhelp);
 
 static inline unsigned short GET_USHORT(const BYTE* buffer, unsigned i)
@@ -693,6 +700,7 @@ static BOOL HLPFILE_RtfAddRawString(struct RtfData* rd, 
const char* str, size_t
 
 static BOOL HLPFILE_RtfAddControl(struct RtfData* rd, const char* str)
 {
+    WINE_TRACE("HLPFILE_RtfAddControl: %s\n", str);
     if (*str == '\\' || *str == '{') rd->in_text = FALSE;
     else if (*str == '}') rd->in_text = TRUE;
     return HLPFILE_RtfAddRawString(rd, str, strlen(str));
@@ -1198,7 +1206,7 @@ static HLPFILE_LINK*       HLPFILE_AllocLink(struct 
RtfData* rd, int cookie,
     return link;
 }
 
-static unsigned HLPFILE_HalfPointsToTwips(unsigned pts)
+static unsigned HLPFILE_HalfPointsToTwips(HLPFILE_PAGE* page, unsigned pts)
 {
     static unsigned logPxY;
     if (!logPxY)
@@ -1207,7 +1215,8 @@ static unsigned HLPFILE_HalfPointsToTwips(unsigned pts)
         logPxY = GetDeviceCaps(hdc, LOGPIXELSY);
         ReleaseDC(NULL, hdc);
     }
-    return MulDiv(pts, 72 * 10, logPxY);
+    /* For the DPI, use the value previously read from the registry */
+    return MulDiv(pts, screen_dpi * page->file->scale - page->file->rounderr, 
logPxY);
 }
 
 /***********************************************************************
@@ -1222,9 +1231,8 @@ static BOOL HLPFILE_BrowseParagraph(HLPFILE_PAGE* page, 
struct RtfData* rd,
     char              *text, *text_base, *text_end;
     LONG               size, blocksize, datalen;
     unsigned short     bits;
-    unsigned           nc, ncol = 1;
-    short              table_width;
-    BOOL               in_table = FALSE;
+    unsigned           ncol = 1;
+    short              nc, lastcol, table_width;
     char               tmp[256];
     BOOL               ret = FALSE;
 
@@ -1258,27 +1266,29 @@ static BOOL HLPFILE_BrowseParagraph(HLPFILE_PAGE* 
page, struct RtfData* rd,
     format = buf + 0x15;
     format_end = buf + GET_UINT(buf, 0x10);
 
-    if (buf[0x14] == 0x20 || buf[0x14] == 0x23)
+    WINE_TRACE("Record type (buf[0x14]) = 0x%x\n", buf[0x14]);
+
+    if (buf[0x14] == HLP_DISPLAY || buf[0x14] == HLP_TABLE)
     {
         fetch_long(&format);
         *parlen = fetch_ushort(&format);
     }
 
-    if (buf[0x14] == 0x23)
+    if (buf[0x14] == HLP_TABLE)
     {
-        char    type;
+        unsigned char    type;
 
-        in_table = TRUE;
         ncol = *format++;
 
         if (!HLPFILE_RtfAddControl(rd, "\\trowd")) goto done;
         type = *format++;
-        if (type == 0 || type == 2)
+        if (type == 0 || type == 2) /* variable width table */
         {
-            table_width = GET_SHORT(format, 0);
+            table_width = GET_SHORT(format, 0); /* min table width */
             format += 2;
+            if (!HLPFILE_RtfAddControl(rd, "\\trqc")) goto done;
         }
-        else
+        else /* type == 1 || type == 3 */ /* normal table */
             table_width = 32767;
         WINE_TRACE("New table: cols=%d type=%x width=%d\n",
                    ncol, type, table_width);
@@ -1286,10 +1296,11 @@ static BOOL HLPFILE_BrowseParagraph(HLPFILE_PAGE* 
page, struct RtfData* rd,
         {
             int     pos;
             sprintf(tmp, "\\trgaph%d\\trleft%d",
-                    HLPFILE_HalfPointsToTwips(MulDiv(GET_SHORT(format, 6), 
table_width, 32767)),
-                    HLPFILE_HalfPointsToTwips(MulDiv(GET_SHORT(format, 0), 
table_width, 32767)));
+                    HLPFILE_HalfPointsToTwips(page, MulDiv(GET_SHORT(format, 
6), table_width, 32767)),
+                    HLPFILE_HalfPointsToTwips(page, MulDiv(GET_SHORT(format, 
2) - GET_SHORT(format, 6), table_width, 32767)) - 1
+                   ); 
             if (!HLPFILE_RtfAddControl(rd, tmp)) goto done;
-            pos = HLPFILE_HalfPointsToTwips(MulDiv(GET_SHORT(format, 6) / 2, 
table_width, 32767));
+            pos = GET_SHORT(format, 6) / 2;
             for (nc = 0; nc < ncol; nc++)
             {
                 WINE_TRACE("column(%d/%d) gap=%d width=%d\n",
@@ -1297,7 +1308,7 @@ static BOOL HLPFILE_BrowseParagraph(HLPFILE_PAGE* page, 
struct RtfData* rd,
                            GET_SHORT(format, nc*4+2));
                 pos += GET_SHORT(format, nc * 4) + GET_SHORT(format, nc * 4 + 
2);
                 sprintf(tmp, "\\cellx%d",
-                        HLPFILE_HalfPointsToTwips(MulDiv(pos, table_width, 
32767)));
+                        HLPFILE_HalfPointsToTwips(page, MulDiv(pos, 
table_width, 32767)));
                 if (!HLPFILE_RtfAddControl(rd, tmp)) goto done;
             }
         }
@@ -1306,27 +1317,32 @@ static BOOL HLPFILE_BrowseParagraph(HLPFILE_PAGE* 
page, struct RtfData* rd,
             WINE_TRACE("column(0/%d) gap=%d width=%d\n",
                        ncol, GET_SHORT(format, 0), GET_SHORT(format, 2));
             sprintf(tmp, "\\trleft%d\\cellx%d ",
-                    HLPFILE_HalfPointsToTwips(MulDiv(GET_SHORT(format, 0), 
table_width, 32767)),
-                    HLPFILE_HalfPointsToTwips(MulDiv(GET_SHORT(format, 0) + 
GET_SHORT(format, 2),
-                                      table_width, 32767)));
+                    HLPFILE_HalfPointsToTwips(page, MulDiv(GET_SHORT(format, 
2), table_width, 32767)) - 1,
+                    HLPFILE_HalfPointsToTwips(page, MulDiv(GET_SHORT(format, 
0), table_width, 32767)));
             if (!HLPFILE_RtfAddControl(rd, tmp)) goto done;
         }
         format += ncol * 4;
     }
 
+    lastcol = -1;
     for (nc = 0; nc < ncol; /**/)
     {
         WINE_TRACE("looking for format at offset %lu in column %d\n", (SIZE_T)
(format - (buf + 0x15)), nc);
         if (!HLPFILE_RtfAddControl(rd, "\\pard")) goto done;
-        if (in_table)
+        if (buf[0x14] == HLP_TABLE)
         {
-            nc = GET_SHORT(format, 0);
-            if (nc == -1) break;
+            nc = lastcol = GET_SHORT(format, 0);
+            if (nc == -1) /* last column */
+            {
+                if (!HLPFILE_RtfAddControl(rd, "\\row")) goto done;
+                rd->char_pos += 2;
+                break;
+            }
             format += 5;
             if (!HLPFILE_RtfAddControl(rd, "\\intbl")) goto done;
         }
         else nc++;
-        if (buf[0x14] == 0x01)
+        if (buf[0x14] == HLP_DISPLAY30)
             format += 6;
         else
             format += 4;
@@ -1334,32 +1350,32 @@ static BOOL HLPFILE_BrowseParagraph(HLPFILE_PAGE* 
page, struct RtfData* rd,
         if (bits & 0x0001) fetch_long(&format);
         if (bits & 0x0002)
         {
-            sprintf(tmp, "\\sb%d", 
HLPFILE_HalfPointsToTwips(fetch_short(&format)));
+            sprintf(tmp, "\\sb%d", HLPFILE_HalfPointsToTwips(page, 
fetch_short(&format)));
             if (!HLPFILE_RtfAddControl(rd, tmp)) goto done;
         }
         if (bits & 0x0004)
         {
-            sprintf(tmp, "\\sa%d", 
HLPFILE_HalfPointsToTwips(fetch_short(&format)));
+            sprintf(tmp, "\\sa%d", HLPFILE_HalfPointsToTwips(page, 
fetch_short(&format)));
             if (!HLPFILE_RtfAddControl(rd, tmp)) goto done;
         }
         if (bits & 0x0008)
         {
-            sprintf(tmp, "\\sl%d", 
HLPFILE_HalfPointsToTwips(fetch_short(&format)));
+            sprintf(tmp, "\\sl%d", HLPFILE_HalfPointsToTwips(page, 
fetch_short(&format)));
             if (!HLPFILE_RtfAddControl(rd, tmp)) goto done;
         }
         if (bits & 0x0010)
         {
-            sprintf(tmp, "\\li%d", 
HLPFILE_HalfPointsToTwips(fetch_short(&format)));
+            sprintf(tmp, "\\li%d", HLPFILE_HalfPointsToTwips(page, 
fetch_short(&format)));
             if (!HLPFILE_RtfAddControl(rd, tmp)) goto done;
         }
         if (bits & 0x0020)
         {
-            sprintf(tmp, "\\ri%d", 
HLPFILE_HalfPointsToTwips(fetch_short(&format)));
+            sprintf(tmp, "\\ri%d", HLPFILE_HalfPointsToTwips(page, 
fetch_short(&format)));
             if (!HLPFILE_RtfAddControl(rd, tmp)) goto done;
         }
         if (bits & 0x0040)
         {
-            sprintf(tmp, "\\fi%d", 
HLPFILE_HalfPointsToTwips(fetch_short(&format)));
+            sprintf(tmp, "\\fi%d", HLPFILE_HalfPointsToTwips(page, 
fetch_short(&format)));
             if (!HLPFILE_RtfAddControl(rd, tmp)) goto done;
         }
         if (bits & 0x0100)
@@ -1380,7 +1396,7 @@ static BOOL HLPFILE_BrowseParagraph(HLPFILE_PAGE* page, 
struct RtfData* rd,
             w = GET_SHORT(format, 0); format += 2;
             if (w)
             {
-                sprintf(tmp, "\\brdrw%d", HLPFILE_HalfPointsToTwips(w));
+                sprintf(tmp, "\\brdrw%d", HLPFILE_HalfPointsToTwips(page, 
w));
                 if (!HLPFILE_RtfAddControl(rd, tmp)) goto done;
             }
         }
@@ -1404,7 +1420,7 @@ static BOOL HLPFILE_BrowseParagraph(HLPFILE_PAGE* page, 
struct RtfData* rd,
                 }
                 /* FIXME: do kind */
                 sprintf(tmp, "%s\\tx%d",
-                        kind, HLPFILE_HalfPointsToTwips(tab & 0x3FFF));
+                        kind, HLPFILE_HalfPointsToTwips(page, tab & 0x3FFF));
                 if (!HLPFILE_RtfAddControl(rd, tmp)) goto done;
             }
         }
@@ -1440,27 +1456,45 @@ static BOOL HLPFILE_BrowseParagraph(HLPFILE_PAGE* 
page, struct RtfData* rd,
             /* else: null text, keep on storing attributes */
             text += textsize + 1;
 
-	    if (*format == 0xff)
+            WINE_TRACE("format=0x%02x\n", *format);
+            if (*format == 0xff)
             {
                 format++;
                 break;
             }
-
-            WINE_TRACE("format=%02x\n", *format);
-            switch (*format)
+            else switch (*format)
             {
-            case 0x20:
-                WINE_FIXME("NIY20\n");
-                format += 5;
+            case 0x20: /* vfld MVB */
+                ++format;
+                if (fetch_long(&format))
+                {
+                    sprintf(tmp, "\\{vfld%u\\}", fetch_long(&format));
+                }
+                else
+                {
+                    sprintf(tmp, "\\{vfld\\}");
+                }
+                if (!HLPFILE_RtfAddControl(rd, tmp)) goto done;
+                format += 4;
                 break;
 
-            case 0x21:
-                WINE_FIXME("NIY21\n");
-                format += 3;
+            case 0x21: /* dtype MVB */
+                ++format;
+                if (fetch_short(&format))
+                {
+                    sprintf(tmp, "\\{dtype%d\\}", fetch_short(&format));
+                }
+                else
+                {
+                    sprintf(tmp, "\\{dtype\\}");
+                }
+                if (!HLPFILE_RtfAddControl(rd, tmp)) goto done;
+                format += 2;
                 break;
 
-	    case 0x80:
+            case 0x80: /* font change */
                 {
+                    /* TODO: create a HLPFILE_FontChange function to better 
handle this */
                     unsigned    font = GET_USHORT(format, 1);
                     unsigned    fs;
 
@@ -1494,15 +1528,24 @@ static BOOL HLPFILE_BrowseParagraph(HLPFILE_PAGE* 
page, struct RtfData* rd,
                 break;
 
 	    case 0x82:
-                if (in_table)
+                if (buf[0x14] == HLP_TABLE)
                 {
                     if (format[1] != 0xFF)
                     {
                         if (!HLPFILE_RtfAddControl(rd, "\\par\\intbl")) goto 
done;
                     }
+                    else if (GET_SHORT(format, 2) == -1)
+                    {
+                        if (!HLPFILE_RtfAddControl(rd, "\\cell\\intbl\\row")) 
goto done;
+                        rd->char_pos += 2;
+                    }
+                    else if (GET_SHORT(format, 2) == lastcol)
+                    {
+                        if (!HLPFILE_RtfAddControl(rd, "\\par\\pard")) goto 
done;
+                    }
                     else
                     {
-                        if (!HLPFILE_RtfAddControl(rd, 
"\\cell\\pard\\intbl")) goto done;
+                        if (!HLPFILE_RtfAddControl(rd, "\\cell\\pard")) goto 
done;
                     }
                 }
                 else if (!HLPFILE_RtfAddControl(rd, "\\par")) goto done;
@@ -1567,7 +1610,7 @@ static BOOL HLPFILE_BrowseParagraph(HLPFILE_PAGE* page, 
struct RtfData* rd,
                 }
                 break;
 
-	    case 0x89:
+            case 0x89: /* hotspot end */
                 format += 1;
                 if (!rd->current_link)
                     WINE_FIXME("No existing link\n");
@@ -1617,6 +1660,7 @@ static BOOL HLPFILE_BrowseParagraph(HLPFILE_PAGE* page, 
struct RtfData* rd,
 	    case 0xE3:
             case 0xE6:
             case 0xE7:
+                WINE_WARN("jump topic 2 => %u\n", GET_UINT(format, 1));
                 HLPFILE_AllocLink(rd, (*format & 1) ? hlp_link_link : 
hlp_link_popup,
                                   page->file->lpszPath, -1, GET_UINT(format, 
1),
                                   !(*format & 4), FALSE, -1);
@@ -1667,18 +1711,88 @@ static BOOL HLPFILE_BrowseParagraph(HLPFILE_PAGE* 
page, struct RtfData* rd,
 	    }
 	}
     }
-    if (in_table)
-    {
-        if (!HLPFILE_RtfAddControl(rd, "\\row\\par\\pard\\plain")) goto done;
-        rd->char_pos += 2;
-    }
     ret = TRUE;
+
 done:
 
     HeapFree(GetProcessHeap(), 0, text_base);
     return ret;
 }
 
+static inline WCHAR *strdupW(const WCHAR *s)
+{
+    WCHAR *r = HeapAlloc(GetProcessHeap(), 0, (lstrlenW(s)+1)*sizeof(WCHAR));
+    return lstrcpyW(r, s);
+}
+
+/**
+ * get_config_key: Retrieves a configuration value from the registry
+ *
+ * char *subkey : the name of the config section
+ * char *name : the name of the config value
+ * char *default : if the key isn't found, return this value instead
+ *
+ * Returns a buffer holding the value if successful, NULL if
+ * not. Caller is responsible for releasing the result.
+ *
+ */
+static WCHAR *get_config_key (HKEY root, const WCHAR *subkey, const WCHAR 
*name, const WCHAR *def)
+{
+    LPWSTR buffer = NULL;
+    DWORD len;
+    HKEY hSubKey = NULL;
+    DWORD res;
+
+    WINE_TRACE("subkey=%s, name=%s, def=%s\n", wine_dbgstr_w(subkey),
+               wine_dbgstr_w(name), wine_dbgstr_w(def));
+
+    res = RegOpenKeyExW(root, subkey, 0, MAXIMUM_ALLOWED, &hSubKey);
+    if (res != ERROR_SUCCESS)
+    {
+        if (res == ERROR_FILE_NOT_FOUND)
+        {
+            WINE_TRACE("Section key not present - using default\n");
+            return def ? strdupW(def) : NULL;
+        }
+        else
+        {
+            WINE_ERR("RegOpenKey failed on wine config key (res=%d)\n", res);
+        }
+        goto end;
+    }
+
+    res = RegQueryValueExW(hSubKey, name, NULL, NULL, NULL, &len);
+    if (res == ERROR_FILE_NOT_FOUND)
+    {
+        WINE_TRACE("Value not present - using default\n");
+        buffer = def ? strdupW(def) : NULL;
+    goto end;
+    } else if (res != ERROR_SUCCESS)
+    {
+        WINE_ERR("Couldn't query value's length (res=%d)\n", res);
+        goto end;
+    }
+
+    buffer = HeapAlloc(GetProcessHeap(), 0, len + sizeof(WCHAR));
+
+    RegQueryValueExW(hSubKey, name, NULL, NULL, (LPBYTE) buffer, &len);
+
+    WINE_TRACE("buffer=%s\n", wine_dbgstr_w(buffer));
+end:
+    RegCloseKey(hSubKey);
+
+    return buffer;
+}
+
+static INT read_logpixels_reg(void)
+{
+    DWORD dwLogPixels;
+    WCHAR *buf = get_config_key(HKEY_LOCAL_MACHINE, logpixels_reg, logpixels, 
NULL);
+    dwLogPixels = buf ? *buf : DEFDPI;
+    HeapFree(GetProcessHeap(), 0, buf);
+    return dwLogPixels;
+}
+
 /******************************************************************
  *		HLPFILE_BrowsePage
  *
@@ -1702,6 +1816,8 @@ BOOL    HLPFILE_BrowsePage(HLPFILE_PAGE* page, struct 
RtfData* rd,
     rd->font_scale = font_scale;
     rd->relative = relative;
     rd->char_pos_rel = 0;
+    
+    screen_dpi = read_logpixels_reg();
 
     switch (hlpfile->charset)
     {
@@ -1799,12 +1915,12 @@ BOOL    HLPFILE_BrowsePage(HLPFILE_PAGE* page, struct 
RtfData* rd,
 
         switch (buf[0x14])
         {
-        case 0x02:
+        case HLP_TOPICHDR:
             if (count++) goto done;
             break;
-        case 0x01:
-        case 0x20:
-        case 0x23:
+        case HLP_DISPLAY30:
+        case HLP_DISPLAY:
+        case HLP_TABLE:
             if (!HLPFILE_BrowseParagraph(page, rd, buf, end, &parlen)) return 
FALSE;
             if (relative > index * 0x8000 + offs)
                 rd->char_pos_rel = rd->char_pos;
@@ -1861,65 +1977,86 @@ static BOOL HLPFILE_ReadFont(HLPFILE* hlpfile)
     hlpfile->fonts = HeapAlloc(GetProcessHeap(), 0, sizeof(HLPFILE_FONT) * 
dscr_num);
 
     len = (dscr_offset - face_offset) / face_num;
+
+    if (face_offset >= 16) /* mvb font */
+    {
+        hlpfile->scale = 1L;
+        hlpfile->rounderr = 0;
+        WINE_FIXME("mvb font: not implemented\n");
+    }
+    else if (face_offset >= 12) /* new font */
+    {
+        hlpfile->scale = 1L;
+        hlpfile->rounderr = 0;
+        WINE_FIXME("new font: not implemented\n");
+    }
+    else /* old font */
+    {
+        hlpfile->scale = 10L;
+        hlpfile->rounderr = 5;
 /* EPP     for (i = face_offset; i < dscr_offset; i += len) */
 /* EPP         WINE_FIXME("[%d]: %*s\n", i / len, len, ref + i); */
-    for (i = 0; i < dscr_num; i++)
-    {
-        flag = ref[dscr_offset + i * 11 + 0];
-        family = ref[dscr_offset + i * 11 + 2];
-
-        hlpfile->fonts[i].LogFont.lfHeight = ref[dscr_offset + i * 11 + 1];
-        hlpfile->fonts[i].LogFont.lfWidth = 0;
-        hlpfile->fonts[i].LogFont.lfEscapement = 0;
-        hlpfile->fonts[i].LogFont.lfOrientation = 0;
-        hlpfile->fonts[i].LogFont.lfWeight = (flag & 1) ? 700 : 400;
-        hlpfile->fonts[i].LogFont.lfItalic = (flag & 2) != 0;
-        hlpfile->fonts[i].LogFont.lfUnderline = (flag & 4) != 0;
-        hlpfile->fonts[i].LogFont.lfStrikeOut = (flag & 8) != 0;
-        hlpfile->fonts[i].LogFont.lfCharSet = hlpfile->charset;
-        hlpfile->fonts[i].LogFont.lfOutPrecision = OUT_DEFAULT_PRECIS;
-        hlpfile->fonts[i].LogFont.lfClipPrecision = CLIP_DEFAULT_PRECIS;
-        hlpfile->fonts[i].LogFont.lfQuality = DEFAULT_QUALITY;
-        hlpfile->fonts[i].LogFont.lfPitchAndFamily = DEFAULT_PITCH;
-
-        switch (family)
+        for (i = 0; i < dscr_num; i++)
         {
-        case 0x01: hlpfile->fonts[i].LogFont.lfPitchAndFamily |= FF_MODERN;     
break;
-        case 0x02: hlpfile->fonts[i].LogFont.lfPitchAndFamily |= FF_ROMAN;      
break;
-        case 0x03: hlpfile->fonts[i].LogFont.lfPitchAndFamily |= FF_SWISS;      
break;
-        case 0x04: hlpfile->fonts[i].LogFont.lfPitchAndFamily |= FF_SCRIPT;     
break;
-        case 0x05: hlpfile->fonts[i].LogFont.lfPitchAndFamily |= 
FF_DECORATIVE; break;
-        default: WINE_FIXME("Unknown family %u\n", family);
-        }
-        idx = GET_USHORT(ref, dscr_offset + i * 11 + 3);
+            flag = ref[dscr_offset + i * 11 + 0];
+            family = ref[dscr_offset + i * 11 + 2];
+
+            hlpfile->fonts[i].LogFont.lfHeight = ref[dscr_offset + i * 11 + 1];
+            hlpfile->fonts[i].LogFont.lfWidth = 0;
+            hlpfile->fonts[i].LogFont.lfEscapement = 0;
+            hlpfile->fonts[i].LogFont.lfOrientation = 0;
+            hlpfile->fonts[i].LogFont.lfWeight = (flag & 1) ? 700 : 400;
+            hlpfile->fonts[i].LogFont.lfItalic = (flag & 2) != 0;
+            hlpfile->fonts[i].LogFont.lfUnderline = (flag & 4) != 0;
+            hlpfile->fonts[i].LogFont.lfStrikeOut = (flag & 8) != 0;
+            /* TODO */
+            /* hlpfile->fonts[i].LogFont.lfDblUnderline = (flag & 0x10) != 0; 
*/
+            /* hlpfile->fonts[i].LogFont.lfSmallCaps = (flag & 0x20) != 0; */
+            hlpfile->fonts[i].LogFont.lfCharSet = hlpfile->charset;
+            hlpfile->fonts[i].LogFont.lfOutPrecision = OUT_DEFAULT_PRECIS;
+            hlpfile->fonts[i].LogFont.lfClipPrecision = CLIP_DEFAULT_PRECIS;
+            hlpfile->fonts[i].LogFont.lfQuality = DEFAULT_QUALITY;
+            hlpfile->fonts[i].LogFont.lfPitchAndFamily = DEFAULT_PITCH;
+
+            switch (family)
+            {
+                case 0x01: hlpfile->fonts[i].LogFont.lfPitchAndFamily |= 
FF_MODERN; break;
+                case 0x02: hlpfile->fonts[i].LogFont.lfPitchAndFamily |= 
FF_ROMAN; break;
+                case 0x03: hlpfile->fonts[i].LogFont.lfPitchAndFamily |= 
FF_SWISS; break;
+                case 0x04: hlpfile->fonts[i].LogFont.lfPitchAndFamily |= 
FF_SCRIPT; break;
+                case 0x05: hlpfile->fonts[i].LogFont.lfPitchAndFamily |= 
FF_DECORATIVE; break;
+                default: WINE_FIXME("Unknown family %u\n", family);
+            }
+            idx = GET_USHORT(ref, dscr_offset + i * 11 + 3);
 
-        if (idx < face_num)
-        {
-            memcpy(hlpfile->fonts[i].LogFont.lfFaceName, ref + face_offset + 
idx * len, min(len, LF_FACESIZE - 1));
-            hlpfile->fonts[i].LogFont.lfFaceName[min(len, LF_FACESIZE - 1)] = 
'\0';
-        }
-        else
-        {
-            WINE_FIXME("Too high face ref (%u/%u)\n", idx, face_num);
-            strcpy(hlpfile->fonts[i].LogFont.lfFaceName, "Helv");
-        }
-        hlpfile->fonts[i].hFont = 0;
-        hlpfile->fonts[i].color = RGB(ref[dscr_offset + i * 11 + 5],
-                                      ref[dscr_offset + i * 11 + 6],
-                                      ref[dscr_offset + i * 11 + 7]);
+            if (idx < face_num)
+            {
+                memcpy(hlpfile->fonts[i].LogFont.lfFaceName, ref + face_offset 
+ idx * len, min(len, LF_FACESIZE - 1));
+                hlpfile->fonts[i].LogFont.lfFaceName[min(len, LF_FACESIZE - 
1)] = '\0';
+            }
+            else
+            {
+                WINE_FIXME("Too high face ref (%u/%u)\n", idx, face_num);
+                strcpy(hlpfile->fonts[i].LogFont.lfFaceName, "Helv");
+            }
+            hlpfile->fonts[i].hFont = 0;
+            hlpfile->fonts[i].color = RGB(ref[dscr_offset + i * 11 + 5],
+                                          ref[dscr_offset + i * 11 + 6],
+                                          ref[dscr_offset + i * 11 + 7]);
 #define X(b,s) ((flag & (1 << b)) ? "-"s: "")
-        WINE_TRACE("Font[%d]: flags=%02x%s%s%s%s%s%s pSize=%u family=%u 
face=%s[%u] color=%08x\n",
-                   i, flag,
-                   X(0, "bold"),
-                   X(1, "italic"),
-                   X(2, "underline"),
-                   X(3, "strikeOut"),
-                   X(4, "dblUnderline"),
-                   X(5, "smallCaps"),
-                   ref[dscr_offset + i * 11 + 1],
-                   family,
-                   hlpfile->fonts[i].LogFont.lfFaceName, idx,
-                   GET_UINT(ref, dscr_offset + i * 11 + 5) & 0x00FFFFFF);
+            WINE_TRACE("Font[%d]: flags=%02x%s%s%s%s%s%s pSize=%u family=%u 
face=%s[%u] color=%08x\n",
+                       i, flag,
+                       X(0, "bold"),
+                       X(1, "italic"),
+                       X(2, "underline"),
+                       X(3, "strikeOut"),
+                       X(4, "dblUnderline"),
+                       X(5, "smallCaps"),
+                       ref[dscr_offset + i * 11 + 1],
+                       family,
+                       hlpfile->fonts[i].LogFont.lfFaceName, idx,
+                       GET_UINT(ref, dscr_offset + i * 11 + 5) & 0x00FFFFFF);
+        }
     }
     return TRUE;
 }
@@ -2680,7 +2817,7 @@ static BOOL HLPFILE_DoReadHlpFile(HLPFILE *hlpfile, 
LPCSTR lpszPath)
 
         switch (buf[0x14])
 	{
-	case 0x02:
+	case HLP_TOPICHDR: /* Topic Header */
             if (hlpfile->version <= 16)
                 topicoffset = ref + index * 12;
             else
@@ -2688,9 +2825,9 @@ static BOOL HLPFILE_DoReadHlpFile(HLPFILE *hlpfile, 
LPCSTR lpszPath)
             if (!HLPFILE_AddPage(hlpfile, buf, end, ref, topicoffset)) return 
FALSE;
             break;
 
-	case 0x01:
-	case 0x20:
-	case 0x23:
+	case HLP_DISPLAY30:
+	case HLP_DISPLAY:
+	case HLP_TABLE:
             if (!HLPFILE_SkipParagraph(hlpfile, buf, end, &len)) return FALSE;
             offs += len;
             break;
diff --git a/programs/winhlp32/hlpfile.h b/programs/winhlp32/hlpfile.h
index c3fa4b0..2bdec22 100644
--- a/programs/winhlp32/hlpfile.h
+++ b/programs/winhlp32/hlpfile.h
@@ -149,6 +149,9 @@ typedef struct tagHlpFileFile
     COLORREF                    popup_color;
 
     LPSTR                       help_on_file;
+
+    long                        scale;
+    int                         rounderr;
 } HLPFILE;
 
 /*
@@ -194,8 +197,14 @@ struct RtfData {
     HLPFILE_LINK*current_link;
     BOOL        force_color;
     unsigned    relative;       /* offset within page to lookup for */
-    unsigned    char_pos_rel;   /* char_pos correspondinf to relative */
+    unsigned    char_pos_rel;   /* char_pos corresponding to relative */
 };
 
 BOOL          HLPFILE_BrowsePage(HLPFILE_PAGE*, struct RtfData* rd,
                                  unsigned font_scale, unsigned relative);
+
+#define HLP_DISPLAY30 0x01     /* version 3.0 displayable information */
+#define HLP_TOPICHDR  0x02     /* topic header information */
+#define HLP_DISPLAY   0x20     /* version 3.1 displayable information */
+#define HLP_TABLE     0x23     /* version 3.1 table */
+
diff --git a/programs/winhlp32/winhelp.c b/programs/winhlp32/winhelp.c
index 49fdf5d..891079c 100644
--- a/programs/winhlp32/winhelp.c
+++ b/programs/winhlp32/winhelp.c
@@ -381,6 +381,7 @@ static LRESULT  WINHELP_HandleCommand(HWND hSrcWnd, LPARAM 
lParam)
         case HELP_QUIT:
             MACRO_Exit();
             break;
+        case HELP_PARTIALKEY:
         case HELP_CONTENTS:
             if (ptr)
             {
@@ -1394,7 +1395,6 @@ static LRESULT CALLBACK WINHELP_MainWndProc(HWND hWnd, 
UINT msg, WPARAM wParam,
                 WINHELP_SetupText(GetDlgItem(hWnd, CTL_ID_TEXT), win, 0 /* 
FIXME */);
             }
             break;
-
 	default:
             /* Buttons */
             for (button = win->first_button; button; button = button->next)
-- 
2.3.10





More information about the wine-patches mailing list