[PATCH 4/4] dwrite: Do not create fontface instance for GetUnicodeRanges().

Nikolay Sivov nsivov at codeweavers.com
Sun Jan 26 23:52:51 CST 2020


Signed-off-by: Nikolay Sivov <nsivov at codeweavers.com>
---
 dlls/dwrite/dwrite_private.h |  2 +-
 dlls/dwrite/font.c           | 26 +++++++++++++++++---------
 dlls/dwrite/opentype.c       | 30 +++++++++++++++++++-----------
 3 files changed, 37 insertions(+), 21 deletions(-)

diff --git a/dlls/dwrite/dwrite_private.h b/dlls/dwrite/dwrite_private.h
index e5ca5306c2..200a9d39ba 100644
--- a/dlls/dwrite/dwrite_private.h
+++ b/dlls/dwrite/dwrite_private.h
@@ -327,7 +327,7 @@ extern const void* get_fontface_table(IDWriteFontFace5 *fontface, UINT32 tag,
 extern HRESULT opentype_analyze_font(IDWriteFontFileStream*,BOOL*,DWRITE_FONT_FILE_TYPE*,DWRITE_FONT_FACE_TYPE*,UINT32*) DECLSPEC_HIDDEN;
 extern HRESULT opentype_try_get_font_table(const struct file_stream_desc *stream_desc, UINT32 tag, const void **data,
         void **context, UINT32 *size, BOOL *exists) DECLSPEC_HIDDEN;
-extern HRESULT opentype_cmap_get_unicode_ranges(const struct dwrite_fonttable *table, unsigned int max_count,
+extern HRESULT opentype_cmap_get_unicode_ranges(const struct file_stream_desc *stream_desc, unsigned int max_count,
         DWRITE_UNICODE_RANGE *ranges, unsigned int *count) DECLSPEC_HIDDEN;
 extern void opentype_get_font_properties(struct file_stream_desc*,struct dwrite_font_props*) DECLSPEC_HIDDEN;
 extern void opentype_get_font_metrics(struct file_stream_desc*,DWRITE_FONT_METRICS1*,DWRITE_CARET_METRICS*) DECLSPEC_HIDDEN;
diff --git a/dlls/dwrite/font.c b/dlls/dwrite/font.c
index a3af30afe5..507099b24e 100644
--- a/dlls/dwrite/font.c
+++ b/dlls/dwrite/font.c
@@ -972,6 +972,7 @@ static HRESULT WINAPI dwritefontface1_GetUnicodeRanges(IDWriteFontFace5 *iface,
     DWRITE_UNICODE_RANGE *ranges, UINT32 *count)
 {
     struct dwrite_fontface *fontface = impl_from_IDWriteFontFace5(iface);
+    struct file_stream_desc stream_desc;
 
     TRACE("%p, %u, %p, %p.\n", iface, max_count, ranges, count);
 
@@ -979,8 +980,10 @@ static HRESULT WINAPI dwritefontface1_GetUnicodeRanges(IDWriteFontFace5 *iface,
     if (max_count && !ranges)
         return E_INVALIDARG;
 
-    get_fontface_table(iface, MS_CMAP_TAG, &fontface->cmap);
-    return opentype_cmap_get_unicode_ranges(&fontface->cmap, max_count, ranges, count);
+    stream_desc.stream = fontface->stream;
+    stream_desc.face_index = fontface->index;
+    stream_desc.face_type = fontface->type;
+    return opentype_cmap_get_unicode_ranges(&stream_desc, max_count, ranges, count);
 }
 
 static BOOL WINAPI dwritefontface1_IsMonospacedFont(IDWriteFontFace5 *iface)
@@ -1795,20 +1798,25 @@ static void WINAPI dwritefont1_GetPanose(IDWriteFont3 *iface, DWRITE_PANOSE *pan
     *panose = This->data->panose;
 }
 
-static HRESULT WINAPI dwritefont1_GetUnicodeRanges(IDWriteFont3 *iface, UINT32 max_count, DWRITE_UNICODE_RANGE *ranges, UINT32 *count)
+static HRESULT WINAPI dwritefont1_GetUnicodeRanges(IDWriteFont3 *iface, UINT32 max_count, DWRITE_UNICODE_RANGE *ranges,
+        UINT32 *count)
 {
     struct dwrite_font *font = impl_from_IDWriteFont3(iface);
-    IDWriteFontFace5 *fontface;
+    struct file_stream_desc stream_desc;
     HRESULT hr;
 
     TRACE("%p, %u, %p, %p.\n", iface, max_count, ranges, count);
 
-    hr = get_fontface_from_font(font, &fontface);
-    if (FAILED(hr))
-        return hr;
+    *count = 0;
+    if (max_count && !ranges)
+        return E_INVALIDARG;
 
-    hr = IDWriteFontFace5_GetUnicodeRanges(fontface, max_count, ranges, count);
-    IDWriteFontFace5_Release(fontface);
+    if (FAILED(hr = get_filestream_from_file(font->data->file, &stream_desc.stream)))
+        return hr;
+    stream_desc.face_index = font->data->face_index;
+    stream_desc.face_type = font->data->face_type;
+    hr = opentype_cmap_get_unicode_ranges(&stream_desc, max_count, ranges, count);
+    IDWriteFontFileStream_Release(stream_desc.stream);
     return hr;
 }
 
diff --git a/dlls/dwrite/opentype.c b/dlls/dwrite/opentype.c
index 23d7669eb6..0aa1b10460 100644
--- a/dlls/dwrite/opentype.c
+++ b/dlls/dwrite/opentype.c
@@ -1521,22 +1521,28 @@ static unsigned int opentype_cmap_get_unicode_ranges_count(const struct dwrite_f
     return count;
 }
 
-HRESULT opentype_cmap_get_unicode_ranges(const struct dwrite_fonttable *cmap, unsigned int max_count,
+HRESULT opentype_cmap_get_unicode_ranges(const struct file_stream_desc *stream_desc, unsigned int max_count,
         DWRITE_UNICODE_RANGE *ranges, unsigned int *count)
 {
     unsigned int i, num_tables, k = 0;
     const struct cmap_header *header;
+    struct dwrite_fonttable cmap;
 
-    if (!cmap->exists)
+    opentype_get_font_table(stream_desc, MS_CMAP_TAG, &cmap);
+
+    if (!cmap.exists)
         return E_FAIL;
 
-    *count = opentype_cmap_get_unicode_ranges_count(cmap);
+    *count = opentype_cmap_get_unicode_ranges_count(&cmap);
 
-    num_tables = table_read_be_word(cmap, FIELD_OFFSET(struct cmap_header, num_tables));
-    header = table_read_ensure(cmap, 0, FIELD_OFFSET(struct cmap_header, tables[num_tables]));
+    num_tables = table_read_be_word(&cmap, FIELD_OFFSET(struct cmap_header, num_tables));
+    header = table_read_ensure(&cmap, 0, FIELD_OFFSET(struct cmap_header, tables[num_tables]));
 
     if (!header)
+    {
+        IDWriteFontFileStream_ReleaseFileFragment(stream_desc->stream, cmap.context);
         return S_OK;
+    }
 
     for (i = 0; i < num_tables && k < max_count; ++i)
     {
@@ -1547,18 +1553,18 @@ HRESULT opentype_cmap_get_unicode_ranges(const struct dwrite_fonttable *cmap, un
 
         offset = GET_BE_DWORD(header->tables[i].offset);
 
-        format = table_read_be_word(cmap, offset);
+        format = table_read_be_word(&cmap, offset);
         switch (format)
         {
             case OPENTYPE_CMAP_TABLE_SEGMENT_MAPPING:
             {
-                unsigned int segment_count = table_read_be_word(cmap, offset +
+                unsigned int segment_count = table_read_be_word(&cmap, offset +
                         FIELD_OFFSET(struct cmap_segment_mapping, seg_count_x2)) / 2;
-                const UINT16 *start_code = table_read_ensure(cmap, offset,
+                const UINT16 *start_code = table_read_ensure(&cmap, offset,
                         FIELD_OFFSET(struct cmap_segment_mapping, end_code[segment_count]) +
                         2 /* reservedPad */ +
                         2 * segment_count /* start code array */);
-                const UINT16 *end_code = table_read_ensure(cmap, offset,
+                const UINT16 *end_code = table_read_ensure(&cmap, offset,
                         FIELD_OFFSET(struct cmap_segment_mapping, end_code[segment_count]));
 
                 if (!start_code || !end_code)
@@ -1573,11 +1579,11 @@ HRESULT opentype_cmap_get_unicode_ranges(const struct dwrite_fonttable *cmap, un
             }
             case OPENTYPE_CMAP_TABLE_SEGMENTED_COVERAGE:
             {
-                unsigned int num_groups = table_read_be_dword(cmap, offset +
+                unsigned int num_groups = table_read_be_dword(&cmap, offset +
                         FIELD_OFFSET(struct cmap_segmented_coverage, num_groups));
                 const struct cmap_segmented_coverage *coverage;
 
-                coverage = table_read_ensure(cmap, offset,
+                coverage = table_read_ensure(&cmap, offset,
                         FIELD_OFFSET(struct cmap_segmented_coverage, groups[num_groups]));
 
                 for (j = 0; j < num_groups && k < max_count; j++, k++)
@@ -1592,6 +1598,8 @@ HRESULT opentype_cmap_get_unicode_ranges(const struct dwrite_fonttable *cmap, un
         }
     }
 
+    IDWriteFontFileStream_ReleaseFileFragment(stream_desc->stream, cmap.context);
+
     return *count > max_count ? E_NOT_SUFFICIENT_BUFFER : S_OK;
 }
 
-- 
2.24.1




More information about the wine-devel mailing list