[PATCH 5/5] dwrite: Use table access helpers for reading names.

Nikolay Sivov nsivov at codeweavers.com
Mon Jan 18 06:05:42 CST 2021


Signed-off-by: Nikolay Sivov <nsivov at codeweavers.com>
---
 dlls/dwrite/opentype.c | 115 ++++++++++++++++++++++-------------------
 1 file changed, 62 insertions(+), 53 deletions(-)

diff --git a/dlls/dwrite/opentype.c b/dlls/dwrite/opentype.c
index ff341f03232..7c30678234a 100644
--- a/dlls/dwrite/opentype.c
+++ b/dlls/dwrite/opentype.c
@@ -320,21 +320,23 @@ enum OS2_FSSELECTION {
     OS2_FSSELECTION_OBLIQUE          = 1 << 9
 };
 
-typedef struct {
+struct name_record
+{
     WORD platformID;
     WORD encodingID;
     WORD languageID;
     WORD nameID;
     WORD length;
     WORD offset;
-} TT_NameRecord;
+};
 
-typedef struct {
+struct name_header
+{
     WORD format;
     WORD count;
     WORD stringOffset;
-    TT_NameRecord nameRecord[1];
-} TT_NAME_V0;
+    struct name_record records[1];
+};
 
 struct vdmx_header
 {
@@ -2278,11 +2280,19 @@ static void get_name_record_locale(enum OPENTYPE_PLATFORM_ID platform, USHORT la
     }
 }
 
-static BOOL opentype_decode_namerecord(const TT_NAME_V0 *header, BYTE *storage_area, USHORT recid, IDWriteLocalizedStrings *strings)
+static BOOL opentype_decode_namerecord(const struct dwrite_fonttable *table, unsigned int idx,
+        IDWriteLocalizedStrings *strings)
 {
-    const TT_NameRecord *record = &header->nameRecord[recid];
     USHORT lang_id, length, offset, encoding, platform;
+    const struct name_header *header = (const struct name_header *)table->data;
+    const struct name_record *record;
+    unsigned int i, string_offset;
     BOOL ret = FALSE;
+    const void *name;
+
+    string_offset = table_read_be_word(table, FIELD_OFFSET(struct name_header, stringOffset));
+
+    record = &header->records[idx];
 
     platform = GET_BE_WORD(record->platformID);
     lang_id = GET_BE_WORD(record->languageID);
@@ -2290,7 +2300,11 @@ static BOOL opentype_decode_namerecord(const TT_NAME_V0 *header, BYTE *storage_a
     offset = GET_BE_WORD(record->offset);
     encoding = GET_BE_WORD(record->encodingID);
 
-    if (lang_id < 0x8000) {
+    if (!(name = table_read_ensure(table, string_offset + offset, length)))
+        return FALSE;
+
+    if (lang_id < 0x8000)
+    {
         WCHAR locale[LOCALE_NAME_MAX_LENGTH];
         WCHAR *name_string;
         UINT codepage;
@@ -2298,17 +2312,17 @@ static BOOL opentype_decode_namerecord(const TT_NAME_V0 *header, BYTE *storage_a
         codepage = get_name_record_codepage(platform, encoding);
         get_name_record_locale(platform, lang_id, locale, ARRAY_SIZE(locale));
 
-        if (codepage) {
-            DWORD len = MultiByteToWideChar(codepage, 0, (LPSTR)(storage_area + offset), length, NULL, 0);
+        if (codepage)
+        {
+            DWORD len = MultiByteToWideChar(codepage, 0, name, length, NULL, 0);
             name_string = heap_alloc(sizeof(WCHAR) * (len+1));
-            MultiByteToWideChar(codepage, 0, (LPSTR)(storage_area + offset), length, name_string, len);
+            MultiByteToWideChar(codepage, 0, name, length, name_string, len);
             name_string[len] = 0;
         }
-        else {
-            int i;
-
+        else
+        {
             length /= sizeof(WCHAR);
-            name_string = heap_strdupnW((LPWSTR)(storage_area + offset), length);
+            name_string = heap_strdupnW(name, length);
             for (i = 0; i < length; i++)
                 name_string[i] = GET_BE_WORD(name_string[i]);
         }
@@ -2324,45 +2338,45 @@ static BOOL opentype_decode_namerecord(const TT_NAME_V0 *header, BYTE *storage_a
     return ret;
 }
 
-static HRESULT opentype_get_font_strings_from_id(const void *table_data, enum OPENTYPE_STRING_ID id, IDWriteLocalizedStrings **strings)
+static HRESULT opentype_get_font_strings_from_id(const struct dwrite_fonttable *table, enum OPENTYPE_STRING_ID id,
+        IDWriteLocalizedStrings **strings)
 {
     int i, count, candidate_mac, candidate_unicode;
-    const TT_NAME_V0 *header;
-    BYTE *storage_area = 0;
+    const struct name_record *records;
     WORD format;
     BOOL exists;
     HRESULT hr;
 
-    if (!table_data)
+    if (!table->data)
         return E_FAIL;
 
-    hr = create_localizedstrings(strings);
-    if (FAILED(hr)) return hr;
+    if (FAILED(hr = create_localizedstrings(strings)))
+        return hr;
 
-    header = table_data;
-    format = GET_BE_WORD(header->format);
+    format = table_read_be_word(table, FIELD_OFFSET(struct name_header, format));
 
-    switch (format) {
-    case 0:
-    case 1:
-        break;
-    default:
+    if (format != 0 && format != 1)
         FIXME("unsupported NAME format %d\n", format);
-    }
 
-    storage_area = (LPBYTE)table_data + GET_BE_WORD(header->stringOffset);
-    count = GET_BE_WORD(header->count);
+    count = table_read_be_word(table, FIELD_OFFSET(struct name_header, count));
+
+    if (!(records = table_read_ensure(table, FIELD_OFFSET(struct name_header, records),
+                count * sizeof(struct name_record))))
+    {
+        count = 0;
+    }
 
     exists = FALSE;
     candidate_unicode = candidate_mac = -1;
-    for (i = 0; i < count; i++) {
-        const TT_NameRecord *record = &header->nameRecord[i];
-        USHORT platform;
 
-        if (GET_BE_WORD(record->nameID) != id)
+    for (i = 0; i < count; i++)
+    {
+        unsigned short platform;
+
+        if (GET_BE_WORD(records[i].nameID) != id)
             continue;
 
-        platform = GET_BE_WORD(record->platformID);
+        platform = GET_BE_WORD(records[i].platformID);
         switch (platform)
         {
             /* Skip Unicode or Mac entries for now, fonts tend to duplicate those
@@ -2378,7 +2392,7 @@ static HRESULT opentype_get_font_strings_from_id(const void *table_data, enum OP
                     candidate_mac = i;
                 break;
             case OPENTYPE_PLATFORM_WIN:
-                if (opentype_decode_namerecord(header, storage_area, i, *strings))
+                if (opentype_decode_namerecord(table, i, *strings))
                     exists = TRUE;
                 break;
             default:
@@ -2390,9 +2404,9 @@ static HRESULT opentype_get_font_strings_from_id(const void *table_data, enum OP
     if (!exists)
     {
         if (candidate_mac != -1)
-            exists = opentype_decode_namerecord(header, storage_area, candidate_mac, *strings);
+            exists = opentype_decode_namerecord(table, candidate_mac, *strings);
         if (!exists && candidate_unicode != -1)
-            exists = opentype_decode_namerecord(header, storage_area, candidate_unicode, *strings);
+            exists = opentype_decode_namerecord(table, candidate_unicode, *strings);
 
         if (!exists)
         {
@@ -2527,7 +2541,7 @@ HRESULT opentype_get_font_info_strings(const struct file_stream_desc *stream_des
             break;
         default:
             opentype_get_font_table(stream_desc, MS_NAME_TAG, &name);
-            opentype_get_font_strings_from_id(name.data, dwriteid_to_opentypeid[id], strings);
+            opentype_get_font_strings_from_id(&name, dwriteid_to_opentypeid[id], strings);
             if (name.context)
                 IDWriteFontFileStream_ReleaseFileFragment(stream_desc->stream, name.context);
     }
@@ -2540,28 +2554,25 @@ HRESULT opentype_get_font_info_strings(const struct file_stream_desc *stream_des
 HRESULT opentype_get_font_familyname(struct file_stream_desc *stream_desc, IDWriteLocalizedStrings **names)
 {
     struct dwrite_fonttable os2, name;
-    const void *name_table;
     UINT16 fsselection;
     HRESULT hr;
 
     opentype_get_font_table(stream_desc, MS_OS2_TAG, &os2);
     opentype_get_font_table(stream_desc, MS_NAME_TAG, &name);
 
-    name_table = (const void *)name.data;
-
     *names = NULL;
 
     /* If Preferred Family doesn't conform to WWS model try WWS name. */
     fsselection = os2.data ? table_read_be_word(&os2, FIELD_OFFSET(struct tt_os2, fsSelection)) : 0;
     if (os2.data && !(fsselection & OS2_FSSELECTION_WWS))
-        hr = opentype_get_font_strings_from_id(name_table, OPENTYPE_STRING_WWS_FAMILY_NAME, names);
+        hr = opentype_get_font_strings_from_id(&name, OPENTYPE_STRING_WWS_FAMILY_NAME, names);
     else
         hr = E_FAIL;
 
     if (FAILED(hr))
-        hr = opentype_get_font_strings_from_id(name_table, OPENTYPE_STRING_TYPOGRAPHIC_FAMILY_NAME, names);
+        hr = opentype_get_font_strings_from_id(&name, OPENTYPE_STRING_TYPOGRAPHIC_FAMILY_NAME, names);
     if (FAILED(hr))
-        hr = opentype_get_font_strings_from_id(name_table, OPENTYPE_STRING_FAMILY_NAME, names);
+        hr = opentype_get_font_strings_from_id(&name, OPENTYPE_STRING_FAMILY_NAME, names);
 
     if (os2.context)
         IDWriteFontFileStream_ReleaseFileFragment(stream_desc->stream, os2.context);
@@ -2577,32 +2588,30 @@ HRESULT opentype_get_font_facename(struct file_stream_desc *stream_desc, WCHAR *
 {
     struct dwrite_fonttable os2, name;
     IDWriteLocalizedStrings *lfnames;
-    const void *name_table;
     UINT16 fsselection;
     HRESULT hr;
 
     opentype_get_font_table(stream_desc, MS_OS2_TAG, &os2);
     opentype_get_font_table(stream_desc, MS_NAME_TAG, &name);
 
-    name_table = name.data;
-
     *names = NULL;
 
     /* if Preferred Family doesn't conform to WWS model try WWS name */
     fsselection = os2.data ? table_read_be_word(&os2, FIELD_OFFSET(struct tt_os2, fsSelection)) : 0;
     if (os2.data && !(fsselection & OS2_FSSELECTION_WWS))
-        hr = opentype_get_font_strings_from_id(name_table, OPENTYPE_STRING_WWS_SUBFAMILY_NAME, names);
+        hr = opentype_get_font_strings_from_id(&name, OPENTYPE_STRING_WWS_SUBFAMILY_NAME, names);
     else
         hr = E_FAIL;
 
     if (FAILED(hr))
-        hr = opentype_get_font_strings_from_id(name_table, OPENTYPE_STRING_TYPOGRAPHIC_SUBFAMILY_NAME, names);
+        hr = opentype_get_font_strings_from_id(&name, OPENTYPE_STRING_TYPOGRAPHIC_SUBFAMILY_NAME, names);
     if (FAILED(hr))
-        hr = opentype_get_font_strings_from_id(name_table, OPENTYPE_STRING_SUBFAMILY_NAME, names);
+        hr = opentype_get_font_strings_from_id(&name, OPENTYPE_STRING_SUBFAMILY_NAME, names);
 
     /* User locale is preferred, with fallback to en-us. */
     *lfname = 0;
-    if (SUCCEEDED(opentype_get_font_strings_from_id(name_table, OPENTYPE_STRING_FAMILY_NAME, &lfnames))) {
+    if (SUCCEEDED(opentype_get_font_strings_from_id(&name, OPENTYPE_STRING_FAMILY_NAME, &lfnames)))
+    {
         static const WCHAR enusW[] = {'e','n','-','u','s',0};
         WCHAR localeW[LOCALE_NAME_MAX_LENGTH];
         UINT32 index;
-- 
2.29.2




More information about the wine-devel mailing list