2 * Copyright 2014 Henri Verbeet for CodeWeavers
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
23 #include "wine/test.h"
27 static void set_point(D2D1_POINT_2F
*point
, float x
, float y
)
33 static void set_rect(D2D1_RECT_F
*rect
, float left
, float top
, float right
, float bottom
)
38 rect
->bottom
= bottom
;
41 static void set_color(D2D1_COLOR_F
*color
, float r
, float g
, float b
, float a
)
49 static void set_size_u(D2D1_SIZE_U
*size
, unsigned int w
, unsigned int h
)
55 static void set_matrix_identity(D2D1_MATRIX_3X2_F
*matrix
)
65 static void rotate_matrix(D2D1_MATRIX_3X2_F
*matrix
, float theta
)
67 float sin_theta
, cos_theta
, tmp_11
, tmp_12
;
69 sin_theta
= sinf(theta
);
70 cos_theta
= cosf(theta
);
74 matrix
->_11
= cos_theta
* tmp_11
+ sin_theta
* matrix
->_21
;
75 matrix
->_12
= cos_theta
* tmp_12
+ sin_theta
* matrix
->_22
;
76 matrix
->_21
= -sin_theta
* tmp_11
+ cos_theta
* matrix
->_21
;
77 matrix
->_22
= -sin_theta
* tmp_12
+ cos_theta
* matrix
->_22
;
80 static void scale_matrix(D2D1_MATRIX_3X2_F
*matrix
, float x
, float y
)
88 static void translate_matrix(D2D1_MATRIX_3X2_F
*matrix
, float x
, float y
)
90 matrix
->_31
+= x
* matrix
->_11
+ y
* matrix
->_21
;
91 matrix
->_32
+= x
* matrix
->_12
+ y
* matrix
->_22
;
94 static BOOL
compare_sha1(void *data
, unsigned int pitch
, unsigned int bpp
,
95 unsigned int w
, unsigned int h
, const char *ref_sha1
)
97 static const char hex_chars
[] = "0123456789abcdef";
105 ret
= CryptAcquireContextW(&provider
, NULL
, NULL
, PROV_RSA_FULL
, CRYPT_VERIFYCONTEXT
);
106 ok(ret
, "Failed to acquire crypt context.\n");
107 ret
= CryptCreateHash(provider
, CALG_SHA1
, 0, 0, &hash
);
108 ok(ret
, "Failed to create hash.\n");
110 for (i
= 0; i
< h
; ++i
)
112 if (!(ret
= CryptHashData(hash
, (BYTE
*)data
+ pitch
* i
, w
* bpp
, 0)))
115 ok(ret
, "Failed to hash data.\n");
117 i
= sizeof(hash_data
);
118 ret
= CryptGetHashParam(hash
, HP_HASHVAL
, hash_data
, &i
, 0);
119 ok(ret
, "Failed to get hash value.\n");
120 ok(i
== sizeof(hash_data
), "Got unexpected hash size %u.\n", i
);
122 ret
= CryptDestroyHash(hash
);
123 ok(ret
, "Failed to destroy hash.\n");
124 ret
= CryptReleaseContext(provider
, 0);
125 ok(ret
, "Failed to release crypt context.\n");
127 for (i
= 0; i
< 20; ++i
)
129 sha1
[i
* 2] = hex_chars
[hash_data
[i
] >> 4];
130 sha1
[i
* 2 + 1] = hex_chars
[hash_data
[i
] & 0xf];
134 return !strcmp(ref_sha1
, (char *)sha1
);
137 static BOOL
compare_surface(IDXGISurface
*surface
, const char *ref_sha1
)
139 D3D10_MAPPED_TEXTURE2D mapped_texture
;
140 D3D10_TEXTURE2D_DESC texture_desc
;
141 DXGI_SURFACE_DESC surface_desc
;
142 ID3D10Resource
*src_resource
;
143 ID3D10Texture2D
*texture
;
144 ID3D10Device
*device
;
148 hr
= IDXGISurface_GetDevice(surface
, &IID_ID3D10Device
, (void **)&device
);
149 ok(SUCCEEDED(hr
), "Failed to get device, hr %#x.\n", hr
);
150 hr
= IDXGISurface_QueryInterface(surface
, &IID_ID3D10Resource
, (void **)&src_resource
);
151 ok(SUCCEEDED(hr
), "Failed to query resource interface, hr %#x.\n", hr
);
153 hr
= IDXGISurface_GetDesc(surface
, &surface_desc
);
154 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#x.\n", hr
);
155 texture_desc
.Width
= surface_desc
.Width
;
156 texture_desc
.Height
= surface_desc
.Height
;
157 texture_desc
.MipLevels
= 1;
158 texture_desc
.ArraySize
= 1;
159 texture_desc
.Format
= surface_desc
.Format
;
160 texture_desc
.SampleDesc
= surface_desc
.SampleDesc
;
161 texture_desc
.Usage
= D3D10_USAGE_STAGING
;
162 texture_desc
.BindFlags
= 0;
163 texture_desc
.CPUAccessFlags
= D3D10_CPU_ACCESS_READ
;
164 texture_desc
.MiscFlags
= 0;
165 hr
= ID3D10Device_CreateTexture2D(device
, &texture_desc
, NULL
, &texture
);
166 ok(SUCCEEDED(hr
), "Failed to create texture, hr %#x.\n", hr
);
168 ID3D10Device_CopyResource(device
, (ID3D10Resource
*)texture
, src_resource
);
169 hr
= ID3D10Texture2D_Map(texture
, 0, D3D10_MAP_READ
, 0, &mapped_texture
);
170 ok(SUCCEEDED(hr
), "Failed to map texture, hr %#x.\n", hr
);
171 ret
= compare_sha1(mapped_texture
.pData
, mapped_texture
.RowPitch
, 4,
172 texture_desc
.Width
, texture_desc
.Height
, ref_sha1
);
173 ID3D10Texture2D_Unmap(texture
, 0);
175 ID3D10Texture2D_Release(texture
);
176 ID3D10Resource_Release(src_resource
);
177 ID3D10Device_Release(device
);
182 static ID3D10Device1
*create_device(void)
184 ID3D10Device1
*device
;
186 if (SUCCEEDED(D3D10CreateDevice1(NULL
, D3D10_DRIVER_TYPE_HARDWARE
, NULL
,
187 D3D10_CREATE_DEVICE_BGRA_SUPPORT
, D3D10_FEATURE_LEVEL_10_0
, D3D10_1_SDK_VERSION
, &device
)))
189 if (SUCCEEDED(D3D10CreateDevice1(NULL
, D3D10_DRIVER_TYPE_WARP
, NULL
,
190 D3D10_CREATE_DEVICE_BGRA_SUPPORT
, D3D10_FEATURE_LEVEL_10_0
, D3D10_1_SDK_VERSION
, &device
)))
192 if (SUCCEEDED(D3D10CreateDevice1(NULL
, D3D10_DRIVER_TYPE_REFERENCE
, NULL
,
193 D3D10_CREATE_DEVICE_BGRA_SUPPORT
, D3D10_FEATURE_LEVEL_10_0
, D3D10_1_SDK_VERSION
, &device
)))
199 static IDXGISwapChain
*create_swapchain(ID3D10Device1
*device
, HWND window
, BOOL windowed
)
201 IDXGISwapChain
*swapchain
;
202 DXGI_SWAP_CHAIN_DESC desc
;
203 IDXGIDevice
*dxgi_device
;
204 IDXGIAdapter
*adapter
;
205 IDXGIFactory
*factory
;
208 hr
= ID3D10Device1_QueryInterface(device
, &IID_IDXGIDevice
, (void **)&dxgi_device
);
209 ok(SUCCEEDED(hr
), "Failed to get DXGI device, hr %#x.\n", hr
);
210 hr
= IDXGIDevice_GetAdapter(dxgi_device
, &adapter
);
211 ok(SUCCEEDED(hr
), "Failed to get adapter, hr %#x.\n", hr
);
212 IDXGIDevice_Release(dxgi_device
);
213 hr
= IDXGIAdapter_GetParent(adapter
, &IID_IDXGIFactory
, (void **)&factory
);
214 ok(SUCCEEDED(hr
), "Failed to get factory, hr %#x.\n", hr
);
215 IDXGIAdapter_Release(adapter
);
217 desc
.BufferDesc
.Width
= 640;
218 desc
.BufferDesc
.Height
= 480;
219 desc
.BufferDesc
.RefreshRate
.Numerator
= 60;
220 desc
.BufferDesc
.RefreshRate
.Denominator
= 1;
221 desc
.BufferDesc
.Format
= DXGI_FORMAT_B8G8R8A8_UNORM
;
222 desc
.BufferDesc
.ScanlineOrdering
= DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED
;
223 desc
.BufferDesc
.Scaling
= DXGI_MODE_SCALING_UNSPECIFIED
;
224 desc
.SampleDesc
.Count
= 1;
225 desc
.SampleDesc
.Quality
= 0;
226 desc
.BufferUsage
= DXGI_USAGE_RENDER_TARGET_OUTPUT
;
227 desc
.BufferCount
= 1;
228 desc
.OutputWindow
= window
;
229 desc
.Windowed
= windowed
;
230 desc
.SwapEffect
= DXGI_SWAP_EFFECT_DISCARD
;
233 hr
= IDXGIFactory_CreateSwapChain(factory
, (IUnknown
*)device
, &desc
, &swapchain
);
234 ok(SUCCEEDED(hr
), "Failed to create swapchain, hr %#x.\n", hr
);
235 IDXGIFactory_Release(factory
);
240 static ID2D1RenderTarget
*create_render_target(IDXGISurface
*surface
)
242 D2D1_RENDER_TARGET_PROPERTIES desc
;
243 ID2D1RenderTarget
*render_target
;
244 ID2D1Factory
*factory
;
247 hr
= D2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED
, &IID_ID2D1Factory
, NULL
, (void **)&factory
);
248 ok(SUCCEEDED(hr
), "Failed to create factory, hr %#x.\n", hr
);
250 desc
.type
= D2D1_RENDER_TARGET_TYPE_DEFAULT
;
251 desc
.pixelFormat
.format
= DXGI_FORMAT_UNKNOWN
;
252 desc
.pixelFormat
.alphaMode
= D2D1_ALPHA_MODE_IGNORE
;
255 desc
.usage
= D2D1_RENDER_TARGET_USAGE_NONE
;
256 desc
.minLevel
= D2D1_FEATURE_LEVEL_DEFAULT
;
257 hr
= ID2D1Factory_CreateDxgiSurfaceRenderTarget(factory
, surface
, &desc
, &render_target
);
258 ok(SUCCEEDED(hr
), "Failed to create render target, hr %#x.\n", hr
);
260 ID2D1Factory_Release(factory
);
262 return render_target
;
265 static void test_clip(void)
267 IDXGISwapChain
*swapchain
;
268 D2D1_MATRIX_3X2_F matrix
;
269 D2D1_SIZE_U pixel_size
;
270 ID2D1RenderTarget
*rt
;
271 ID3D10Device1
*device
;
272 IDXGISurface
*surface
;
280 static const D2D1_MATRIX_3X2_F identity
=
287 if (!(device
= create_device()))
289 skip("Failed to create device, skipping tests.\n");
292 window
= CreateWindowA("static", "d2d1_test", WS_OVERLAPPEDWINDOW
| WS_VISIBLE
,
293 0, 0, 640, 480, NULL
, NULL
, NULL
, NULL
);
294 swapchain
= create_swapchain(device
, window
, TRUE
);
295 hr
= IDXGISwapChain_GetBuffer(swapchain
, 0, &IID_IDXGISurface
, (void **)&surface
);
296 ok(SUCCEEDED(hr
), "Failed to get buffer, hr %#x.\n", hr
);
297 rt
= create_render_target(surface
);
298 ok(!!rt
, "Failed to create render target.\n");
300 ID2D1RenderTarget_GetDpi(rt
, &dpi_x
, &dpi_y
);
301 ok(dpi_x
== 96.0f
, "Got unexpected dpi_x %.8e.\n", dpi_x
);
302 ok(dpi_y
== 96.0f
, "Got unexpected dpi_x %.8e.\n", dpi_y
);
303 size
= ID2D1RenderTarget_GetSize(rt
);
304 ok(size
.width
== 640.0f
, "Got unexpected width %.8e.\n", size
.width
);
305 ok(size
.height
== 480.0f
, "Got unexpected height %.8e.\n", size
.height
);
306 pixel_size
= ID2D1RenderTarget_GetPixelSize(rt
);
307 ok(pixel_size
.width
== 640, "Got unexpected width %u.\n", pixel_size
.width
);
308 ok(pixel_size
.height
== 480, "Got unexpected height %u.\n", pixel_size
.height
);
310 ID2D1RenderTarget_GetTransform(rt
, &matrix
);
311 ok(!memcmp(&matrix
, &identity
, sizeof(matrix
)),
312 "Got unexpected matrix {%.8e, %.8e, %.8e, %.8e, %.8e, %.8e}.\n",
313 matrix
._11
, matrix
._12
, matrix
._21
, matrix
._22
, matrix
._31
, matrix
._32
);
315 ID2D1RenderTarget_BeginDraw(rt
);
317 set_color(&color
, 1.0f
, 1.0f
, 0.0f
, 1.0f
);
318 ID2D1RenderTarget_Clear(rt
, &color
);
320 ID2D1RenderTarget_SetDpi(rt
, 48.0f
, 192.0f
);
321 ID2D1RenderTarget_GetDpi(rt
, &dpi_x
, &dpi_y
);
322 ok(dpi_x
== 48.0f
, "Got unexpected dpi_x %.8e.\n", dpi_x
);
323 ok(dpi_y
== 192.0f
, "Got unexpected dpi_x %.8e.\n", dpi_y
);
324 size
= ID2D1RenderTarget_GetSize(rt
);
325 ok(size
.width
== 1280.0f
, "Got unexpected width %.8e.\n", size
.width
);
326 ok(size
.height
== 240.0f
, "Got unexpected height %.8e.\n", size
.height
);
327 pixel_size
= ID2D1RenderTarget_GetPixelSize(rt
);
328 ok(pixel_size
.width
== 640, "Got unexpected width %u.\n", pixel_size
.width
);
329 ok(pixel_size
.height
== 480, "Got unexpected height %u.\n", pixel_size
.height
);
331 /* The effective clip rect is the intersection of all currently pushed
332 * clip rects. Clip rects are in DIPs. */
333 set_rect(&rect
, 0.0f
, 0.0f
, 1280.0f
, 80.0f
);
334 ID2D1RenderTarget_PushAxisAlignedClip(rt
, &rect
, D2D1_ANTIALIAS_MODE_ALIASED
);
335 set_rect(&rect
, 0.0f
, 0.0f
, 426.0f
, 240.0f
);
336 ID2D1RenderTarget_PushAxisAlignedClip(rt
, &rect
, D2D1_ANTIALIAS_MODE_ALIASED
);
338 set_color(&color
, 0.0f
, 1.0f
, 0.0f
, 1.0f
);
339 ID2D1RenderTarget_Clear(rt
, &color
);
340 ID2D1RenderTarget_PopAxisAlignedClip(rt
);
341 ID2D1RenderTarget_PopAxisAlignedClip(rt
);
343 ID2D1RenderTarget_SetDpi(rt
, 0.0f
, 0.0f
);
344 ID2D1RenderTarget_GetDpi(rt
, &dpi_x
, &dpi_y
);
345 ok(dpi_x
== 96.0f
, "Got unexpected dpi_x %.8e.\n", dpi_x
);
346 ok(dpi_y
== 96.0f
, "Got unexpected dpi_y %.8e.\n", dpi_y
);
348 /* Transformations apply to clip rects, the effective clip rect is the
349 * (axis-aligned) bounding box of the transformed clip rect. */
350 set_point(&point
, 320.0f
, 240.0f
);
351 D2D1MakeRotateMatrix(30.0f
, point
, &matrix
);
352 ID2D1RenderTarget_SetTransform(rt
, &matrix
);
353 set_rect(&rect
, 215.0f
, 208.0f
, 425.0f
, 272.0f
);
354 ID2D1RenderTarget_PushAxisAlignedClip(rt
, &rect
, D2D1_ANTIALIAS_MODE_ALIASED
);
355 set_color(&color
, 1.0f
, 1.0f
, 1.0f
, 1.0f
);
356 ID2D1RenderTarget_Clear(rt
, &color
);
357 ID2D1RenderTarget_PopAxisAlignedClip(rt
);
359 /* Transformations are applied when pushing the clip rect, transformations
360 * set afterwards have no effect on the current clip rect. This includes
362 ID2D1RenderTarget_SetTransform(rt
, &identity
);
363 set_rect(&rect
, 427.0f
, 320.0f
, 640.0f
, 480.0f
);
364 ID2D1RenderTarget_PushAxisAlignedClip(rt
, &rect
, D2D1_ANTIALIAS_MODE_ALIASED
);
365 ID2D1RenderTarget_SetTransform(rt
, &matrix
);
366 ID2D1RenderTarget_SetDpi(rt
, 48.0f
, 192.0f
);
367 set_color(&color
, 1.0f
, 0.0f
, 0.0f
, 1.0f
);
368 ID2D1RenderTarget_Clear(rt
, &color
);
369 ID2D1RenderTarget_PopAxisAlignedClip(rt
);
371 hr
= ID2D1RenderTarget_EndDraw(rt
, NULL
, NULL
);
372 ok(SUCCEEDED(hr
), "Failed to end draw, hr %#x.\n", hr
);
373 ok(compare_surface(surface
, "035a44d4198d6e422e9de6185b5b2c2bac5e33c9"), "Surface does not match.\n");
375 ID2D1RenderTarget_Release(rt
);
376 IDXGISurface_Release(surface
);
377 IDXGISwapChain_Release(swapchain
);
378 ID3D10Device1_Release(device
);
379 DestroyWindow(window
);
382 static void test_state_block(void)
384 IDWriteRenderingParams
*text_rendering_params1
, *text_rendering_params2
;
385 D2D1_DRAWING_STATE_DESCRIPTION drawing_state
;
386 ID2D1DrawingStateBlock
*state_block
;
387 IDWriteFactory
*dwrite_factory
;
388 IDXGISwapChain
*swapchain
;
389 ID2D1RenderTarget
*rt
;
390 ID3D10Device1
*device
;
391 IDXGISurface
*surface
;
392 ID2D1Factory
*factory
;
396 static const D2D1_MATRIX_3X2_F identity
=
402 static const D2D1_MATRIX_3X2_F transform1
=
408 static const D2D1_MATRIX_3X2_F transform2
=
415 if (!(device
= create_device()))
417 skip("Failed to create device, skipping tests.\n");
420 window
= CreateWindowA("static", "d2d1_test", WS_OVERLAPPEDWINDOW
| WS_VISIBLE
,
421 0, 0, 640, 480, NULL
, NULL
, NULL
, NULL
);
422 swapchain
= create_swapchain(device
, window
, TRUE
);
423 hr
= IDXGISwapChain_GetBuffer(swapchain
, 0, &IID_IDXGISurface
, (void **)&surface
);
424 ok(SUCCEEDED(hr
), "Failed to get buffer, hr %#x.\n", hr
);
425 rt
= create_render_target(surface
);
426 ok(!!rt
, "Failed to create render target.\n");
427 ID2D1RenderTarget_GetFactory(rt
, &factory
);
428 hr
= DWriteCreateFactory(DWRITE_FACTORY_TYPE_SHARED
, &IID_IDWriteFactory
, (IUnknown
**)&dwrite_factory
);
429 ok(SUCCEEDED(hr
), "Failed to create dwrite factory, hr %#x.\n", hr
);
430 hr
= IDWriteFactory_CreateRenderingParams(dwrite_factory
, &text_rendering_params1
);
431 ok(SUCCEEDED(hr
), "Failed to create dwrite rendering params, hr %#x.\n", hr
);
432 IDWriteFactory_Release(dwrite_factory
);
434 drawing_state
.antialiasMode
= ID2D1RenderTarget_GetAntialiasMode(rt
);
435 ok(drawing_state
.antialiasMode
== D2D1_ANTIALIAS_MODE_PER_PRIMITIVE
,
436 "Got unexpected antialias mode %#x.\n", drawing_state
.antialiasMode
);
437 drawing_state
.textAntialiasMode
= ID2D1RenderTarget_GetTextAntialiasMode(rt
);
438 ok(drawing_state
.textAntialiasMode
== D2D1_TEXT_ANTIALIAS_MODE_DEFAULT
,
439 "Got unexpected text antialias mode %#x.\n", drawing_state
.textAntialiasMode
);
440 ID2D1RenderTarget_GetTags(rt
, &drawing_state
.tag1
, &drawing_state
.tag2
);
441 ok(!drawing_state
.tag1
&& !drawing_state
.tag2
, "Got unexpected tags %08x%08x:%08x%08x.\n",
442 (unsigned int)(drawing_state
.tag1
>> 32), (unsigned int)(drawing_state
.tag1
),
443 (unsigned int)(drawing_state
.tag2
>> 32), (unsigned int)(drawing_state
.tag2
));
444 ID2D1RenderTarget_GetTransform(rt
, &drawing_state
.transform
);
445 ok(!memcmp(&drawing_state
.transform
, &identity
, sizeof(drawing_state
.transform
)),
446 "Got unexpected matrix {%.8e, %.8e, %.8e, %.8e, %.8e, %.8e}.\n",
447 drawing_state
.transform
._11
, drawing_state
.transform
._12
, drawing_state
.transform
._21
,
448 drawing_state
.transform
._22
, drawing_state
.transform
._31
, drawing_state
.transform
._32
);
449 ID2D1RenderTarget_GetTextRenderingParams(rt
, &text_rendering_params2
);
450 ok(!text_rendering_params2
, "Got unexpected text rendering params %p.\n", text_rendering_params2
);
452 hr
= ID2D1Factory_CreateDrawingStateBlock(factory
, NULL
, NULL
, &state_block
);
453 ok(SUCCEEDED(hr
), "Failed to create drawing state block, hr %#x\n", hr
);
454 ID2D1DrawingStateBlock_GetDescription(state_block
, &drawing_state
);
455 ok(drawing_state
.antialiasMode
== D2D1_ANTIALIAS_MODE_PER_PRIMITIVE
,
456 "Got unexpected antialias mode %#x.\n", drawing_state
.antialiasMode
);
457 ok(drawing_state
.textAntialiasMode
== D2D1_TEXT_ANTIALIAS_MODE_DEFAULT
,
458 "Got unexpected text antialias mode %#x.\n", drawing_state
.textAntialiasMode
);
459 ok(!drawing_state
.tag1
&& !drawing_state
.tag2
, "Got unexpected tags %08x%08x:%08x%08x.\n",
460 (unsigned int)(drawing_state
.tag1
>> 32), (unsigned int)(drawing_state
.tag1
),
461 (unsigned int)(drawing_state
.tag2
>> 32), (unsigned int)(drawing_state
.tag2
));
462 ok(!memcmp(&drawing_state
.transform
, &identity
, sizeof(drawing_state
.transform
)),
463 "Got unexpected matrix {%.8e, %.8e, %.8e, %.8e, %.8e, %.8e}.\n",
464 drawing_state
.transform
._11
, drawing_state
.transform
._12
, drawing_state
.transform
._21
,
465 drawing_state
.transform
._22
, drawing_state
.transform
._31
, drawing_state
.transform
._32
);
466 ID2D1DrawingStateBlock_GetTextRenderingParams(state_block
, &text_rendering_params2
);
467 ok(!text_rendering_params2
, "Got unexpected text rendering params %p.\n", text_rendering_params2
);
468 ID2D1DrawingStateBlock_Release(state_block
);
470 drawing_state
.antialiasMode
= D2D1_ANTIALIAS_MODE_ALIASED
;
471 drawing_state
.textAntialiasMode
= D2D1_TEXT_ANTIALIAS_MODE_ALIASED
;
472 drawing_state
.tag1
= 0xdead;
473 drawing_state
.tag2
= 0xbeef;
474 drawing_state
.transform
= transform1
;
475 hr
= ID2D1Factory_CreateDrawingStateBlock(factory
, &drawing_state
, text_rendering_params1
, &state_block
);
476 ok(SUCCEEDED(hr
), "Failed to create drawing state block, hr %#x\n", hr
);
478 ID2D1DrawingStateBlock_GetDescription(state_block
, &drawing_state
);
479 ok(drawing_state
.antialiasMode
== D2D1_ANTIALIAS_MODE_ALIASED
,
480 "Got unexpected antialias mode %#x.\n", drawing_state
.antialiasMode
);
481 ok(drawing_state
.textAntialiasMode
== D2D1_TEXT_ANTIALIAS_MODE_ALIASED
,
482 "Got unexpected text antialias mode %#x.\n", drawing_state
.textAntialiasMode
);
483 ok(drawing_state
.tag1
== 0xdead && drawing_state
.tag2
== 0xbeef, "Got unexpected tags %08x%08x:%08x%08x.\n",
484 (unsigned int)(drawing_state
.tag1
>> 32), (unsigned int)(drawing_state
.tag1
),
485 (unsigned int)(drawing_state
.tag2
>> 32), (unsigned int)(drawing_state
.tag2
));
486 ok(!memcmp(&drawing_state
.transform
, &transform1
, sizeof(drawing_state
.transform
)),
487 "Got unexpected matrix {%.8e, %.8e, %.8e, %.8e, %.8e, %.8e}.\n",
488 drawing_state
.transform
._11
, drawing_state
.transform
._12
, drawing_state
.transform
._21
,
489 drawing_state
.transform
._22
, drawing_state
.transform
._31
, drawing_state
.transform
._32
);
490 ID2D1DrawingStateBlock_GetTextRenderingParams(state_block
, &text_rendering_params2
);
491 ok(text_rendering_params2
== text_rendering_params1
, "Got unexpected text rendering params %p, expected %p.\n",
492 text_rendering_params2
, text_rendering_params1
);
493 IDWriteRenderingParams_Release(text_rendering_params2
);
495 ID2D1RenderTarget_RestoreDrawingState(rt
, state_block
);
497 drawing_state
.antialiasMode
= ID2D1RenderTarget_GetAntialiasMode(rt
);
498 ok(drawing_state
.antialiasMode
== D2D1_ANTIALIAS_MODE_ALIASED
,
499 "Got unexpected antialias mode %#x.\n", drawing_state
.antialiasMode
);
500 drawing_state
.textAntialiasMode
= ID2D1RenderTarget_GetTextAntialiasMode(rt
);
501 ok(drawing_state
.textAntialiasMode
== D2D1_TEXT_ANTIALIAS_MODE_ALIASED
,
502 "Got unexpected text antialias mode %#x.\n", drawing_state
.textAntialiasMode
);
503 ID2D1RenderTarget_GetTags(rt
, &drawing_state
.tag1
, &drawing_state
.tag2
);
504 ok(drawing_state
.tag1
== 0xdead && drawing_state
.tag2
== 0xbeef, "Got unexpected tags %08x%08x:%08x%08x.\n",
505 (unsigned int)(drawing_state
.tag1
>> 32), (unsigned int)(drawing_state
.tag1
),
506 (unsigned int)(drawing_state
.tag2
>> 32), (unsigned int)(drawing_state
.tag2
));
507 ID2D1RenderTarget_GetTransform(rt
, &drawing_state
.transform
);
508 ok(!memcmp(&drawing_state
.transform
, &transform1
, sizeof(drawing_state
.transform
)),
509 "Got unexpected matrix {%.8e, %.8e, %.8e, %.8e, %.8e, %.8e}.\n",
510 drawing_state
.transform
._11
, drawing_state
.transform
._12
, drawing_state
.transform
._21
,
511 drawing_state
.transform
._22
, drawing_state
.transform
._31
, drawing_state
.transform
._32
);
512 ID2D1RenderTarget_GetTextRenderingParams(rt
, &text_rendering_params2
);
513 ok(text_rendering_params2
== text_rendering_params1
, "Got unexpected text rendering params %p, expected %p.\n",
514 text_rendering_params2
, text_rendering_params1
);
515 IDWriteRenderingParams_Release(text_rendering_params2
);
517 ID2D1RenderTarget_SetAntialiasMode(rt
, D2D1_ANTIALIAS_MODE_PER_PRIMITIVE
);
518 ID2D1RenderTarget_SetTextAntialiasMode(rt
, D2D1_TEXT_ANTIALIAS_MODE_GRAYSCALE
);
519 ID2D1RenderTarget_SetTags(rt
, 1, 2);
520 ID2D1RenderTarget_SetTransform(rt
, &transform2
);
521 ID2D1RenderTarget_SetTextRenderingParams(rt
, NULL
);
523 drawing_state
.antialiasMode
= ID2D1RenderTarget_GetAntialiasMode(rt
);
524 ok(drawing_state
.antialiasMode
== D2D1_ANTIALIAS_MODE_PER_PRIMITIVE
,
525 "Got unexpected antialias mode %#x.\n", drawing_state
.antialiasMode
);
526 drawing_state
.textAntialiasMode
= ID2D1RenderTarget_GetTextAntialiasMode(rt
);
527 ok(drawing_state
.textAntialiasMode
== D2D1_TEXT_ANTIALIAS_MODE_GRAYSCALE
,
528 "Got unexpected text antialias mode %#x.\n", drawing_state
.textAntialiasMode
);
529 ID2D1RenderTarget_GetTags(rt
, &drawing_state
.tag1
, &drawing_state
.tag2
);
530 ok(drawing_state
.tag1
== 1 && drawing_state
.tag2
== 2, "Got unexpected tags %08x%08x:%08x%08x.\n",
531 (unsigned int)(drawing_state
.tag1
>> 32), (unsigned int)(drawing_state
.tag1
),
532 (unsigned int)(drawing_state
.tag2
>> 32), (unsigned int)(drawing_state
.tag2
));
533 ID2D1RenderTarget_GetTransform(rt
, &drawing_state
.transform
);
534 ok(!memcmp(&drawing_state
.transform
, &transform2
, sizeof(drawing_state
.transform
)),
535 "Got unexpected matrix {%.8e, %.8e, %.8e, %.8e, %.8e, %.8e}.\n",
536 drawing_state
.transform
._11
, drawing_state
.transform
._12
, drawing_state
.transform
._21
,
537 drawing_state
.transform
._22
, drawing_state
.transform
._31
, drawing_state
.transform
._32
);
538 ID2D1RenderTarget_GetTextRenderingParams(rt
, &text_rendering_params2
);
539 ok(!text_rendering_params2
, "Got unexpected text rendering params %p.\n", text_rendering_params2
);
541 ID2D1RenderTarget_SaveDrawingState(rt
, state_block
);
543 ID2D1DrawingStateBlock_GetDescription(state_block
, &drawing_state
);
544 ok(drawing_state
.antialiasMode
== D2D1_ANTIALIAS_MODE_PER_PRIMITIVE
,
545 "Got unexpected antialias mode %#x.\n", drawing_state
.antialiasMode
);
546 ok(drawing_state
.textAntialiasMode
== D2D1_TEXT_ANTIALIAS_MODE_GRAYSCALE
,
547 "Got unexpected text antialias mode %#x.\n", drawing_state
.textAntialiasMode
);
548 ok(drawing_state
.tag1
== 1 && drawing_state
.tag2
== 2, "Got unexpected tags %08x%08x:%08x%08x.\n",
549 (unsigned int)(drawing_state
.tag1
>> 32), (unsigned int)(drawing_state
.tag1
),
550 (unsigned int)(drawing_state
.tag2
>> 32), (unsigned int)(drawing_state
.tag2
));
551 ok(!memcmp(&drawing_state
.transform
, &transform2
, sizeof(drawing_state
.transform
)),
552 "Got unexpected matrix {%.8e, %.8e, %.8e, %.8e, %.8e, %.8e}.\n",
553 drawing_state
.transform
._11
, drawing_state
.transform
._12
, drawing_state
.transform
._21
,
554 drawing_state
.transform
._22
, drawing_state
.transform
._31
, drawing_state
.transform
._32
);
555 ID2D1DrawingStateBlock_GetTextRenderingParams(state_block
, &text_rendering_params2
);
556 ok(!text_rendering_params2
, "Got unexpected text rendering params %p.\n", text_rendering_params2
);
558 drawing_state
.antialiasMode
= D2D1_ANTIALIAS_MODE_ALIASED
;
559 drawing_state
.textAntialiasMode
= D2D1_TEXT_ANTIALIAS_MODE_CLEARTYPE
;
560 drawing_state
.tag1
= 3;
561 drawing_state
.tag2
= 4;
562 drawing_state
.transform
= transform1
;
563 ID2D1DrawingStateBlock_SetDescription(state_block
, &drawing_state
);
564 ID2D1DrawingStateBlock_SetTextRenderingParams(state_block
, text_rendering_params1
);
566 ID2D1DrawingStateBlock_GetDescription(state_block
, &drawing_state
);
567 ok(drawing_state
.antialiasMode
== D2D1_ANTIALIAS_MODE_ALIASED
,
568 "Got unexpected antialias mode %#x.\n", drawing_state
.antialiasMode
);
569 ok(drawing_state
.textAntialiasMode
== D2D1_TEXT_ANTIALIAS_MODE_CLEARTYPE
,
570 "Got unexpected text antialias mode %#x.\n", drawing_state
.textAntialiasMode
);
571 ok(drawing_state
.tag1
== 3 && drawing_state
.tag2
== 4, "Got unexpected tags %08x%08x:%08x%08x.\n",
572 (unsigned int)(drawing_state
.tag1
>> 32), (unsigned int)(drawing_state
.tag1
),
573 (unsigned int)(drawing_state
.tag2
>> 32), (unsigned int)(drawing_state
.tag2
));
574 ok(!memcmp(&drawing_state
.transform
, &transform1
, sizeof(drawing_state
.transform
)),
575 "Got unexpected matrix {%.8e, %.8e, %.8e, %.8e, %.8e, %.8e}.\n",
576 drawing_state
.transform
._11
, drawing_state
.transform
._12
, drawing_state
.transform
._21
,
577 drawing_state
.transform
._22
, drawing_state
.transform
._31
, drawing_state
.transform
._32
);
578 ID2D1DrawingStateBlock_GetTextRenderingParams(state_block
, &text_rendering_params2
);
579 ok(text_rendering_params2
== text_rendering_params1
, "Got unexpected text rendering params %p, expected %p.\n",
580 text_rendering_params2
, text_rendering_params1
);
581 IDWriteRenderingParams_Release(text_rendering_params2
);
583 ID2D1DrawingStateBlock_Release(state_block
);
585 refcount
= IDWriteRenderingParams_Release(text_rendering_params1
);
586 ok(!refcount
, "Rendering params %u references left.\n", refcount
);
587 ID2D1Factory_Release(factory
);
588 ID2D1RenderTarget_Release(rt
);
589 IDXGISurface_Release(surface
);
590 IDXGISwapChain_Release(swapchain
);
591 ID3D10Device1_Release(device
);
592 DestroyWindow(window
);
595 static void test_color_brush(void)
597 D2D1_MATRIX_3X2_F matrix
, tmp_matrix
;
598 D2D1_BRUSH_PROPERTIES brush_desc
;
599 D2D1_COLOR_F color
, tmp_color
;
600 ID2D1SolidColorBrush
*brush
;
601 IDXGISwapChain
*swapchain
;
602 ID2D1RenderTarget
*rt
;
603 ID3D10Device1
*device
;
604 IDXGISurface
*surface
;
610 if (!(device
= create_device()))
612 skip("Failed to create device, skipping tests.\n");
615 window
= CreateWindowA("static", "d2d1_test", WS_OVERLAPPEDWINDOW
| WS_VISIBLE
,
616 0, 0, 640, 480, NULL
, NULL
, NULL
, NULL
);
617 swapchain
= create_swapchain(device
, window
, TRUE
);
618 hr
= IDXGISwapChain_GetBuffer(swapchain
, 0, &IID_IDXGISurface
, (void **)&surface
);
619 ok(SUCCEEDED(hr
), "Failed to get buffer, hr %#x.\n", hr
);
620 rt
= create_render_target(surface
);
621 ok(!!rt
, "Failed to create render target.\n");
623 ID2D1RenderTarget_SetDpi(rt
, 192.0f
, 48.0f
);
624 ID2D1RenderTarget_SetAntialiasMode(rt
, D2D1_ANTIALIAS_MODE_ALIASED
);
626 set_color(&color
, 0.0f
, 0.0f
, 0.0f
, 0.0f
);
627 hr
= ID2D1RenderTarget_CreateSolidColorBrush(rt
, &color
, NULL
, &brush
);
628 ok(SUCCEEDED(hr
), "Failed to create brush, hr %#x.\n", hr
);
629 opacity
= ID2D1SolidColorBrush_GetOpacity(brush
);
630 ok(opacity
== 1.0f
, "Got unexpected opacity %.8e.\n", opacity
);
631 set_matrix_identity(&matrix
);
632 ID2D1SolidColorBrush_GetTransform(brush
, &tmp_matrix
);
633 ok(!memcmp(&tmp_matrix
, &matrix
, sizeof(matrix
)),
634 "Got unexpected matrix {%.8e, %.8e, %.8e, %.8e, %.8e, %.8e}.\n",
635 tmp_matrix
._11
, tmp_matrix
._12
, tmp_matrix
._21
,
636 tmp_matrix
._22
, tmp_matrix
._31
, tmp_matrix
._32
);
637 tmp_color
= ID2D1SolidColorBrush_GetColor(brush
);
638 ok(!memcmp(&tmp_color
, &color
, sizeof(color
)),
639 "Got unexpected color {%.8e, %.8e, %.8e, %.8e}.\n",
640 tmp_color
.r
, tmp_color
.g
, tmp_color
.b
, tmp_color
.a
);
641 ID2D1SolidColorBrush_Release(brush
);
643 set_color(&color
, 0.0f
, 1.0f
, 0.0f
, 0.8f
);
644 brush_desc
.opacity
= 0.3f
;
645 set_matrix_identity(&matrix
);
646 scale_matrix(&matrix
, 2.0f
, 2.0f
);
647 brush_desc
.transform
= matrix
;
648 hr
= ID2D1RenderTarget_CreateSolidColorBrush(rt
, &color
, &brush_desc
, &brush
);
649 ok(SUCCEEDED(hr
), "Failed to create brush, hr %#x.\n", hr
);
650 opacity
= ID2D1SolidColorBrush_GetOpacity(brush
);
651 ok(opacity
== 0.3f
, "Got unexpected opacity %.8e.\n", opacity
);
652 ID2D1SolidColorBrush_GetTransform(brush
, &tmp_matrix
);
653 ok(!memcmp(&tmp_matrix
, &matrix
, sizeof(matrix
)),
654 "Got unexpected matrix {%.8e, %.8e, %.8e, %.8e, %.8e, %.8e}.\n",
655 tmp_matrix
._11
, tmp_matrix
._12
, tmp_matrix
._21
,
656 tmp_matrix
._22
, tmp_matrix
._31
, tmp_matrix
._32
);
657 tmp_color
= ID2D1SolidColorBrush_GetColor(brush
);
658 ok(!memcmp(&tmp_color
, &color
, sizeof(color
)),
659 "Got unexpected color {%.8e, %.8e, %.8e, %.8e}.\n",
660 tmp_color
.r
, tmp_color
.g
, tmp_color
.b
, tmp_color
.a
);
662 ID2D1RenderTarget_BeginDraw(rt
);
664 set_color(&color
, 0.0f
, 0.0f
, 1.0f
, 1.0f
);
665 ID2D1RenderTarget_Clear(rt
, &color
);
667 ID2D1SolidColorBrush_SetOpacity(brush
, 1.0f
);
668 set_rect(&rect
, 40.0f
, 120.0f
, 120.0f
, 360.0f
);
669 ID2D1RenderTarget_FillRectangle(rt
, &rect
, (ID2D1Brush
*)brush
);
671 set_matrix_identity(&matrix
);
672 scale_matrix(&matrix
, 0.5f
, 2.0f
);
673 translate_matrix(&matrix
, 320.0f
, 240.0f
);
674 rotate_matrix(&matrix
, M_PI
/ 4.0f
);
675 ID2D1RenderTarget_SetTransform(rt
, &matrix
);
676 set_color(&color
, 1.0f
, 0.0f
, 0.0f
, 0.625f
);
677 ID2D1SolidColorBrush_SetColor(brush
, &color
);
678 ID2D1SolidColorBrush_SetOpacity(brush
, 0.75f
);
679 set_rect(&rect
, -80.0f
, -60.0f
, 80.0f
, 60.0f
);
680 ID2D1RenderTarget_FillRectangle(rt
, &rect
, (ID2D1Brush
*)brush
);
682 hr
= ID2D1RenderTarget_EndDraw(rt
, NULL
, NULL
);
683 ok(SUCCEEDED(hr
), "Failed to end draw, hr %#x.\n", hr
);
684 ok(compare_surface(surface
, "6d1218fca5e21fb7e287b3a439d60dbc251f5ceb"), "Surface does not match.\n");
686 ID2D1SolidColorBrush_Release(brush
);
687 ID2D1RenderTarget_Release(rt
);
688 IDXGISurface_Release(surface
);
689 IDXGISwapChain_Release(swapchain
);
690 ID3D10Device1_Release(device
);
691 DestroyWindow(window
);
694 static void test_bitmap_brush(void)
696 D2D1_BITMAP_INTERPOLATION_MODE interpolation_mode
;
697 D2D1_MATRIX_3X2_F matrix
, tmp_matrix
;
698 D2D1_BITMAP_PROPERTIES bitmap_desc
;
699 ID2D1Bitmap
*bitmap
, *tmp_bitmap
;
700 D2D1_RECT_F src_rect
, dst_rect
;
701 D2D1_EXTEND_MODE extend_mode
;
702 IDXGISwapChain
*swapchain
;
703 ID2D1BitmapBrush
*brush
;
704 ID2D1RenderTarget
*rt
;
705 ID3D10Device1
*device
;
706 IDXGISurface
*surface
;
717 D2D1_EXTEND_MODE extend_mode_x
;
718 D2D1_EXTEND_MODE extend_mode_y
;
723 extend_mode_tests
[] =
725 {D2D1_EXTEND_MODE_MIRROR
, D2D1_EXTEND_MODE_MIRROR
, -7.0f
, 1.0f
, {-4.0f
, 0.0f
, -8.0f
, 4.0f
}},
726 {D2D1_EXTEND_MODE_WRAP
, D2D1_EXTEND_MODE_MIRROR
, -3.0f
, 1.0f
, {-4.0f
, 4.0f
, 0.0f
, 0.0f
}},
727 {D2D1_EXTEND_MODE_CLAMP
, D2D1_EXTEND_MODE_MIRROR
, 1.0f
, 1.0f
, { 4.0f
, 0.0f
, 0.0f
, 4.0f
}},
728 {D2D1_EXTEND_MODE_MIRROR
, D2D1_EXTEND_MODE_WRAP
, -7.0f
, 5.0f
, {-8.0f
, 8.0f
, -4.0f
, 4.0f
}},
729 {D2D1_EXTEND_MODE_WRAP
, D2D1_EXTEND_MODE_WRAP
, -3.0f
, 5.0f
, { 0.0f
, 4.0f
, -4.0f
, 8.0f
}},
730 {D2D1_EXTEND_MODE_CLAMP
, D2D1_EXTEND_MODE_WRAP
, 1.0f
, 5.0f
, { 0.0f
, 8.0f
, 4.0f
, 4.0f
}},
731 {D2D1_EXTEND_MODE_MIRROR
, D2D1_EXTEND_MODE_CLAMP
, -7.0f
, 9.0f
, {-4.0f
, 8.0f
, -8.0f
, 12.0f
}},
732 {D2D1_EXTEND_MODE_WRAP
, D2D1_EXTEND_MODE_CLAMP
, -3.0f
, 9.0f
, {-4.0f
, 12.0f
, 0.0f
, 8.0f
}},
733 {D2D1_EXTEND_MODE_CLAMP
, D2D1_EXTEND_MODE_CLAMP
, 1.0f
, 9.0f
, { 4.0f
, 8.0f
, 0.0f
, 12.0f
}},
735 static const DWORD bitmap_data
[] =
737 0xffff0000, 0xffffff00, 0xff00ff00, 0xff00ffff,
738 0xff0000ff, 0xffff00ff, 0xff000000, 0xff7f7f7f,
739 0xffffffff, 0xffffffff, 0xffffffff, 0xff000000,
740 0xffffffff, 0xff000000, 0xff000000, 0xff000000,
743 if (!(device
= create_device()))
745 skip("Failed to create device, skipping tests.\n");
748 window
= CreateWindowA("static", "d2d1_test", WS_OVERLAPPEDWINDOW
| WS_VISIBLE
,
749 0, 0, 640, 480, NULL
, NULL
, NULL
, NULL
);
750 swapchain
= create_swapchain(device
, window
, TRUE
);
751 hr
= IDXGISwapChain_GetBuffer(swapchain
, 0, &IID_IDXGISurface
, (void **)&surface
);
752 ok(SUCCEEDED(hr
), "Failed to get buffer, hr %#x.\n", hr
);
753 rt
= create_render_target(surface
);
754 ok(!!rt
, "Failed to create render target.\n");
756 ID2D1RenderTarget_SetDpi(rt
, 192.0f
, 48.0f
);
757 ID2D1RenderTarget_SetAntialiasMode(rt
, D2D1_ANTIALIAS_MODE_ALIASED
);
759 set_size_u(&size
, 4, 4);
760 bitmap_desc
.pixelFormat
.format
= DXGI_FORMAT_B8G8R8A8_UNORM
;
761 bitmap_desc
.pixelFormat
.alphaMode
= D2D1_ALPHA_MODE_IGNORE
;
762 bitmap_desc
.dpiX
= 96.0f
;
763 bitmap_desc
.dpiY
= 96.0f
;
764 hr
= ID2D1RenderTarget_CreateBitmap(rt
, size
, bitmap_data
, 4 * sizeof(*bitmap_data
), &bitmap_desc
, &bitmap
);
765 ok(SUCCEEDED(hr
), "Failed to create bitmap, hr %#x.\n", hr
);
767 /* Creating a brush with a NULL bitmap crashes on Vista, but works fine on
769 hr
= ID2D1RenderTarget_CreateBitmapBrush(rt
, bitmap
, NULL
, NULL
, &brush
);
770 ok(SUCCEEDED(hr
), "Failed to create brush, hr %#x.\n", hr
);
771 ID2D1BitmapBrush_GetBitmap(brush
, &tmp_bitmap
);
772 ok(tmp_bitmap
== bitmap
, "Got unexpected bitmap %p, expected %p.\n", tmp_bitmap
, bitmap
);
773 ID2D1Bitmap_Release(tmp_bitmap
);
774 opacity
= ID2D1BitmapBrush_GetOpacity(brush
);
775 ok(opacity
== 1.0f
, "Got unexpected opacity %.8e.\n", opacity
);
776 set_matrix_identity(&matrix
);
777 ID2D1BitmapBrush_GetTransform(brush
, &tmp_matrix
);
778 ok(!memcmp(&tmp_matrix
, &matrix
, sizeof(matrix
)),
779 "Got unexpected matrix {%.8e, %.8e, %.8e, %.8e, %.8e, %.8e}.\n",
780 tmp_matrix
._11
, tmp_matrix
._12
, tmp_matrix
._21
,
781 tmp_matrix
._22
, tmp_matrix
._31
, tmp_matrix
._32
);
782 extend_mode
= ID2D1BitmapBrush_GetExtendModeX(brush
);
783 ok(extend_mode
== D2D1_EXTEND_MODE_CLAMP
, "Got unexpected extend mode %#x.\n", extend_mode
);
784 extend_mode
= ID2D1BitmapBrush_GetExtendModeY(brush
);
785 ok(extend_mode
== D2D1_EXTEND_MODE_CLAMP
, "Got unexpected extend mode %#x.\n", extend_mode
);
786 interpolation_mode
= ID2D1BitmapBrush_GetInterpolationMode(brush
);
787 ok(interpolation_mode
== D2D1_BITMAP_INTERPOLATION_MODE_LINEAR
,
788 "Got unexpected interpolation mode %#x.\n", interpolation_mode
);
789 ID2D1BitmapBrush_Release(brush
);
791 hr
= ID2D1RenderTarget_CreateBitmapBrush(rt
, bitmap
, NULL
, NULL
, &brush
);
792 ok(SUCCEEDED(hr
), "Failed to create brush, hr %#x.\n", hr
);
793 set_matrix_identity(&matrix
);
794 translate_matrix(&matrix
, 40.0f
, 120.0f
);
795 scale_matrix(&matrix
, 20.0f
, 60.0f
);
796 ID2D1BitmapBrush_SetTransform(brush
, &matrix
);
797 ID2D1BitmapBrush_SetInterpolationMode(brush
, D2D1_BITMAP_INTERPOLATION_MODE_NEAREST_NEIGHBOR
);
799 ID2D1RenderTarget_BeginDraw(rt
);
801 set_color(&color
, 0.0f
, 0.0f
, 1.0f
, 1.0f
);
802 ID2D1RenderTarget_Clear(rt
, &color
);
804 set_rect(&dst_rect
, 40.0f
, 120.0f
, 120.0f
, 360.0f
);
805 ID2D1RenderTarget_FillRectangle(rt
, &dst_rect
, (ID2D1Brush
*)brush
);
807 set_matrix_identity(&matrix
);
808 scale_matrix(&matrix
, 0.5f
, 2.0f
);
809 translate_matrix(&matrix
, 320.0f
, 240.0f
);
810 rotate_matrix(&matrix
, M_PI
/ 4.0f
);
811 ID2D1RenderTarget_SetTransform(rt
, &matrix
);
812 set_matrix_identity(&matrix
);
813 translate_matrix(&matrix
, -80.0f
, -60.0f
);
814 scale_matrix(&matrix
, 40.0f
, 30.0f
);
815 ID2D1BitmapBrush_SetTransform(brush
, &matrix
);
816 ID2D1BitmapBrush_SetOpacity(brush
, 0.75f
);
817 set_rect(&dst_rect
, -80.0f
, -60.0f
, 80.0f
, 60.0f
);
818 ID2D1RenderTarget_FillRectangle(rt
, &dst_rect
, (ID2D1Brush
*)brush
);
820 set_matrix_identity(&matrix
);
821 translate_matrix(&matrix
, 200.0f
, 120.0f
);
822 scale_matrix(&matrix
, 20.0f
, 60.0f
);
823 ID2D1RenderTarget_SetTransform(rt
, &matrix
);
824 ID2D1RenderTarget_DrawBitmap(rt
, bitmap
, NULL
, 0.25f
,
825 D2D1_BITMAP_INTERPOLATION_MODE_NEAREST_NEIGHBOR
, NULL
);
826 set_rect(&dst_rect
, -4.0f
, 12.0f
, -8.0f
, 8.0f
);
827 ID2D1RenderTarget_DrawBitmap(rt
, bitmap
, &dst_rect
, 0.75f
,
828 D2D1_BITMAP_INTERPOLATION_MODE_NEAREST_NEIGHBOR
, NULL
);
829 set_rect(&dst_rect
, 0.0f
, 8.0f
, 4.0f
, 12.0f
);
830 set_rect(&src_rect
, 2.0f
, 1.0f
, 4.0f
, 3.0f
);
831 ID2D1RenderTarget_DrawBitmap(rt
, bitmap
, &dst_rect
, 1.0f
,
832 D2D1_BITMAP_INTERPOLATION_MODE_NEAREST_NEIGHBOR
, &src_rect
);
834 hr
= ID2D1RenderTarget_EndDraw(rt
, NULL
, NULL
);
835 ok(SUCCEEDED(hr
), "Failed to end draw, hr %#x.\n", hr
);
836 ok(compare_surface(surface
, "393636185359a550d459e1e5f0e25411814f724c"), "Surface does not match.\n");
838 ID2D1RenderTarget_BeginDraw(rt
);
840 ID2D1RenderTarget_Clear(rt
, &color
);
842 ID2D1BitmapBrush_SetOpacity(brush
, 1.0f
);
843 for (i
= 0; i
< sizeof(extend_mode_tests
) / sizeof(*extend_mode_tests
); ++i
)
845 ID2D1BitmapBrush_SetExtendModeX(brush
, extend_mode_tests
[i
].extend_mode_x
);
846 extend_mode
= ID2D1BitmapBrush_GetExtendModeX(brush
);
847 ok(extend_mode
== extend_mode_tests
[i
].extend_mode_x
,
848 "Test %u: Got unexpected extend mode %#x, expected %#x.\n",
849 i
, extend_mode
, extend_mode_tests
[i
].extend_mode_x
);
850 ID2D1BitmapBrush_SetExtendModeY(brush
, extend_mode_tests
[i
].extend_mode_y
);
851 extend_mode
= ID2D1BitmapBrush_GetExtendModeY(brush
);
852 ok(extend_mode
== extend_mode_tests
[i
].extend_mode_y
,
853 "Test %u: Got unexpected extend mode %#x, expected %#x.\n",
854 i
, extend_mode
, extend_mode_tests
[i
].extend_mode_y
);
855 set_matrix_identity(&matrix
);
856 translate_matrix(&matrix
, extend_mode_tests
[i
].translate_x
, extend_mode_tests
[i
].translate_y
);
857 scale_matrix(&matrix
, 0.5f
, 0.5f
);
858 ID2D1BitmapBrush_SetTransform(brush
, &matrix
);
859 ID2D1RenderTarget_FillRectangle(rt
, &extend_mode_tests
[i
].rect
, (ID2D1Brush
*)brush
);
862 hr
= ID2D1RenderTarget_EndDraw(rt
, NULL
, NULL
);
863 ok(SUCCEEDED(hr
), "Failed to end draw, hr %#x.\n", hr
);
864 ok(compare_surface(surface
, "b4b775afecdae2d26642001f4faff73663bb8b31"), "Surface does not match.\n");
866 ID2D1BitmapBrush_Release(brush
);
867 refcount
= ID2D1Bitmap_Release(bitmap
);
868 ok(!refcount
, "Bitmap has %u references left.\n", refcount
);
869 ID2D1RenderTarget_Release(rt
);
870 IDXGISurface_Release(surface
);
871 IDXGISwapChain_Release(swapchain
);
872 ID3D10Device1_Release(device
);
873 DestroyWindow(window
);