[PATCH 1/3] dwrite: Cleanup rendering interface with freetype

Nikolay Sivov nsivov at codeweavers.com
Thu Aug 27 00:38:50 CDT 2015


---

-------------- next part --------------
>From d3967de3d935288d6b1b745581befaa9204dda6d Mon Sep 17 00:00:00 2001
From: Nikolay Sivov <nsivov at codeweavers.com>
Date: Thu, 27 Aug 2015 08:30:19 +0300
Subject: [PATCH 1/3] dwrite: Cleanup rendering interface with freetype

---
 dlls/dwrite/dwrite_private.h | 14 +++++++--
 dlls/dwrite/font.c           | 71 +++++++++++++++++++++++++++-----------------
 dlls/dwrite/freetype.c       | 58 ++++++++++++++++++------------------
 3 files changed, 84 insertions(+), 59 deletions(-)

diff --git a/dlls/dwrite/dwrite_private.h b/dlls/dwrite/dwrite_private.h
index d1127f1..39043d9 100644
--- a/dlls/dwrite/dwrite_private.h
+++ b/dlls/dwrite/dwrite_private.h
@@ -191,6 +191,16 @@ struct glyph_outline {
 extern HRESULT new_glyph_outline(UINT32,struct glyph_outline**) DECLSPEC_HIDDEN;
 
 /* FreeType integration */
+struct dwrite_glyphbitmap {
+    IDWriteFontFace2 *fontface;
+    FLOAT emsize;
+    BOOL nohint;
+    UINT16 index;
+    INT pitch;
+    RECT bbox;
+    BYTE *buf;
+};
+
 extern BOOL init_freetype(void) DECLSPEC_HIDDEN;
 extern void release_freetype(void) DECLSPEC_HIDDEN;
 extern HRESULT freetype_get_design_glyph_metrics(IDWriteFontFace2*,UINT16,UINT16,DWRITE_GLYPH_METRICS*) DECLSPEC_HIDDEN;
@@ -201,8 +211,8 @@ extern UINT16 freetype_get_glyphcount(IDWriteFontFace2*) DECLSPEC_HIDDEN;
 extern UINT16 freetype_get_glyphindex(IDWriteFontFace2*,UINT32,INT) DECLSPEC_HIDDEN;
 extern BOOL freetype_has_kerning_pairs(IDWriteFontFace2*) DECLSPEC_HIDDEN;
 extern INT32 freetype_get_kerning_pair_adjustment(IDWriteFontFace2*,UINT16,UINT16) DECLSPEC_HIDDEN;
-extern void freetype_get_glyph_bbox(IDWriteFontFace2*,FLOAT,UINT16,BOOL,RECT*) DECLSPEC_HIDDEN;
-extern void freetype_get_glyph_bitmap(IDWriteFontFace2*,FLOAT,UINT16,const RECT*,BYTE*) DECLSPEC_HIDDEN;
+extern void freetype_get_glyph_bbox(struct dwrite_glyphbitmap*) DECLSPEC_HIDDEN;
+extern void freetype_get_glyph_bitmap(struct dwrite_glyphbitmap*) DECLSPEC_HIDDEN;
 extern INT freetype_get_charmap_index(IDWriteFontFace2*,BOOL*) DECLSPEC_HIDDEN;
 extern INT32 freetype_get_glyph_advance(IDWriteFontFace2*,FLOAT,UINT16,DWRITE_MEASURING_MODE) DECLSPEC_HIDDEN;
 
diff --git a/dlls/dwrite/font.c b/dlls/dwrite/font.c
index 0d5cbc0..f66d49c 100644
--- a/dlls/dwrite/font.c
+++ b/dlls/dwrite/font.c
@@ -3496,9 +3496,10 @@ static ULONG WINAPI glyphrunanalysis_Release(IDWriteGlyphRunAnalysis *iface)
 
 static void glyphrunanalysis_get_texturebounds(struct dwrite_glyphrunanalysis *analysis, RECT *bounds)
 {
+    struct dwrite_glyphbitmap glyph_bitmap;
     IDWriteFontFace2 *fontface2;
-    BOOL nohint, is_rtl;
     FLOAT origin_x;
+    BOOL is_rtl;
     HRESULT hr;
     UINT32 i;
 
@@ -3514,29 +3515,35 @@ static void glyphrunanalysis_get_texturebounds(struct dwrite_glyphrunanalysis *a
     if (FAILED(hr))
         WARN("failed to get IDWriteFontFace2, 0x%08x\n", hr);
 
-    nohint = analysis->rendering_mode == DWRITE_RENDERING_MODE_NATURAL || analysis->rendering_mode == DWRITE_RENDERING_MODE_NATURAL_SYMMETRIC;
-
     /* Start with empty bounds at (0,0) origin, returned bounds are not translated back to (0,0), e.g. for
        RTL run negative left bound is returned, same goes for vertical direction - top bound will be negative
        for any non-zero glyph ascender */
     origin_x = 0.0;
     is_rtl = analysis->run.bidiLevel & 1;
+
+    memset(&glyph_bitmap, 0, sizeof(glyph_bitmap));
+    glyph_bitmap.fontface = fontface2;
+    glyph_bitmap.emsize = analysis->run.fontEmSize * analysis->ppdip;
+    glyph_bitmap.nohint = analysis->rendering_mode == DWRITE_RENDERING_MODE_NATURAL ||
+        analysis->rendering_mode == DWRITE_RENDERING_MODE_NATURAL_SYMMETRIC;
+
     for (i = 0; i < analysis->run.glyphCount; i++) {
         const DWRITE_GLYPH_OFFSET *offset = analysis->offsets ? &analysis->offsets[i] : NULL;
         FLOAT advance = analysis->advances[i];
-        RECT bbox;
+        RECT *bbox = &glyph_bitmap.bbox;
 
-        freetype_get_glyph_bbox(fontface2, analysis->run.fontEmSize * analysis->ppdip, analysis->run.glyphIndices[i], nohint, &bbox);
+        glyph_bitmap.index = analysis->run.glyphIndices[i];
+        freetype_get_glyph_bbox(&glyph_bitmap);
 
         if (is_rtl)
-            OffsetRect(&bbox, origin_x - advance, 0);
+            OffsetRect(bbox, origin_x - advance, 0);
         else
-            OffsetRect(&bbox, origin_x, 0);
+            OffsetRect(bbox, origin_x, 0);
 
         if (offset)
-            OffsetRect(&bbox, is_rtl ? -offset->advanceOffset : offset->advanceOffset, is_rtl ? -offset->ascenderOffset : offset->ascenderOffset);
+            OffsetRect(bbox, is_rtl ? -offset->advanceOffset : offset->advanceOffset, is_rtl ? -offset->ascenderOffset : offset->ascenderOffset);
 
-        UnionRect(&analysis->bounds, &analysis->bounds, &bbox);
+        UnionRect(&analysis->bounds, &analysis->bounds, bbox);
         origin_x += is_rtl ? -advance : advance;
     }
 
@@ -3588,11 +3595,13 @@ static inline BYTE *get_pixel_ptr(BYTE *ptr, DWRITE_TEXTURE_TYPE type, const REC
 static void glyphrunanalysis_render(struct dwrite_glyphrunanalysis *analysis, DWRITE_TEXTURE_TYPE type)
 {
     static const BYTE masks[8] = {0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01};
+    struct dwrite_glyphbitmap glyph_bitmap;
     IDWriteFontFace2 *fontface2;
-    BOOL is_rtl, nohint;
     FLOAT origin_x;
     UINT32 i, size;
+    BOOL is_rtl;
     HRESULT hr;
+    RECT *bbox;
 
     hr = IDWriteFontFace_QueryInterface(analysis->run.fontFace, &IID_IDWriteFontFace2, (void**)&fontface2);
     if (FAILED(hr)) {
@@ -3600,8 +3609,6 @@ static void glyphrunanalysis_render(struct dwrite_glyphrunanalysis *analysis, DW
         return;
     }
 
-    nohint = analysis->rendering_mode == DWRITE_RENDERING_MODE_NATURAL || analysis->rendering_mode == DWRITE_RENDERING_MODE_NATURAL_SYMMETRIC;
-
     size = (analysis->bounds.right - analysis->bounds.left)*(analysis->bounds.bottom - analysis->bounds.top);
     if (type == DWRITE_TEXTURE_CLEARTYPE_3x1)
         size *= 3;
@@ -3609,39 +3616,47 @@ static void glyphrunanalysis_render(struct dwrite_glyphrunanalysis *analysis, DW
 
     origin_x = 0.0;
     is_rtl = analysis->run.bidiLevel & 1;
+
+    memset(&glyph_bitmap, 0, sizeof(glyph_bitmap));
+    glyph_bitmap.fontface = fontface2;
+    glyph_bitmap.emsize = analysis->run.fontEmSize * analysis->ppdip;
+    glyph_bitmap.nohint = analysis->rendering_mode == DWRITE_RENDERING_MODE_NATURAL ||
+        analysis->rendering_mode == DWRITE_RENDERING_MODE_NATURAL_SYMMETRIC;
+    bbox = &glyph_bitmap.bbox;
+
     for (i = 0; i < analysis->run.glyphCount; i++) {
         const DWRITE_GLYPH_OFFSET *offset = analysis->offsets ? &analysis->offsets[i] : NULL;
         FLOAT advance = analysis->advances[i];
-        int pitch, x, y, width, height;
-        BYTE *glyph, *src, *dst;
-        RECT bbox;
+        int x, y, width, height;
+        BYTE *src, *dst;
 
-        freetype_get_glyph_bbox(fontface2, analysis->run.fontEmSize * analysis->ppdip, analysis->run.glyphIndices[i], nohint, &bbox);
+        glyph_bitmap.index = analysis->run.glyphIndices[i];
+        freetype_get_glyph_bbox(&glyph_bitmap);
 
-        if (IsRectEmpty(&bbox)) {
+        if (IsRectEmpty(bbox)) {
             origin_x += is_rtl ? -advance : advance;
             continue;
         }
 
-        width = bbox.right - bbox.left;
-        height = bbox.bottom - bbox.top;
-        pitch = ((width + 31) >> 5) << 2;
+        width = bbox->right - bbox->left;
+        height = bbox->bottom - bbox->top;
+        glyph_bitmap.pitch = ((width + 31) >> 5) << 2;
 
-        src = glyph = heap_alloc_zero((bbox.bottom - bbox.top) * pitch);
-        freetype_get_glyph_bitmap(fontface2, analysis->run.fontEmSize * analysis->ppdip, analysis->run.glyphIndices[i], &bbox, glyph);
+        glyph_bitmap.buf = src = heap_alloc_zero(height * glyph_bitmap.pitch);
+        freetype_get_glyph_bitmap(&glyph_bitmap);
 
         if (is_rtl)
-            OffsetRect(&bbox, origin_x - advance, 0);
+            OffsetRect(bbox, origin_x - advance, 0);
         else
-            OffsetRect(&bbox, origin_x, 0);
+            OffsetRect(bbox, origin_x, 0);
 
         if (offset)
-            OffsetRect(&bbox, is_rtl ? -offset->advanceOffset : offset->advanceOffset, is_rtl ? -offset->ascenderOffset : offset->ascenderOffset);
+            OffsetRect(bbox, is_rtl ? -offset->advanceOffset : offset->advanceOffset, is_rtl ? -offset->ascenderOffset : offset->ascenderOffset);
 
-        OffsetRect(&bbox, analysis->originX, analysis->originY);
+        OffsetRect(bbox, analysis->originX, analysis->originY);
 
         /* blit to analysis bitmap */
-        dst = get_pixel_ptr(analysis->bitmap, type, &bbox, &analysis->bounds);
+        dst = get_pixel_ptr(analysis->bitmap, type, bbox, &analysis->bounds);
 
         /* convert 1bpp to 8bpp/24bpp */
         if (type == DWRITE_TEXTURE_CLEARTYPE_3x1) {
@@ -3661,7 +3676,7 @@ static void glyphrunanalysis_render(struct dwrite_glyphrunanalysis *analysis, DW
             }
         }
 
-        heap_free(glyph);
+        heap_free(glyph_bitmap.buf);
 
         origin_x += is_rtl ? -advance : advance;
     }
diff --git a/dlls/dwrite/freetype.c b/dlls/dwrite/freetype.c
index ec6a13f..dc6d701 100644
--- a/dlls/dwrite/freetype.c
+++ b/dlls/dwrite/freetype.c
@@ -487,43 +487,43 @@ INT32 freetype_get_kerning_pair_adjustment(IDWriteFontFace2 *fontface, UINT16 le
     return adjustment;
 }
 
-void freetype_get_glyph_bbox(IDWriteFontFace2 *fontface, FLOAT emSize, UINT16 index, BOOL nohint, RECT *ret)
+void freetype_get_glyph_bbox(struct dwrite_glyphbitmap *bitmap)
 {
     FTC_ImageTypeRec imagetype;
     FT_BBox bbox = { 0 };
     FT_Glyph glyph;
 
-    imagetype.face_id = fontface;
+    imagetype.face_id = bitmap->fontface;
     imagetype.width = 0;
-    imagetype.height = emSize;
+    imagetype.height = bitmap->emsize;
     imagetype.flags = FT_LOAD_DEFAULT;
 
     EnterCriticalSection(&freetype_cs);
-    if (pFTC_ImageCache_Lookup(image_cache, &imagetype, index, &glyph, NULL) == 0)
+    if (pFTC_ImageCache_Lookup(image_cache, &imagetype, bitmap->index, &glyph, NULL) == 0)
         pFT_Glyph_Get_CBox(glyph, FT_GLYPH_BBOX_PIXELS, &bbox);
     LeaveCriticalSection(&freetype_cs);
 
     /* flip Y axis */
-    ret->left = bbox.xMin;
-    ret->right = bbox.xMax;
-    ret->top = -bbox.yMax;
-    ret->bottom = -bbox.yMin;
+    bitmap->bbox.left = bbox.xMin;
+    bitmap->bbox.right = bbox.xMax;
+    bitmap->bbox.top = -bbox.yMax;
+    bitmap->bbox.bottom = -bbox.yMin;
 }
 
-void freetype_get_glyph_bitmap(IDWriteFontFace2 *fontface, FLOAT emSize, UINT16 index, const RECT *bbox, BYTE *buf)
+void freetype_get_glyph_bitmap(struct dwrite_glyphbitmap *bitmap)
 {
+    const RECT *bbox = &bitmap->bbox;
     FTC_ImageTypeRec imagetype;
     FT_Glyph glyph;
 
-    imagetype.face_id = fontface;
+    imagetype.face_id = bitmap->fontface;
     imagetype.width = 0;
-    imagetype.height = emSize;
+    imagetype.height = bitmap->emsize;
     imagetype.flags = FT_LOAD_DEFAULT;
 
     EnterCriticalSection(&freetype_cs);
-    if (pFTC_ImageCache_Lookup(image_cache, &imagetype, index, &glyph, NULL) == 0) {
+    if (pFTC_ImageCache_Lookup(image_cache, &imagetype, bitmap->index, &glyph, NULL) == 0) {
         int width = bbox->right - bbox->left;
-        int pitch = ((width + 31) >> 5) << 2;
         int height = bbox->bottom - bbox->top;
 
         if (glyph->format == FT_GLYPH_FORMAT_OUTLINE) {
@@ -534,12 +534,12 @@ void freetype_get_glyph_bitmap(IDWriteFontFace2 *fontface, FLOAT emSize, UINT16
 
             ft_bitmap.width = width;
             ft_bitmap.rows = height;
-            ft_bitmap.pitch = pitch;
+            ft_bitmap.pitch = bitmap->pitch;
             ft_bitmap.pixel_mode = FT_PIXEL_MODE_MONO;
-            ft_bitmap.buffer = buf;
+            ft_bitmap.buffer = bitmap->buf;
 
             /* Note: FreeType will only set 'black' bits for us. */
-            memset(buf, 0, height*pitch);
+            memset(bitmap->buf, 0, height * bitmap->pitch);
             if (pFT_Outline_New(library, src->n_points, src->n_contours, &copy) == 0) {
                 pFT_Outline_Copy(src, &copy);
                 pFT_Outline_Translate(&copy, -bbox->left << 6, bbox->bottom << 6);
@@ -548,21 +548,21 @@ void freetype_get_glyph_bitmap(IDWriteFontFace2 *fontface, FLOAT emSize, UINT16
             }
         }
         else if (glyph->format == FT_GLYPH_FORMAT_BITMAP) {
-            FT_Bitmap *bitmap = &((FT_BitmapGlyph)glyph)->bitmap;
-            BYTE *src = bitmap->buffer, *dst = buf;
-            int w = min(pitch, (bitmap->width + 7) >> 3);
-            int h = min(height, bitmap->rows);
+            FT_Bitmap *ft_bitmap = &((FT_BitmapGlyph)glyph)->bitmap;
+            BYTE *src = ft_bitmap->buffer, *dst = bitmap->buf;
+            int w = min(bitmap->pitch, (ft_bitmap->width + 7) >> 3);
+            int h = min(height, ft_bitmap->rows);
 
-            memset(buf, 0, height*pitch);
+            memset(bitmap->buf, 0, height * bitmap->pitch);
 
             while (h--) {
                 memcpy(dst, src, w);
-                src += bitmap->pitch;
-                dst += pitch;
+                src += ft_bitmap->pitch;
+                dst += bitmap->pitch;
             }
         }
         else
-            FIXME("format %d not handled\n", glyph->format);
+            FIXME("format %x not handled\n", glyph->format);
     }
     LeaveCriticalSection(&freetype_cs);
 }
@@ -673,15 +673,15 @@ INT32 freetype_get_kerning_pair_adjustment(IDWriteFontFace2 *fontface, UINT16 le
     return 0;
 }
 
-void freetype_get_glyph_bbox(IDWriteFontFace2 *fontface, FLOAT emSize, UINT16 index, BOOL nohint, RECT *ret)
+void freetype_get_glyph_bbox(struct dwrite_glyphbitmap *bitmap)
 {
-    ret->left = ret->right = ret->top = ret->bottom = 0;
+    memset(&bitmap->bbox, 0, sizeof(bitmap->bbox));
 }
 
-void freetype_get_glyph_bitmap(IDWriteFontFace2 *fontface, FLOAT emSize, UINT16 index, const RECT *bbox, BYTE *buf)
+void freetype_get_glyph_bitmap(struct dwrite_glyphbitmap *bitmap)
 {
-    UINT32 size = (bbox->right - bbox->left)*(bbox->bottom - bbox->top);
-    memset(buf, 0, size);
+    UINT32 size = (bitmap->bbox.right - bitmap->bbox.left)*(bitmap->bbox.bottom - bitmap->bbox.top);
+    memset(bitmap->buf, 0, size);
 }
 
 INT freetype_get_charmap_index(IDWriteFontFace2 *fontface, BOOL *is_symbol)
-- 
2.1.4



More information about the wine-patches mailing list