Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/d2d1/device.c | 30 ++++++++++++++++++------------ 1 file changed, 18 insertions(+), 12 deletions(-)
diff --git a/dlls/d2d1/device.c b/dlls/d2d1/device.c index 67b3fab906..58e39b30b2 100644 --- a/dlls/d2d1/device.c +++ b/dlls/d2d1/device.c @@ -1107,10 +1107,10 @@ static void d2d_rt_draw_glyph_run_outline(struct d2d_d3d_render_target *render_t
static void d2d_rt_draw_glyph_run_bitmap(struct d2d_d3d_render_target *render_target, D2D1_POINT_2F baseline_origin, const DWRITE_GLYPH_RUN *glyph_run, ID2D1Brush *brush, - float ppd, DWRITE_RENDERING_MODE rendering_mode, DWRITE_MEASURING_MODE measuring_mode, + DWRITE_RENDERING_MODE rendering_mode, DWRITE_MEASURING_MODE measuring_mode, DWRITE_TEXT_ANTIALIAS_MODE antialias_mode) { - D2D1_MATRIX_3X2_F prev_transform, *transform; + D2D1_MATRIX_3X2_F prev_transform, *transform, scale, m; ID2D1RectangleGeometry *geometry = NULL; ID2D1BitmapBrush *opacity_brush = NULL; D2D1_BITMAP_PROPERTIES bitmap_desc; @@ -1119,10 +1119,10 @@ static void d2d_rt_draw_glyph_run_bitmap(struct d2d_d3d_render_target *render_ta DWRITE_TEXTURE_TYPE texture_type; D2D1_BRUSH_PROPERTIES brush_desc; IDWriteFactory2 *dwrite_factory; - DWRITE_GLYPH_RUN scaled_run; void *opacity_values = NULL; size_t opacity_values_size; D2D1_SIZE_U bitmap_size; + float scale_x, scale_y; D2D1_RECT_F run_rect; RECT bounds; HRESULT hr; @@ -1134,11 +1134,13 @@ static void d2d_rt_draw_glyph_run_bitmap(struct d2d_d3d_render_target *render_ta return; }
- scaled_run = *glyph_run; - scaled_run.fontEmSize *= ppd; - hr = IDWriteFactory2_CreateGlyphRunAnalysis(dwrite_factory, &scaled_run, - (DWRITE_MATRIX *)&render_target->drawing_state.transform, rendering_mode, measuring_mode, - DWRITE_GRID_FIT_MODE_DEFAULT, antialias_mode, baseline_origin.x, + m = render_target->drawing_state.transform; + memset(&scale, 0, sizeof(scale)); + scale._11 = render_target->desc.dpiX / 96.0f; + scale._22 = render_target->desc.dpiY / 96.0f; + d2d_matrix_multiply(&m, &scale); + hr = IDWriteFactory2_CreateGlyphRunAnalysis(dwrite_factory, glyph_run, (DWRITE_MATRIX *)&m, + rendering_mode, measuring_mode, DWRITE_GRID_FIT_MODE_DEFAULT, antialias_mode, baseline_origin.x, baseline_origin.y, &analysis); IDWriteFactory2_Release(dwrite_factory); if (FAILED(hr)) @@ -1194,13 +1196,18 @@ static void d2d_rt_draw_glyph_run_bitmap(struct d2d_d3d_render_target *render_ta goto done; }
+ scale_x = 96.0f / render_target->desc.dpiX; + scale_y = 96.0f / render_target->desc.dpiY; + d2d_rect_set(&run_rect, bounds.left * scale_x, bounds.top * scale_y, bounds.right * scale_x, + bounds.bottom * scale_y); + brush_desc.opacity = 1.0f; brush_desc.transform._11 = 1.0f; brush_desc.transform._12 = 0.0f; brush_desc.transform._21 = 0.0f; brush_desc.transform._22 = 1.0f; - brush_desc.transform._31 = bounds.left; - brush_desc.transform._32 = bounds.top; + brush_desc.transform._31 = run_rect.left; + brush_desc.transform._32 = run_rect.top; if (FAILED(hr = d2d_d3d_render_target_CreateBitmapBrush(&render_target->ID2D1RenderTarget_iface, opacity_bitmap, NULL, &brush_desc, &opacity_brush))) { @@ -1208,7 +1215,6 @@ static void d2d_rt_draw_glyph_run_bitmap(struct d2d_d3d_render_target *render_ta goto done; }
- d2d_rect_set(&run_rect, bounds.left, bounds.top, bounds.right, bounds.bottom); if (FAILED(hr = ID2D1Factory_CreateRectangleGeometry(render_target->factory, &run_rect, &geometry))) { ERR("Failed to create geometry, hr %#x.\n", hr); @@ -1313,7 +1319,7 @@ static void STDMETHODCALLTYPE d2d_d3d_render_target_DrawGlyphRun(ID2D1RenderTarg d2d_rt_draw_glyph_run_outline(render_target, baseline_origin, glyph_run, brush); else d2d_rt_draw_glyph_run_bitmap(render_target, baseline_origin, glyph_run, brush, - ppd, rendering_mode, measuring_mode, antialias_mode); + rendering_mode, measuring_mode, antialias_mode); }
static void STDMETHODCALLTYPE d2d_d3d_render_target_SetTransform(ID2D1RenderTarget *iface,
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/dwrite/dwrite_private.h | 4 +-- dlls/dwrite/font.c | 17 +++++---- dlls/dwrite/main.c | 67 ++++++++++++++++++++++-------------- 3 files changed, 50 insertions(+), 38 deletions(-)
diff --git a/dlls/dwrite/dwrite_private.h b/dlls/dwrite/dwrite_private.h index 31b977a159..a19380a636 100644 --- a/dlls/dwrite/dwrite_private.h +++ b/dlls/dwrite/dwrite_private.h @@ -117,9 +117,7 @@ struct glyphrunanalysis_desc DWRITE_MEASURING_MODE measuring_mode; DWRITE_GRID_FIT_MODE gridfit_mode; DWRITE_TEXT_ANTIALIAS_MODE aa_mode; - FLOAT origin_x; - FLOAT origin_y; - FLOAT ppdip; + D2D_POINT_2F origin; };
struct fontface_desc diff --git a/dlls/dwrite/font.c b/dlls/dwrite/font.c index 9556fd3756..5fc0de733d 100644 --- a/dlls/dwrite/font.c +++ b/dlls/dwrite/font.c @@ -5397,7 +5397,6 @@ HRESULT create_glyphrunanalysis(const struct glyphrunanalysis_desc *desc, IDWrit analysis->max_glyph_bitmap_size = 0; SetRectEmpty(&analysis->bounds); analysis->run = *desc->run; - analysis->run.fontEmSize *= desc->ppdip; IDWriteFontFace_AddRef(analysis->run.fontFace); analysis->glyphs = heap_alloc(desc->run->glyphCount * sizeof(*analysis->glyphs)); analysis->origins = heap_alloc(desc->run->glyphCount * sizeof(*analysis->origins)); @@ -5433,14 +5432,14 @@ HRESULT create_glyphrunanalysis(const struct glyphrunanalysis_desc *desc, IDWrit if (FAILED(hr = IDWriteFontFace_QueryInterface(desc->run->fontFace, &IID_IDWriteFontFace1, (void **)&fontface1))) WARN("Failed to get IDWriteFontFace1, %#x.\n", hr);
- origin.x = desc->origin_x * desc->ppdip; - origin.y = desc->origin_y * desc->ppdip; + origin.x = desc->origin.x; + origin.y = desc->origin.y; for (i = 0; i < desc->run->glyphCount; i++) { FLOAT advance;
/* Use nominal advances if not provided by caller. */ if (desc->run->glyphAdvances) - advance = rtl_factor * desc->run->glyphAdvances[i] * desc->ppdip; + advance = rtl_factor * desc->run->glyphAdvances[i]; else { INT32 a;
@@ -5450,14 +5449,14 @@ HRESULT create_glyphrunanalysis(const struct glyphrunanalysis_desc *desc, IDWrit case DWRITE_MEASURING_MODE_NATURAL: if (SUCCEEDED(IDWriteFontFace1_GetDesignGlyphAdvances(fontface1, 1, desc->run->glyphIndices + i, &a, desc->run->isSideways))) - advance = rtl_factor * get_scaled_advance_width(a, desc->run->fontEmSize, &metrics) * desc->ppdip; + advance = rtl_factor * get_scaled_advance_width(a, desc->run->fontEmSize, &metrics); break; case DWRITE_MEASURING_MODE_GDI_CLASSIC: case DWRITE_MEASURING_MODE_GDI_NATURAL: if (SUCCEEDED(IDWriteFontFace1_GetGdiCompatibleGlyphAdvances(fontface1, desc->run->fontEmSize, - desc->ppdip, desc->transform, desc->measuring_mode == DWRITE_MEASURING_MODE_GDI_NATURAL, + 1.0f, desc->transform, desc->measuring_mode == DWRITE_MEASURING_MODE_GDI_NATURAL, desc->run->isSideways, 1, desc->run->glyphIndices + i, &a))) - advance = rtl_factor * floorf(a * desc->run->fontEmSize * desc->ppdip / metrics.designUnitsPerEm + 0.5f); + advance = rtl_factor * floorf(a * desc->run->fontEmSize / metrics.designUnitsPerEm + 0.5f); break; default: ; @@ -5468,8 +5467,8 @@ HRESULT create_glyphrunanalysis(const struct glyphrunanalysis_desc *desc, IDWrit
/* Offsets are optional, appled to pre-transformed origin. */ if (desc->run->glyphOffsets) { - FLOAT advanceoffset = rtl_factor * desc->run->glyphOffsets[i].advanceOffset * desc->ppdip; - FLOAT ascenderoffset = -desc->run->glyphOffsets[i].ascenderOffset * desc->ppdip; + FLOAT advanceoffset = rtl_factor * desc->run->glyphOffsets[i].advanceOffset; + FLOAT ascenderoffset = -desc->run->glyphOffsets[i].ascenderOffset;
if (desc->run->isSideways) { analysis->origins[i].x += ascenderoffset; diff --git a/dlls/dwrite/main.c b/dlls/dwrite/main.c index c4d2a5f5e7..522bac84fe 100644 --- a/dlls/dwrite/main.c +++ b/dlls/dwrite/main.c @@ -1222,12 +1222,25 @@ static HRESULT WINAPI dwritefactory_CreateNumberSubstitution(IDWriteFactory5 *if return create_numbersubstitution(method, locale, ignore_user_override, substitution); }
+static inline void dwrite_matrix_multiply(DWRITE_MATRIX *a, const DWRITE_MATRIX *b) +{ + DWRITE_MATRIX tmp = *a; + + a->m11 = tmp.m11 * b->m11 + tmp.m12 * b->m21; + a->m12 = tmp.m11 * b->m12 + tmp.m12 * b->m22; + a->m21 = tmp.m21 * b->m11 + tmp.m22 * b->m21; + a->m22 = tmp.m21 * b->m12 + tmp.m22 * b->m22; + a->dx = tmp.dx * b->m11 + tmp.dy * b->m21 + b->dx; + a->dy = tmp.dy * b->m12 + tmp.dy * b->m22 + b->dx; +} + static HRESULT WINAPI dwritefactory_CreateGlyphRunAnalysis(IDWriteFactory5 *iface, DWRITE_GLYPH_RUN const *run, FLOAT ppdip, DWRITE_MATRIX const* transform, DWRITE_RENDERING_MODE rendering_mode, DWRITE_MEASURING_MODE measuring_mode, FLOAT originX, FLOAT originY, IDWriteGlyphRunAnalysis **analysis) { struct dwritefactory *This = impl_from_IDWriteFactory5(iface); struct glyphrunanalysis_desc desc; + DWRITE_MATRIX m, scale = { 0 };
TRACE("(%p)->(%p %.2f %p %d %d %.2f %.2f %p)\n", This, run, ppdip, transform, rendering_mode, measuring_mode, originX, originY, analysis); @@ -1237,15 +1250,18 @@ static HRESULT WINAPI dwritefactory_CreateGlyphRunAnalysis(IDWriteFactory5 *ifac return E_INVALIDARG; }
+ m = transform ? *transform : identity; + scale.m11 = ppdip; + scale.m22 = ppdip; + dwrite_matrix_multiply(&m, &scale); desc.run = run; - desc.ppdip = ppdip; - desc.transform = transform; + desc.transform = &m; desc.rendering_mode = (DWRITE_RENDERING_MODE1)rendering_mode; desc.measuring_mode = measuring_mode; desc.gridfit_mode = DWRITE_GRID_FIT_MODE_DEFAULT; desc.aa_mode = DWRITE_TEXT_ANTIALIAS_MODE_CLEARTYPE; - desc.origin_x = originX; - desc.origin_y = originY; + desc.origin.x = originX; + desc.origin.y = originY; return create_glyphrunanalysis(&desc, analysis); }
@@ -1363,27 +1379,35 @@ static HRESULT WINAPI dwritefactory2_CreateCustomRenderingParams(IDWriteFactory5 return hr; }
+static HRESULT factory_create_glyphrun_analysis(const DWRITE_GLYPH_RUN *run, const DWRITE_MATRIX *transform, + DWRITE_RENDERING_MODE1 rendering_mode, DWRITE_MEASURING_MODE measuring_mode, DWRITE_GRID_FIT_MODE gridfit_mode, + DWRITE_TEXT_ANTIALIAS_MODE aa_mode, FLOAT originX, FLOAT originY, IDWriteGlyphRunAnalysis **analysis) +{ + struct glyphrunanalysis_desc desc; + + desc.run = run; + desc.transform = transform; + desc.rendering_mode = rendering_mode; + desc.measuring_mode = measuring_mode; + desc.gridfit_mode = gridfit_mode; + desc.aa_mode = aa_mode; + desc.origin.x = originX; + desc.origin.y = originY; + return create_glyphrunanalysis(&desc, analysis); +} + static HRESULT WINAPI dwritefactory2_CreateGlyphRunAnalysis(IDWriteFactory5 *iface, const DWRITE_GLYPH_RUN *run, const DWRITE_MATRIX *transform, DWRITE_RENDERING_MODE rendering_mode, DWRITE_MEASURING_MODE measuring_mode, DWRITE_GRID_FIT_MODE gridfit_mode, DWRITE_TEXT_ANTIALIAS_MODE aa_mode, FLOAT originX, FLOAT originY, IDWriteGlyphRunAnalysis **analysis) { struct dwritefactory *This = impl_from_IDWriteFactory5(iface); - struct glyphrunanalysis_desc desc;
TRACE("(%p)->(%p %p %d %d %d %d %.2f %.2f %p)\n", This, run, transform, rendering_mode, measuring_mode, gridfit_mode, aa_mode, originX, originY, analysis);
- desc.run = run; - desc.ppdip = 1.0f; - desc.transform = transform; - desc.rendering_mode = (DWRITE_RENDERING_MODE1)rendering_mode; - desc.measuring_mode = measuring_mode; - desc.gridfit_mode = gridfit_mode; - desc.aa_mode = aa_mode; - desc.origin_x = originX; - desc.origin_y = originY; - return create_glyphrunanalysis(&desc, analysis); + return factory_create_glyphrun_analysis(run, transform, (DWRITE_RENDERING_MODE1)rendering_mode, measuring_mode, + gridfit_mode, aa_mode, originX, originY, analysis); }
static HRESULT WINAPI dwritefactory3_CreateGlyphRunAnalysis(IDWriteFactory5 *iface, DWRITE_GLYPH_RUN const *run, @@ -1392,21 +1416,12 @@ static HRESULT WINAPI dwritefactory3_CreateGlyphRunAnalysis(IDWriteFactory5 *ifa IDWriteGlyphRunAnalysis **analysis) { struct dwritefactory *This = impl_from_IDWriteFactory5(iface); - struct glyphrunanalysis_desc desc;
TRACE("(%p)->(%p %p %d %d %d %d %.2f %.2f %p)\n", This, run, transform, rendering_mode, measuring_mode, gridfit_mode, aa_mode, originX, originY, analysis);
- desc.run = run; - desc.ppdip = 1.0f; - desc.transform = transform; - desc.rendering_mode = rendering_mode; - desc.measuring_mode = measuring_mode; - desc.gridfit_mode = gridfit_mode; - desc.aa_mode = aa_mode; - desc.origin_x = originX; - desc.origin_y = originY; - return create_glyphrunanalysis(&desc, analysis); + return factory_create_glyphrun_analysis(run, transform, rendering_mode, measuring_mode, gridfit_mode, + aa_mode, originX, originY, analysis); }
static HRESULT WINAPI dwritefactory3_CreateCustomRenderingParams(IDWriteFactory5 *iface, FLOAT gamma, FLOAT contrast,