[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, ©) == 0) {
pFT_Outline_Copy(src, ©);
pFT_Outline_Translate(©, -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