dwrite: Implement pixel snapping in Draw()

Nikolay Sivov nsivov at codeweavers.com
Fri Jul 10 04:19:12 CDT 2015


---
-------------- next part --------------
From 8251526cad4cf2dbf4802ecedebe55afc7cbfdd2 Mon Sep 17 00:00:00 2001
From: Nikolay Sivov <nsivov at codeweavers.com>
Date: Fri, 10 Jul 2015 11:20:11 +0300
Subject: [PATCH] dwrite: Implement pixel snapping in Draw()

---
 dlls/dwrite/layout.c | 37 ++++++++++++++++++++++++++++++++++---
 1 file changed, 34 insertions(+), 3 deletions(-)

diff --git a/dlls/dwrite/layout.c b/dlls/dwrite/layout.c
index b07aec0..a6b49f6 100644
--- a/dlls/dwrite/layout.c
+++ b/dlls/dwrite/layout.c
@@ -21,6 +21,7 @@
 #define COBJMACROS
 
 #include <stdarg.h>
+#include <math.h>
 
 #include "windef.h"
 #include "winbase.h"
@@ -2732,6 +2733,11 @@ static HRESULT WINAPI dwritetextlayout_layout_GetLocaleName(IDWriteTextLayout2 *
     return get_string_attribute_value(This, LAYOUT_RANGE_ATTR_LOCALE, position, locale, length, r);
 }
 
+static inline FLOAT renderer_apply_snapping(FLOAT coord, FLOAT factor)
+{
+    return floor((coord * factor) + 0.5) / factor;
+}
+
 static HRESULT WINAPI dwritetextlayout_Draw(IDWriteTextLayout2 *iface,
     void *context, IDWriteTextRenderer* renderer, FLOAT origin_x, FLOAT origin_y)
 {
@@ -2739,6 +2745,8 @@ static HRESULT WINAPI dwritetextlayout_Draw(IDWriteTextLayout2 *iface,
     struct layout_effective_inline *inlineobject;
     struct layout_effective_run *run;
     struct layout_strikethrough *s;
+    FLOAT snappingfactor = 1.0;
+    BOOL disabled = FALSE;
     HRESULT hr;
 
     TRACE("(%p)->(%p %p %.2f %.2f)\n", This, context, renderer, origin_x, origin_y);
@@ -2747,6 +2755,28 @@ static HRESULT WINAPI dwritetextlayout_Draw(IDWriteTextLayout2 *iface,
     if (FAILED(hr))
         return hr;
 
+    hr = IDWriteTextRenderer_IsPixelSnappingDisabled(renderer, context, &disabled);
+    if (FAILED(hr))
+        return hr;
+
+    if (!disabled) {
+        DWRITE_MATRIX m = { 0 };
+        FLOAT ppdip = 0.0;
+
+        hr = IDWriteTextRenderer_GetPixelsPerDip(renderer, context, &ppdip);
+        if (FAILED(hr))
+            return hr;
+
+        hr = IDWriteTextRenderer_GetCurrentTransform(renderer, context, &m);
+        if (FAILED(hr))
+            return hr;
+
+        snappingfactor = ppdip * m.m22;
+        if (snappingfactor == 0.0)
+            disabled = TRUE;
+    }
+
+#define SNAP_COORD(x) renderer_apply_snapping((x), snappingfactor)
     /* 1. Regular runs */
     LIST_FOR_EACH_ENTRY(run, &This->eruns, struct layout_effective_run, entry) {
         const struct regular_layout_run *regular = &run->run->u.regular;
@@ -2776,7 +2806,7 @@ static HRESULT WINAPI dwritetextlayout_Draw(IDWriteTextLayout2 *iface,
         IDWriteTextRenderer_DrawGlyphRun(renderer,
             context,
             run->origin_x + run->align_dx + origin_x,
-            run->origin_y + origin_y,
+            disabled ? run->origin_y + origin_y : SNAP_COORD(run->origin_y + origin_y),
             DWRITE_MEASURING_MODE_NATURAL,
             &glyph_run,
             &descr,
@@ -2788,7 +2818,7 @@ static HRESULT WINAPI dwritetextlayout_Draw(IDWriteTextLayout2 *iface,
         IDWriteTextRenderer_DrawInlineObject(renderer,
             context,
             inlineobject->origin_x + inlineobject->align_dx + origin_x,
-            inlineobject->origin_y + origin_y,
+            disabled ? inlineobject->origin_y + origin_y : SNAP_COORD(inlineobject->origin_y + origin_y),
             inlineobject->object,
             inlineobject->is_sideways,
             inlineobject->is_rtl,
@@ -2802,10 +2832,11 @@ static HRESULT WINAPI dwritetextlayout_Draw(IDWriteTextLayout2 *iface,
         IDWriteTextRenderer_DrawStrikethrough(renderer,
             context,
             s->run->origin_x,
-            s->run->origin_y,
+            disabled ? s->run->origin_y : SNAP_COORD(s->run->origin_y),
             &s->s,
             NULL);
     }
+#undef SNAP_COORD
 
     return S_OK;
 }
-- 
2.1.4



More information about the wine-patches mailing list