Nikolay Sivov : dwrite: Implement GetKerningPairAdjustments().

Alexandre Julliard julliard at wine.codeweavers.com
Mon Mar 16 10:34:23 CDT 2015


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

Author: Nikolay Sivov <nsivov at codeweavers.com>
Date:   Fri Mar 13 23:19:18 2015 +0300

dwrite: Implement GetKerningPairAdjustments().

---

 dlls/dwrite/dwrite_private.h |  1 +
 dlls/dwrite/font.c           | 21 +++++++++++++++++---
 dlls/dwrite/freetype.c       | 25 ++++++++++++++++++++++++
 dlls/dwrite/tests/font.c     | 46 ++++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 90 insertions(+), 3 deletions(-)

diff --git a/dlls/dwrite/dwrite_private.h b/dlls/dwrite/dwrite_private.h
index 92f0427..aa73b4b 100644
--- a/dlls/dwrite/dwrite_private.h
+++ b/dlls/dwrite/dwrite_private.h
@@ -163,6 +163,7 @@ extern HRESULT freetype_get_glyph_outline(IDWriteFontFace2*,FLOAT,UINT16,USHORT,
 extern UINT16 freetype_get_glyphcount(IDWriteFontFace2*) DECLSPEC_HIDDEN;
 extern UINT16 freetype_get_glyphindex(IDWriteFontFace2*,UINT32) DECLSPEC_HIDDEN;
 extern BOOL freetype_has_kerning_pairs(IDWriteFontFace2*) DECLSPEC_HIDDEN;
+extern INT32 freetype_get_kerning_pair_adjustment(IDWriteFontFace2*,UINT16,UINT16) DECLSPEC_HIDDEN;
 
 /* Glyph shaping */
 enum SCRIPT_JUSTIFY
diff --git a/dlls/dwrite/font.c b/dlls/dwrite/font.c
index 66dbc68..59eda80 100644
--- a/dlls/dwrite/font.c
+++ b/dlls/dwrite/font.c
@@ -658,12 +658,27 @@ static HRESULT WINAPI dwritefontface1_GetGdiCompatibleGlyphAdvances(IDWriteFontF
     return E_NOTIMPL;
 }
 
-static HRESULT WINAPI dwritefontface1_GetKerningPairAdjustments(IDWriteFontFace2 *iface, UINT32 glyph_count,
+static HRESULT WINAPI dwritefontface1_GetKerningPairAdjustments(IDWriteFontFace2 *iface, UINT32 count,
     const UINT16 *indices, INT32 *adjustments)
 {
     struct dwrite_fontface *This = impl_from_IDWriteFontFace2(iface);
-    FIXME("(%p)->(%u %p %p): stub\n", This, glyph_count, indices, adjustments);
-    return E_NOTIMPL;
+    UINT32 i;
+
+    TRACE("(%p)->(%u %p %p)\n", This, count, indices, adjustments);
+
+    if (!(indices || adjustments) || !count)
+        return E_INVALIDARG;
+
+    if (!indices || count == 1) {
+        memset(adjustments, 0, count*sizeof(INT32));
+        return E_INVALIDARG;
+    }
+
+    for (i = 0; i < count-1; i++)
+        adjustments[i] = freetype_get_kerning_pair_adjustment(iface, indices[i], indices[i+1]);
+    adjustments[count-1] = 0;
+
+    return S_OK;
 }
 
 static BOOL WINAPI dwritefontface1_HasKerningPairs(IDWriteFontFace2 *iface)
diff --git a/dlls/dwrite/freetype.c b/dlls/dwrite/freetype.c
index 325f156..a18c542 100644
--- a/dlls/dwrite/freetype.c
+++ b/dlls/dwrite/freetype.c
@@ -63,6 +63,7 @@ typedef struct
 
 #define MAKE_FUNCPTR(f) static typeof(f) * p##f = NULL
 MAKE_FUNCPTR(FT_Done_FreeType);
+MAKE_FUNCPTR(FT_Get_Kerning);
 MAKE_FUNCPTR(FT_Init_FreeType);
 MAKE_FUNCPTR(FT_Library_Version);
 MAKE_FUNCPTR(FT_Load_Glyph);
@@ -135,6 +136,7 @@ BOOL init_freetype(void)
 
 #define LOAD_FUNCPTR(f) if((p##f = wine_dlsym(ft_handle, #f, NULL, 0)) == NULL){WARN("Can't find symbol %s\n", #f); goto sym_not_found;}
     LOAD_FUNCPTR(FT_Done_FreeType)
+    LOAD_FUNCPTR(FT_Get_Kerning)
     LOAD_FUNCPTR(FT_Init_FreeType)
     LOAD_FUNCPTR(FT_Library_Version)
     LOAD_FUNCPTR(FT_Load_Glyph)
@@ -420,6 +422,24 @@ BOOL freetype_has_kerning_pairs(IDWriteFontFace2 *fontface)
     return has_kerning_pairs;
 }
 
+INT32 freetype_get_kerning_pair_adjustment(IDWriteFontFace2 *fontface, UINT16 left, UINT16 right)
+{
+    INT32 adjustment = 0;
+    FT_Face face;
+
+    EnterCriticalSection(&freetype_cs);
+    if (pFTC_Manager_LookupFace(cache_manager, fontface, &face) == 0) {
+        FT_Vector kern;
+        if (FT_HAS_KERNING(face)) {
+            pFT_Get_Kerning(face, left, right, FT_KERNING_UNSCALED, &kern);
+            adjustment = kern.x;
+        }
+    }
+    LeaveCriticalSection(&freetype_cs);
+
+    return adjustment;
+}
+
 #else /* HAVE_FREETYPE */
 
 BOOL init_freetype(void)
@@ -466,4 +486,9 @@ BOOL freetype_has_kerning_pairs(IDWriteFontFace2 *fontface)
     return FALSE;
 }
 
+INT32 freetype_get_kerning_pair_adjustment(IDWriteFontFace2 *fontface, UINT16 left, UINT16 right)
+{
+    return 0;
+}
+
 #endif /* HAVE_FREETYPE */
diff --git a/dlls/dwrite/tests/font.c b/dlls/dwrite/tests/font.c
index a9a6802..9762d49 100644
--- a/dlls/dwrite/tests/font.c
+++ b/dlls/dwrite/tests/font.c
@@ -3136,6 +3136,51 @@ static void test_GetGlyphCount(void)
     DELETE_FONTFILE(path);
 }
 
+static void test_GetKerningPairAdjustments(void)
+{
+    IDWriteFontFace1 *fontface1;
+    IDWriteFontFace *fontface;
+    IDWriteFactory *factory;
+    IDWriteFontFile *file;
+    WCHAR *path;
+    HRESULT hr;
+
+    path = create_testfontfile(test_fontfile);
+    factory = create_factory();
+
+    hr = IDWriteFactory_CreateFontFileReference(factory, path, NULL, &file);
+    ok(hr == S_OK, "got 0x%08x\n", hr);
+
+    hr = IDWriteFactory_CreateFontFace(factory, DWRITE_FONT_FACE_TYPE_TRUETYPE, 1, &file, 0, DWRITE_FONT_SIMULATIONS_NONE, &fontface);
+    ok(hr == S_OK, "got 0x%08x\n", hr);
+    IDWriteFontFile_Release(file);
+
+    hr = IDWriteFontFace_QueryInterface(fontface, &IID_IDWriteFontFace1, (void**)&fontface1);
+    if (hr == S_OK) {
+        INT32 adjustments[1];
+
+        hr = IDWriteFontFace1_GetKerningPairAdjustments(fontface1, 0, NULL, NULL);
+        ok(hr == E_INVALIDARG || broken(hr == S_OK) /* win8 */, "got 0x%08x\n", hr);
+
+    if (0) /* crashes on native */
+        hr = IDWriteFontFace1_GetKerningPairAdjustments(fontface1, 1, NULL, NULL);
+
+        adjustments[0] = 1;
+        hr = IDWriteFontFace1_GetKerningPairAdjustments(fontface1, 1, NULL, adjustments);
+        ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
+        ok(adjustments[0] == 0, "got %d\n", adjustments[0]);
+
+        IDWriteFontFace1_Release(fontface1);
+    }
+    else
+        win_skip("GetKerningPairAdjustments() is not supported.\n");
+
+    IDWriteFontFace_Release(fontface);
+    IDWriteFactory_Release(factory);
+    DELETE_FONTFILE(path);
+}
+
+
 START_TEST(font)
 {
     IDWriteFactory *factory;
@@ -3176,6 +3221,7 @@ START_TEST(font)
     test_GetEudcFontCollection();
     test_GetCaretMetrics();
     test_GetGlyphCount();
+    test_GetKerningPairAdjustments();
 
     IDWriteFactory_Release(factory);
 }




More information about the wine-cvs mailing list