Nikolay Sivov : dwrite: Use FreeType CMAP cache system instead of parsing tables manually.

Alexandre Julliard julliard at wine.codeweavers.com
Mon Feb 23 09:04:43 CST 2015


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

Author: Nikolay Sivov <nsivov at codeweavers.com>
Date:   Fri Feb 20 13:47:30 2015 +0300

dwrite: Use FreeType CMAP cache system instead of parsing tables manually.

---

 dlls/dwrite/dwrite_private.h |   2 +-
 dlls/dwrite/font.c           |   9 +---
 dlls/dwrite/freetype.c       |  26 ++++++++++-
 dlls/dwrite/opentype.c       | 100 -------------------------------------------
 4 files changed, 28 insertions(+), 109 deletions(-)

diff --git a/dlls/dwrite/dwrite_private.h b/dlls/dwrite/dwrite_private.h
index 9a27a5e..9481c74 100644
--- a/dlls/dwrite/dwrite_private.h
+++ b/dlls/dwrite/dwrite_private.h
@@ -126,7 +126,6 @@ extern HRESULT get_family_names_from_stream(IDWriteFontFileStream*,UINT32,DWRITE
 /* Opentype font table functions */
 extern HRESULT opentype_analyze_font(IDWriteFontFileStream*,UINT32*,DWRITE_FONT_FILE_TYPE*,DWRITE_FONT_FACE_TYPE*,BOOL*) DECLSPEC_HIDDEN;
 extern HRESULT opentype_get_font_table(IDWriteFontFileStream*,DWRITE_FONT_FACE_TYPE,UINT32,UINT32,const void**,void**,UINT32*,BOOL*) DECLSPEC_HIDDEN;
-extern void opentype_cmap_get_glyphindex(void*,UINT32,UINT16*) DECLSPEC_HIDDEN;
 extern HRESULT opentype_cmap_get_unicode_ranges(void*,UINT32,DWRITE_UNICODE_RANGE*,UINT32*) DECLSPEC_HIDDEN;
 extern void opentype_get_font_properties(IDWriteFontFileStream*,DWRITE_FONT_FACE_TYPE,UINT32,DWRITE_FONT_STRETCH*,
     DWRITE_FONT_WEIGHT*,DWRITE_FONT_STYLE*) DECLSPEC_HIDDEN;
@@ -162,6 +161,7 @@ extern void freetype_notify_cacheremove(IDWriteFontFace2*) DECLSPEC_HIDDEN;
 extern BOOL freetype_is_monospaced(IDWriteFontFace2*) DECLSPEC_HIDDEN;
 extern HRESULT freetype_get_glyph_outline(IDWriteFontFace2*,FLOAT,UINT16,USHORT,struct glyph_outline**) DECLSPEC_HIDDEN;
 extern UINT16 freetype_get_glyphcount(IDWriteFontFace2*) DECLSPEC_HIDDEN;
+extern UINT16 freetype_get_glyphindex(IDWriteFontFace2*,UINT32) DECLSPEC_HIDDEN;
 
 /* Glyph shaping */
 enum SCRIPT_JUSTIFY
diff --git a/dlls/dwrite/font.c b/dlls/dwrite/font.c
index 2092576..12ce3ca 100644
--- a/dlls/dwrite/font.c
+++ b/dlls/dwrite/font.c
@@ -388,17 +388,12 @@ static HRESULT WINAPI dwritefontface_GetGlyphIndices(IDWriteFontFace2 *iface, UI
     UINT32 count, UINT16 *glyph_indices)
 {
     struct dwrite_fontface *This = impl_from_IDWriteFontFace2(iface);
-    unsigned int i;
-    void *data;
+    UINT32 i;
 
     TRACE("(%p)->(%p %u %p)\n", This, codepoints, count, glyph_indices);
 
-    data = get_fontface_cmap(This);
-    if (!data)
-        return E_FAIL;
-
     for (i = 0; i < count; i++)
-        opentype_cmap_get_glyphindex(data, codepoints[i], &glyph_indices[i]);
+        glyph_indices[i] = freetype_get_glyphindex(iface, codepoints[i]);
 
     return S_OK;
 }
diff --git a/dlls/dwrite/freetype.c b/dlls/dwrite/freetype.c
index 3b9681d..84c9cad 100644
--- a/dlls/dwrite/freetype.c
+++ b/dlls/dwrite/freetype.c
@@ -53,6 +53,7 @@ static CRITICAL_SECTION freetype_cs = { &critsect_debug, -1, 0, 0, 0, 0 };
 static void *ft_handle = NULL;
 static FT_Library library = 0;
 static FTC_Manager cache_manager = 0;
+static FTC_CMapCache cmap_cache = 0;
 typedef struct
 {
     FT_Int major;
@@ -67,6 +68,8 @@ MAKE_FUNCPTR(FT_Library_Version);
 MAKE_FUNCPTR(FT_Load_Glyph);
 MAKE_FUNCPTR(FT_New_Memory_Face);
 MAKE_FUNCPTR(FT_Outline_Transform);
+MAKE_FUNCPTR(FTC_CMapCache_Lookup);
+MAKE_FUNCPTR(FTC_CMapCache_New);
 MAKE_FUNCPTR(FTC_Manager_New);
 MAKE_FUNCPTR(FTC_Manager_Done);
 MAKE_FUNCPTR(FTC_Manager_LookupFace);
@@ -137,6 +140,8 @@ BOOL init_freetype(void)
     LOAD_FUNCPTR(FT_Load_Glyph)
     LOAD_FUNCPTR(FT_New_Memory_Face)
     LOAD_FUNCPTR(FT_Outline_Transform)
+    LOAD_FUNCPTR(FTC_CMapCache_Lookup)
+    LOAD_FUNCPTR(FTC_CMapCache_New)
     LOAD_FUNCPTR(FTC_Manager_New)
     LOAD_FUNCPTR(FTC_Manager_Done)
     LOAD_FUNCPTR(FTC_Manager_LookupFace)
@@ -153,8 +158,11 @@ BOOL init_freetype(void)
     pFT_Library_Version(library, &FT_Version.major, &FT_Version.minor, &FT_Version.patch);
 
     /* init cache manager */
-    if (pFTC_Manager_New(library, 0, 0, 0, &face_requester, NULL, &cache_manager) != 0) {
+    if (pFTC_Manager_New(library, 0, 0, 0, &face_requester, NULL, &cache_manager) != 0 ||
+        pFTC_CMapCache_New(cache_manager, &cmap_cache) != 0) {
+
         ERR("Failed to init FreeType cache\n");
+        pFTC_Manager_Done(cache_manager);
         pFT_Done_FreeType(library);
         wine_dlclose(ft_handle, NULL, 0);
         ft_handle = NULL;
@@ -388,6 +396,17 @@ UINT16 freetype_get_glyphcount(IDWriteFontFace2 *fontface)
     return count;
 }
 
+UINT16 freetype_get_glyphindex(IDWriteFontFace2 *fontface, UINT32 codepoint)
+{
+    UINT16 glyph;
+
+    EnterCriticalSection(&freetype_cs);
+    glyph = pFTC_CMapCache_Lookup(cmap_cache, fontface, -1, codepoint);
+    LeaveCriticalSection(&freetype_cs);
+
+    return glyph;
+}
+
 #else /* HAVE_FREETYPE */
 
 BOOL init_freetype(void)
@@ -424,4 +443,9 @@ UINT16 freetype_get_glyphcount(IDWriteFontFace2 *fontface)
     return 0;
 }
 
+UINT16 freetype_get_glyphindex(IDWriteFontFace2 *fontface, UINT32 codepoint)
+{
+    return 0;
+}
+
 #endif /* HAVE_FREETYPE */
diff --git a/dlls/dwrite/opentype.c b/dlls/dwrite/opentype.c
index aabc049..cbc5090 100644
--- a/dlls/dwrite/opentype.c
+++ b/dlls/dwrite/opentype.c
@@ -757,106 +757,6 @@ HRESULT opentype_get_font_table(IDWriteFontFileStream *stream, DWRITE_FONT_FACE_
  * CMAP
  **********/
 
-static int compare_group(const void *a, const void* b)
-{
-    const DWORD *chr = a;
-    const CMAP_SegmentedCoverage_group *group = b;
-
-    if (*chr < GET_BE_DWORD(group->startCharCode))
-        return -1;
-    if (*chr > GET_BE_DWORD(group->endCharCode))
-        return 1;
-    return 0;
-}
-
-static void CMAP4_GetGlyphIndex(CMAP_SegmentMapping_0* format, UINT32 utf32c, UINT16 *pgi)
-{
-    WORD *startCode;
-    SHORT *idDelta;
-    WORD *idRangeOffset;
-    int segment;
-
-    int segment_count = GET_BE_WORD(format->segCountX2)/2;
-    /* This is correct because of the padding before startCode */
-    startCode = (WORD*)((BYTE*)format + sizeof(CMAP_SegmentMapping_0) + (sizeof(WORD) * segment_count));
-    idDelta = (SHORT*)(((BYTE*)startCode) + (sizeof(WORD) * segment_count));
-    idRangeOffset = (WORD*)(((BYTE*)idDelta) + (sizeof(WORD) * segment_count));
-
-    segment = 0;
-    while(GET_BE_WORD(format->endCode[segment]) < 0xffff)
-    {
-        if (utf32c <= GET_BE_WORD(format->endCode[segment]))
-            break;
-        segment++;
-    }
-    if (segment >= segment_count)
-        return;
-    TRACE("Segment %i of %i\n",segment, segment_count);
-    if (GET_BE_WORD(startCode[segment]) > utf32c)
-        return;
-    TRACE("In range %i -> %i\n", GET_BE_WORD(startCode[segment]), GET_BE_WORD(format->endCode[segment]));
-    if (GET_BE_WORD(idRangeOffset[segment]) == 0)
-    {
-        *pgi = (SHORT)(GET_BE_WORD(idDelta[segment])) + utf32c;
-    }
-    else
-    {
-        WORD ro = GET_BE_WORD(idRangeOffset[segment])/2;
-        WORD co =  (utf32c - GET_BE_WORD(startCode[segment]));
-        WORD *index = (WORD*)((BYTE*)&idRangeOffset[segment] + (ro + co));
-        *pgi = GET_BE_WORD(*index);
-    }
-}
-
-static void CMAP12_GetGlyphIndex(CMAP_SegmentedCoverage* format, UINT32 utf32c, UINT16 *pgi)
-{
-    CMAP_SegmentedCoverage_group *group;
-
-    group = bsearch(&utf32c, format->groups, GET_BE_DWORD(format->nGroups),
-                    sizeof(CMAP_SegmentedCoverage_group), compare_group);
-
-    if (group)
-    {
-        DWORD offset = utf32c - GET_BE_DWORD(group->startCharCode);
-        *pgi = GET_BE_DWORD(group->startGlyphID) + offset;
-    }
-}
-
-void opentype_cmap_get_glyphindex(void *data, UINT32 utf32c, UINT16 *pgi)
-{
-    CMAP_Header *CMAP_Table = data;
-    int i;
-
-    *pgi = 0;
-
-    for (i = 0; i < GET_BE_WORD(CMAP_Table->numTables); i++)
-    {
-        WORD type;
-        WORD *table;
-
-        if (GET_BE_WORD(CMAP_Table->tables[i].platformID) != 3)
-            continue;
-
-        table = (WORD*)(((BYTE*)CMAP_Table) + GET_BE_DWORD(CMAP_Table->tables[i].offset));
-        type = GET_BE_WORD(*table);
-        TRACE("table type %i\n", type);
-
-        switch (type)
-        {
-            case OPENTYPE_CMAP_TABLE_SEGMENT_MAPPING:
-                CMAP4_GetGlyphIndex((CMAP_SegmentMapping_0*) table, utf32c, pgi);
-                break;
-            case OPENTYPE_CMAP_TABLE_SEGMENTED_COVERAGE:
-                CMAP12_GetGlyphIndex((CMAP_SegmentedCoverage*) table, utf32c, pgi);
-                break;
-            default:
-                TRACE("table type %i unhandled.\n", type);
-        }
-
-        if (*pgi) return;
-    }
-}
-
 static UINT32 opentype_cmap_get_unicode_ranges_count(const CMAP_Header *CMAP_Table)
 {
     UINT32 count = 0;




More information about the wine-cvs mailing list