mirror of
git://source.winehq.org/git/wine.git
synced 2024-11-05 18:01:34 +00:00
d2d1: Take the recommended rendering mode into account in d2d_d3d_render_target_DrawGlyphRun().
Signed-off-by: Henri Verbeet <hverbeet@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
b5685efc80
commit
55d403deb9
2 changed files with 223 additions and 50 deletions
|
@ -85,6 +85,7 @@ struct d2d_d3d_render_target
|
|||
struct d2d_error_state error;
|
||||
D2D1_DRAWING_STATE_DESCRIPTION drawing_state;
|
||||
IDWriteRenderingParams *text_rendering_params;
|
||||
IDWriteRenderingParams *default_text_rendering_params;
|
||||
|
||||
D2D1_PIXEL_FORMAT format;
|
||||
D2D1_SIZE_U pixel_size;
|
||||
|
|
|
@ -76,6 +76,12 @@ static void d2d_rect_set(D2D1_RECT_F *dst, float left, float top, float right, f
|
|||
dst->bottom = bottom;
|
||||
}
|
||||
|
||||
static void d2d_size_set(D2D1_SIZE_U *dst, float width, float height)
|
||||
{
|
||||
dst->width = width;
|
||||
dst->height = height;
|
||||
}
|
||||
|
||||
static BOOL d2d_clip_stack_init(struct d2d_clip_stack *stack)
|
||||
{
|
||||
if (!(stack->stack = HeapAlloc(GetProcessHeap(), 0, INITIAL_CLIP_STACK_SIZE * sizeof(*stack->stack))))
|
||||
|
@ -242,6 +248,7 @@ static ULONG STDMETHODCALLTYPE d2d_d3d_render_target_Release(ID2D1RenderTarget *
|
|||
unsigned int i, j, k;
|
||||
|
||||
d2d_clip_stack_cleanup(&render_target->clip_stack);
|
||||
IDWriteRenderingParams_Release(render_target->default_text_rendering_params);
|
||||
if (render_target->text_rendering_params)
|
||||
IDWriteRenderingParams_Release(render_target->text_rendering_params);
|
||||
ID3D10BlendState_Release(render_target->bs);
|
||||
|
@ -665,13 +672,9 @@ static void STDMETHODCALLTYPE d2d_d3d_render_target_DrawGeometry(ID2D1RenderTarg
|
|||
iface, geometry, brush, stroke_width, stroke_style);
|
||||
}
|
||||
|
||||
static void STDMETHODCALLTYPE d2d_d3d_render_target_FillGeometry(ID2D1RenderTarget *iface,
|
||||
ID2D1Geometry *geometry, ID2D1Brush *brush, ID2D1Brush *opacity_brush)
|
||||
static void STDMETHODCALLTYPE d2d_rt_fill_geometry(struct d2d_d3d_render_target *render_target,
|
||||
const struct d2d_geometry *geometry, struct d2d_brush *brush, struct d2d_brush *opacity_brush)
|
||||
{
|
||||
struct d2d_brush *opacity_brush_impl = unsafe_impl_from_ID2D1Brush(opacity_brush);
|
||||
struct d2d_d3d_render_target *render_target = impl_from_ID2D1RenderTarget(iface);
|
||||
struct d2d_brush *brush_impl = unsafe_impl_from_ID2D1Brush(brush);
|
||||
const struct d2d_geometry *geometry_impl;
|
||||
ID3D10Buffer *ib, *vb, *vs_cb, *ps_cb;
|
||||
D3D10_SUBRESOURCE_DATA buffer_data;
|
||||
D3D10_BUFFER_DESC buffer_desc;
|
||||
|
@ -684,21 +687,6 @@ static void STDMETHODCALLTYPE d2d_d3d_render_target_FillGeometry(ID2D1RenderTarg
|
|||
float _12, _22, _32, pad1;
|
||||
} transform;
|
||||
|
||||
TRACE("iface %p, geometry %p, brush %p, opacity_brush %p.\n", iface, geometry, brush, opacity_brush);
|
||||
|
||||
if (FAILED(render_target->error.code))
|
||||
return;
|
||||
|
||||
if (opacity_brush && brush_impl->type != D2D_BRUSH_TYPE_BITMAP)
|
||||
{
|
||||
render_target->error.code = D2DERR_INCOMPATIBLE_BRUSH_TYPES;
|
||||
render_target->error.tag1 = render_target->drawing_state.tag1;
|
||||
render_target->error.tag2 = render_target->drawing_state.tag2;
|
||||
return;
|
||||
}
|
||||
|
||||
geometry_impl = unsafe_impl_from_ID2D1Geometry(geometry);
|
||||
|
||||
tmp_x = (2.0f * render_target->dpi_x) / (96.0f * render_target->pixel_size.width);
|
||||
tmp_y = -(2.0f * render_target->dpi_y) / (96.0f * render_target->pixel_size.height);
|
||||
w = render_target->drawing_state.transform;
|
||||
|
@ -709,7 +697,7 @@ static void STDMETHODCALLTYPE d2d_d3d_render_target_FillGeometry(ID2D1RenderTarg
|
|||
w._22 *= tmp_y;
|
||||
w._32 = w._32 * tmp_y + 1.0f;
|
||||
|
||||
g = geometry_impl->transform;
|
||||
g = geometry->transform;
|
||||
d2d_matrix_multiply(&g, &w);
|
||||
|
||||
transform._11 = g._11;
|
||||
|
@ -737,18 +725,18 @@ static void STDMETHODCALLTYPE d2d_d3d_render_target_FillGeometry(ID2D1RenderTarg
|
|||
return;
|
||||
}
|
||||
|
||||
if (FAILED(hr = d2d_brush_get_ps_cb(brush_impl, opacity_brush_impl, render_target, &ps_cb)))
|
||||
if (FAILED(hr = d2d_brush_get_ps_cb(brush, opacity_brush, render_target, &ps_cb)))
|
||||
{
|
||||
WARN("Failed to get ps constant buffer, hr %#x.\n", hr);
|
||||
ID3D10Buffer_Release(vs_cb);
|
||||
return;
|
||||
}
|
||||
|
||||
if (geometry_impl->face_count)
|
||||
if (geometry->face_count)
|
||||
{
|
||||
buffer_desc.ByteWidth = geometry_impl->face_count * sizeof(*geometry_impl->faces);
|
||||
buffer_desc.ByteWidth = geometry->face_count * sizeof(*geometry->faces);
|
||||
buffer_desc.BindFlags = D3D10_BIND_INDEX_BUFFER;
|
||||
buffer_data.pSysMem = geometry_impl->faces;
|
||||
buffer_data.pSysMem = geometry->faces;
|
||||
|
||||
if (FAILED(hr = ID3D10Device_CreateBuffer(render_target->device, &buffer_desc, &buffer_data, &ib)))
|
||||
{
|
||||
|
@ -756,9 +744,9 @@ static void STDMETHODCALLTYPE d2d_d3d_render_target_FillGeometry(ID2D1RenderTarg
|
|||
goto done;
|
||||
}
|
||||
|
||||
buffer_desc.ByteWidth = geometry_impl->vertex_count * sizeof(*geometry_impl->vertices);
|
||||
buffer_desc.ByteWidth = geometry->vertex_count * sizeof(*geometry->vertices);
|
||||
buffer_desc.BindFlags = D3D10_BIND_VERTEX_BUFFER;
|
||||
buffer_data.pSysMem = geometry_impl->vertices;
|
||||
buffer_data.pSysMem = geometry->vertices;
|
||||
|
||||
if (FAILED(hr = ID3D10Device_CreateBuffer(render_target->device, &buffer_desc, &buffer_data, &vb)))
|
||||
{
|
||||
|
@ -767,17 +755,17 @@ static void STDMETHODCALLTYPE d2d_d3d_render_target_FillGeometry(ID2D1RenderTarg
|
|||
goto done;
|
||||
}
|
||||
|
||||
d2d_rt_draw(render_target, D2D_SHAPE_TYPE_TRIANGLE, ib, 3 * geometry_impl->face_count, vb,
|
||||
sizeof(*geometry_impl->vertices), vs_cb, ps_cb, brush_impl, opacity_brush_impl);
|
||||
d2d_rt_draw(render_target, D2D_SHAPE_TYPE_TRIANGLE, ib, 3 * geometry->face_count, vb,
|
||||
sizeof(*geometry->vertices), vs_cb, ps_cb, brush, opacity_brush);
|
||||
|
||||
ID3D10Buffer_Release(vb);
|
||||
ID3D10Buffer_Release(ib);
|
||||
}
|
||||
|
||||
if (geometry_impl->bezier_count)
|
||||
if (geometry->bezier_count)
|
||||
{
|
||||
buffer_desc.ByteWidth = geometry_impl->bezier_count * sizeof(*geometry_impl->beziers);
|
||||
buffer_data.pSysMem = geometry_impl->beziers;
|
||||
buffer_desc.ByteWidth = geometry->bezier_count * sizeof(*geometry->beziers);
|
||||
buffer_data.pSysMem = geometry->beziers;
|
||||
|
||||
if (FAILED(hr = ID3D10Device_CreateBuffer(render_target->device, &buffer_desc, &buffer_data, &vb)))
|
||||
{
|
||||
|
@ -785,8 +773,8 @@ static void STDMETHODCALLTYPE d2d_d3d_render_target_FillGeometry(ID2D1RenderTarg
|
|||
goto done;
|
||||
}
|
||||
|
||||
d2d_rt_draw(render_target, D2D_SHAPE_TYPE_BEZIER, NULL, 3 * geometry_impl->bezier_count, vb,
|
||||
sizeof(*geometry_impl->beziers->v), vs_cb, ps_cb, brush_impl, opacity_brush_impl);
|
||||
d2d_rt_draw(render_target, D2D_SHAPE_TYPE_BEZIER, NULL, 3 * geometry->bezier_count, vb,
|
||||
sizeof(*geometry->beziers->v), vs_cb, ps_cb, brush, opacity_brush);
|
||||
|
||||
ID3D10Buffer_Release(vb);
|
||||
}
|
||||
|
@ -796,6 +784,30 @@ done:
|
|||
ID3D10Buffer_Release(vs_cb);
|
||||
}
|
||||
|
||||
static void STDMETHODCALLTYPE d2d_d3d_render_target_FillGeometry(ID2D1RenderTarget *iface,
|
||||
ID2D1Geometry *geometry, ID2D1Brush *brush, ID2D1Brush *opacity_brush)
|
||||
{
|
||||
const struct d2d_geometry *geometry_impl = unsafe_impl_from_ID2D1Geometry(geometry);
|
||||
struct d2d_brush *opacity_brush_impl = unsafe_impl_from_ID2D1Brush(opacity_brush);
|
||||
struct d2d_d3d_render_target *render_target = impl_from_ID2D1RenderTarget(iface);
|
||||
struct d2d_brush *brush_impl = unsafe_impl_from_ID2D1Brush(brush);
|
||||
|
||||
TRACE("iface %p, geometry %p, brush %p, opacity_brush %p.\n", iface, geometry, brush, opacity_brush);
|
||||
|
||||
if (FAILED(render_target->error.code))
|
||||
return;
|
||||
|
||||
if (opacity_brush && brush_impl->type != D2D_BRUSH_TYPE_BITMAP)
|
||||
{
|
||||
render_target->error.code = D2DERR_INCOMPATIBLE_BRUSH_TYPES;
|
||||
render_target->error.tag1 = render_target->drawing_state.tag1;
|
||||
render_target->error.tag2 = render_target->drawing_state.tag2;
|
||||
return;
|
||||
}
|
||||
|
||||
d2d_rt_fill_geometry(render_target, geometry_impl, brush_impl, opacity_brush_impl);
|
||||
}
|
||||
|
||||
static void STDMETHODCALLTYPE d2d_d3d_render_target_FillMesh(ID2D1RenderTarget *iface,
|
||||
ID2D1Mesh *mesh, ID2D1Brush *brush)
|
||||
{
|
||||
|
@ -928,26 +940,14 @@ static void STDMETHODCALLTYPE d2d_d3d_render_target_DrawTextLayout(ID2D1RenderTa
|
|||
FIXME("Failed to draw text layout, hr %#x.\n", hr);
|
||||
}
|
||||
|
||||
static void STDMETHODCALLTYPE d2d_d3d_render_target_DrawGlyphRun(ID2D1RenderTarget *iface,
|
||||
D2D1_POINT_2F baseline_origin, const DWRITE_GLYPH_RUN *glyph_run, ID2D1Brush *brush,
|
||||
DWRITE_MEASURING_MODE measuring_mode)
|
||||
static void d2d_rt_draw_glyph_run_outline(struct d2d_d3d_render_target *render_target,
|
||||
D2D1_POINT_2F baseline_origin, const DWRITE_GLYPH_RUN *glyph_run, ID2D1Brush *brush)
|
||||
{
|
||||
struct d2d_d3d_render_target *render_target = impl_from_ID2D1RenderTarget(iface);
|
||||
D2D1_MATRIX_3X2_F *transform, prev_transform;
|
||||
ID2D1PathGeometry *geometry;
|
||||
ID2D1GeometrySink *sink;
|
||||
HRESULT hr;
|
||||
|
||||
TRACE("iface %p, baseline_origin {%.8e, %.8e}, glyph_run %p, brush %p, measuring_mode %#x.\n",
|
||||
iface, baseline_origin.x, baseline_origin.y, glyph_run, brush, measuring_mode);
|
||||
|
||||
if (measuring_mode)
|
||||
FIXME("Ignoring measuring mode %#x.\n", measuring_mode);
|
||||
if (render_target->text_rendering_params)
|
||||
FIXME("Ignoring text rendering parameters %p.\n", render_target->text_rendering_params);
|
||||
if (render_target->drawing_state.textAntialiasMode != D2D1_TEXT_ANTIALIAS_MODE_ALIASED)
|
||||
FIXME("Ignoring text antialiasing mode %#x.\n", render_target->drawing_state.textAntialiasMode);
|
||||
|
||||
if (FAILED(hr = ID2D1Factory_CreatePathGeometry(render_target->factory, &geometry)))
|
||||
{
|
||||
ERR("Failed to create geometry, hr %#x.\n", hr);
|
||||
|
@ -979,12 +979,166 @@ static void STDMETHODCALLTYPE d2d_d3d_render_target_DrawGlyphRun(ID2D1RenderTarg
|
|||
prev_transform = *transform;
|
||||
transform->_31 += baseline_origin.x * transform->_11 + baseline_origin.y * transform->_21;
|
||||
transform->_32 += baseline_origin.x * transform->_12 + baseline_origin.y * transform->_22;
|
||||
ID2D1RenderTarget_FillGeometry(iface, (ID2D1Geometry *)geometry, brush, NULL);
|
||||
d2d_rt_fill_geometry(render_target, unsafe_impl_from_ID2D1Geometry((ID2D1Geometry *)geometry),
|
||||
unsafe_impl_from_ID2D1Brush(brush), NULL);
|
||||
*transform = prev_transform;
|
||||
|
||||
ID2D1PathGeometry_Release(geometry);
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
ID2D1RectangleGeometry *geometry = NULL;
|
||||
ID2D1BitmapBrush *opacity_brush = NULL;
|
||||
D2D1_BITMAP_PROPERTIES bitmap_desc;
|
||||
ID2D1Bitmap *opacity_bitmap = NULL;
|
||||
IDWriteGlyphRunAnalysis *analysis;
|
||||
DWRITE_TEXTURE_TYPE texture_type;
|
||||
D2D1_BRUSH_PROPERTIES brush_desc;
|
||||
IDWriteFactory *dwrite_factory;
|
||||
void *opacity_values = NULL;
|
||||
size_t opacity_values_size;
|
||||
D2D1_SIZE_U bitmap_size;
|
||||
D2D1_RECT_F run_rect;
|
||||
RECT bounds;
|
||||
HRESULT hr;
|
||||
|
||||
if (FAILED(hr = DWriteCreateFactory(DWRITE_FACTORY_TYPE_SHARED,
|
||||
&IID_IDWriteFactory, (IUnknown **)&dwrite_factory)))
|
||||
{
|
||||
ERR("Failed to create dwrite factory, hr %#x.\n", hr);
|
||||
return;
|
||||
}
|
||||
|
||||
hr = IDWriteFactory_CreateGlyphRunAnalysis(dwrite_factory, glyph_run, ppd, NULL,
|
||||
rendering_mode, measuring_mode, baseline_origin.x, baseline_origin.y, &analysis);
|
||||
IDWriteFactory_Release(dwrite_factory);
|
||||
if (FAILED(hr))
|
||||
{
|
||||
ERR("Failed to create glyph run analysis, hr %#x.\n", hr);
|
||||
return;
|
||||
}
|
||||
|
||||
if (rendering_mode == DWRITE_RENDERING_MODE_ALIASED)
|
||||
texture_type = DWRITE_TEXTURE_ALIASED_1x1;
|
||||
else
|
||||
texture_type = DWRITE_TEXTURE_CLEARTYPE_3x1;
|
||||
|
||||
if (FAILED(hr = IDWriteGlyphRunAnalysis_GetAlphaTextureBounds(analysis, texture_type, &bounds)))
|
||||
{
|
||||
ERR("Failed to get alpha texture bounds, hr %#x.\n", hr);
|
||||
goto done;
|
||||
}
|
||||
|
||||
d2d_size_set(&bitmap_size, bounds.right - bounds.left, bounds.bottom - bounds.top);
|
||||
if (!bitmap_size.width || !bitmap_size.height)
|
||||
{
|
||||
/* Empty run, nothing to do. */
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (texture_type == DWRITE_TEXTURE_CLEARTYPE_3x1)
|
||||
bitmap_size.width *= 3;
|
||||
opacity_values_size = bitmap_size.width * bitmap_size.height;
|
||||
if (!(opacity_values = HeapAlloc(GetProcessHeap(), 0, opacity_values_size)))
|
||||
{
|
||||
ERR("Failed to allocate opacity values.\n");
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (FAILED(hr = IDWriteGlyphRunAnalysis_CreateAlphaTexture(analysis,
|
||||
texture_type, &bounds, opacity_values, opacity_values_size)))
|
||||
{
|
||||
ERR("Failed to create alpha texture, hr %#x.\n", hr);
|
||||
goto done;
|
||||
}
|
||||
|
||||
bitmap_desc.pixelFormat.format = DXGI_FORMAT_A8_UNORM;
|
||||
bitmap_desc.pixelFormat.alphaMode = D2D1_ALPHA_MODE_PREMULTIPLIED;
|
||||
bitmap_desc.dpiX = render_target->dpi_x;
|
||||
if (texture_type == DWRITE_TEXTURE_CLEARTYPE_3x1)
|
||||
bitmap_desc.dpiX *= 3.0f;
|
||||
bitmap_desc.dpiY = render_target->dpi_y;
|
||||
if (FAILED(hr = d2d_d3d_render_target_CreateBitmap(&render_target->ID2D1RenderTarget_iface,
|
||||
bitmap_size, opacity_values, bitmap_size.width, &bitmap_desc, &opacity_bitmap)))
|
||||
{
|
||||
ERR("Failed to create opacity bitmap, hr %#x.\n", hr);
|
||||
goto done;
|
||||
}
|
||||
|
||||
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;
|
||||
if (FAILED(hr = d2d_d3d_render_target_CreateBitmapBrush(&render_target->ID2D1RenderTarget_iface,
|
||||
opacity_bitmap, NULL, &brush_desc, &opacity_brush)))
|
||||
{
|
||||
ERR("Failed to create opacity bitmap brush, hr %#x.\n", hr);
|
||||
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);
|
||||
goto done;
|
||||
}
|
||||
|
||||
d2d_rt_fill_geometry(render_target, unsafe_impl_from_ID2D1Geometry((ID2D1Geometry *)geometry),
|
||||
unsafe_impl_from_ID2D1Brush(brush), unsafe_impl_from_ID2D1Brush((ID2D1Brush *)opacity_brush));
|
||||
|
||||
done:
|
||||
if (geometry)
|
||||
ID2D1RectangleGeometry_Release(geometry);
|
||||
if (opacity_brush)
|
||||
ID2D1BitmapBrush_Release(opacity_brush);
|
||||
if (opacity_bitmap)
|
||||
ID2D1Bitmap_Release(opacity_bitmap);
|
||||
HeapFree(GetProcessHeap(), 0, opacity_values);
|
||||
IDWriteGlyphRunAnalysis_Release(analysis);
|
||||
}
|
||||
|
||||
static void STDMETHODCALLTYPE d2d_d3d_render_target_DrawGlyphRun(ID2D1RenderTarget *iface,
|
||||
D2D1_POINT_2F baseline_origin, const DWRITE_GLYPH_RUN *glyph_run, ID2D1Brush *brush,
|
||||
DWRITE_MEASURING_MODE measuring_mode)
|
||||
{
|
||||
struct d2d_d3d_render_target *render_target = impl_from_ID2D1RenderTarget(iface);
|
||||
IDWriteRenderingParams *rendering_params;
|
||||
DWRITE_RENDERING_MODE rendering_mode;
|
||||
HRESULT hr;
|
||||
float ppd;
|
||||
|
||||
TRACE("iface %p, baseline_origin {%.8e, %.8e}, glyph_run %p, brush %p, measuring_mode %#x.\n",
|
||||
iface, baseline_origin.x, baseline_origin.y, glyph_run, brush, measuring_mode);
|
||||
|
||||
if (FAILED(render_target->error.code))
|
||||
return;
|
||||
|
||||
if (render_target->drawing_state.textAntialiasMode != D2D1_TEXT_ANTIALIAS_MODE_DEFAULT)
|
||||
FIXME("Ignoring text antialiasing mode %#x.\n", render_target->drawing_state.textAntialiasMode);
|
||||
|
||||
ppd = max(render_target->dpi_x, render_target->dpi_y) / 96.0f;
|
||||
rendering_params = render_target->text_rendering_params ? render_target->text_rendering_params
|
||||
: render_target->default_text_rendering_params;
|
||||
if (FAILED(hr = IDWriteFontFace_GetRecommendedRenderingMode(glyph_run->fontFace, glyph_run->fontEmSize,
|
||||
ppd, measuring_mode, rendering_params, &rendering_mode)))
|
||||
{
|
||||
ERR("Failed to get recommended rendering mode, hr %#x.\n", hr);
|
||||
rendering_mode = DWRITE_RENDERING_MODE_OUTLINE;
|
||||
}
|
||||
|
||||
if (rendering_mode == DWRITE_RENDERING_MODE_OUTLINE)
|
||||
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);
|
||||
}
|
||||
|
||||
static void STDMETHODCALLTYPE d2d_d3d_render_target_SetTransform(ID2D1RenderTarget *iface,
|
||||
const D2D1_MATRIX_3X2_F *transform)
|
||||
{
|
||||
|
@ -1546,6 +1700,7 @@ HRESULT d2d_d3d_render_target_init(struct d2d_d3d_render_target *render_target,
|
|||
D3D10_SUBRESOURCE_DATA buffer_data;
|
||||
D3D10_STATE_BLOCK_MASK state_mask;
|
||||
DXGI_SURFACE_DESC surface_desc;
|
||||
IDWriteFactory *dwrite_factory;
|
||||
D3D10_RASTERIZER_DESC rs_desc;
|
||||
D3D10_BUFFER_DESC buffer_desc;
|
||||
D3D10_BLEND_DESC blend_desc;
|
||||
|
@ -2035,6 +2190,21 @@ HRESULT d2d_d3d_render_target_init(struct d2d_d3d_render_target *render_target,
|
|||
goto err;
|
||||
}
|
||||
|
||||
if (FAILED(hr = DWriteCreateFactory(DWRITE_FACTORY_TYPE_SHARED,
|
||||
&IID_IDWriteFactory, (IUnknown **)&dwrite_factory)))
|
||||
{
|
||||
ERR("Failed to create dwrite factory, hr %#x.\n", hr);
|
||||
goto err;
|
||||
}
|
||||
|
||||
hr = IDWriteFactory_CreateRenderingParams(dwrite_factory, &render_target->default_text_rendering_params);
|
||||
IDWriteFactory_Release(dwrite_factory);
|
||||
if (FAILED(hr))
|
||||
{
|
||||
ERR("Failed to create default text rendering parameters, hr %#x.\n", hr);
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (FAILED(hr = IDXGISurface_GetDesc(surface, &surface_desc)))
|
||||
{
|
||||
WARN("Failed to get surface desc, hr %#x.\n", hr);
|
||||
|
@ -2065,6 +2235,8 @@ HRESULT d2d_d3d_render_target_init(struct d2d_d3d_render_target *render_target,
|
|||
return S_OK;
|
||||
|
||||
err:
|
||||
if (render_target->default_text_rendering_params)
|
||||
IDWriteRenderingParams_Release(render_target->default_text_rendering_params);
|
||||
if (render_target->bs)
|
||||
ID3D10BlendState_Release(render_target->bs);
|
||||
if (render_target->rs)
|
||||
|
|
Loading…
Reference in a new issue