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