d2d1: Check the vertex count again after duplicate removal in d2d_path_geometry_trian...
[wine.git] / dlls / d2d1 / tests / d2d1.c
blobd38d49cd139a61ea05ccf57f6aa0edd91a2aa8a6
1 /*
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
19 #define COBJMACROS
20 #include <limits.h>
21 #include <math.h>
22 #include <float.h>
23 #include "d2d1_1.h"
24 #include "d3d11.h"
25 #include "wincrypt.h"
26 #include "wine/test.h"
27 #include "initguid.h"
28 #include "dwrite.h"
29 #include "wincodec.h"
30 #include "wine/heap.h"
32 static HRESULT (WINAPI *pD2D1CreateDevice)(IDXGIDevice *dxgi_device,
33 const D2D1_CREATION_PROPERTIES *properties, ID2D1Device **device);
34 static void (WINAPI *pD2D1SinCos)(float angle, float *s, float *c);
35 static float (WINAPI *pD2D1Tan)(float angle);
36 static float (WINAPI *pD2D1Vec3Length)(float x, float y, float z);
37 static D2D1_COLOR_F (WINAPI *pD2D1ConvertColorSpace)(D2D1_COLOR_SPACE src_colour_space,
38 D2D1_COLOR_SPACE dst_colour_space, const D2D1_COLOR_F *colour);
40 static BOOL use_mt = TRUE;
42 static struct test_entry
44 void (*test)(BOOL d3d11);
45 BOOL d3d11;
46 } *mt_tests;
47 size_t mt_tests_size, mt_test_count;
49 struct d2d1_test_context
51 BOOL d3d11;
52 IDXGIDevice *device;
53 HWND window;
54 IDXGISwapChain *swapchain;
55 IDXGISurface *surface;
56 ID2D1RenderTarget *rt;
59 struct resource_readback
61 BOOL d3d11;
62 union
64 ID3D10Resource *d3d10_resource;
65 ID3D11Resource *d3d11_resource;
66 } u;
67 unsigned int pitch, width, height;
68 void *data;
71 struct figure
73 unsigned int *spans;
74 unsigned int spans_size;
75 unsigned int span_count;
78 struct geometry_sink
80 ID2D1SimplifiedGeometrySink ID2D1SimplifiedGeometrySink_iface;
82 struct geometry_figure
84 D2D1_FIGURE_BEGIN begin;
85 D2D1_FIGURE_END end;
86 D2D1_POINT_2F start_point;
87 struct geometry_segment
89 enum
91 SEGMENT_BEZIER,
92 SEGMENT_LINE,
93 } type;
94 union
96 D2D1_BEZIER_SEGMENT bezier;
97 D2D1_POINT_2F line;
98 } u;
99 DWORD flags;
100 } *segments;
101 unsigned int segments_size;
102 unsigned int segment_count;
103 } *figures;
104 unsigned int figures_size;
105 unsigned int figure_count;
107 D2D1_FILL_MODE fill_mode;
108 DWORD segment_flags;
109 BOOL closed;
112 struct expected_geometry_figure
114 D2D1_FIGURE_BEGIN begin;
115 D2D1_FIGURE_END end;
116 D2D1_POINT_2F start_point;
117 unsigned int segment_count;
118 const struct geometry_segment *segments;
121 static void queue_d3d1x_test(void (*test)(BOOL d3d11), BOOL d3d11)
123 if (mt_test_count >= mt_tests_size)
125 mt_tests_size = max(16, mt_tests_size * 2);
126 mt_tests = heap_realloc(mt_tests, mt_tests_size * sizeof(*mt_tests));
128 mt_tests[mt_test_count].test = test;
129 mt_tests[mt_test_count++].d3d11 = d3d11;
132 static void queue_d3d10_test(void (*test)(BOOL d3d11))
134 queue_d3d1x_test(test, FALSE);
137 static void queue_test(void (*test)(BOOL d3d11))
139 queue_d3d1x_test(test, FALSE);
140 queue_d3d1x_test(test, TRUE);
143 static DWORD WINAPI thread_func(void *ctx)
145 LONG *i = ctx, j;
147 while (*i < mt_test_count)
149 j = *i;
150 if (InterlockedCompareExchange(i, j + 1, j) == j)
151 mt_tests[j].test(mt_tests[j].d3d11);
154 return 0;
157 static void run_queued_tests(void)
159 unsigned int thread_count, i;
160 HANDLE *threads;
161 SYSTEM_INFO si;
162 LONG test_idx;
164 if (!use_mt)
166 for (i = 0; i < mt_test_count; ++i)
168 mt_tests[i].test(mt_tests[i].d3d11);
171 return;
174 GetSystemInfo(&si);
175 thread_count = si.dwNumberOfProcessors;
176 threads = heap_calloc(thread_count, sizeof(*threads));
177 for (i = 0, test_idx = 0; i < thread_count; ++i)
179 threads[i] = CreateThread(NULL, 0, thread_func, &test_idx, 0, NULL);
180 ok(!!threads[i], "Failed to create thread %u.\n", i);
182 WaitForMultipleObjects(thread_count, threads, TRUE, INFINITE);
183 for (i = 0; i < thread_count; ++i)
185 CloseHandle(threads[i]);
187 heap_free(threads);
190 static void set_point(D2D1_POINT_2F *point, float x, float y)
192 point->x = x;
193 point->y = y;
196 static void set_quadratic(D2D1_QUADRATIC_BEZIER_SEGMENT *quadratic, float x1, float y1, float x2, float y2)
198 quadratic->point1.x = x1;
199 quadratic->point1.y = y1;
200 quadratic->point2.x = x2;
201 quadratic->point2.y = y2;
204 static void set_rect(D2D1_RECT_F *rect, float left, float top, float right, float bottom)
206 rect->left = left;
207 rect->top = top;
208 rect->right = right;
209 rect->bottom = bottom;
212 static void set_rounded_rect(D2D1_ROUNDED_RECT *rect, float left, float top, float right, float bottom,
213 float radius_x, float radius_y)
215 set_rect(&rect->rect, left, top, right, bottom);
216 rect->radiusX = radius_x;
217 rect->radiusY = radius_y;
220 static void set_rect_u(D2D1_RECT_U *rect, UINT32 left, UINT32 top, UINT32 right, UINT32 bottom)
222 rect->left = left;
223 rect->top = top;
224 rect->right = right;
225 rect->bottom = bottom;
228 static void set_ellipse(D2D1_ELLIPSE *ellipse, float x, float y, float rx, float ry)
230 set_point(&ellipse->point, x, y);
231 ellipse->radiusX = rx;
232 ellipse->radiusY = ry;
235 static void set_color(D2D1_COLOR_F *color, float r, float g, float b, float a)
237 color->r = r;
238 color->g = g;
239 color->b = b;
240 color->a = a;
243 static void set_size_u(D2D1_SIZE_U *size, unsigned int w, unsigned int h)
245 size->width = w;
246 size->height = h;
249 static void set_size_f(D2D1_SIZE_F *size, float w, float h)
251 size->width = w;
252 size->height = h;
255 static void set_matrix_identity(D2D1_MATRIX_3X2_F *matrix)
257 matrix->_11 = 1.0f;
258 matrix->_12 = 0.0f;
259 matrix->_21 = 0.0f;
260 matrix->_22 = 1.0f;
261 matrix->_31 = 0.0f;
262 matrix->_32 = 0.0f;
265 static void rotate_matrix(D2D1_MATRIX_3X2_F *matrix, float theta)
267 float sin_theta, cos_theta, tmp_11, tmp_12;
269 sin_theta = sinf(theta);
270 cos_theta = cosf(theta);
271 tmp_11 = matrix->_11;
272 tmp_12 = matrix->_12;
274 matrix->_11 = cos_theta * tmp_11 + sin_theta * matrix->_21;
275 matrix->_12 = cos_theta * tmp_12 + sin_theta * matrix->_22;
276 matrix->_21 = -sin_theta * tmp_11 + cos_theta * matrix->_21;
277 matrix->_22 = -sin_theta * tmp_12 + cos_theta * matrix->_22;
280 static void skew_matrix(D2D1_MATRIX_3X2_F *matrix, float x, float y)
282 float tmp_11, tmp_12;
284 tmp_11 = matrix->_11;
285 tmp_12 = matrix->_12;
287 matrix->_11 += y * matrix->_21;
288 matrix->_12 += y * matrix->_22;
289 matrix->_21 += x * tmp_11;
290 matrix->_22 += x * tmp_12;
293 static void scale_matrix(D2D1_MATRIX_3X2_F *matrix, float x, float y)
295 matrix->_11 *= x;
296 matrix->_12 *= x;
297 matrix->_21 *= y;
298 matrix->_22 *= y;
301 static void translate_matrix(D2D1_MATRIX_3X2_F *matrix, float x, float y)
303 matrix->_31 += x * matrix->_11 + y * matrix->_21;
304 matrix->_32 += x * matrix->_12 + y * matrix->_22;
307 static void line_to(ID2D1GeometrySink *sink, float x, float y)
309 D2D1_POINT_2F point;
311 set_point(&point, x, y);
312 ID2D1GeometrySink_AddLine(sink, point);
315 static void quadratic_to(ID2D1GeometrySink *sink, float x1, float y1, float x2, float y2)
317 D2D1_QUADRATIC_BEZIER_SEGMENT quadratic;
319 set_quadratic(&quadratic, x1, y1, x2, y2);
320 ID2D1GeometrySink_AddQuadraticBezier(sink, &quadratic);
323 static void cubic_to(ID2D1GeometrySink *sink, float x1, float y1, float x2, float y2, float x3, float y3)
325 D2D1_BEZIER_SEGMENT b;
327 b.point1.x = x1;
328 b.point1.y = y1;
329 b.point2.x = x2;
330 b.point2.y = y2;
331 b.point3.x = x3;
332 b.point3.y = y3;
333 ID2D1GeometrySink_AddBezier(sink, &b);
336 static void get_d3d10_surface_readback(IDXGISurface *surface, struct resource_readback *rb)
338 D3D10_TEXTURE2D_DESC texture_desc;
339 D3D10_MAPPED_TEXTURE2D map_desc;
340 DXGI_SURFACE_DESC surface_desc;
341 ID3D10Resource *src_resource;
342 ID3D10Device *device;
343 HRESULT hr;
345 hr = IDXGISurface_GetDevice(surface, &IID_ID3D10Device, (void **)&device);
346 ok(SUCCEEDED(hr), "Failed to get device, hr %#x.\n", hr);
347 hr = IDXGISurface_QueryInterface(surface, &IID_ID3D10Resource, (void **)&src_resource);
348 ok(SUCCEEDED(hr), "Failed to query resource interface, hr %#x.\n", hr);
350 hr = IDXGISurface_GetDesc(surface, &surface_desc);
351 ok(SUCCEEDED(hr), "Failed to get surface desc, hr %#x.\n", hr);
352 texture_desc.Width = surface_desc.Width;
353 texture_desc.Height = surface_desc.Height;
354 texture_desc.MipLevels = 1;
355 texture_desc.ArraySize = 1;
356 texture_desc.Format = surface_desc.Format;
357 texture_desc.SampleDesc = surface_desc.SampleDesc;
358 texture_desc.Usage = D3D10_USAGE_STAGING;
359 texture_desc.BindFlags = 0;
360 texture_desc.CPUAccessFlags = D3D10_CPU_ACCESS_READ;
361 texture_desc.MiscFlags = 0;
362 hr = ID3D10Device_CreateTexture2D(device, &texture_desc, NULL, (ID3D10Texture2D **)&rb->u.d3d10_resource);
363 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
365 rb->width = texture_desc.Width;
366 rb->height = texture_desc.Height;
368 ID3D10Device_CopyResource(device, rb->u.d3d10_resource, src_resource);
369 ID3D10Resource_Release(src_resource);
370 ID3D10Device_Release(device);
372 hr = ID3D10Texture2D_Map((ID3D10Texture2D *)rb->u.d3d10_resource, 0, D3D10_MAP_READ, 0, &map_desc);
373 ok(SUCCEEDED(hr), "Failed to map texture, hr %#x.\n", hr);
375 rb->pitch = map_desc.RowPitch;
376 rb->data = map_desc.pData;
379 static void get_d3d11_surface_readback(IDXGISurface *surface, struct resource_readback *rb)
381 D3D11_TEXTURE2D_DESC texture_desc;
382 D3D11_MAPPED_SUBRESOURCE map_desc;
383 DXGI_SURFACE_DESC surface_desc;
384 ID3D11Resource *src_resource;
385 ID3D11DeviceContext *context;
386 ID3D11Device *device;
387 HRESULT hr;
389 hr = IDXGISurface_GetDevice(surface, &IID_ID3D11Device, (void **)&device);
390 ok(SUCCEEDED(hr), "Failed to get device, hr %#x.\n", hr);
391 hr = IDXGISurface_QueryInterface(surface, &IID_ID3D11Resource, (void **)&src_resource);
392 ok(SUCCEEDED(hr), "Failed to query resource interface, hr %#x.\n", hr);
394 hr = IDXGISurface_GetDesc(surface, &surface_desc);
395 ok(SUCCEEDED(hr), "Failed to get surface desc, hr %#x.\n", hr);
396 texture_desc.Width = surface_desc.Width;
397 texture_desc.Height = surface_desc.Height;
398 texture_desc.MipLevels = 1;
399 texture_desc.ArraySize = 1;
400 texture_desc.Format = surface_desc.Format;
401 texture_desc.SampleDesc = surface_desc.SampleDesc;
402 texture_desc.Usage = D3D11_USAGE_STAGING;
403 texture_desc.BindFlags = 0;
404 texture_desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ;
405 texture_desc.MiscFlags = 0;
406 hr = ID3D11Device_CreateTexture2D(device, &texture_desc, NULL, (ID3D11Texture2D **)&rb->u.d3d11_resource);
407 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
409 rb->width = texture_desc.Width;
410 rb->height = texture_desc.Height;
412 ID3D11Device_GetImmediateContext(device, &context);
413 ID3D11DeviceContext_CopyResource(context, rb->u.d3d11_resource, src_resource);
414 ID3D11Resource_Release(src_resource);
415 ID3D11Device_Release(device);
417 hr = ID3D11DeviceContext_Map(context, rb->u.d3d11_resource, 0, D3D11_MAP_READ, 0, &map_desc);
418 ok(SUCCEEDED(hr), "Failed to map texture, hr %#x.\n", hr);
419 ID3D11DeviceContext_Release(context);
421 rb->pitch = map_desc.RowPitch;
422 rb->data = map_desc.pData;
425 static void get_surface_readback(struct d2d1_test_context *ctx, struct resource_readback *rb)
427 if ((rb->d3d11 = ctx->d3d11))
428 get_d3d11_surface_readback(ctx->surface, rb);
429 else
430 get_d3d10_surface_readback(ctx->surface, rb);
433 static void release_d3d10_resource_readback(struct resource_readback *rb)
435 ID3D10Texture2D_Unmap((ID3D10Texture2D *)rb->u.d3d10_resource, 0);
436 ID3D10Resource_Release(rb->u.d3d10_resource);
439 static void release_d3d11_resource_readback(struct resource_readback *rb)
441 ID3D11DeviceContext *context;
442 ID3D11Device *device;
444 ID3D11Resource_GetDevice(rb->u.d3d11_resource, &device);
445 ID3D11Device_GetImmediateContext(device, &context);
446 ID3D11Device_Release(device);
448 ID3D11DeviceContext_Unmap(context, rb->u.d3d11_resource, 0);
449 ID3D11Resource_Release(rb->u.d3d11_resource);
450 ID3D11DeviceContext_Release(context);
453 static void release_resource_readback(struct resource_readback *rb)
455 if (rb->d3d11)
456 release_d3d11_resource_readback(rb);
457 else
458 release_d3d10_resource_readback(rb);
461 static DWORD get_readback_colour(struct resource_readback *rb, unsigned int x, unsigned int y)
463 return ((DWORD *)((BYTE *)rb->data + y * rb->pitch))[x];
466 static float clamp_float(float f, float lower, float upper)
468 return f < lower ? lower : f > upper ? upper : f;
471 static BOOL compare_uint(unsigned int x, unsigned int y, unsigned int max_diff)
473 unsigned int diff = x > y ? x - y : y - x;
475 return diff <= max_diff;
478 static BOOL compare_colour(DWORD c1, DWORD c2, BYTE max_diff)
480 return compare_uint(c1 & 0xff, c2 & 0xff, max_diff)
481 && compare_uint((c1 >> 8) & 0xff, (c2 >> 8) & 0xff, max_diff)
482 && compare_uint((c1 >> 16) & 0xff, (c2 >> 16) & 0xff, max_diff)
483 && compare_uint((c1 >> 24) & 0xff, (c2 >> 24) & 0xff, max_diff);
486 static BOOL compare_float(float f, float g, unsigned int ulps)
488 int x = *(int *)&f;
489 int y = *(int *)&g;
491 if (x < 0)
492 x = INT_MIN - x;
493 if (y < 0)
494 y = INT_MIN - y;
496 if (abs(x - y) > ulps)
497 return FALSE;
499 return TRUE;
502 static BOOL compare_colour_f(const D2D1_COLOR_F *colour, float r, float g, float b, float a, unsigned int ulps)
504 return compare_float(colour->r, r, ulps)
505 && compare_float(colour->g, g, ulps)
506 && compare_float(colour->b, b, ulps)
507 && compare_float(colour->a, a, ulps);
510 static BOOL compare_point(const D2D1_POINT_2F *point, float x, float y, unsigned int ulps)
512 return compare_float(point->x, x, ulps)
513 && compare_float(point->y, y, ulps);
516 static BOOL compare_rect(const D2D1_RECT_F *rect, float left, float top, float right, float bottom, unsigned int ulps)
518 return compare_float(rect->left, left, ulps)
519 && compare_float(rect->top, top, ulps)
520 && compare_float(rect->right, right, ulps)
521 && compare_float(rect->bottom, bottom, ulps);
524 static BOOL compare_bezier_segment(const D2D1_BEZIER_SEGMENT *b, float x1, float y1,
525 float x2, float y2, float x3, float y3, unsigned int ulps)
527 return compare_point(&b->point1, x1, y1, ulps)
528 && compare_point(&b->point2, x2, y2, ulps)
529 && compare_point(&b->point3, x3, y3, ulps);
532 static BOOL compare_sha1(void *data, unsigned int pitch, unsigned int bpp,
533 unsigned int w, unsigned int h, const char *ref_sha1)
535 static const char hex_chars[] = "0123456789abcdef";
536 HCRYPTPROV provider;
537 BYTE hash_data[20];
538 HCRYPTHASH hash;
539 unsigned int i;
540 char sha1[41];
541 BOOL ret;
543 ret = CryptAcquireContextW(&provider, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT);
544 ok(ret, "Failed to acquire crypt context.\n");
545 ret = CryptCreateHash(provider, CALG_SHA1, 0, 0, &hash);
546 ok(ret, "Failed to create hash.\n");
548 for (i = 0; i < h; ++i)
550 if (!(ret = CryptHashData(hash, (BYTE *)data + pitch * i, w * bpp, 0)))
551 break;
553 ok(ret, "Failed to hash data.\n");
555 i = sizeof(hash_data);
556 ret = CryptGetHashParam(hash, HP_HASHVAL, hash_data, &i, 0);
557 ok(ret, "Failed to get hash value.\n");
558 ok(i == sizeof(hash_data), "Got unexpected hash size %u.\n", i);
560 ret = CryptDestroyHash(hash);
561 ok(ret, "Failed to destroy hash.\n");
562 ret = CryptReleaseContext(provider, 0);
563 ok(ret, "Failed to release crypt context.\n");
565 for (i = 0; i < 20; ++i)
567 sha1[i * 2] = hex_chars[hash_data[i] >> 4];
568 sha1[i * 2 + 1] = hex_chars[hash_data[i] & 0xf];
570 sha1[40] = 0;
572 return !strcmp(ref_sha1, (char *)sha1);
575 static BOOL compare_surface(struct d2d1_test_context *ctx, const char *ref_sha1)
577 struct resource_readback rb;
578 BOOL ret;
580 get_surface_readback(ctx, &rb);
581 ret = compare_sha1(rb.data, rb.pitch, 4, rb.width, rb.height, ref_sha1);
582 release_resource_readback(&rb);
584 return ret;
587 static BOOL compare_wic_bitmap(IWICBitmap *bitmap, const char *ref_sha1)
589 UINT stride, width, height, buffer_size;
590 IWICBitmapLock *lock;
591 BYTE *data;
592 HRESULT hr;
593 BOOL ret;
595 hr = IWICBitmap_Lock(bitmap, NULL, WICBitmapLockRead, &lock);
596 ok(SUCCEEDED(hr), "Failed to lock bitmap, hr %#x.\n", hr);
598 hr = IWICBitmapLock_GetDataPointer(lock, &buffer_size, &data);
599 ok(SUCCEEDED(hr), "Failed to get bitmap data, hr %#x.\n", hr);
601 hr = IWICBitmapLock_GetStride(lock, &stride);
602 ok(SUCCEEDED(hr), "Failed to get bitmap stride, hr %#x.\n", hr);
604 hr = IWICBitmapLock_GetSize(lock, &width, &height);
605 ok(SUCCEEDED(hr), "Failed to get bitmap size, hr %#x.\n", hr);
607 ret = compare_sha1(data, stride, 4, width, height, ref_sha1);
609 IWICBitmapLock_Release(lock);
611 return ret;
614 static void serialize_figure(struct figure *figure)
616 static const char lookup[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
617 unsigned int i, j, k, span;
618 char output[76];
619 char t[3];
620 char *p;
622 for (i = 0, j = 0, k = 0, p = output; i < figure->span_count; ++i)
624 span = figure->spans[i];
625 while (span)
627 t[j] = span & 0x7f;
628 if (span > 0x7f)
629 t[j] |= 0x80;
630 span >>= 7;
631 if (++j == 3)
633 p[0] = lookup[(t[0] & 0xfc) >> 2];
634 p[1] = lookup[((t[0] & 0x03) << 4) | ((t[1] & 0xf0) >> 4)];
635 p[2] = lookup[((t[1] & 0x0f) << 2) | ((t[2] & 0xc0) >> 6)];
636 p[3] = lookup[t[2] & 0x3f];
637 p += 4;
638 if (++k == 19)
640 trace("%.76s\n", output);
641 p = output;
642 k = 0;
644 j = 0;
648 if (j)
650 for (i = j; i < 3; ++i)
651 t[i] = 0;
652 p[0] = lookup[(t[0] & 0xfc) >> 2];
653 p[1] = lookup[((t[0] & 0x03) << 4) | ((t[1] & 0xf0) >> 4)];
654 p[2] = lookup[((t[1] & 0x0f) << 2) | ((t[2] & 0xc0) >> 6)];
655 p[3] = lookup[t[2] & 0x3f];
656 ++k;
658 if (k)
659 trace("%.*s\n", k * 4, output);
662 static void figure_add_span(struct figure *figure, unsigned int span)
664 if (figure->span_count == figure->spans_size)
666 figure->spans_size *= 2;
667 figure->spans = HeapReAlloc(GetProcessHeap(), 0, figure->spans,
668 figure->spans_size * sizeof(*figure->spans));
671 figure->spans[figure->span_count++] = span;
674 static void deserialize_span(struct figure *figure, unsigned int *current, unsigned int *shift, unsigned int c)
676 *current |= (c & 0x7f) << *shift;
677 if (c & 0x80)
679 *shift += 7;
680 return;
683 if (*current)
684 figure_add_span(figure, *current);
685 *current = 0;
686 *shift = 0;
689 static void deserialize_figure(struct figure *figure, const BYTE *s)
691 static const BYTE lookup[] =
693 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
694 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
695 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3e, 0xff, 0xff, 0xff, 0x3f,
696 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
697 0xff, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e,
698 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0xff, 0xff, 0xff, 0xff, 0xff,
699 0xff, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28,
700 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x31, 0x32, 0x33, 0xff, 0xff, 0xff, 0xff, 0xff,
702 unsigned int current = 0, shift = 0;
703 const BYTE *ptr;
704 BYTE x, y;
706 figure->span_count = 0;
707 figure->spans_size = 64;
708 figure->spans = HeapAlloc(GetProcessHeap(), 0, figure->spans_size * sizeof(*figure->spans));
710 for (ptr = s; *ptr; ptr += 4)
712 x = lookup[ptr[0]];
713 y = lookup[ptr[1]];
714 deserialize_span(figure, &current, &shift, ((x & 0x3f) << 2) | ((y & 0x3f) >> 4));
715 x = lookup[ptr[2]];
716 deserialize_span(figure, &current, &shift, ((y & 0x0f) << 4) | ((x & 0x3f) >> 2));
717 y = lookup[ptr[3]];
718 deserialize_span(figure, &current, &shift, ((x & 0x03) << 6) | (y & 0x3f));
722 static void read_figure(struct figure *figure, BYTE *data, unsigned int pitch,
723 unsigned int x, unsigned int y, unsigned int w, unsigned int h, DWORD prev)
725 unsigned int i, j, span;
727 figure->span_count = 0;
728 for (i = 0, span = 0; i < h; ++i)
730 const DWORD *row = (DWORD *)&data[(y + i) * pitch + x * 4];
731 for (j = 0; j < w; ++j, ++span)
733 if ((i || j) && prev != row[j])
735 figure_add_span(figure, span);
736 prev = row[j];
737 span = 0;
741 if (span)
742 figure_add_span(figure, span);
745 static BOOL compare_figure(struct d2d1_test_context *ctx, unsigned int x, unsigned int y,
746 unsigned int w, unsigned int h, DWORD prev, unsigned int max_diff, const char *ref)
748 struct figure ref_figure, figure;
749 unsigned int i, j, span, diff;
750 struct resource_readback rb;
752 get_surface_readback(ctx, &rb);
754 figure.span_count = 0;
755 figure.spans_size = 64;
756 figure.spans = HeapAlloc(GetProcessHeap(), 0, figure.spans_size * sizeof(*figure.spans));
758 read_figure(&figure, rb.data, rb.pitch, x, y, w, h, prev);
760 deserialize_figure(&ref_figure, (BYTE *)ref);
761 span = w * h;
762 for (i = 0; i < ref_figure.span_count; ++i)
764 span -= ref_figure.spans[i];
766 if (span)
767 figure_add_span(&ref_figure, span);
769 for (i = 0, j = 0, diff = 0; i < figure.span_count && j < ref_figure.span_count;)
771 if (figure.spans[i] == ref_figure.spans[j])
773 if ((i ^ j) & 1)
774 diff += ref_figure.spans[j];
775 ++i;
776 ++j;
778 else if (figure.spans[i] > ref_figure.spans[j])
780 if ((i ^ j) & 1)
781 diff += ref_figure.spans[j];
782 figure.spans[i] -= ref_figure.spans[j];
783 ++j;
785 else
787 if ((i ^ j) & 1)
788 diff += figure.spans[i];
789 ref_figure.spans[j] -= figure.spans[i];
790 ++i;
793 if (diff > max_diff)
795 trace("diff %u > max_diff %u.\n", diff, max_diff);
796 read_figure(&figure, rb.data, rb.pitch, x, y, w, h, prev);
797 serialize_figure(&figure);
800 HeapFree(GetProcessHeap(), 0, ref_figure.spans);
801 HeapFree(GetProcessHeap(), 0, figure.spans);
802 release_resource_readback(&rb);
804 return diff <= max_diff;
807 static ID3D10Device1 *create_d3d10_device(void)
809 ID3D10Device1 *device;
811 if (SUCCEEDED(D3D10CreateDevice1(NULL, D3D10_DRIVER_TYPE_HARDWARE, NULL,
812 D3D10_CREATE_DEVICE_BGRA_SUPPORT, D3D10_FEATURE_LEVEL_10_0, D3D10_1_SDK_VERSION, &device)))
813 return device;
814 if (SUCCEEDED(D3D10CreateDevice1(NULL, D3D10_DRIVER_TYPE_WARP, NULL,
815 D3D10_CREATE_DEVICE_BGRA_SUPPORT, D3D10_FEATURE_LEVEL_10_0, D3D10_1_SDK_VERSION, &device)))
816 return device;
817 if (SUCCEEDED(D3D10CreateDevice1(NULL, D3D10_DRIVER_TYPE_REFERENCE, NULL,
818 D3D10_CREATE_DEVICE_BGRA_SUPPORT, D3D10_FEATURE_LEVEL_10_0, D3D10_1_SDK_VERSION, &device)))
819 return device;
821 return NULL;
824 static ID3D11Device *create_d3d11_device(void)
826 DWORD level = D3D_FEATURE_LEVEL_11_0;
827 ID3D11Device *device;
829 if (SUCCEEDED(D3D11CreateDevice(NULL, D3D_DRIVER_TYPE_HARDWARE, NULL,
830 D3D10_CREATE_DEVICE_BGRA_SUPPORT, &level, 1, D3D11_SDK_VERSION, &device, NULL, NULL)))
831 return device;
832 if (SUCCEEDED(D3D11CreateDevice(NULL, D3D_DRIVER_TYPE_WARP, NULL,
833 D3D10_CREATE_DEVICE_BGRA_SUPPORT, &level, 1, D3D11_SDK_VERSION, &device, NULL, NULL)))
834 return device;
835 if (SUCCEEDED(D3D11CreateDevice(NULL, D3D_DRIVER_TYPE_REFERENCE, NULL,
836 D3D10_CREATE_DEVICE_BGRA_SUPPORT, &level, 1, D3D11_SDK_VERSION, &device, NULL, NULL)))
837 return device;
839 return NULL;
842 static IDXGIDevice *create_device(BOOL d3d11)
844 ID3D10Device1 *d3d10_device;
845 ID3D11Device *d3d11_device;
846 IDXGIDevice *device;
847 HRESULT hr;
849 if (d3d11)
851 if (!(d3d11_device = create_d3d11_device()))
852 return NULL;
853 hr = ID3D11Device_QueryInterface(d3d11_device, &IID_IDXGIDevice, (void **)&device);
854 ID3D11Device_Release(d3d11_device);
856 else
858 if (!(d3d10_device = create_d3d10_device()))
859 return NULL;
860 hr = ID3D10Device1_QueryInterface(d3d10_device, &IID_IDXGIDevice, (void **)&device);
861 ID3D10Device1_Release(d3d10_device);
864 ok(SUCCEEDED(hr), "Failed to get DXGI device, hr %#x.\n", hr);
866 return device;
869 static HWND create_window(void)
871 RECT r = {0, 0, 640, 480};
873 AdjustWindowRect(&r, WS_OVERLAPPEDWINDOW | WS_VISIBLE, FALSE);
875 return CreateWindowA("static", "d2d1_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
876 0, 0, r.right - r.left, r.bottom - r.top, NULL, NULL, NULL, NULL);
879 static IDXGISwapChain *create_swapchain(IDXGIDevice *device, HWND window, BOOL windowed)
881 IDXGISwapChain *swapchain;
882 DXGI_SWAP_CHAIN_DESC desc;
883 IDXGIAdapter *adapter;
884 IDXGIFactory *factory;
885 HRESULT hr;
887 hr = IDXGIDevice_GetAdapter(device, &adapter);
888 ok(SUCCEEDED(hr), "Failed to get adapter, hr %#x.\n", hr);
889 hr = IDXGIAdapter_GetParent(adapter, &IID_IDXGIFactory, (void **)&factory);
890 ok(SUCCEEDED(hr), "Failed to get factory, hr %#x.\n", hr);
891 IDXGIAdapter_Release(adapter);
893 desc.BufferDesc.Width = 640;
894 desc.BufferDesc.Height = 480;
895 desc.BufferDesc.RefreshRate.Numerator = 60;
896 desc.BufferDesc.RefreshRate.Denominator = 1;
897 desc.BufferDesc.Format = DXGI_FORMAT_B8G8R8A8_UNORM;
898 desc.BufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED;
899 desc.BufferDesc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED;
900 desc.SampleDesc.Count = 1;
901 desc.SampleDesc.Quality = 0;
902 desc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
903 desc.BufferCount = 1;
904 desc.OutputWindow = window;
905 desc.Windowed = windowed;
906 desc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD;
907 desc.Flags = 0;
909 hr = IDXGIFactory_CreateSwapChain(factory, (IUnknown *)device, &desc, &swapchain);
910 ok(SUCCEEDED(hr), "Failed to create swapchain, hr %#x.\n", hr);
911 IDXGIFactory_Release(factory);
913 return swapchain;
916 static IDXGISwapChain *create_d3d10_swapchain(ID3D10Device1 *device, HWND window, BOOL windowed)
918 IDXGISwapChain *swapchain;
919 IDXGIDevice *dxgi_device;
920 HRESULT hr;
922 hr = ID3D10Device1_QueryInterface(device, &IID_IDXGIDevice, (void **)&dxgi_device);
923 ok(SUCCEEDED(hr), "Failed to get DXGI device, hr %#x.\n", hr);
924 swapchain = create_swapchain(dxgi_device, window, windowed);
925 IDXGIDevice_Release(dxgi_device);
926 return swapchain;
929 static ID2D1RenderTarget *create_render_target_desc(IDXGISurface *surface,
930 const D2D1_RENDER_TARGET_PROPERTIES *desc, BOOL d3d11)
932 ID2D1RenderTarget *render_target;
933 ID2D1Factory *factory;
934 HRESULT hr;
936 hr = D2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED, &IID_ID2D1Factory, NULL, (void **)&factory);
937 ok(SUCCEEDED(hr), "Failed to create factory, hr %#x.\n", hr);
938 hr = ID2D1Factory_CreateDxgiSurfaceRenderTarget(factory, surface, desc, &render_target);
939 ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr);
940 ID2D1Factory_Release(factory);
942 return render_target;
945 static ID2D1RenderTarget *create_render_target(IDXGISurface *surface, BOOL d3d11)
947 D2D1_RENDER_TARGET_PROPERTIES desc;
949 desc.type = D2D1_RENDER_TARGET_TYPE_DEFAULT;
950 desc.pixelFormat.format = DXGI_FORMAT_UNKNOWN;
951 desc.pixelFormat.alphaMode = D2D1_ALPHA_MODE_PREMULTIPLIED;
952 desc.dpiX = 0.0f;
953 desc.dpiY = 0.0f;
954 desc.usage = D2D1_RENDER_TARGET_USAGE_NONE;
955 desc.minLevel = D2D1_FEATURE_LEVEL_DEFAULT;
957 return create_render_target_desc(surface, &desc, d3d11);
960 #define release_test_context(ctx) release_test_context_(__LINE__, ctx)
961 static void release_test_context_(unsigned int line, struct d2d1_test_context *ctx)
963 ID2D1Factory *factory;
964 ULONG ref;
966 ID2D1RenderTarget_GetFactory(ctx->rt, &factory);
967 ID2D1RenderTarget_Release(ctx->rt);
968 ref = ID2D1Factory_Release(factory);
969 ok_(__FILE__, line)(!ref, "Factory has %u references left.\n", ref);
971 IDXGISurface_Release(ctx->surface);
972 IDXGISwapChain_Release(ctx->swapchain);
973 DestroyWindow(ctx->window);
974 IDXGIDevice_Release(ctx->device);
977 #define init_test_context(ctx, d3d11) init_test_context_(__LINE__, ctx, d3d11)
978 static BOOL init_test_context_(unsigned int line, struct d2d1_test_context *ctx, BOOL d3d11)
980 HRESULT hr;
982 memset(ctx, 0, sizeof(*ctx));
984 ctx->d3d11 = d3d11;
985 if (!(ctx->device = create_device(d3d11)))
987 skip_(__FILE__, line)("Failed to create device, skipping tests.\n");
988 return FALSE;
991 ctx->window = create_window();
992 ok_(__FILE__, line)(!!ctx->window, "Failed to create test window.\n");
993 ctx->swapchain = create_swapchain(ctx->device, ctx->window, TRUE);
994 ok_(__FILE__, line)(!!ctx->swapchain, "Failed to create swapchain.\n");
995 hr = IDXGISwapChain_GetBuffer(ctx->swapchain, 0, &IID_IDXGISurface, (void **)&ctx->surface);
996 ok_(__FILE__, line)(SUCCEEDED(hr), "Failed to get buffer, hr %#x.\n", hr);
998 ctx->rt = create_render_target(ctx->surface, d3d11);
999 if (!ctx->rt && d3d11)
1001 todo_wine win_skip_(__FILE__, line)("Skipping d3d11 tests.\n");
1003 IDXGISurface_Release(ctx->surface);
1004 IDXGISwapChain_Release(ctx->swapchain);
1005 DestroyWindow(ctx->window);
1006 IDXGIDevice_Release(ctx->device);
1008 return FALSE;
1010 ok_(__FILE__, line)(!!ctx->rt, "Failed to create render target.\n");
1012 return TRUE;
1015 #define check_bitmap_surface(b, s, o) check_bitmap_surface_(__LINE__, b, s, o)
1016 static void check_bitmap_surface_(unsigned int line, ID2D1Bitmap *bitmap, BOOL has_surface, DWORD expected_options)
1018 D2D1_BITMAP_OPTIONS options;
1019 IDXGISurface *surface;
1020 ID2D1Bitmap1 *bitmap1;
1021 HRESULT hr;
1023 hr = ID2D1Bitmap_QueryInterface(bitmap, &IID_ID2D1Bitmap1, (void **)&bitmap1);
1024 if (FAILED(hr))
1025 return;
1027 options = ID2D1Bitmap1_GetOptions(bitmap1);
1028 ok_(__FILE__, line)(options == expected_options, "Unexpected bitmap options %#x, expected %#x.\n",
1029 options, expected_options);
1031 surface = (void *)0xdeadbeef;
1032 hr = ID2D1Bitmap1_GetSurface(bitmap1, &surface);
1033 if (has_surface)
1035 D3D10_TEXTURE2D_DESC desc;
1036 ID3D10Texture2D *texture;
1037 D2D1_SIZE_U pixel_size;
1038 DWORD bind_flags = 0;
1040 ok_(__FILE__, line)(SUCCEEDED(hr), "Failed to get bitmap surface, hr %#x.\n", hr);
1041 ok_(__FILE__, line)(!!surface, "Expected surface instance.\n");
1043 /* Correlate with resource configuration. */
1044 hr = IDXGISurface_QueryInterface(surface, &IID_ID3D10Texture2D, (void **)&texture);
1045 ok_(__FILE__, line)(SUCCEEDED(hr), "Failed to get texture pointer, hr %#x.\n", hr);
1047 ID3D10Texture2D_GetDesc(texture, &desc);
1048 ok_(__FILE__, line)(desc.Usage == 0, "Unexpected usage %#x.\n", desc.Usage);
1050 if (options & D2D1_BITMAP_OPTIONS_TARGET)
1051 bind_flags |= D3D10_BIND_RENDER_TARGET;
1052 if (!(options & D2D1_BITMAP_OPTIONS_CANNOT_DRAW))
1053 bind_flags |= D3D10_BIND_SHADER_RESOURCE;
1055 ok_(__FILE__, line)(desc.BindFlags == bind_flags, "Unexpected bind flags %#x for bitmap options %#x.\n",
1056 desc.BindFlags, options);
1057 ok_(__FILE__, line)(!desc.CPUAccessFlags, "Unexpected cpu access flags %#x.\n", desc.CPUAccessFlags);
1058 ok_(__FILE__, line)(!desc.MiscFlags, "Unexpected misc flags %#x.\n", desc.MiscFlags);
1060 pixel_size = ID2D1Bitmap_GetPixelSize(bitmap);
1061 if (!pixel_size.width || !pixel_size.height)
1062 pixel_size.width = pixel_size.height = 1;
1063 ok_(__FILE__, line)(desc.Width == pixel_size.width, "Got width %u, expected %u.\n",
1064 desc.Width, pixel_size.width);
1065 ok_(__FILE__, line)(desc.Height == pixel_size.height, "Got height %u, expected %u.\n",
1066 desc.Height, pixel_size.height);
1068 ID3D10Texture2D_Release(texture);
1070 IDXGISurface_Release(surface);
1072 else
1074 ok_(__FILE__, line)(hr == D2DERR_INVALID_CALL, "Unexpected hr %#x.\n", hr);
1075 ok_(__FILE__, line)(!surface, "Unexpected surface instance.\n");
1078 ID2D1Bitmap1_Release(bitmap1);
1081 static inline struct geometry_sink *impl_from_ID2D1SimplifiedGeometrySink(ID2D1SimplifiedGeometrySink *iface)
1083 return CONTAINING_RECORD(iface, struct geometry_sink, ID2D1SimplifiedGeometrySink_iface);
1086 static HRESULT STDMETHODCALLTYPE geometry_sink_QueryInterface(ID2D1SimplifiedGeometrySink *iface,
1087 REFIID iid, void **out)
1089 if (IsEqualGUID(iid, &IID_ID2D1SimplifiedGeometrySink)
1090 || IsEqualGUID(iid, &IID_IUnknown))
1092 *out = iface;
1093 return S_OK;
1096 *out = NULL;
1097 return E_NOINTERFACE;
1100 static ULONG STDMETHODCALLTYPE geometry_sink_AddRef(ID2D1SimplifiedGeometrySink *iface)
1102 return 0;
1105 static ULONG STDMETHODCALLTYPE geometry_sink_Release(ID2D1SimplifiedGeometrySink *iface)
1107 return 0;
1110 static void STDMETHODCALLTYPE geometry_sink_SetFillMode(ID2D1SimplifiedGeometrySink *iface, D2D1_FILL_MODE mode)
1112 struct geometry_sink *sink = impl_from_ID2D1SimplifiedGeometrySink(iface);
1114 sink->fill_mode = mode;
1117 static void STDMETHODCALLTYPE geometry_sink_SetSegmentFlags(ID2D1SimplifiedGeometrySink *iface,
1118 D2D1_PATH_SEGMENT flags)
1120 struct geometry_sink *sink = impl_from_ID2D1SimplifiedGeometrySink(iface);
1122 sink->segment_flags = flags;
1125 static void STDMETHODCALLTYPE geometry_sink_BeginFigure(ID2D1SimplifiedGeometrySink *iface,
1126 D2D1_POINT_2F start_point, D2D1_FIGURE_BEGIN figure_begin)
1128 struct geometry_sink *sink = impl_from_ID2D1SimplifiedGeometrySink(iface);
1129 struct geometry_figure *figure;
1131 if (sink->figure_count == sink->figures_size)
1133 sink->figures_size *= 2;
1134 sink->figures = HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sink->figures,
1135 sink->figures_size * sizeof(*sink->figures));
1137 figure = &sink->figures[sink->figure_count++];
1139 figure->begin = figure_begin;
1140 figure->start_point = start_point;
1141 figure->segments_size = 4;
1142 figure->segments = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
1143 figure->segments_size * sizeof(*figure->segments));
1146 static struct geometry_segment *geometry_figure_add_segment(struct geometry_figure *figure)
1148 if (figure->segment_count == figure->segments_size)
1150 figure->segments_size *= 2;
1151 figure->segments = HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, figure->segments,
1152 figure->segments_size * sizeof(*figure->segments));
1154 return &figure->segments[figure->segment_count++];
1157 static void STDMETHODCALLTYPE geometry_sink_AddLines(ID2D1SimplifiedGeometrySink *iface,
1158 const D2D1_POINT_2F *points, UINT32 count)
1160 struct geometry_sink *sink = impl_from_ID2D1SimplifiedGeometrySink(iface);
1161 struct geometry_figure *figure = &sink->figures[sink->figure_count - 1];
1162 struct geometry_segment *segment;
1163 unsigned int i;
1165 for (i = 0; i < count; ++i)
1167 segment = geometry_figure_add_segment(figure);
1168 segment->type = SEGMENT_LINE;
1169 segment->u.line = points[i];
1170 segment->flags = sink->segment_flags;
1174 static void STDMETHODCALLTYPE geometry_sink_AddBeziers(ID2D1SimplifiedGeometrySink *iface,
1175 const D2D1_BEZIER_SEGMENT *beziers, UINT32 count)
1177 struct geometry_sink *sink = impl_from_ID2D1SimplifiedGeometrySink(iface);
1178 struct geometry_figure *figure = &sink->figures[sink->figure_count - 1];
1179 struct geometry_segment *segment;
1180 unsigned int i;
1182 for (i = 0; i < count; ++i)
1184 segment = geometry_figure_add_segment(figure);
1185 segment->type = SEGMENT_BEZIER;
1186 segment->u.bezier = beziers[i];
1187 segment->flags = sink->segment_flags;
1191 static void STDMETHODCALLTYPE geometry_sink_EndFigure(ID2D1SimplifiedGeometrySink *iface,
1192 D2D1_FIGURE_END figure_end)
1194 struct geometry_sink *sink = impl_from_ID2D1SimplifiedGeometrySink(iface);
1195 struct geometry_figure *figure = &sink->figures[sink->figure_count - 1];
1197 figure->end = figure_end;
1200 static HRESULT STDMETHODCALLTYPE geometry_sink_Close(ID2D1SimplifiedGeometrySink *iface)
1202 struct geometry_sink *sink = impl_from_ID2D1SimplifiedGeometrySink(iface);
1204 sink->closed = TRUE;
1206 return S_OK;
1209 static const struct ID2D1SimplifiedGeometrySinkVtbl geometry_sink_vtbl =
1211 geometry_sink_QueryInterface,
1212 geometry_sink_AddRef,
1213 geometry_sink_Release,
1214 geometry_sink_SetFillMode,
1215 geometry_sink_SetSegmentFlags,
1216 geometry_sink_BeginFigure,
1217 geometry_sink_AddLines,
1218 geometry_sink_AddBeziers,
1219 geometry_sink_EndFigure,
1220 geometry_sink_Close,
1223 static void geometry_sink_init(struct geometry_sink *sink)
1225 memset(sink, 0, sizeof(*sink));
1226 sink->ID2D1SimplifiedGeometrySink_iface.lpVtbl = &geometry_sink_vtbl;
1227 sink->figures_size = 4;
1228 sink->figures = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
1229 sink->figures_size * sizeof(*sink->figures));
1232 static void geometry_sink_cleanup(struct geometry_sink *sink)
1234 unsigned int i;
1236 for (i = 0; i < sink->figure_count; ++i)
1238 HeapFree(GetProcessHeap(), 0, sink->figures[i].segments);
1240 HeapFree(GetProcessHeap(), 0, sink->figures);
1243 #define geometry_sink_check(a, b, c, d, e) geometry_sink_check_(__LINE__, a, b, c, d, e)
1244 static void geometry_sink_check_(unsigned int line, const struct geometry_sink *sink, D2D1_FILL_MODE fill_mode,
1245 unsigned int figure_count, const struct expected_geometry_figure *expected_figures, unsigned int ulps)
1247 const struct geometry_segment *segment, *expected_segment;
1248 const struct expected_geometry_figure *expected_figure;
1249 const struct geometry_figure *figure;
1250 unsigned int i, j;
1251 BOOL match;
1253 ok_(__FILE__, line)(sink->fill_mode == fill_mode,
1254 "Got unexpected fill mode %#x.\n", sink->fill_mode);
1255 ok_(__FILE__, line)(sink->figure_count == figure_count,
1256 "Got unexpected figure count %u, expected %u.\n", sink->figure_count, figure_count);
1257 ok_(__FILE__, line)(!sink->closed, "Sink is closed.\n");
1259 for (i = 0; i < figure_count; ++i)
1261 expected_figure = &expected_figures[i];
1262 figure = &sink->figures[i];
1264 ok_(__FILE__, line)(figure->begin == expected_figure->begin,
1265 "Got unexpected figure %u begin %#x, expected %#x.\n",
1266 i, figure->begin, expected_figure->begin);
1267 ok_(__FILE__, line)(figure->end == expected_figure->end,
1268 "Got unexpected figure %u end %#x, expected %#x.\n",
1269 i, figure->end, expected_figure->end);
1270 match = compare_point(&figure->start_point,
1271 expected_figure->start_point.x, expected_figure->start_point.y, ulps);
1272 ok_(__FILE__, line)(match, "Got unexpected figure %u start point {%.8e, %.8e}, expected {%.8e, %.8e}.\n",
1273 i, figure->start_point.x, figure->start_point.y,
1274 expected_figure->start_point.x, expected_figure->start_point.y);
1275 ok_(__FILE__, line)(figure->segment_count == expected_figure->segment_count,
1276 "Got unexpected figure %u segment count %u, expected %u.\n",
1277 i, figure->segment_count, expected_figure->segment_count);
1279 for (j = 0; j < figure->segment_count; ++j)
1281 expected_segment = &expected_figure->segments[j];
1282 segment = &figure->segments[j];
1283 ok_(__FILE__, line)(segment->type == expected_segment->type,
1284 "Got unexpected figure %u, segment %u type %#x, expected %#x.\n",
1285 i, j, segment->type, expected_segment->type);
1286 ok_(__FILE__, line)(segment->flags == expected_segment->flags,
1287 "Got unexpected figure %u, segment %u flags %#x, expected %#x.\n",
1288 i, j, segment->flags, expected_segment->flags);
1289 switch (segment->type)
1291 case SEGMENT_LINE:
1292 match = compare_point(&segment->u.line,
1293 expected_segment->u.line.x, expected_segment->u.line.y, ulps);
1294 ok_(__FILE__, line)(match, "Got unexpected figure %u segment %u {%.8e, %.8e}, "
1295 "expected {%.8e, %.8e}.\n",
1296 i, j, segment->u.line.x, segment->u.line.y,
1297 expected_segment->u.line.x, expected_segment->u.line.y);
1298 break;
1300 case SEGMENT_BEZIER:
1301 match = compare_bezier_segment(&segment->u.bezier,
1302 expected_segment->u.bezier.point1.x, expected_segment->u.bezier.point1.y,
1303 expected_segment->u.bezier.point2.x, expected_segment->u.bezier.point2.y,
1304 expected_segment->u.bezier.point3.x, expected_segment->u.bezier.point3.y,
1305 ulps);
1306 ok_(__FILE__, line)(match, "Got unexpected figure %u segment %u "
1307 "{%.8e, %.8e, %.8e, %.8e, %.8e, %.8e}, "
1308 "expected {%.8e, %.8e, %.8e, %.8e, %.8e, %.8e}.\n",
1309 i, j, segment->u.bezier.point1.x, segment->u.bezier.point1.y,
1310 segment->u.bezier.point2.x, segment->u.bezier.point2.y,
1311 segment->u.bezier.point3.x, segment->u.bezier.point3.y,
1312 expected_segment->u.bezier.point1.x, expected_segment->u.bezier.point1.y,
1313 expected_segment->u.bezier.point2.x, expected_segment->u.bezier.point2.y,
1314 expected_segment->u.bezier.point3.x, expected_segment->u.bezier.point3.y);
1315 break;
1321 static void test_clip(BOOL d3d11)
1323 struct d2d1_test_context ctx;
1324 D2D1_MATRIX_3X2_F matrix;
1325 D2D1_SIZE_U pixel_size;
1326 ID2D1RenderTarget *rt;
1327 D2D1_POINT_2F point;
1328 D2D1_COLOR_F color;
1329 float dpi_x, dpi_y;
1330 D2D1_RECT_F rect;
1331 D2D1_SIZE_F size;
1332 HRESULT hr;
1333 BOOL match;
1334 static const D2D1_MATRIX_3X2_F identity =
1336 1.0f, 0.0f,
1337 0.0f, 1.0f,
1338 0.0f, 0.0f,
1339 }}};
1341 if (!init_test_context(&ctx, d3d11))
1342 return;
1344 rt = ctx.rt;
1345 ID2D1RenderTarget_GetDpi(rt, &dpi_x, &dpi_y);
1346 ok(dpi_x == 96.0f, "Got unexpected dpi_x %.8e.\n", dpi_x);
1347 ok(dpi_y == 96.0f, "Got unexpected dpi_x %.8e.\n", dpi_y);
1348 size = ID2D1RenderTarget_GetSize(rt);
1349 ok(size.width == 640.0f, "Got unexpected width %.8e.\n", size.width);
1350 ok(size.height == 480.0f, "Got unexpected height %.8e.\n", size.height);
1351 pixel_size = ID2D1RenderTarget_GetPixelSize(rt);
1352 ok(pixel_size.width == 640, "Got unexpected width %u.\n", pixel_size.width);
1353 ok(pixel_size.height == 480, "Got unexpected height %u.\n", pixel_size.height);
1355 ID2D1RenderTarget_GetTransform(rt, &matrix);
1356 ok(!memcmp(&matrix, &identity, sizeof(matrix)),
1357 "Got unexpected matrix {%.8e, %.8e, %.8e, %.8e, %.8e, %.8e}.\n",
1358 matrix._11, matrix._12, matrix._21, matrix._22, matrix._31, matrix._32);
1360 ID2D1RenderTarget_BeginDraw(rt);
1362 set_color(&color, 1.0f, 1.0f, 0.0f, 1.0f);
1363 ID2D1RenderTarget_Clear(rt, &color);
1365 ID2D1RenderTarget_SetDpi(rt, 48.0f, 192.0f);
1366 ID2D1RenderTarget_GetDpi(rt, &dpi_x, &dpi_y);
1367 ok(dpi_x == 48.0f, "Got unexpected dpi_x %.8e.\n", dpi_x);
1368 ok(dpi_y == 192.0f, "Got unexpected dpi_x %.8e.\n", dpi_y);
1369 size = ID2D1RenderTarget_GetSize(rt);
1370 ok(size.width == 1280.0f, "Got unexpected width %.8e.\n", size.width);
1371 ok(size.height == 240.0f, "Got unexpected height %.8e.\n", size.height);
1372 pixel_size = ID2D1RenderTarget_GetPixelSize(rt);
1373 ok(pixel_size.width == 640, "Got unexpected width %u.\n", pixel_size.width);
1374 ok(pixel_size.height == 480, "Got unexpected height %u.\n", pixel_size.height);
1376 /* The effective clip rect is the intersection of all currently pushed
1377 * clip rects. Clip rects are in DIPs. */
1378 set_rect(&rect, 0.0f, 0.0f, 1280.0f, 80.0f);
1379 ID2D1RenderTarget_PushAxisAlignedClip(rt, &rect, D2D1_ANTIALIAS_MODE_ALIASED);
1380 set_rect(&rect, 0.0f, 0.0f, 426.0f, 240.0f);
1381 ID2D1RenderTarget_PushAxisAlignedClip(rt, &rect, D2D1_ANTIALIAS_MODE_ALIASED);
1383 set_color(&color, 0.0f, 1.0f, 0.0f, 1.0f);
1384 ID2D1RenderTarget_Clear(rt, &color);
1385 ID2D1RenderTarget_PopAxisAlignedClip(rt);
1386 ID2D1RenderTarget_PopAxisAlignedClip(rt);
1388 ID2D1RenderTarget_SetDpi(rt, 0.0f, 0.0f);
1389 ID2D1RenderTarget_GetDpi(rt, &dpi_x, &dpi_y);
1390 ok(dpi_x == 96.0f, "Got unexpected dpi_x %.8e.\n", dpi_x);
1391 ok(dpi_y == 96.0f, "Got unexpected dpi_y %.8e.\n", dpi_y);
1393 ID2D1RenderTarget_SetDpi(rt, 192.0f, 192.0f);
1394 ID2D1RenderTarget_SetDpi(rt, 0.0f, 96.0f);
1395 ID2D1RenderTarget_GetDpi(rt, &dpi_x, &dpi_y);
1396 ok(dpi_x == 192.0f, "Got unexpected dpi_x %.8e.\n", dpi_x);
1397 ok(dpi_y == 192.0f, "Got unexpected dpi_y %.8e.\n", dpi_y);
1399 ID2D1RenderTarget_SetDpi(rt, -10.0f, 96.0f);
1400 ID2D1RenderTarget_GetDpi(rt, &dpi_x, &dpi_y);
1401 ok(dpi_x == 192.0f, "Got unexpected dpi_x %.8e.\n", dpi_x);
1402 ok(dpi_y == 192.0f, "Got unexpected dpi_y %.8e.\n", dpi_y);
1404 ID2D1RenderTarget_SetDpi(rt, 96.0f, -10.0f);
1405 ID2D1RenderTarget_GetDpi(rt, &dpi_x, &dpi_y);
1406 ok(dpi_x == 192.0f, "Got unexpected dpi_x %.8e.\n", dpi_x);
1407 ok(dpi_y == 192.0f, "Got unexpected dpi_y %.8e.\n", dpi_y);
1409 ID2D1RenderTarget_SetDpi(rt, 96.0f, 0.0f);
1410 ID2D1RenderTarget_GetDpi(rt, &dpi_x, &dpi_y);
1411 ok(dpi_x == 192.0f, "Got unexpected dpi_x %.8e.\n", dpi_x);
1412 ok(dpi_y == 192.0f, "Got unexpected dpi_y %.8e.\n", dpi_y);
1414 ID2D1RenderTarget_SetDpi(rt, 96.0f, 96.0f);
1416 /* Transformations apply to clip rects, the effective clip rect is the
1417 * (axis-aligned) bounding box of the transformed clip rect. */
1418 set_point(&point, 320.0f, 240.0f);
1419 D2D1MakeRotateMatrix(30.0f, point, &matrix);
1420 ID2D1RenderTarget_SetTransform(rt, &matrix);
1421 set_rect(&rect, 215.0f, 208.0f, 425.0f, 272.0f);
1422 ID2D1RenderTarget_PushAxisAlignedClip(rt, &rect, D2D1_ANTIALIAS_MODE_ALIASED);
1423 set_color(&color, 1.0f, 1.0f, 1.0f, 1.0f);
1424 ID2D1RenderTarget_Clear(rt, &color);
1425 ID2D1RenderTarget_PopAxisAlignedClip(rt);
1427 /* Transformations are applied when pushing the clip rect, transformations
1428 * set afterwards have no effect on the current clip rect. This includes
1429 * SetDpi(). */
1430 ID2D1RenderTarget_SetTransform(rt, &identity);
1431 set_rect(&rect, 427.0f, 320.0f, 640.0f, 480.0f);
1432 ID2D1RenderTarget_PushAxisAlignedClip(rt, &rect, D2D1_ANTIALIAS_MODE_ALIASED);
1433 ID2D1RenderTarget_SetTransform(rt, &matrix);
1434 ID2D1RenderTarget_SetDpi(rt, 48.0f, 192.0f);
1435 set_color(&color, 1.0f, 0.0f, 0.0f, 1.0f);
1436 ID2D1RenderTarget_Clear(rt, &color);
1437 ID2D1RenderTarget_PopAxisAlignedClip(rt);
1439 hr = ID2D1RenderTarget_EndDraw(rt, NULL, NULL);
1440 ok(SUCCEEDED(hr), "Failed to end draw, hr %#x.\n", hr);
1441 match = compare_surface(&ctx, "035a44d4198d6e422e9de6185b5b2c2bac5e33c9");
1442 ok(match, "Surface does not match.\n");
1444 /* Fractional clip rectangle coordinates, aliased mode. */
1445 set_matrix_identity(&matrix);
1446 ID2D1RenderTarget_SetTransform(rt, &matrix);
1447 ID2D1RenderTarget_SetDpi(rt, 96.0f, 96.0f);
1449 ID2D1RenderTarget_BeginDraw(rt);
1451 set_color(&color, 0.0f, 0.0f, 0.0f, 1.0f);
1452 ID2D1RenderTarget_Clear(rt, &color);
1454 scale_matrix(&matrix, 2.0f, 2.0f);
1455 ID2D1RenderTarget_SetTransform(rt, &matrix);
1456 set_rect(&rect, 0.0f, 0.5f, 200.0f, 100.5f);
1457 set_color(&color, 1.0f, 0.0f, 1.0f, 1.0f);
1458 ID2D1RenderTarget_PushAxisAlignedClip(rt, &rect, D2D1_ANTIALIAS_MODE_ALIASED);
1459 ID2D1RenderTarget_Clear(rt, &color);
1460 ID2D1RenderTarget_PopAxisAlignedClip(rt);
1462 set_matrix_identity(&matrix);
1463 ID2D1RenderTarget_SetTransform(rt, &matrix);
1464 set_rect(&rect, 0.0f, 0.5f, 100.0f, 200.5f);
1465 set_color(&color, 1.0f, 0.0f, 0.0f, 1.0f);
1466 ID2D1RenderTarget_PushAxisAlignedClip(rt, &rect, D2D1_ANTIALIAS_MODE_ALIASED);
1467 ID2D1RenderTarget_Clear(rt, &color);
1468 ID2D1RenderTarget_PopAxisAlignedClip(rt);
1470 ID2D1RenderTarget_SetTransform(rt, &matrix);
1471 set_rect(&rect, 0.5f, 250.0f, 100.5f, 300.0f);
1472 set_color(&color, 1.0f, 1.0f, 0.0f, 1.0f);
1473 ID2D1RenderTarget_PushAxisAlignedClip(rt, &rect, D2D1_ANTIALIAS_MODE_ALIASED);
1474 ID2D1RenderTarget_Clear(rt, &color);
1475 ID2D1RenderTarget_PopAxisAlignedClip(rt);
1477 translate_matrix(&matrix, 0.1f, 0.0f);
1478 ID2D1RenderTarget_SetTransform(rt, &matrix);
1479 set_rect(&rect, 110.0f, 250.25f, 150.0f, 300.25f);
1480 set_color(&color, 0.0f, 1.0f, 0.0f, 1.0f);
1481 ID2D1RenderTarget_PushAxisAlignedClip(rt, &rect, D2D1_ANTIALIAS_MODE_ALIASED);
1482 ID2D1RenderTarget_Clear(rt, &color);
1483 ID2D1RenderTarget_PopAxisAlignedClip(rt);
1485 set_rect(&rect, 160.0f, 250.75f, 200.0f, 300.75f);
1486 set_color(&color, 0.0f, 0.0f, 1.0f, 1.0f);
1487 ID2D1RenderTarget_PushAxisAlignedClip(rt, &rect, D2D1_ANTIALIAS_MODE_ALIASED);
1488 ID2D1RenderTarget_Clear(rt, &color);
1489 ID2D1RenderTarget_PopAxisAlignedClip(rt);
1491 ID2D1RenderTarget_SetDpi(rt, 48.0f, 192.0f);
1492 set_rect(&rect, 160.25f, 0.0f, 200.25f, 100.0f);
1493 set_color(&color, 1.0f, 0.0f, 1.0f, 1.0f);
1494 ID2D1RenderTarget_PushAxisAlignedClip(rt, &rect, D2D1_ANTIALIAS_MODE_ALIASED);
1495 ID2D1RenderTarget_Clear(rt, &color);
1496 ID2D1RenderTarget_PopAxisAlignedClip(rt);
1498 ID2D1RenderTarget_SetDpi(rt, 192.0f, 48.0f);
1499 set_rect(&rect, 160.75f, 100.0f, 200.75f, 120.0f);
1500 set_color(&color, 0.0f, 1.0f, 1.0f, 1.0f);
1501 ID2D1RenderTarget_PushAxisAlignedClip(rt, &rect, D2D1_ANTIALIAS_MODE_ALIASED);
1502 ID2D1RenderTarget_Clear(rt, &color);
1503 ID2D1RenderTarget_PopAxisAlignedClip(rt);
1505 hr = ID2D1RenderTarget_EndDraw(rt, NULL, NULL);
1506 ok(SUCCEEDED(hr), "Failed to end draw, hr %#x.\n", hr);
1507 match = compare_surface(&ctx, "cb418ec4a7c8407b5e36db06fc6292a06bb8476c");
1508 ok(match, "Surface does not match.\n");
1510 release_test_context(&ctx);
1513 static void test_state_block(BOOL d3d11)
1515 IDWriteRenderingParams *text_rendering_params1, *text_rendering_params2;
1516 D2D1_DRAWING_STATE_DESCRIPTION drawing_state;
1517 ID2D1DrawingStateBlock *state_block;
1518 IDWriteFactory *dwrite_factory;
1519 struct d2d1_test_context ctx;
1520 ID2D1Factory1 *factory1;
1521 ID2D1RenderTarget *rt;
1522 ID2D1Factory *factory;
1523 ULONG refcount;
1524 HRESULT hr;
1525 static const D2D1_MATRIX_3X2_F identity =
1527 1.0f, 0.0f,
1528 0.0f, 1.0f,
1529 0.0f, 0.0f,
1530 }}};
1531 static const D2D1_MATRIX_3X2_F transform1 =
1533 1.0f, 2.0f,
1534 3.0f, 4.0f,
1535 5.0f, 6.0f,
1536 }}};
1537 static const D2D1_MATRIX_3X2_F transform2 =
1539 7.0f, 8.0f,
1540 9.0f, 10.0f,
1541 11.0f, 12.0f,
1542 }}};
1544 if (!init_test_context(&ctx, d3d11))
1545 return;
1547 rt = ctx.rt;
1548 ID2D1RenderTarget_GetFactory(rt, &factory);
1549 hr = DWriteCreateFactory(DWRITE_FACTORY_TYPE_SHARED, &IID_IDWriteFactory, (IUnknown **)&dwrite_factory);
1550 ok(SUCCEEDED(hr), "Failed to create dwrite factory, hr %#x.\n", hr);
1551 hr = IDWriteFactory_CreateRenderingParams(dwrite_factory, &text_rendering_params1);
1552 ok(SUCCEEDED(hr), "Failed to create dwrite rendering params, hr %#x.\n", hr);
1553 IDWriteFactory_Release(dwrite_factory);
1555 drawing_state.antialiasMode = ID2D1RenderTarget_GetAntialiasMode(rt);
1556 ok(drawing_state.antialiasMode == D2D1_ANTIALIAS_MODE_PER_PRIMITIVE,
1557 "Got unexpected antialias mode %#x.\n", drawing_state.antialiasMode);
1558 drawing_state.textAntialiasMode = ID2D1RenderTarget_GetTextAntialiasMode(rt);
1559 ok(drawing_state.textAntialiasMode == D2D1_TEXT_ANTIALIAS_MODE_DEFAULT,
1560 "Got unexpected text antialias mode %#x.\n", drawing_state.textAntialiasMode);
1561 ID2D1RenderTarget_GetTags(rt, &drawing_state.tag1, &drawing_state.tag2);
1562 ok(!drawing_state.tag1 && !drawing_state.tag2, "Got unexpected tags %s:%s.\n",
1563 wine_dbgstr_longlong(drawing_state.tag1), wine_dbgstr_longlong(drawing_state.tag2));
1564 ID2D1RenderTarget_GetTransform(rt, &drawing_state.transform);
1565 ok(!memcmp(&drawing_state.transform, &identity, sizeof(drawing_state.transform)),
1566 "Got unexpected matrix {%.8e, %.8e, %.8e, %.8e, %.8e, %.8e}.\n",
1567 drawing_state.transform._11, drawing_state.transform._12, drawing_state.transform._21,
1568 drawing_state.transform._22, drawing_state.transform._31, drawing_state.transform._32);
1569 ID2D1RenderTarget_GetTextRenderingParams(rt, &text_rendering_params2);
1570 ok(!text_rendering_params2, "Got unexpected text rendering params %p.\n", text_rendering_params2);
1572 hr = ID2D1Factory_CreateDrawingStateBlock(factory, NULL, NULL, &state_block);
1573 ok(SUCCEEDED(hr), "Failed to create drawing state block, hr %#x\n", hr);
1574 ID2D1DrawingStateBlock_GetDescription(state_block, &drawing_state);
1575 ok(drawing_state.antialiasMode == D2D1_ANTIALIAS_MODE_PER_PRIMITIVE,
1576 "Got unexpected antialias mode %#x.\n", drawing_state.antialiasMode);
1577 ok(drawing_state.textAntialiasMode == D2D1_TEXT_ANTIALIAS_MODE_DEFAULT,
1578 "Got unexpected text antialias mode %#x.\n", drawing_state.textAntialiasMode);
1579 ok(!drawing_state.tag1 && !drawing_state.tag2, "Got unexpected tags %s:%s.\n",
1580 wine_dbgstr_longlong(drawing_state.tag1), wine_dbgstr_longlong(drawing_state.tag2));
1581 ok(!memcmp(&drawing_state.transform, &identity, sizeof(drawing_state.transform)),
1582 "Got unexpected matrix {%.8e, %.8e, %.8e, %.8e, %.8e, %.8e}.\n",
1583 drawing_state.transform._11, drawing_state.transform._12, drawing_state.transform._21,
1584 drawing_state.transform._22, drawing_state.transform._31, drawing_state.transform._32);
1585 ID2D1DrawingStateBlock_GetTextRenderingParams(state_block, &text_rendering_params2);
1586 ok(!text_rendering_params2, "Got unexpected text rendering params %p.\n", text_rendering_params2);
1587 ID2D1DrawingStateBlock_Release(state_block);
1589 drawing_state.antialiasMode = D2D1_ANTIALIAS_MODE_ALIASED;
1590 drawing_state.textAntialiasMode = D2D1_TEXT_ANTIALIAS_MODE_ALIASED;
1591 drawing_state.tag1 = 0xdead;
1592 drawing_state.tag2 = 0xbeef;
1593 drawing_state.transform = transform1;
1594 hr = ID2D1Factory_CreateDrawingStateBlock(factory, &drawing_state, text_rendering_params1, &state_block);
1595 ok(SUCCEEDED(hr), "Failed to create drawing state block, hr %#x\n", hr);
1597 ID2D1DrawingStateBlock_GetDescription(state_block, &drawing_state);
1598 ok(drawing_state.antialiasMode == D2D1_ANTIALIAS_MODE_ALIASED,
1599 "Got unexpected antialias mode %#x.\n", drawing_state.antialiasMode);
1600 ok(drawing_state.textAntialiasMode == D2D1_TEXT_ANTIALIAS_MODE_ALIASED,
1601 "Got unexpected text antialias mode %#x.\n", drawing_state.textAntialiasMode);
1602 ok(drawing_state.tag1 == 0xdead && drawing_state.tag2 == 0xbeef, "Got unexpected tags %s:%s.\n",
1603 wine_dbgstr_longlong(drawing_state.tag1), wine_dbgstr_longlong(drawing_state.tag2));
1604 ok(!memcmp(&drawing_state.transform, &transform1, sizeof(drawing_state.transform)),
1605 "Got unexpected matrix {%.8e, %.8e, %.8e, %.8e, %.8e, %.8e}.\n",
1606 drawing_state.transform._11, drawing_state.transform._12, drawing_state.transform._21,
1607 drawing_state.transform._22, drawing_state.transform._31, drawing_state.transform._32);
1608 ID2D1DrawingStateBlock_GetTextRenderingParams(state_block, &text_rendering_params2);
1609 ok(text_rendering_params2 == text_rendering_params1, "Got unexpected text rendering params %p, expected %p.\n",
1610 text_rendering_params2, text_rendering_params1);
1611 IDWriteRenderingParams_Release(text_rendering_params2);
1613 ID2D1RenderTarget_RestoreDrawingState(rt, state_block);
1615 drawing_state.antialiasMode = ID2D1RenderTarget_GetAntialiasMode(rt);
1616 ok(drawing_state.antialiasMode == D2D1_ANTIALIAS_MODE_ALIASED,
1617 "Got unexpected antialias mode %#x.\n", drawing_state.antialiasMode);
1618 drawing_state.textAntialiasMode = ID2D1RenderTarget_GetTextAntialiasMode(rt);
1619 ok(drawing_state.textAntialiasMode == D2D1_TEXT_ANTIALIAS_MODE_ALIASED,
1620 "Got unexpected text antialias mode %#x.\n", drawing_state.textAntialiasMode);
1621 ID2D1RenderTarget_GetTags(rt, &drawing_state.tag1, &drawing_state.tag2);
1622 ok(drawing_state.tag1 == 0xdead && drawing_state.tag2 == 0xbeef, "Got unexpected tags %s:%s.\n",
1623 wine_dbgstr_longlong(drawing_state.tag1), wine_dbgstr_longlong(drawing_state.tag2));
1624 ID2D1RenderTarget_GetTransform(rt, &drawing_state.transform);
1625 ok(!memcmp(&drawing_state.transform, &transform1, sizeof(drawing_state.transform)),
1626 "Got unexpected matrix {%.8e, %.8e, %.8e, %.8e, %.8e, %.8e}.\n",
1627 drawing_state.transform._11, drawing_state.transform._12, drawing_state.transform._21,
1628 drawing_state.transform._22, drawing_state.transform._31, drawing_state.transform._32);
1629 ID2D1RenderTarget_GetTextRenderingParams(rt, &text_rendering_params2);
1630 ok(text_rendering_params2 == text_rendering_params1, "Got unexpected text rendering params %p, expected %p.\n",
1631 text_rendering_params2, text_rendering_params1);
1632 IDWriteRenderingParams_Release(text_rendering_params2);
1634 ID2D1RenderTarget_SetAntialiasMode(rt, D2D1_ANTIALIAS_MODE_PER_PRIMITIVE);
1635 ID2D1RenderTarget_SetTextAntialiasMode(rt, D2D1_TEXT_ANTIALIAS_MODE_GRAYSCALE);
1636 ID2D1RenderTarget_SetTags(rt, 1, 2);
1637 ID2D1RenderTarget_SetTransform(rt, &transform2);
1638 ID2D1RenderTarget_SetTextRenderingParams(rt, NULL);
1640 drawing_state.antialiasMode = ID2D1RenderTarget_GetAntialiasMode(rt);
1641 ok(drawing_state.antialiasMode == D2D1_ANTIALIAS_MODE_PER_PRIMITIVE,
1642 "Got unexpected antialias mode %#x.\n", drawing_state.antialiasMode);
1643 drawing_state.textAntialiasMode = ID2D1RenderTarget_GetTextAntialiasMode(rt);
1644 ok(drawing_state.textAntialiasMode == D2D1_TEXT_ANTIALIAS_MODE_GRAYSCALE,
1645 "Got unexpected text antialias mode %#x.\n", drawing_state.textAntialiasMode);
1646 ID2D1RenderTarget_GetTags(rt, &drawing_state.tag1, &drawing_state.tag2);
1647 ok(drawing_state.tag1 == 1 && drawing_state.tag2 == 2, "Got unexpected tags %s:%s.\n",
1648 wine_dbgstr_longlong(drawing_state.tag1), wine_dbgstr_longlong(drawing_state.tag2));
1649 ID2D1RenderTarget_GetTransform(rt, &drawing_state.transform);
1650 ok(!memcmp(&drawing_state.transform, &transform2, sizeof(drawing_state.transform)),
1651 "Got unexpected matrix {%.8e, %.8e, %.8e, %.8e, %.8e, %.8e}.\n",
1652 drawing_state.transform._11, drawing_state.transform._12, drawing_state.transform._21,
1653 drawing_state.transform._22, drawing_state.transform._31, drawing_state.transform._32);
1654 ID2D1RenderTarget_GetTextRenderingParams(rt, &text_rendering_params2);
1655 ok(!text_rendering_params2, "Got unexpected text rendering params %p.\n", text_rendering_params2);
1657 ID2D1RenderTarget_SaveDrawingState(rt, state_block);
1659 ID2D1DrawingStateBlock_GetDescription(state_block, &drawing_state);
1660 ok(drawing_state.antialiasMode == D2D1_ANTIALIAS_MODE_PER_PRIMITIVE,
1661 "Got unexpected antialias mode %#x.\n", drawing_state.antialiasMode);
1662 ok(drawing_state.textAntialiasMode == D2D1_TEXT_ANTIALIAS_MODE_GRAYSCALE,
1663 "Got unexpected text antialias mode %#x.\n", drawing_state.textAntialiasMode);
1664 ok(drawing_state.tag1 == 1 && drawing_state.tag2 == 2, "Got unexpected tags %s:%s.\n",
1665 wine_dbgstr_longlong(drawing_state.tag1), wine_dbgstr_longlong(drawing_state.tag2));
1666 ok(!memcmp(&drawing_state.transform, &transform2, sizeof(drawing_state.transform)),
1667 "Got unexpected matrix {%.8e, %.8e, %.8e, %.8e, %.8e, %.8e}.\n",
1668 drawing_state.transform._11, drawing_state.transform._12, drawing_state.transform._21,
1669 drawing_state.transform._22, drawing_state.transform._31, drawing_state.transform._32);
1670 ID2D1DrawingStateBlock_GetTextRenderingParams(state_block, &text_rendering_params2);
1671 ok(!text_rendering_params2, "Got unexpected text rendering params %p.\n", text_rendering_params2);
1673 drawing_state.antialiasMode = D2D1_ANTIALIAS_MODE_ALIASED;
1674 drawing_state.textAntialiasMode = D2D1_TEXT_ANTIALIAS_MODE_CLEARTYPE;
1675 drawing_state.tag1 = 3;
1676 drawing_state.tag2 = 4;
1677 drawing_state.transform = transform1;
1678 ID2D1DrawingStateBlock_SetDescription(state_block, &drawing_state);
1679 ID2D1DrawingStateBlock_SetTextRenderingParams(state_block, text_rendering_params1);
1681 ID2D1DrawingStateBlock_GetDescription(state_block, &drawing_state);
1682 ok(drawing_state.antialiasMode == D2D1_ANTIALIAS_MODE_ALIASED,
1683 "Got unexpected antialias mode %#x.\n", drawing_state.antialiasMode);
1684 ok(drawing_state.textAntialiasMode == D2D1_TEXT_ANTIALIAS_MODE_CLEARTYPE,
1685 "Got unexpected text antialias mode %#x.\n", drawing_state.textAntialiasMode);
1686 ok(drawing_state.tag1 == 3 && drawing_state.tag2 == 4, "Got unexpected tags %s:%s.\n",
1687 wine_dbgstr_longlong(drawing_state.tag1), wine_dbgstr_longlong(drawing_state.tag2));
1688 ok(!memcmp(&drawing_state.transform, &transform1, sizeof(drawing_state.transform)),
1689 "Got unexpected matrix {%.8e, %.8e, %.8e, %.8e, %.8e, %.8e}.\n",
1690 drawing_state.transform._11, drawing_state.transform._12, drawing_state.transform._21,
1691 drawing_state.transform._22, drawing_state.transform._31, drawing_state.transform._32);
1692 ID2D1DrawingStateBlock_GetTextRenderingParams(state_block, &text_rendering_params2);
1693 ok(text_rendering_params2 == text_rendering_params1, "Got unexpected text rendering params %p, expected %p.\n",
1694 text_rendering_params2, text_rendering_params1);
1695 IDWriteRenderingParams_Release(text_rendering_params2);
1697 if (SUCCEEDED(ID2D1Factory_QueryInterface(factory, &IID_ID2D1Factory1, (void **)&factory1)))
1699 D2D1_DRAWING_STATE_DESCRIPTION1 drawing_state1;
1700 ID2D1DrawingStateBlock1 *state_block1;
1702 hr = ID2D1DrawingStateBlock_QueryInterface(state_block, &IID_ID2D1DrawingStateBlock1, (void **)&state_block1);
1703 ok(SUCCEEDED(hr), "Failed to get ID2D1DrawingStateBlock1 interface, hr %#x.\n", hr);
1705 ID2D1DrawingStateBlock1_GetDescription(state_block1, &drawing_state1);
1706 ok(drawing_state1.antialiasMode == D2D1_ANTIALIAS_MODE_ALIASED,
1707 "Got unexpected antialias mode %#x.\n", drawing_state1.antialiasMode);
1708 ok(drawing_state1.textAntialiasMode == D2D1_TEXT_ANTIALIAS_MODE_CLEARTYPE,
1709 "Got unexpected text antialias mode %#x.\n", drawing_state1.textAntialiasMode);
1710 ok(drawing_state1.tag1 == 3 && drawing_state1.tag2 == 4, "Got unexpected tags %s:%s.\n",
1711 wine_dbgstr_longlong(drawing_state1.tag1), wine_dbgstr_longlong(drawing_state1.tag2));
1712 ok(!memcmp(&drawing_state1.transform, &transform1, sizeof(drawing_state1.transform)),
1713 "Got unexpected matrix {%.8e, %.8e, %.8e, %.8e, %.8e, %.8e}.\n",
1714 drawing_state1.transform._11, drawing_state1.transform._12, drawing_state1.transform._21,
1715 drawing_state1.transform._22, drawing_state1.transform._31, drawing_state1.transform._32);
1716 ok(drawing_state1.primitiveBlend == D2D1_PRIMITIVE_BLEND_SOURCE_OVER,
1717 "Got unexpected primitive blend mode %#x.\n", drawing_state1.primitiveBlend);
1718 ok(drawing_state1.unitMode == D2D1_UNIT_MODE_DIPS, "Got unexpected unit mode %#x.\n", drawing_state1.unitMode);
1719 ID2D1DrawingStateBlock1_GetTextRenderingParams(state_block1, &text_rendering_params2);
1720 ok(text_rendering_params2 == text_rendering_params1, "Got unexpected text rendering params %p, expected %p.\n",
1721 text_rendering_params2, text_rendering_params1);
1722 IDWriteRenderingParams_Release(text_rendering_params2);
1724 drawing_state1.primitiveBlend = D2D1_PRIMITIVE_BLEND_COPY;
1725 drawing_state1.unitMode = D2D1_UNIT_MODE_PIXELS;
1726 ID2D1DrawingStateBlock1_SetDescription(state_block1, &drawing_state1);
1727 ID2D1DrawingStateBlock1_GetDescription(state_block1, &drawing_state1);
1728 ok(drawing_state1.primitiveBlend == D2D1_PRIMITIVE_BLEND_COPY,
1729 "Got unexpected primitive blend mode %#x.\n", drawing_state1.primitiveBlend);
1730 ok(drawing_state1.unitMode == D2D1_UNIT_MODE_PIXELS,
1731 "Got unexpected unit mode %#x.\n", drawing_state1.unitMode);
1733 ID2D1DrawingStateBlock_SetDescription(state_block, &drawing_state);
1734 ID2D1DrawingStateBlock1_GetDescription(state_block1, &drawing_state1);
1735 ok(drawing_state1.primitiveBlend == D2D1_PRIMITIVE_BLEND_COPY,
1736 "Got unexpected primitive blend mode %#x.\n", drawing_state1.primitiveBlend);
1737 ok(drawing_state1.unitMode == D2D1_UNIT_MODE_PIXELS,
1738 "Got unexpected unit mode %#x.\n", drawing_state1.unitMode);
1740 ID2D1DrawingStateBlock1_Release(state_block1);
1742 hr = ID2D1Factory1_CreateDrawingStateBlock(factory1, NULL, NULL, &state_block1);
1743 ok(SUCCEEDED(hr), "Failed to create drawing state block, hr %#x\n", hr);
1744 ID2D1DrawingStateBlock1_GetDescription(state_block1, &drawing_state1);
1745 ok(drawing_state1.antialiasMode == D2D1_ANTIALIAS_MODE_PER_PRIMITIVE,
1746 "Got unexpected antialias mode %#x.\n", drawing_state1.antialiasMode);
1747 ok(drawing_state1.textAntialiasMode == D2D1_TEXT_ANTIALIAS_MODE_DEFAULT,
1748 "Got unexpected text antialias mode %#x.\n", drawing_state1.textAntialiasMode);
1749 ok(drawing_state1.tag1 == 0 && drawing_state1.tag2 == 0, "Got unexpected tags %s:%s.\n",
1750 wine_dbgstr_longlong(drawing_state1.tag1), wine_dbgstr_longlong(drawing_state1.tag2));
1751 ok(!memcmp(&drawing_state1.transform, &identity, sizeof(drawing_state1.transform)),
1752 "Got unexpected matrix {%.8e, %.8e, %.8e, %.8e, %.8e, %.8e}.\n",
1753 drawing_state1.transform._11, drawing_state1.transform._12, drawing_state1.transform._21,
1754 drawing_state1.transform._22, drawing_state1.transform._31, drawing_state1.transform._32);
1755 ok(drawing_state1.primitiveBlend == D2D1_PRIMITIVE_BLEND_SOURCE_OVER,
1756 "Got unexpected primitive blend mode %#x.\n", drawing_state1.primitiveBlend);
1757 ok(drawing_state1.unitMode == D2D1_UNIT_MODE_DIPS, "Got unexpected unit mode %#x.\n", drawing_state1.unitMode);
1758 ID2D1DrawingStateBlock1_GetTextRenderingParams(state_block1, &text_rendering_params2);
1759 ok(!text_rendering_params2, "Got unexpected text rendering params %p.\n", text_rendering_params2);
1760 ID2D1DrawingStateBlock1_Release(state_block1);
1762 ID2D1Factory1_Release(factory1);
1765 ID2D1DrawingStateBlock_Release(state_block);
1767 refcount = IDWriteRenderingParams_Release(text_rendering_params1);
1768 ok(!refcount, "Rendering params %u references left.\n", refcount);
1769 ID2D1Factory_Release(factory);
1770 release_test_context(&ctx);
1773 static void test_color_brush(BOOL d3d11)
1775 D2D1_MATRIX_3X2_F matrix, tmp_matrix;
1776 D2D1_BRUSH_PROPERTIES brush_desc;
1777 D2D1_COLOR_F color, tmp_color;
1778 struct d2d1_test_context ctx;
1779 ID2D1SolidColorBrush *brush;
1780 ID2D1RenderTarget *rt;
1781 D2D1_RECT_F rect;
1782 float opacity;
1783 HRESULT hr;
1784 BOOL match;
1786 if (!init_test_context(&ctx, d3d11))
1787 return;
1789 rt = ctx.rt;
1790 ID2D1RenderTarget_SetDpi(rt, 192.0f, 48.0f);
1791 ID2D1RenderTarget_SetAntialiasMode(rt, D2D1_ANTIALIAS_MODE_ALIASED);
1793 set_color(&color, 0.0f, 0.0f, 0.0f, 0.0f);
1794 hr = ID2D1RenderTarget_CreateSolidColorBrush(rt, &color, NULL, &brush);
1795 ok(SUCCEEDED(hr), "Failed to create brush, hr %#x.\n", hr);
1796 opacity = ID2D1SolidColorBrush_GetOpacity(brush);
1797 ok(opacity == 1.0f, "Got unexpected opacity %.8e.\n", opacity);
1798 set_matrix_identity(&matrix);
1799 ID2D1SolidColorBrush_GetTransform(brush, &tmp_matrix);
1800 ok(!memcmp(&tmp_matrix, &matrix, sizeof(matrix)),
1801 "Got unexpected matrix {%.8e, %.8e, %.8e, %.8e, %.8e, %.8e}.\n",
1802 tmp_matrix._11, tmp_matrix._12, tmp_matrix._21,
1803 tmp_matrix._22, tmp_matrix._31, tmp_matrix._32);
1804 tmp_color = ID2D1SolidColorBrush_GetColor(brush);
1805 ok(!memcmp(&tmp_color, &color, sizeof(color)),
1806 "Got unexpected color {%.8e, %.8e, %.8e, %.8e}.\n",
1807 tmp_color.r, tmp_color.g, tmp_color.b, tmp_color.a);
1808 ID2D1SolidColorBrush_Release(brush);
1810 set_color(&color, 0.0f, 1.0f, 0.0f, 0.8f);
1811 brush_desc.opacity = 0.3f;
1812 set_matrix_identity(&matrix);
1813 scale_matrix(&matrix, 2.0f, 2.0f);
1814 brush_desc.transform = matrix;
1815 hr = ID2D1RenderTarget_CreateSolidColorBrush(rt, &color, &brush_desc, &brush);
1816 ok(SUCCEEDED(hr), "Failed to create brush, hr %#x.\n", hr);
1817 opacity = ID2D1SolidColorBrush_GetOpacity(brush);
1818 ok(opacity == 0.3f, "Got unexpected opacity %.8e.\n", opacity);
1819 ID2D1SolidColorBrush_GetTransform(brush, &tmp_matrix);
1820 ok(!memcmp(&tmp_matrix, &matrix, sizeof(matrix)),
1821 "Got unexpected matrix {%.8e, %.8e, %.8e, %.8e, %.8e, %.8e}.\n",
1822 tmp_matrix._11, tmp_matrix._12, tmp_matrix._21,
1823 tmp_matrix._22, tmp_matrix._31, tmp_matrix._32);
1824 tmp_color = ID2D1SolidColorBrush_GetColor(brush);
1825 ok(!memcmp(&tmp_color, &color, sizeof(color)),
1826 "Got unexpected color {%.8e, %.8e, %.8e, %.8e}.\n",
1827 tmp_color.r, tmp_color.g, tmp_color.b, tmp_color.a);
1829 ID2D1RenderTarget_BeginDraw(rt);
1831 set_color(&color, 0.0f, 0.0f, 1.0f, 1.0f);
1832 ID2D1RenderTarget_Clear(rt, &color);
1834 ID2D1SolidColorBrush_SetOpacity(brush, 1.0f);
1835 set_rect(&rect, 40.0f, 120.0f, 120.0f, 360.0f);
1836 ID2D1RenderTarget_FillRectangle(rt, &rect, (ID2D1Brush *)brush);
1838 set_matrix_identity(&matrix);
1839 scale_matrix(&matrix, 0.5f, 2.0f);
1840 translate_matrix(&matrix, 320.0f, 240.0f);
1841 rotate_matrix(&matrix, M_PI / 4.0f);
1842 ID2D1RenderTarget_SetTransform(rt, &matrix);
1843 set_color(&color, 1.0f, 0.0f, 0.0f, 0.625f);
1844 ID2D1SolidColorBrush_SetColor(brush, &color);
1845 ID2D1SolidColorBrush_SetOpacity(brush, 0.75f);
1846 set_rect(&rect, -80.0f, -60.0f, 80.0f, 60.0f);
1847 ID2D1RenderTarget_FillRectangle(rt, &rect, (ID2D1Brush *)brush);
1849 hr = ID2D1RenderTarget_EndDraw(rt, NULL, NULL);
1850 ok(SUCCEEDED(hr), "Failed to end draw, hr %#x.\n", hr);
1851 match = compare_surface(&ctx, "6d1218fca5e21fb7e287b3a439d60dbc251f5ceb");
1852 ok(match, "Surface does not match.\n");
1854 ID2D1SolidColorBrush_Release(brush);
1855 release_test_context(&ctx);
1858 static void test_bitmap_brush(BOOL d3d11)
1860 D2D1_BITMAP_INTERPOLATION_MODE interpolation_mode;
1861 ID2D1TransformedGeometry *transformed_geometry;
1862 ID2D1RectangleGeometry *rectangle_geometry;
1863 D2D1_MATRIX_3X2_F matrix, tmp_matrix;
1864 D2D1_BITMAP_PROPERTIES bitmap_desc;
1865 ID2D1Bitmap *bitmap, *tmp_bitmap;
1866 D2D1_RECT_F src_rect, dst_rect;
1867 struct d2d1_test_context ctx;
1868 D2D1_EXTEND_MODE extend_mode;
1869 ID2D1BitmapBrush1 *brush1;
1870 ID2D1BitmapBrush *brush;
1871 D2D1_SIZE_F image_size;
1872 ID2D1RenderTarget *rt;
1873 ID2D1Factory *factory;
1874 D2D1_COLOR_F color;
1875 ID2D1Image *image;
1876 D2D1_SIZE_U size;
1877 unsigned int i;
1878 ULONG refcount;
1879 float opacity;
1880 HRESULT hr;
1881 BOOL match;
1883 static const struct
1885 D2D1_EXTEND_MODE extend_mode_x;
1886 D2D1_EXTEND_MODE extend_mode_y;
1887 float translate_x;
1888 float translate_y;
1889 D2D1_RECT_F rect;
1891 extend_mode_tests[] =
1893 {D2D1_EXTEND_MODE_MIRROR, D2D1_EXTEND_MODE_MIRROR, -7.0f, 1.0f, {-4.0f, 0.0f, -8.0f, 4.0f}},
1894 {D2D1_EXTEND_MODE_WRAP, D2D1_EXTEND_MODE_MIRROR, -3.0f, 1.0f, {-4.0f, 4.0f, 0.0f, 0.0f}},
1895 {D2D1_EXTEND_MODE_CLAMP, D2D1_EXTEND_MODE_MIRROR, 1.0f, 1.0f, { 4.0f, 0.0f, 0.0f, 4.0f}},
1896 {D2D1_EXTEND_MODE_MIRROR, D2D1_EXTEND_MODE_WRAP, -7.0f, 5.0f, {-8.0f, 8.0f, -4.0f, 4.0f}},
1897 {D2D1_EXTEND_MODE_WRAP, D2D1_EXTEND_MODE_WRAP, -3.0f, 5.0f, { 0.0f, 4.0f, -4.0f, 8.0f}},
1898 {D2D1_EXTEND_MODE_CLAMP, D2D1_EXTEND_MODE_WRAP, 1.0f, 5.0f, { 0.0f, 8.0f, 4.0f, 4.0f}},
1899 {D2D1_EXTEND_MODE_MIRROR, D2D1_EXTEND_MODE_CLAMP, -7.0f, 9.0f, {-4.0f, 8.0f, -8.0f, 12.0f}},
1900 {D2D1_EXTEND_MODE_WRAP, D2D1_EXTEND_MODE_CLAMP, -3.0f, 9.0f, {-4.0f, 12.0f, 0.0f, 8.0f}},
1901 {D2D1_EXTEND_MODE_CLAMP, D2D1_EXTEND_MODE_CLAMP, 1.0f, 9.0f, { 4.0f, 8.0f, 0.0f, 12.0f}},
1903 static const DWORD bitmap_data[] =
1905 0xffff0000, 0xffffff00, 0xff00ff00, 0xff00ffff,
1906 0xff0000ff, 0xffff00ff, 0xff000000, 0xff7f7f7f,
1907 0xffffffff, 0xffffffff, 0xffffffff, 0xff000000,
1908 0xffffffff, 0xff000000, 0xff000000, 0xff000000,
1911 if (!init_test_context(&ctx, d3d11))
1912 return;
1914 rt = ctx.rt;
1915 ID2D1RenderTarget_SetDpi(rt, 192.0f, 48.0f);
1916 ID2D1RenderTarget_SetAntialiasMode(rt, D2D1_ANTIALIAS_MODE_ALIASED);
1918 set_size_u(&size, 4, 4);
1919 bitmap_desc.pixelFormat.format = DXGI_FORMAT_B8G8R8A8_UNORM;
1920 bitmap_desc.pixelFormat.alphaMode = D2D1_ALPHA_MODE_IGNORE;
1921 bitmap_desc.dpiX = 96.0f;
1922 bitmap_desc.dpiY = 96.0f;
1923 hr = ID2D1RenderTarget_CreateBitmap(rt, size, bitmap_data, 4 * sizeof(*bitmap_data), &bitmap_desc, &bitmap);
1924 ok(SUCCEEDED(hr), "Failed to create bitmap, hr %#x.\n", hr);
1925 image_size = ID2D1Bitmap_GetSize(bitmap);
1927 hr = ID2D1Bitmap_QueryInterface(bitmap, &IID_ID2D1Image, (void **)&image);
1928 ok(SUCCEEDED(hr) || broken(hr == E_NOINTERFACE) /* Vista */, "Failed to get ID2D1Image, hr %#x.\n", hr);
1929 if (hr == S_OK)
1931 ID2D1DeviceContext *context;
1932 D2D1_POINT_2F offset;
1933 D2D1_RECT_F src_rect;
1935 hr = ID2D1RenderTarget_QueryInterface(rt, &IID_ID2D1DeviceContext, (void **)&context);
1936 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1938 ID2D1RenderTarget_BeginDraw(rt);
1939 set_color(&color, 0.0f, 0.0f, 1.0f, 1.0f);
1940 ID2D1RenderTarget_Clear(rt, &color);
1942 ID2D1RenderTarget_GetTransform(rt, &tmp_matrix);
1943 set_matrix_identity(&matrix);
1944 translate_matrix(&matrix, 20.0f, 12.0f);
1945 scale_matrix(&matrix, 2.0f, 6.0f);
1946 ID2D1RenderTarget_SetTransform(rt, &matrix);
1948 /* Crash on Windows 7+ */
1949 if (0)
1951 ID2D1DeviceContext_DrawImage(context, NULL, NULL, NULL, D2D1_BITMAP_INTERPOLATION_MODE_NEAREST_NEIGHBOR,
1952 D2D1_COMPOSITE_MODE_SOURCE_OVER);
1955 ID2D1DeviceContext_DrawImage(context, image, NULL, NULL, D2D1_BITMAP_INTERPOLATION_MODE_NEAREST_NEIGHBOR,
1956 D2D1_COMPOSITE_MODE_SOURCE_OVER);
1958 set_rect(&src_rect, 0.0f, 0.0f, image_size.width, image_size.height);
1960 ID2D1DeviceContext_DrawImage(context, image, NULL, &src_rect, D2D1_BITMAP_INTERPOLATION_MODE_NEAREST_NEIGHBOR,
1961 D2D1_COMPOSITE_MODE_SOURCE_OVER);
1963 offset.x = -1;
1964 offset.y = -1;
1965 ID2D1DeviceContext_DrawImage(context, image, &offset, NULL, D2D1_BITMAP_INTERPOLATION_MODE_NEAREST_NEIGHBOR,
1966 D2D1_COMPOSITE_MODE_SOURCE_OVER);
1968 offset.x = image_size.width * 2;
1969 offset.y = image_size.height;
1970 ID2D1DeviceContext_DrawImage(context, image, &offset, NULL, D2D1_BITMAP_INTERPOLATION_MODE_NEAREST_NEIGHBOR,
1971 D2D1_COMPOSITE_MODE_SOURCE_OVER);
1973 offset.x = image_size.width * 3;
1974 set_rect(&src_rect, image_size.width / 2, image_size.height / 2, image_size.width, image_size.height);
1975 ID2D1DeviceContext_DrawImage(context, image, &offset, &src_rect, D2D1_BITMAP_INTERPOLATION_MODE_NEAREST_NEIGHBOR,
1976 D2D1_COMPOSITE_MODE_SOURCE_OVER);
1978 offset.x = image_size.width * 4;
1979 set_rect(&src_rect, 0.0f, 0.0f, image_size.width * 2, image_size.height * 2);
1980 ID2D1DeviceContext_DrawImage(context, image, &offset, &src_rect, D2D1_BITMAP_INTERPOLATION_MODE_NEAREST_NEIGHBOR,
1981 D2D1_COMPOSITE_MODE_SOURCE_OVER);
1983 offset.x = image_size.width * 5;
1984 set_rect(&src_rect, image_size.width, image_size.height, 0.0f, 0.0f);
1985 ID2D1DeviceContext_DrawImage(context, image, &offset, &src_rect, D2D1_BITMAP_INTERPOLATION_MODE_NEAREST_NEIGHBOR,
1986 D2D1_COMPOSITE_MODE_SOURCE_OVER);
1988 hr = ID2D1RenderTarget_EndDraw(rt, NULL, NULL);
1989 ok(SUCCEEDED(hr), "Failed to end draw, hr %#x.\n", hr);
1990 match = compare_surface(&ctx, "95675fbc4a16404c9568d41b14e8f6be64240998");
1991 ok(match, "Surface does not match.\n");
1993 ID2D1RenderTarget_BeginDraw(rt);
1995 offset.x = image_size.width * 6;
1996 set_rect(&src_rect, 1.0f, 0.0f, 1.0f, image_size.height);
1997 ID2D1DeviceContext_DrawImage(context, image, &offset, &src_rect, D2D1_BITMAP_INTERPOLATION_MODE_NEAREST_NEIGHBOR,
1998 D2D1_COMPOSITE_MODE_SOURCE_OVER);
2000 hr = ID2D1RenderTarget_EndDraw(rt, NULL, NULL);
2001 ok(SUCCEEDED(hr), "Failed to end draw, hr %#x.\n", hr);
2002 match = compare_surface(&ctx, "95675fbc4a16404c9568d41b14e8f6be64240998");
2003 ok(match, "Surface does not match.\n");
2005 ID2D1RenderTarget_SetTransform(rt, &tmp_matrix);
2006 ID2D1DeviceContext_Release(context);
2007 ID2D1Image_Release(image);
2010 /* Creating a brush with a NULL bitmap crashes on Vista, but works fine on
2011 * Windows 7+. */
2012 hr = ID2D1RenderTarget_CreateBitmapBrush(rt, bitmap, NULL, NULL, &brush);
2013 ok(SUCCEEDED(hr), "Failed to create brush, hr %#x.\n", hr);
2014 ID2D1BitmapBrush_GetBitmap(brush, &tmp_bitmap);
2015 ok(tmp_bitmap == bitmap, "Got unexpected bitmap %p, expected %p.\n", tmp_bitmap, bitmap);
2016 ID2D1Bitmap_Release(tmp_bitmap);
2017 opacity = ID2D1BitmapBrush_GetOpacity(brush);
2018 ok(opacity == 1.0f, "Got unexpected opacity %.8e.\n", opacity);
2019 set_matrix_identity(&matrix);
2020 ID2D1BitmapBrush_GetTransform(brush, &tmp_matrix);
2021 ok(!memcmp(&tmp_matrix, &matrix, sizeof(matrix)),
2022 "Got unexpected matrix {%.8e, %.8e, %.8e, %.8e, %.8e, %.8e}.\n",
2023 tmp_matrix._11, tmp_matrix._12, tmp_matrix._21,
2024 tmp_matrix._22, tmp_matrix._31, tmp_matrix._32);
2025 extend_mode = ID2D1BitmapBrush_GetExtendModeX(brush);
2026 ok(extend_mode == D2D1_EXTEND_MODE_CLAMP, "Got unexpected extend mode %#x.\n", extend_mode);
2027 extend_mode = ID2D1BitmapBrush_GetExtendModeY(brush);
2028 ok(extend_mode == D2D1_EXTEND_MODE_CLAMP, "Got unexpected extend mode %#x.\n", extend_mode);
2029 interpolation_mode = ID2D1BitmapBrush_GetInterpolationMode(brush);
2030 ok(interpolation_mode == D2D1_BITMAP_INTERPOLATION_MODE_LINEAR,
2031 "Got unexpected interpolation mode %#x.\n", interpolation_mode);
2032 ID2D1BitmapBrush_Release(brush);
2034 hr = ID2D1RenderTarget_CreateBitmapBrush(rt, bitmap, NULL, NULL, &brush);
2035 ok(SUCCEEDED(hr), "Failed to create brush, hr %#x.\n", hr);
2036 set_matrix_identity(&matrix);
2037 translate_matrix(&matrix, 40.0f, 120.0f);
2038 scale_matrix(&matrix, 20.0f, 60.0f);
2039 ID2D1BitmapBrush_SetTransform(brush, &matrix);
2040 ID2D1BitmapBrush_SetInterpolationMode(brush, D2D1_BITMAP_INTERPOLATION_MODE_NEAREST_NEIGHBOR);
2042 ID2D1RenderTarget_BeginDraw(rt);
2044 set_color(&color, 0.0f, 0.0f, 1.0f, 1.0f);
2045 ID2D1RenderTarget_Clear(rt, &color);
2047 set_rect(&dst_rect, 40.0f, 120.0f, 120.0f, 360.0f);
2048 ID2D1RenderTarget_FillRectangle(rt, &dst_rect, (ID2D1Brush *)brush);
2050 set_matrix_identity(&matrix);
2051 scale_matrix(&matrix, 0.5f, 2.0f);
2052 translate_matrix(&matrix, 320.0f, 240.0f);
2053 rotate_matrix(&matrix, M_PI / 4.0f);
2054 ID2D1RenderTarget_SetTransform(rt, &matrix);
2055 set_matrix_identity(&matrix);
2056 translate_matrix(&matrix, -80.0f, -60.0f);
2057 scale_matrix(&matrix, 64.0f, 32.0f);
2058 ID2D1BitmapBrush_SetTransform(brush, &matrix);
2059 ID2D1BitmapBrush_SetOpacity(brush, 0.75f);
2060 set_rect(&dst_rect, -80.0f, -60.0f, 80.0f, 60.0f);
2061 ID2D1RenderTarget_FillRectangle(rt, &dst_rect, (ID2D1Brush *)brush);
2063 set_matrix_identity(&matrix);
2064 translate_matrix(&matrix, 200.0f, 120.0f);
2065 scale_matrix(&matrix, 20.0f, 60.0f);
2066 ID2D1RenderTarget_SetTransform(rt, &matrix);
2067 ID2D1RenderTarget_DrawBitmap(rt, bitmap, NULL, 0.25f,
2068 D2D1_BITMAP_INTERPOLATION_MODE_NEAREST_NEIGHBOR, NULL);
2069 set_rect(&dst_rect, -4.0f, 12.0f, -8.0f, 8.0f);
2070 ID2D1RenderTarget_DrawBitmap(rt, bitmap, &dst_rect, 0.75f,
2071 D2D1_BITMAP_INTERPOLATION_MODE_NEAREST_NEIGHBOR, NULL);
2072 set_rect(&dst_rect, 0.0f, 8.0f, 4.0f, 12.0f);
2073 set_rect(&src_rect, 2.0f, 1.0f, 4.0f, 3.0f);
2074 ID2D1RenderTarget_DrawBitmap(rt, bitmap, &dst_rect, 1.0f,
2075 D2D1_BITMAP_INTERPOLATION_MODE_NEAREST_NEIGHBOR, &src_rect);
2076 set_rect(&dst_rect, 4.0f, 12.0f, 12.0f, 20.0f);
2077 set_rect(&src_rect, 0.0f, 0.0f, image_size.width * 2, image_size.height * 2);
2078 ID2D1RenderTarget_DrawBitmap(rt, bitmap, &dst_rect, 1.0f,
2079 D2D1_BITMAP_INTERPOLATION_MODE_NEAREST_NEIGHBOR, &src_rect);
2080 set_rect(&dst_rect, 4.0f, 8.0f, 12.0f, 12.0f);
2081 set_rect(&src_rect, image_size.width / 2, image_size.height / 2, image_size.width, image_size.height);
2082 ID2D1RenderTarget_DrawBitmap(rt, bitmap, &dst_rect, 1.0f,
2083 D2D1_BITMAP_INTERPOLATION_MODE_NEAREST_NEIGHBOR, &src_rect);
2084 set_rect(&dst_rect, 0.0f, 4.0f, 4.0f, 8.0f);
2085 set_rect(&src_rect, image_size.width, 0.0f, 0.0f, image_size.height);
2086 ID2D1RenderTarget_DrawBitmap(rt, bitmap, &dst_rect, 1.0f,
2087 D2D1_BITMAP_INTERPOLATION_MODE_NEAREST_NEIGHBOR, &src_rect);
2089 hr = ID2D1RenderTarget_EndDraw(rt, NULL, NULL);
2090 ok(SUCCEEDED(hr), "Failed to end draw, hr %#x.\n", hr);
2091 match = compare_surface(&ctx, "f5d039c280fa33ba05496c9883192a34108efbbe");
2092 ok(match, "Surface does not match.\n");
2094 /* Invalid interpolation mode. */
2095 ID2D1RenderTarget_BeginDraw(rt);
2097 set_rect(&dst_rect, 4.0f, 8.0f, 8.0f, 12.0f);
2098 set_rect(&src_rect, 0.0f, 1.0f, image_size.width, 1.0f);
2099 ID2D1RenderTarget_DrawBitmap(rt, bitmap, &dst_rect, 1.0f,
2100 D2D1_BITMAP_INTERPOLATION_MODE_NEAREST_NEIGHBOR, &src_rect);
2102 set_rect(&dst_rect, 1.0f, 8.0f, 4.0f, 12.0f);
2103 set_rect(&src_rect, 2.0f, 1.0f, 4.0f, 3.0f);
2104 ID2D1RenderTarget_DrawBitmap(rt, bitmap, &dst_rect, 1.0f,
2105 D2D1_BITMAP_INTERPOLATION_MODE_LINEAR + 1, &src_rect);
2107 hr = ID2D1RenderTarget_EndDraw(rt, NULL, NULL);
2108 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
2109 match = compare_surface(&ctx, "f5d039c280fa33ba05496c9883192a34108efbbe");
2110 ok(match, "Surface does not match.\n");
2112 ID2D1RenderTarget_BeginDraw(rt);
2113 ID2D1RenderTarget_Clear(rt, &color);
2115 set_rect(&src_rect, image_size.width, 0.0f, 0.0f, image_size.height);
2116 ID2D1RenderTarget_DrawBitmap(rt, bitmap, NULL, 1.0f,
2117 D2D1_BITMAP_INTERPOLATION_MODE_NEAREST_NEIGHBOR, &src_rect);
2119 hr = ID2D1RenderTarget_EndDraw(rt, NULL, NULL);
2120 ok(SUCCEEDED(hr), "Failed to end draw, hr %#x.\n", hr);
2121 match = compare_surface(&ctx, "59043096393570ad800dbcbfdd644394b79493bd");
2122 ok(match, "Surface does not match.\n");
2124 ID2D1RenderTarget_BeginDraw(rt);
2126 ID2D1RenderTarget_Clear(rt, &color);
2128 ID2D1BitmapBrush_SetOpacity(brush, 1.0f);
2129 for (i = 0; i < ARRAY_SIZE(extend_mode_tests); ++i)
2131 ID2D1BitmapBrush_SetExtendModeX(brush, extend_mode_tests[i].extend_mode_x);
2132 extend_mode = ID2D1BitmapBrush_GetExtendModeX(brush);
2133 ok(extend_mode == extend_mode_tests[i].extend_mode_x,
2134 "Test %u: Got unexpected extend mode %#x, expected %#x.\n",
2135 i, extend_mode, extend_mode_tests[i].extend_mode_x);
2136 ID2D1BitmapBrush_SetExtendModeY(brush, extend_mode_tests[i].extend_mode_y);
2137 extend_mode = ID2D1BitmapBrush_GetExtendModeY(brush);
2138 ok(extend_mode == extend_mode_tests[i].extend_mode_y,
2139 "Test %u: Got unexpected extend mode %#x, expected %#x.\n",
2140 i, extend_mode, extend_mode_tests[i].extend_mode_y);
2141 set_matrix_identity(&matrix);
2142 translate_matrix(&matrix, extend_mode_tests[i].translate_x, extend_mode_tests[i].translate_y);
2143 scale_matrix(&matrix, 0.5f, 0.5f);
2144 ID2D1BitmapBrush_SetTransform(brush, &matrix);
2145 ID2D1RenderTarget_FillRectangle(rt, &extend_mode_tests[i].rect, (ID2D1Brush *)brush);
2148 hr = ID2D1RenderTarget_EndDraw(rt, NULL, NULL);
2149 ok(SUCCEEDED(hr), "Failed to end draw, hr %#x.\n", hr);
2150 match = compare_surface(&ctx, "b4b775afecdae2d26642001f4faff73663bb8b31");
2151 ok(match, "Surface does not match.\n");
2153 ID2D1Bitmap_Release(bitmap);
2154 bitmap_desc.dpiX = 96.0f / 20.0f;
2155 bitmap_desc.dpiY = 96.0f / 60.0f;
2156 hr = ID2D1RenderTarget_CreateBitmap(rt, size, bitmap_data, 4 * sizeof(*bitmap_data), &bitmap_desc, &bitmap);
2157 ok(SUCCEEDED(hr), "Failed to create bitmap, hr %#x.\n", hr);
2158 ID2D1BitmapBrush_SetBitmap(brush, bitmap);
2160 ID2D1RenderTarget_BeginDraw(rt);
2162 ID2D1RenderTarget_Clear(rt, &color);
2164 set_matrix_identity(&matrix);
2165 translate_matrix(&matrix, 40.0f, 120.0f);
2166 skew_matrix(&matrix, 0.125f, 2.0f);
2167 ID2D1RenderTarget_SetTransform(rt, &matrix);
2168 set_matrix_identity(&matrix);
2169 ID2D1BitmapBrush_SetTransform(brush, &matrix);
2170 set_rect(&dst_rect, 0.0f, 0.0f, 80.0f, 240.0f);
2171 ID2D1RenderTarget_FillRectangle(rt, &dst_rect, (ID2D1Brush *)brush);
2173 ID2D1RenderTarget_GetFactory(rt, &factory);
2175 set_rect(&dst_rect, -1.0f, -1.0f, 1.0f, 1.0f);
2176 hr = ID2D1Factory_CreateRectangleGeometry(factory, &dst_rect, &rectangle_geometry);
2177 ok(SUCCEEDED(hr), "Failed to create geometry, hr %#x.\n", hr);
2179 set_matrix_identity(&matrix);
2180 translate_matrix(&matrix, 240.0f, 720.0f);
2181 scale_matrix(&matrix, 40.0f, 120.0f);
2182 hr = ID2D1Factory_CreateTransformedGeometry(factory, (ID2D1Geometry *)rectangle_geometry,
2183 &matrix, &transformed_geometry);
2184 ok(SUCCEEDED(hr), "Failed to create geometry, hr %#x.\n", hr);
2185 ID2D1RectangleGeometry_Release(rectangle_geometry);
2187 set_matrix_identity(&matrix);
2188 ID2D1RenderTarget_SetTransform(rt, &matrix);
2189 set_matrix_identity(&matrix);
2190 translate_matrix(&matrix, 200.0f, 600.0f);
2191 ID2D1BitmapBrush_SetTransform(brush, &matrix);
2192 ID2D1RenderTarget_FillGeometry(rt, (ID2D1Geometry *)transformed_geometry, (ID2D1Brush *)brush, NULL);
2193 ID2D1TransformedGeometry_Release(transformed_geometry);
2195 ID2D1Factory_Release(factory);
2197 hr = ID2D1RenderTarget_EndDraw(rt, NULL, NULL);
2198 ok(SUCCEEDED(hr), "Failed to end draw, hr %#x.\n", hr);
2199 match = compare_surface(&ctx, "cf7b90ba7b139fdfbe9347e1907d635cfb4ed197");
2200 ok(match, "Surface does not match.\n");
2202 if (SUCCEEDED(ID2D1BitmapBrush_QueryInterface(brush, &IID_ID2D1BitmapBrush1, (void **)&brush1)))
2204 D2D1_INTERPOLATION_MODE interpolation_mode1;
2206 interpolation_mode = ID2D1BitmapBrush1_GetInterpolationMode(brush1);
2207 ok(interpolation_mode == D2D1_BITMAP_INTERPOLATION_MODE_NEAREST_NEIGHBOR,
2208 "Unexpected interpolation mode %#x.\n", interpolation_mode);
2210 interpolation_mode1 = ID2D1BitmapBrush1_GetInterpolationMode1(brush1);
2211 ok(interpolation_mode1 == D2D1_INTERPOLATION_MODE_NEAREST_NEIGHBOR,
2212 "Unexpected interpolation mode %#x.\n", interpolation_mode1);
2214 ID2D1BitmapBrush1_SetInterpolationMode1(brush1, D2D1_INTERPOLATION_MODE_CUBIC);
2215 interpolation_mode = ID2D1BitmapBrush1_GetInterpolationMode(brush1);
2216 ok(interpolation_mode == D2D1_BITMAP_INTERPOLATION_MODE_LINEAR,
2217 "Unexpected interpolation mode %#x.\n", interpolation_mode);
2219 interpolation_mode1 = ID2D1BitmapBrush1_GetInterpolationMode1(brush1);
2220 ok(interpolation_mode1 == D2D1_INTERPOLATION_MODE_CUBIC,
2221 "Unexpected interpolation mode %#x.\n", interpolation_mode1);
2223 ID2D1BitmapBrush1_SetInterpolationMode1(brush1, 100);
2224 interpolation_mode1 = ID2D1BitmapBrush1_GetInterpolationMode1(brush1);
2225 ok(interpolation_mode1 == D2D1_INTERPOLATION_MODE_CUBIC,
2226 "Unexpected interpolation mode %#x.\n", interpolation_mode1);
2228 ID2D1BitmapBrush1_SetInterpolationMode(brush1, 100);
2229 interpolation_mode1 = ID2D1BitmapBrush1_GetInterpolationMode1(brush1);
2230 ok(interpolation_mode1 == D2D1_INTERPOLATION_MODE_CUBIC,
2231 "Unexpected interpolation mode %#x.\n", interpolation_mode1);
2233 ID2D1BitmapBrush1_SetInterpolationMode(brush1, D2D1_BITMAP_INTERPOLATION_MODE_NEAREST_NEIGHBOR);
2234 interpolation_mode = ID2D1BitmapBrush1_GetInterpolationMode(brush1);
2235 ok(interpolation_mode == D2D1_BITMAP_INTERPOLATION_MODE_NEAREST_NEIGHBOR,
2236 "Unexpected interpolation mode %#x.\n", interpolation_mode);
2238 interpolation_mode1 = ID2D1BitmapBrush1_GetInterpolationMode1(brush1);
2239 ok(interpolation_mode1 == D2D1_INTERPOLATION_MODE_NEAREST_NEIGHBOR,
2240 "Unexpected interpolation mode %#x.\n", interpolation_mode1);
2242 ID2D1BitmapBrush1_Release(brush1);
2245 ID2D1BitmapBrush_Release(brush);
2246 refcount = ID2D1Bitmap_Release(bitmap);
2247 ok(!refcount, "Bitmap has %u references left.\n", refcount);
2248 release_test_context(&ctx);
2251 static void test_linear_brush(BOOL d3d11)
2253 D2D1_LINEAR_GRADIENT_BRUSH_PROPERTIES gradient_properties;
2254 ID2D1GradientStopCollection *gradient, *tmp_gradient;
2255 ID2D1TransformedGeometry *transformed_geometry;
2256 ID2D1RectangleGeometry *rectangle_geometry;
2257 D2D1_MATRIX_3X2_F matrix, tmp_matrix;
2258 ID2D1LinearGradientBrush *brush;
2259 struct d2d1_test_context ctx;
2260 struct resource_readback rb;
2261 ID2D1RenderTarget *rt;
2262 ID2D1Factory *factory;
2263 D2D1_COLOR_F colour;
2264 D2D1_POINT_2F p;
2265 unsigned int i;
2266 ULONG refcount;
2267 D2D1_RECT_F r;
2268 float opacity;
2269 HRESULT hr;
2271 static const D2D1_GRADIENT_STOP stops[] =
2273 {0.0f, {1.0f, 0.0f, 0.0f, 1.0f}},
2274 {0.5f, {0.0f, 1.0f, 0.0f, 1.0f}},
2275 {1.0f, {0.0f, 0.0f, 1.0f, 1.0f}},
2277 static const struct
2279 unsigned int x, y;
2280 DWORD colour;
2282 test1[] =
2284 {80, 80, 0xff857a00}, {240, 80, 0xff926d00}, {400, 80, 0xff9f6000}, {560, 80, 0xffac5300},
2285 {80, 240, 0xff00eb14}, {240, 240, 0xff00f807}, {400, 240, 0xff06f900}, {560, 240, 0xff13ec00},
2286 {80, 400, 0xff0053ac}, {240, 400, 0xff005fa0}, {400, 400, 0xff006c93}, {560, 400, 0xff007986},
2288 test2[] =
2290 { 40, 30, 0xff005ba4}, {120, 30, 0xffffffff}, { 40, 60, 0xffffffff}, { 80, 60, 0xff00b44b},
2291 {120, 60, 0xff006c93}, {200, 60, 0xffffffff}, { 40, 90, 0xffffffff}, {120, 90, 0xff0ef100},
2292 {160, 90, 0xff00c53a}, {200, 90, 0xffffffff}, { 80, 120, 0xffffffff}, {120, 120, 0xffaf5000},
2293 {160, 120, 0xff679800}, {200, 120, 0xff1fe000}, {240, 120, 0xffffffff}, {160, 150, 0xffffffff},
2294 {200, 150, 0xffc03e00}, {240, 150, 0xffffffff}, {280, 150, 0xffffffff}, {320, 150, 0xffffffff},
2295 {240, 180, 0xffffffff}, {280, 180, 0xffff4040}, {320, 180, 0xffff4040}, {380, 180, 0xffffffff},
2296 {200, 210, 0xffffffff}, {240, 210, 0xffa99640}, {280, 210, 0xffb28d40}, {320, 210, 0xffbb8440},
2297 {360, 210, 0xffc47b40}, {400, 210, 0xffffffff}, {200, 240, 0xffffffff}, {280, 240, 0xff41fe40},
2298 {320, 240, 0xff49f540}, {360, 240, 0xff52ec40}, {440, 240, 0xffffffff}, {240, 270, 0xffffffff},
2299 {280, 270, 0xff408eb0}, {320, 270, 0xff4097a7}, {360, 270, 0xff40a19e}, {440, 270, 0xffffffff},
2300 {280, 300, 0xffffffff}, {320, 300, 0xff4040ff}, {360, 300, 0xff4040ff}, {400, 300, 0xff406ad4},
2301 {440, 300, 0xff4061de}, {480, 300, 0xff4057e7}, {520, 300, 0xff404ef1}, {280, 330, 0xffffffff},
2302 {360, 330, 0xffffffff}, {400, 330, 0xff40c17e}, {440, 330, 0xff40b788}, {480, 330, 0xff40ae91},
2303 {520, 330, 0xff40a49b}, {400, 360, 0xff57e740}, {440, 360, 0xff4ef140}, {480, 360, 0xff44fb40},
2304 {520, 360, 0xff40fa45}, {400, 390, 0xffae9140}, {440, 390, 0xffa49b40}, {480, 390, 0xff9aa540},
2305 {520, 390, 0xff90ae40},
2308 if (!init_test_context(&ctx, d3d11))
2309 return;
2311 rt = ctx.rt;
2312 ID2D1RenderTarget_SetDpi(rt, 192.0f, 48.0f);
2313 ID2D1RenderTarget_SetAntialiasMode(rt, D2D1_ANTIALIAS_MODE_ALIASED);
2315 hr = ID2D1RenderTarget_CreateGradientStopCollection(rt, stops, ARRAY_SIZE(stops),
2316 D2D1_GAMMA_2_2, D2D1_EXTEND_MODE_CLAMP, &gradient);
2317 ok(SUCCEEDED(hr), "Failed to create stop collection, hr %#x.\n", hr);
2319 set_point(&gradient_properties.startPoint, 320.0f, 0.0f);
2320 set_point(&gradient_properties.endPoint, 0.0f, 960.0f);
2321 hr = ID2D1RenderTarget_CreateLinearGradientBrush(rt, &gradient_properties, NULL, gradient, &brush);
2322 ok(SUCCEEDED(hr), "Failed to create brush, hr %#x.\n", hr);
2324 opacity = ID2D1LinearGradientBrush_GetOpacity(brush);
2325 ok(opacity == 1.0f, "Got unexpected opacity %.8e.\n", opacity);
2326 set_matrix_identity(&matrix);
2327 ID2D1LinearGradientBrush_GetTransform(brush, &tmp_matrix);
2328 ok(!memcmp(&tmp_matrix, &matrix, sizeof(matrix)),
2329 "Got unexpected matrix {%.8e, %.8e, %.8e, %.8e, %.8e, %.8e}.\n",
2330 tmp_matrix._11, tmp_matrix._12, tmp_matrix._21,
2331 tmp_matrix._22, tmp_matrix._31, tmp_matrix._32);
2332 p = ID2D1LinearGradientBrush_GetStartPoint(brush);
2333 ok(compare_point(&p, 320.0f, 0.0f, 0), "Got unexpected start point {%.8e, %.8e}.\n", p.x, p.y);
2334 p = ID2D1LinearGradientBrush_GetEndPoint(brush);
2335 ok(compare_point(&p, 0.0f, 960.0f, 0), "Got unexpected end point {%.8e, %.8e}.\n", p.x, p.y);
2336 ID2D1LinearGradientBrush_GetGradientStopCollection(brush, &tmp_gradient);
2337 ok(tmp_gradient == gradient, "Got unexpected gradient %p, expected %p.\n", tmp_gradient, gradient);
2338 ID2D1GradientStopCollection_Release(tmp_gradient);
2340 ID2D1RenderTarget_BeginDraw(rt);
2342 set_color(&colour, 1.0f, 1.0f, 1.0f, 1.0f);
2343 ID2D1RenderTarget_Clear(rt, &colour);
2345 set_rect(&r, 0.0f, 0.0f, 320.0f, 960.0f);
2346 ID2D1RenderTarget_FillRectangle(rt, &r, (ID2D1Brush *)brush);
2348 hr = ID2D1RenderTarget_EndDraw(rt, NULL, NULL);
2349 ok(SUCCEEDED(hr), "Failed to end draw, hr %#x.\n", hr);
2351 get_surface_readback(&ctx, &rb);
2352 for (i = 0; i < ARRAY_SIZE(test1); ++i)
2354 DWORD colour;
2356 colour = get_readback_colour(&rb, test1[i].x, test1[i].y);
2357 ok(compare_colour(colour, test1[i].colour, 1),
2358 "Got unexpected colour 0x%08x at position {%u, %u}.\n",
2359 colour, test1[i].x, test1[i].y);
2361 release_resource_readback(&rb);
2363 ID2D1RenderTarget_BeginDraw(rt);
2365 ID2D1RenderTarget_Clear(rt, &colour);
2367 set_matrix_identity(&matrix);
2368 skew_matrix(&matrix, 0.2146f, 1.575f);
2369 ID2D1RenderTarget_SetTransform(rt, &matrix);
2371 set_matrix_identity(&matrix);
2372 translate_matrix(&matrix, 0.0f, 240.0f);
2373 scale_matrix(&matrix, 0.25f, -0.25f);
2374 ID2D1LinearGradientBrush_SetTransform(brush, &matrix);
2376 set_rect(&r, 0.0f, 0.0f, 80.0f, 240.0f);
2377 ID2D1RenderTarget_FillRectangle(rt, &r, (ID2D1Brush *)brush);
2379 set_matrix_identity(&matrix);
2380 scale_matrix(&matrix, 0.5f, 2.0f);
2381 translate_matrix(&matrix, 320.0f, 240.0f);
2382 rotate_matrix(&matrix, M_PI / 4.0f);
2383 ID2D1RenderTarget_SetTransform(rt, &matrix);
2385 set_matrix_identity(&matrix);
2386 translate_matrix(&matrix, 0.0f, -50.0f);
2387 scale_matrix(&matrix, 0.1f, 0.1f);
2388 rotate_matrix(&matrix, -M_PI / 3.0f);
2389 ID2D1LinearGradientBrush_SetTransform(brush, &matrix);
2391 ID2D1LinearGradientBrush_SetOpacity(brush, 0.75f);
2392 set_rect(&r, -80.0f, -60.0f, 80.0f, 60.0f);
2393 ID2D1RenderTarget_FillRectangle(rt, &r, (ID2D1Brush *)brush);
2395 ID2D1RenderTarget_GetFactory(rt, &factory);
2397 set_rect(&r, -1.0f, -1.0f, 1.0f, 1.0f);
2398 hr = ID2D1Factory_CreateRectangleGeometry(factory, &r, &rectangle_geometry);
2399 ok(SUCCEEDED(hr), "Failed to create geometry, hr %#x.\n", hr);
2401 set_matrix_identity(&matrix);
2402 translate_matrix(&matrix, 228.5f, 714.0f);
2403 scale_matrix(&matrix, 40.0f, 120.0f);
2404 hr = ID2D1Factory_CreateTransformedGeometry(factory, (ID2D1Geometry *)rectangle_geometry,
2405 &matrix, &transformed_geometry);
2406 ok(SUCCEEDED(hr), "Failed to create geometry, hr %#x.\n", hr);
2407 ID2D1RectangleGeometry_Release(rectangle_geometry);
2409 set_matrix_identity(&matrix);
2410 ID2D1RenderTarget_SetTransform(rt, &matrix);
2411 ID2D1LinearGradientBrush_SetTransform(brush, &matrix);
2412 set_point(&p, 188.5f, 834.0f);
2413 ID2D1LinearGradientBrush_SetStartPoint(brush, p);
2414 set_point(&p, 268.5f, 594.0f);
2415 ID2D1LinearGradientBrush_SetEndPoint(brush, p);
2416 ID2D1RenderTarget_FillGeometry(rt, (ID2D1Geometry *)transformed_geometry, (ID2D1Brush *)brush, NULL);
2417 ID2D1TransformedGeometry_Release(transformed_geometry);
2419 ID2D1Factory_Release(factory);
2421 hr = ID2D1RenderTarget_EndDraw(rt, NULL, NULL);
2422 ok(SUCCEEDED(hr), "Failed to end draw, hr %#x.\n", hr);
2424 get_surface_readback(&ctx, &rb);
2425 for (i = 0; i < ARRAY_SIZE(test2); ++i)
2427 DWORD colour;
2429 colour = get_readback_colour(&rb, test2[i].x, test2[i].y);
2430 ok(compare_colour(colour, test2[i].colour, 1),
2431 "Got unexpected colour 0x%08x at position {%u, %u}.\n",
2432 colour, test2[i].x, test2[i].y);
2434 release_resource_readback(&rb);
2436 ID2D1LinearGradientBrush_Release(brush);
2437 refcount = ID2D1GradientStopCollection_Release(gradient);
2438 ok(!refcount, "Gradient has %u references left.\n", refcount);
2439 release_test_context(&ctx);
2442 static void test_radial_brush(BOOL d3d11)
2444 D2D1_RADIAL_GRADIENT_BRUSH_PROPERTIES gradient_properties;
2445 ID2D1GradientStopCollection *gradient, *tmp_gradient;
2446 ID2D1TransformedGeometry *transformed_geometry;
2447 ID2D1RectangleGeometry *rectangle_geometry;
2448 D2D1_MATRIX_3X2_F matrix, tmp_matrix;
2449 ID2D1RadialGradientBrush *brush;
2450 struct d2d1_test_context ctx;
2451 struct resource_readback rb;
2452 ID2D1RenderTarget *rt;
2453 ID2D1Factory *factory;
2454 D2D1_COLOR_F colour;
2455 D2D1_POINT_2F p;
2456 unsigned int i;
2457 ULONG refcount;
2458 D2D1_RECT_F r;
2459 HRESULT hr;
2460 float f;
2462 static const D2D1_GRADIENT_STOP stops[] =
2464 {0.0f, {1.0f, 0.0f, 0.0f, 1.0f}},
2465 {0.5f, {0.0f, 1.0f, 0.0f, 1.0f}},
2466 {1.0f, {0.0f, 0.0f, 1.0f, 1.0f}},
2468 static const struct
2470 unsigned int x, y;
2471 DWORD colour;
2473 test1[] =
2475 {80, 80, 0xff0000ff}, {240, 80, 0xff00a857}, {400, 80, 0xff00d728}, {560, 80, 0xff0000ff},
2476 {80, 240, 0xff006699}, {240, 240, 0xff29d600}, {400, 240, 0xff966900}, {560, 240, 0xff00a55a},
2477 {80, 400, 0xff0000ff}, {240, 400, 0xff006e91}, {400, 400, 0xff007d82}, {560, 400, 0xff0000ff},
2479 test2[] =
2481 { 40, 30, 0xff000df2}, {120, 30, 0xffffffff}, { 40, 60, 0xffffffff}, { 80, 60, 0xff00b04f},
2482 {120, 60, 0xff007689}, {200, 60, 0xffffffff}, { 40, 90, 0xffffffff}, {120, 90, 0xff47b800},
2483 {160, 90, 0xff00c13e}, {200, 90, 0xffffffff}, { 80, 120, 0xffffffff}, {120, 120, 0xff0000ff},
2484 {160, 120, 0xff6f9000}, {200, 120, 0xff00718e}, {240, 120, 0xffffffff}, {160, 150, 0xffffffff},
2485 {200, 150, 0xff00609f}, {240, 150, 0xffffffff}, {280, 150, 0xffffffff}, {320, 150, 0xffffffff},
2486 {240, 180, 0xffffffff}, {280, 180, 0xff4040ff}, {320, 180, 0xff40b788}, {380, 180, 0xffffffff},
2487 {200, 210, 0xffffffff}, {240, 210, 0xff4040ff}, {280, 210, 0xff4040ff}, {320, 210, 0xff76c940},
2488 {360, 210, 0xff40cc73}, {400, 210, 0xffffffff}, {200, 240, 0xffffffff}, {280, 240, 0xff4061de},
2489 {320, 240, 0xff9fa040}, {360, 240, 0xff404af5}, {440, 240, 0xffffffff}, {240, 270, 0xffffffff},
2490 {280, 270, 0xff40aa95}, {320, 270, 0xff4ef140}, {360, 270, 0xff4040ff}, {440, 270, 0xffffffff},
2491 {280, 300, 0xffffffff}, {320, 300, 0xff4093ac}, {360, 300, 0xff4040ff}, {400, 300, 0xff4040ff},
2492 {440, 300, 0xff404af5}, {480, 300, 0xff4045fa}, {520, 300, 0xff4040ff}, {280, 330, 0xffffffff},
2493 {360, 330, 0xffffffff}, {400, 330, 0xff4069d6}, {440, 330, 0xff40c579}, {480, 330, 0xff40e956},
2494 {520, 330, 0xff4072cd}, {400, 360, 0xff408ab4}, {440, 360, 0xff49f540}, {480, 360, 0xffb98640},
2495 {520, 360, 0xff40dc62}, {400, 390, 0xff405ee1}, {440, 390, 0xff40d56a}, {480, 390, 0xff62dd40},
2496 {520, 390, 0xff4059e6},
2499 if (!init_test_context(&ctx, d3d11))
2500 return;
2502 rt = ctx.rt;
2503 ID2D1RenderTarget_SetDpi(rt, 192.0f, 48.0f);
2504 ID2D1RenderTarget_SetAntialiasMode(rt, D2D1_ANTIALIAS_MODE_ALIASED);
2506 hr = ID2D1RenderTarget_CreateGradientStopCollection(rt, stops, ARRAY_SIZE(stops),
2507 D2D1_GAMMA_2_2, D2D1_EXTEND_MODE_CLAMP, &gradient);
2508 ok(SUCCEEDED(hr), "Failed to create stop collection, hr %#x.\n", hr);
2510 set_point(&gradient_properties.center, 160.0f, 480.0f);
2511 set_point(&gradient_properties.gradientOriginOffset, 40.0f, -120.0f);
2512 gradient_properties.radiusX = 160.0f;
2513 gradient_properties.radiusY = 480.0f;
2514 hr = ID2D1RenderTarget_CreateRadialGradientBrush(rt, &gradient_properties, NULL, gradient, &brush);
2515 ok(SUCCEEDED(hr), "Failed to create brush, hr %#x.\n", hr);
2517 f = ID2D1RadialGradientBrush_GetOpacity(brush);
2518 ok(f == 1.0f, "Got unexpected opacity %.8e.\n", f);
2519 set_matrix_identity(&matrix);
2520 ID2D1RadialGradientBrush_GetTransform(brush, &tmp_matrix);
2521 ok(!memcmp(&tmp_matrix, &matrix, sizeof(matrix)),
2522 "Got unexpected matrix {%.8e, %.8e, %.8e, %.8e, %.8e, %.8e}.\n",
2523 tmp_matrix._11, tmp_matrix._12, tmp_matrix._21,
2524 tmp_matrix._22, tmp_matrix._31, tmp_matrix._32);
2525 p = ID2D1RadialGradientBrush_GetCenter(brush);
2526 ok(compare_point(&p, 160.0f, 480.0f, 0), "Got unexpected center {%.8e, %.8e}.\n", p.x, p.y);
2527 p = ID2D1RadialGradientBrush_GetGradientOriginOffset(brush);
2528 ok(compare_point(&p, 40.0f, -120.0f, 0), "Got unexpected origin offset {%.8e, %.8e}.\n", p.x, p.y);
2529 f = ID2D1RadialGradientBrush_GetRadiusX(brush);
2530 ok(compare_float(f, 160.0f, 0), "Got unexpected x-radius %.8e.\n", f);
2531 f = ID2D1RadialGradientBrush_GetRadiusY(brush);
2532 ok(compare_float(f, 480.0f, 0), "Got unexpected y-radius %.8e.\n", f);
2533 ID2D1RadialGradientBrush_GetGradientStopCollection(brush, &tmp_gradient);
2534 ok(tmp_gradient == gradient, "Got unexpected gradient %p, expected %p.\n", tmp_gradient, gradient);
2535 ID2D1GradientStopCollection_Release(tmp_gradient);
2537 ID2D1RenderTarget_BeginDraw(rt);
2539 set_color(&colour, 1.0f, 1.0f, 1.0f, 1.0f);
2540 ID2D1RenderTarget_Clear(rt, &colour);
2542 set_rect(&r, 0.0f, 0.0f, 320.0f, 960.0f);
2543 ID2D1RenderTarget_FillRectangle(rt, &r, (ID2D1Brush *)brush);
2545 hr = ID2D1RenderTarget_EndDraw(rt, NULL, NULL);
2546 ok(SUCCEEDED(hr), "Failed to end draw, hr %#x.\n", hr);
2548 get_surface_readback(&ctx, &rb);
2549 for (i = 0; i < ARRAY_SIZE(test1); ++i)
2551 DWORD colour;
2553 colour = get_readback_colour(&rb, test1[i].x, test1[i].y);
2554 ok(compare_colour(colour, test1[i].colour, 1),
2555 "Got unexpected colour 0x%08x at position {%u, %u}.\n",
2556 colour, test1[i].x, test1[i].y);
2558 release_resource_readback(&rb);
2560 ID2D1RenderTarget_BeginDraw(rt);
2562 ID2D1RenderTarget_Clear(rt, &colour);
2564 set_matrix_identity(&matrix);
2565 skew_matrix(&matrix, 0.2146f, 1.575f);
2566 ID2D1RenderTarget_SetTransform(rt, &matrix);
2568 set_matrix_identity(&matrix);
2569 translate_matrix(&matrix, 0.0f, 240.0f);
2570 scale_matrix(&matrix, 0.25f, -0.25f);
2571 ID2D1RadialGradientBrush_SetTransform(brush, &matrix);
2573 set_rect(&r, 0.0f, 0.0f, 80.0f, 240.0f);
2574 ID2D1RenderTarget_FillRectangle(rt, &r, (ID2D1Brush *)brush);
2576 set_matrix_identity(&matrix);
2577 scale_matrix(&matrix, 0.5f, 2.0f);
2578 translate_matrix(&matrix, 320.0f, 240.0f);
2579 rotate_matrix(&matrix, M_PI / 4.0f);
2580 ID2D1RenderTarget_SetTransform(rt, &matrix);
2582 set_matrix_identity(&matrix);
2583 translate_matrix(&matrix, -75.0f, -50.0f);
2584 scale_matrix(&matrix, 0.15f, 0.5f);
2585 rotate_matrix(&matrix, -M_PI / 3.0f);
2586 ID2D1RadialGradientBrush_SetTransform(brush, &matrix);
2588 ID2D1RadialGradientBrush_SetOpacity(brush, 0.75f);
2589 set_rect(&r, -80.0f, -60.0f, 80.0f, 60.0f);
2590 ID2D1RenderTarget_FillRectangle(rt, &r, (ID2D1Brush *)brush);
2592 ID2D1RenderTarget_GetFactory(rt, &factory);
2594 set_rect(&r, -1.0f, -1.0f, 1.0f, 1.0f);
2595 hr = ID2D1Factory_CreateRectangleGeometry(factory, &r, &rectangle_geometry);
2596 ok(SUCCEEDED(hr), "Failed to create geometry, hr %#x.\n", hr);
2598 set_matrix_identity(&matrix);
2599 translate_matrix(&matrix, 228.5f, 714.0f);
2600 scale_matrix(&matrix, 40.0f, 120.0f);
2601 hr = ID2D1Factory_CreateTransformedGeometry(factory, (ID2D1Geometry *)rectangle_geometry,
2602 &matrix, &transformed_geometry);
2603 ok(SUCCEEDED(hr), "Failed to create geometry, hr %#x.\n", hr);
2604 ID2D1RectangleGeometry_Release(rectangle_geometry);
2606 set_matrix_identity(&matrix);
2607 ID2D1RenderTarget_SetTransform(rt, &matrix);
2608 ID2D1RadialGradientBrush_SetTransform(brush, &matrix);
2609 set_point(&p, 228.5f, 714.0f);
2610 ID2D1RadialGradientBrush_SetCenter(brush, p);
2611 ID2D1RadialGradientBrush_SetRadiusX(brush, -40.0f);
2612 ID2D1RadialGradientBrush_SetRadiusY(brush, 120.0f);
2613 set_point(&p, 20.0f, 30.0f);
2614 ID2D1RadialGradientBrush_SetGradientOriginOffset(brush, p);
2615 ID2D1RenderTarget_FillGeometry(rt, (ID2D1Geometry *)transformed_geometry, (ID2D1Brush *)brush, NULL);
2616 ID2D1TransformedGeometry_Release(transformed_geometry);
2618 ID2D1Factory_Release(factory);
2620 hr = ID2D1RenderTarget_EndDraw(rt, NULL, NULL);
2621 ok(SUCCEEDED(hr), "Failed to end draw, hr %#x.\n", hr);
2623 get_surface_readback(&ctx, &rb);
2624 for (i = 0; i < ARRAY_SIZE(test2); ++i)
2626 DWORD colour;
2628 colour = get_readback_colour(&rb, test2[i].x, test2[i].y);
2629 ok(compare_colour(colour, test2[i].colour, 1),
2630 "Got unexpected colour 0x%08x at position {%u, %u}.\n",
2631 colour, test2[i].x, test2[i].y);
2633 release_resource_readback(&rb);
2635 ID2D1RadialGradientBrush_Release(brush);
2636 refcount = ID2D1GradientStopCollection_Release(gradient);
2637 ok(!refcount, "Gradient has %u references left.\n", refcount);
2638 release_test_context(&ctx);
2641 static void fill_geometry_sink(ID2D1GeometrySink *sink, unsigned int hollow_count)
2643 D2D1_FIGURE_BEGIN begin;
2644 unsigned int idx = 0;
2645 D2D1_POINT_2F point;
2647 set_point(&point, 15.0f, 20.0f);
2648 begin = idx++ < hollow_count ? D2D1_FIGURE_BEGIN_HOLLOW : D2D1_FIGURE_BEGIN_FILLED;
2649 ID2D1GeometrySink_BeginFigure(sink, point, begin);
2650 line_to(sink, 55.0f, 20.0f);
2651 line_to(sink, 55.0f, 220.0f);
2652 line_to(sink, 25.0f, 220.0f);
2653 line_to(sink, 25.0f, 100.0f);
2654 line_to(sink, 75.0f, 100.0f);
2655 line_to(sink, 75.0f, 300.0f);
2656 line_to(sink, 5.0f, 300.0f);
2657 line_to(sink, 5.0f, 60.0f);
2658 line_to(sink, 45.0f, 60.0f);
2659 line_to(sink, 45.0f, 180.0f);
2660 line_to(sink, 35.0f, 180.0f);
2661 line_to(sink, 35.0f, 140.0f);
2662 line_to(sink, 65.0f, 140.0f);
2663 line_to(sink, 65.0f, 260.0f);
2664 line_to(sink, 15.0f, 260.0f);
2665 ID2D1GeometrySink_EndFigure(sink, D2D1_FIGURE_END_CLOSED);
2667 set_point(&point, 155.0f, 300.0f);
2668 begin = idx++ < hollow_count ? D2D1_FIGURE_BEGIN_HOLLOW : D2D1_FIGURE_BEGIN_FILLED;
2669 ID2D1GeometrySink_BeginFigure(sink, point, begin);
2670 line_to(sink, 155.0f, 160.0f);
2671 line_to(sink, 85.0f, 160.0f);
2672 line_to(sink, 85.0f, 300.0f);
2673 line_to(sink, 120.0f, 300.0f);
2674 line_to(sink, 120.0f, 20.0f);
2675 line_to(sink, 155.0f, 20.0f);
2676 line_to(sink, 155.0f, 160.0f);
2677 line_to(sink, 85.0f, 160.0f);
2678 line_to(sink, 85.0f, 20.0f);
2679 line_to(sink, 120.0f, 20.0f);
2680 line_to(sink, 120.0f, 300.0f);
2681 ID2D1GeometrySink_EndFigure(sink, D2D1_FIGURE_END_CLOSED);
2683 set_point(&point, 165.0f, 20.0f);
2684 begin = idx++ < hollow_count ? D2D1_FIGURE_BEGIN_HOLLOW : D2D1_FIGURE_BEGIN_FILLED;
2685 ID2D1GeometrySink_BeginFigure(sink, point, begin);
2686 line_to(sink, 165.0f, 300.0f);
2687 line_to(sink, 235.0f, 300.0f);
2688 line_to(sink, 235.0f, 20.0f);
2689 ID2D1GeometrySink_EndFigure(sink, D2D1_FIGURE_END_CLOSED);
2690 set_point(&point, 225.0f, 60.0f);
2691 begin = idx++ < hollow_count ? D2D1_FIGURE_BEGIN_HOLLOW : D2D1_FIGURE_BEGIN_FILLED;
2692 ID2D1GeometrySink_BeginFigure(sink, point, begin);
2693 line_to(sink, 225.0f, 260.0f);
2694 line_to(sink, 175.0f, 260.0f);
2695 line_to(sink, 175.0f, 60.0f);
2696 ID2D1GeometrySink_EndFigure(sink, D2D1_FIGURE_END_CLOSED);
2697 set_point(&point, 215.0f, 220.0f);
2698 begin = idx++ < hollow_count ? D2D1_FIGURE_BEGIN_HOLLOW : D2D1_FIGURE_BEGIN_FILLED;
2699 ID2D1GeometrySink_BeginFigure(sink, point, begin);
2700 line_to(sink, 185.0f, 220.0f);
2701 line_to(sink, 185.0f, 100.0f);
2702 line_to(sink, 215.0f, 100.0f);
2703 ID2D1GeometrySink_EndFigure(sink, D2D1_FIGURE_END_CLOSED);
2704 set_point(&point, 195.0f, 180.0f);
2705 begin = idx++ < hollow_count ? D2D1_FIGURE_BEGIN_HOLLOW : D2D1_FIGURE_BEGIN_FILLED;
2706 ID2D1GeometrySink_BeginFigure(sink, point, begin);
2707 line_to(sink, 205.0f, 180.0f);
2708 line_to(sink, 205.0f, 140.0f);
2709 line_to(sink, 195.0f, 140.0f);
2710 ID2D1GeometrySink_EndFigure(sink, D2D1_FIGURE_END_CLOSED);
2713 static void fill_geometry_sink_bezier(ID2D1GeometrySink *sink, unsigned int hollow_count)
2715 D2D1_FIGURE_BEGIN begin;
2716 unsigned int idx = 0;
2717 D2D1_POINT_2F point;
2719 set_point(&point, 5.0f, 160.0f);
2720 begin = idx++ < hollow_count ? D2D1_FIGURE_BEGIN_HOLLOW : D2D1_FIGURE_BEGIN_FILLED;
2721 ID2D1GeometrySink_BeginFigure(sink, point, begin);
2722 quadratic_to(sink, 40.0f, 160.0f, 40.0f, 20.0f);
2723 quadratic_to(sink, 40.0f, 160.0f, 75.0f, 160.0f);
2724 quadratic_to(sink, 40.0f, 160.0f, 40.0f, 300.0f);
2725 quadratic_to(sink, 40.0f, 160.0f, 5.0f, 160.0f);
2726 ID2D1GeometrySink_EndFigure(sink, D2D1_FIGURE_END_CLOSED);
2728 set_point(&point, 20.0f, 160.0f);
2729 begin = idx++ < hollow_count ? D2D1_FIGURE_BEGIN_HOLLOW : D2D1_FIGURE_BEGIN_FILLED;
2730 ID2D1GeometrySink_BeginFigure(sink, point, begin);
2731 quadratic_to(sink, 20.0f, 80.0f, 40.0f, 80.0f);
2732 quadratic_to(sink, 60.0f, 80.0f, 60.0f, 160.0f);
2733 quadratic_to(sink, 60.0f, 240.0f, 40.0f, 240.0f);
2734 quadratic_to(sink, 20.0f, 240.0f, 20.0f, 160.0f);
2735 ID2D1GeometrySink_EndFigure(sink, D2D1_FIGURE_END_CLOSED);
2737 set_point(&point, 5.0f, 612.0f);
2738 begin = idx++ < hollow_count ? D2D1_FIGURE_BEGIN_HOLLOW : D2D1_FIGURE_BEGIN_FILLED;
2739 ID2D1GeometrySink_BeginFigure(sink, point, begin);
2740 quadratic_to(sink, 40.0f, 612.0f, 40.0f, 752.0f);
2741 quadratic_to(sink, 40.0f, 612.0f, 75.0f, 612.0f);
2742 quadratic_to(sink, 40.0f, 612.0f, 40.0f, 472.0f);
2743 quadratic_to(sink, 40.0f, 612.0f, 5.0f, 612.0f);
2744 ID2D1GeometrySink_EndFigure(sink, D2D1_FIGURE_END_CLOSED);
2746 set_point(&point, 20.0f, 612.0f);
2747 begin = idx++ < hollow_count ? D2D1_FIGURE_BEGIN_HOLLOW : D2D1_FIGURE_BEGIN_FILLED;
2748 ID2D1GeometrySink_BeginFigure(sink, point, begin);
2749 quadratic_to(sink, 20.0f, 692.0f, 40.0f, 692.0f);
2750 quadratic_to(sink, 60.0f, 692.0f, 60.0f, 612.0f);
2751 quadratic_to(sink, 60.0f, 532.0f, 40.0f, 532.0f);
2752 quadratic_to(sink, 20.0f, 532.0f, 20.0f, 612.0f);
2753 ID2D1GeometrySink_EndFigure(sink, D2D1_FIGURE_END_CLOSED);
2756 static void test_path_geometry(BOOL d3d11)
2758 ID2D1TransformedGeometry *transformed_geometry;
2759 D2D1_MATRIX_3X2_F matrix, tmp_matrix;
2760 ID2D1GeometrySink *sink, *tmp_sink;
2761 struct geometry_sink simplify_sink;
2762 D2D1_POINT_2F point = {0.0f, 0.0f};
2763 struct d2d1_test_context ctx;
2764 ID2D1SolidColorBrush *brush;
2765 ID2D1PathGeometry *geometry;
2766 ID2D1Geometry *tmp_geometry;
2767 ID2D1RenderTarget *rt;
2768 ID2D1Factory *factory;
2769 BOOL match, contains;
2770 D2D1_COLOR_F color;
2771 D2D1_RECT_F rect;
2772 UINT32 count;
2773 HRESULT hr;
2775 static const struct geometry_segment expected_segments[] =
2777 /* Figure 0. */
2778 {SEGMENT_LINE, {{{ 55.0f, 20.0f}}}},
2779 {SEGMENT_LINE, {{{ 55.0f, 220.0f}}}},
2780 {SEGMENT_LINE, {{{ 25.0f, 220.0f}}}},
2781 {SEGMENT_LINE, {{{ 25.0f, 100.0f}}}},
2782 {SEGMENT_LINE, {{{ 75.0f, 100.0f}}}},
2783 {SEGMENT_LINE, {{{ 75.0f, 300.0f}}}},
2784 {SEGMENT_LINE, {{{ 5.0f, 300.0f}}}},
2785 {SEGMENT_LINE, {{{ 5.0f, 60.0f}}}},
2786 {SEGMENT_LINE, {{{ 45.0f, 60.0f}}}},
2787 {SEGMENT_LINE, {{{ 45.0f, 180.0f}}}},
2788 {SEGMENT_LINE, {{{ 35.0f, 180.0f}}}},
2789 {SEGMENT_LINE, {{{ 35.0f, 140.0f}}}},
2790 {SEGMENT_LINE, {{{ 65.0f, 140.0f}}}},
2791 {SEGMENT_LINE, {{{ 65.0f, 260.0f}}}},
2792 {SEGMENT_LINE, {{{ 15.0f, 260.0f}}}},
2793 /* Figure 1. */
2794 {SEGMENT_LINE, {{{155.0f, 160.0f}}}},
2795 {SEGMENT_LINE, {{{ 85.0f, 160.0f}}}},
2796 {SEGMENT_LINE, {{{ 85.0f, 300.0f}}}},
2797 {SEGMENT_LINE, {{{120.0f, 300.0f}}}},
2798 {SEGMENT_LINE, {{{120.0f, 20.0f}}}},
2799 {SEGMENT_LINE, {{{155.0f, 20.0f}}}},
2800 {SEGMENT_LINE, {{{155.0f, 160.0f}}}},
2801 {SEGMENT_LINE, {{{ 85.0f, 160.0f}}}},
2802 {SEGMENT_LINE, {{{ 85.0f, 20.0f}}}},
2803 {SEGMENT_LINE, {{{120.0f, 20.0f}}}},
2804 {SEGMENT_LINE, {{{120.0f, 300.0f}}}},
2805 /* Figure 2. */
2806 {SEGMENT_LINE, {{{165.0f, 300.0f}}}},
2807 {SEGMENT_LINE, {{{235.0f, 300.0f}}}},
2808 {SEGMENT_LINE, {{{235.0f, 20.0f}}}},
2809 /* Figure 3. */
2810 {SEGMENT_LINE, {{{225.0f, 260.0f}}}},
2811 {SEGMENT_LINE, {{{175.0f, 260.0f}}}},
2812 {SEGMENT_LINE, {{{175.0f, 60.0f}}}},
2813 /* Figure 4. */
2814 {SEGMENT_LINE, {{{185.0f, 220.0f}}}},
2815 {SEGMENT_LINE, {{{185.0f, 100.0f}}}},
2816 {SEGMENT_LINE, {{{215.0f, 100.0f}}}},
2817 /* Figure 5. */
2818 {SEGMENT_LINE, {{{205.0f, 180.0f}}}},
2819 {SEGMENT_LINE, {{{205.0f, 140.0f}}}},
2820 {SEGMENT_LINE, {{{195.0f, 140.0f}}}},
2821 /* Figure 6. */
2822 {SEGMENT_LINE, {{{135.0f, 620.0f}}}},
2823 {SEGMENT_LINE, {{{135.0f, 420.0f}}}},
2824 {SEGMENT_LINE, {{{105.0f, 420.0f}}}},
2825 {SEGMENT_LINE, {{{105.0f, 540.0f}}}},
2826 {SEGMENT_LINE, {{{155.0f, 540.0f}}}},
2827 {SEGMENT_LINE, {{{155.0f, 340.0f}}}},
2828 {SEGMENT_LINE, {{{ 85.0f, 340.0f}}}},
2829 {SEGMENT_LINE, {{{ 85.0f, 580.0f}}}},
2830 {SEGMENT_LINE, {{{125.0f, 580.0f}}}},
2831 {SEGMENT_LINE, {{{125.0f, 460.0f}}}},
2832 {SEGMENT_LINE, {{{115.0f, 460.0f}}}},
2833 {SEGMENT_LINE, {{{115.0f, 500.0f}}}},
2834 {SEGMENT_LINE, {{{145.0f, 500.0f}}}},
2835 {SEGMENT_LINE, {{{145.0f, 380.0f}}}},
2836 {SEGMENT_LINE, {{{ 95.0f, 380.0f}}}},
2837 /* Figure 7. */
2838 {SEGMENT_LINE, {{{235.0f, 480.0f}}}},
2839 {SEGMENT_LINE, {{{165.0f, 480.0f}}}},
2840 {SEGMENT_LINE, {{{165.0f, 340.0f}}}},
2841 {SEGMENT_LINE, {{{200.0f, 340.0f}}}},
2842 {SEGMENT_LINE, {{{200.0f, 620.0f}}}},
2843 {SEGMENT_LINE, {{{235.0f, 620.0f}}}},
2844 {SEGMENT_LINE, {{{235.0f, 480.0f}}}},
2845 {SEGMENT_LINE, {{{165.0f, 480.0f}}}},
2846 {SEGMENT_LINE, {{{165.0f, 620.0f}}}},
2847 {SEGMENT_LINE, {{{200.0f, 620.0f}}}},
2848 {SEGMENT_LINE, {{{200.0f, 340.0f}}}},
2849 /* Figure 8. */
2850 {SEGMENT_LINE, {{{245.0f, 340.0f}}}},
2851 {SEGMENT_LINE, {{{315.0f, 340.0f}}}},
2852 {SEGMENT_LINE, {{{315.0f, 620.0f}}}},
2853 /* Figure 9. */
2854 {SEGMENT_LINE, {{{305.0f, 380.0f}}}},
2855 {SEGMENT_LINE, {{{255.0f, 380.0f}}}},
2856 {SEGMENT_LINE, {{{255.0f, 580.0f}}}},
2857 /* Figure 10. */
2858 {SEGMENT_LINE, {{{265.0f, 420.0f}}}},
2859 {SEGMENT_LINE, {{{265.0f, 540.0f}}}},
2860 {SEGMENT_LINE, {{{295.0f, 540.0f}}}},
2861 /* Figure 11. */
2862 {SEGMENT_LINE, {{{285.0f, 460.0f}}}},
2863 {SEGMENT_LINE, {{{285.0f, 500.0f}}}},
2864 {SEGMENT_LINE, {{{275.0f, 500.0f}}}},
2865 /* Figure 12. */
2866 {SEGMENT_BEZIER, {{{2.83333340e+01f, 1.60000000e+02f},
2867 {4.00000000e+01f, 1.13333336e+02f},
2868 {4.00000000e+01f, 2.00000000e+01f}}}},
2869 {SEGMENT_BEZIER, {{{4.00000000e+01f, 1.13333336e+02f},
2870 {5.16666641e+01f, 1.60000000e+02f},
2871 {7.50000000e+01f, 1.60000000e+02f}}}},
2872 {SEGMENT_BEZIER, {{{5.16666641e+01f, 1.60000000e+02f},
2873 {4.00000000e+01f, 2.06666656e+02f},
2874 {4.00000000e+01f, 3.00000000e+02f}}}},
2875 {SEGMENT_BEZIER, {{{4.00000000e+01f, 2.06666656e+02f},
2876 {2.83333340e+01f, 1.60000000e+02f},
2877 {5.00000000e+00f, 1.60000000e+02f}}}},
2878 /* Figure 13. */
2879 {SEGMENT_BEZIER, {{{2.00000000e+01f, 1.06666664e+02f},
2880 {2.66666660e+01f, 8.00000000e+01f},
2881 {4.00000000e+01f, 8.00000000e+01f}}}},
2882 {SEGMENT_BEZIER, {{{5.33333321e+01f, 8.00000000e+01f},
2883 {6.00000000e+01f, 1.06666664e+02f},
2884 {6.00000000e+01f, 1.60000000e+02f}}}},
2885 {SEGMENT_BEZIER, {{{6.00000000e+01f, 2.13333328e+02f},
2886 {5.33333321e+01f, 2.40000000e+02f},
2887 {4.00000000e+01f, 2.40000000e+02f}}}},
2888 {SEGMENT_BEZIER, {{{2.66666660e+01f, 2.40000000e+02f},
2889 {2.00000000e+01f, 2.13333328e+02f},
2890 {2.00000000e+01f, 1.60000000e+02f}}}},
2891 /* Figure 14. */
2892 {SEGMENT_BEZIER, {{{2.83333340e+01f, 6.12000000e+02f},
2893 {4.00000000e+01f, 6.58666687e+02f},
2894 {4.00000000e+01f, 7.52000000e+02f}}}},
2895 {SEGMENT_BEZIER, {{{4.00000000e+01f, 6.58666687e+02f},
2896 {5.16666641e+01f, 6.12000000e+02f},
2897 {7.50000000e+01f, 6.12000000e+02f}}}},
2898 {SEGMENT_BEZIER, {{{5.16666641e+01f, 6.12000000e+02f},
2899 {4.00000000e+01f, 5.65333313e+02f},
2900 {4.00000000e+01f, 4.72000000e+02f}}}},
2901 {SEGMENT_BEZIER, {{{4.00000000e+01f, 5.65333313e+02f},
2902 {2.83333340e+01f, 6.12000000e+02f},
2903 {5.00000000e+00f, 6.12000000e+02f}}}},
2904 /* Figure 15. */
2905 {SEGMENT_BEZIER, {{{2.00000000e+01f, 6.65333313e+02f},
2906 {2.66666660e+01f, 6.92000000e+02f},
2907 {4.00000000e+01f, 6.92000000e+02f}}}},
2908 {SEGMENT_BEZIER, {{{5.33333321e+01f, 6.92000000e+02f},
2909 {6.00000000e+01f, 6.65333313e+02f},
2910 {6.00000000e+01f, 6.12000000e+02f}}}},
2911 {SEGMENT_BEZIER, {{{6.00000000e+01f, 5.58666687e+02f},
2912 {5.33333321e+01f, 5.32000000e+02f},
2913 {4.00000000e+01f, 5.32000000e+02f}}}},
2914 {SEGMENT_BEZIER, {{{2.66666660e+01f, 5.32000000e+02f},
2915 {2.00000000e+01f, 5.58666687e+02f},
2916 {2.00000000e+01f, 6.12000000e+02f}}}},
2917 /* Figure 16. */
2918 {SEGMENT_BEZIER, {{{1.91750427e+02f, 1.27275856e+02f},
2919 {2.08249573e+02f, 1.27275856e+02f},
2920 {2.24748734e+02f, 6.12792168e+01f}}}},
2921 {SEGMENT_BEZIER, {{{2.08249573e+02f, 1.27275856e+02f},
2922 {2.08249573e+02f, 1.93272476e+02f},
2923 {2.24748734e+02f, 2.59269104e+02f}}}},
2924 {SEGMENT_BEZIER, {{{2.08249573e+02f, 1.93272476e+02f},
2925 {1.91750427e+02f, 1.93272476e+02f},
2926 {1.75251266e+02f, 2.59269104e+02f}}}},
2927 {SEGMENT_BEZIER, {{{1.91750427e+02f, 1.93272476e+02f},
2928 {1.91750427e+02f, 1.27275856e+02f},
2929 {1.75251266e+02f, 6.12792168e+01f}}}},
2930 /* Figure 17. */
2931 {SEGMENT_BEZIER, {{{1.95285950e+02f, 6.59932632e+01f},
2932 {2.04714050e+02f, 6.59932632e+01f},
2933 {2.14142136e+02f, 1.03705627e+02f}}}},
2934 {SEGMENT_BEZIER, {{{2.23570221e+02f, 1.41417984e+02f},
2935 {2.23570221e+02f, 1.79130356e+02f},
2936 {2.14142136e+02f, 2.16842712e+02f}}}},
2937 {SEGMENT_BEZIER, {{{2.04714050e+02f, 2.54555069e+02f},
2938 {1.95285950e+02f, 2.54555069e+02f},
2939 {1.85857864e+02f, 2.16842712e+02f}}}},
2940 {SEGMENT_BEZIER, {{{1.76429779e+02f, 1.79130356e+02f},
2941 {1.76429779e+02f, 1.41417984e+02f},
2942 {1.85857864e+02f, 1.03705627e+02f}}}},
2943 /* Figure 18. */
2944 {SEGMENT_BEZIER, {{{1.11847351e+02f, 4.46888092e+02f},
2945 {1.11847351e+02f, 5.12884705e+02f},
2946 {9.53481979e+01f, 5.78881348e+02f}}}},
2947 {SEGMENT_BEZIER, {{{1.11847351e+02f, 5.12884705e+02f},
2948 {1.28346512e+02f, 5.12884705e+02f},
2949 {1.44845673e+02f, 5.78881348e+02f}}}},
2950 {SEGMENT_BEZIER, {{{1.28346512e+02f, 5.12884705e+02f},
2951 {1.28346512e+02f, 4.46888092e+02f},
2952 {1.44845673e+02f, 3.80891479e+02f}}}},
2953 {SEGMENT_BEZIER, {{{1.28346512e+02f, 4.46888092e+02f},
2954 {1.11847351e+02f, 4.46888092e+02f},
2955 {9.53481979e+01f, 3.80891479e+02f}}}},
2956 /* Figure 19. */
2957 {SEGMENT_BEZIER, {{{9.65267105e+01f, 4.61030243e+02f},
2958 {9.65267105e+01f, 4.98742584e+02f},
2959 {1.05954803e+02f, 5.36454956e+02f}}}},
2960 {SEGMENT_BEZIER, {{{1.15382889e+02f, 5.74167297e+02f},
2961 {1.24810982e+02f, 5.74167297e+02f},
2962 {1.34239075e+02f, 5.36454956e+02f}}}},
2963 {SEGMENT_BEZIER, {{{1.43667160e+02f, 4.98742584e+02f},
2964 {1.43667160e+02f, 4.61030243e+02f},
2965 {1.34239075e+02f, 4.23317871e+02f}}}},
2966 {SEGMENT_BEZIER, {{{1.24810982e+02f, 3.85605499e+02f},
2967 {1.15382889e+02f, 3.85605499e+02f},
2968 {1.05954803e+02f, 4.23317871e+02f}}}},
2969 /* Figure 20. */
2970 {SEGMENT_LINE, {{{ 40.0f, 20.0f}}}},
2971 {SEGMENT_LINE, {{{ 75.0f, 160.0f}}}},
2972 {SEGMENT_LINE, {{{ 40.0f, 300.0f}}}},
2973 {SEGMENT_LINE, {{{ 5.0f, 160.0f}}}},
2974 /* Figure 21. */
2975 {SEGMENT_LINE, {{{ 40.0f, 80.0f}}}},
2976 {SEGMENT_LINE, {{{ 60.0f, 160.0f}}}},
2977 {SEGMENT_LINE, {{{ 40.0f, 240.0f}}}},
2978 {SEGMENT_LINE, {{{ 20.0f, 160.0f}}}},
2979 /* Figure 22. */
2980 {SEGMENT_LINE, {{{ 40.0f, 752.0f}}}},
2981 {SEGMENT_LINE, {{{ 75.0f, 612.0f}}}},
2982 {SEGMENT_LINE, {{{ 40.0f, 472.0f}}}},
2983 {SEGMENT_LINE, {{{ 5.0f, 612.0f}}}},
2984 /* Figure 23. */
2985 {SEGMENT_LINE, {{{ 40.0f, 692.0f}}}},
2986 {SEGMENT_LINE, {{{ 60.0f, 612.0f}}}},
2987 {SEGMENT_LINE, {{{ 40.0f, 532.0f}}}},
2988 {SEGMENT_LINE, {{{ 20.0f, 612.0f}}}},
2989 /* Figure 24. */
2990 {SEGMENT_LINE, {{{2.03125019e+01f, 1.51250000e+02f}}}},
2991 {SEGMENT_LINE, {{{3.12500019e+01f, 1.25000008e+02f}}}, D2D1_PATH_SEGMENT_FORCE_ROUND_LINE_JOIN},
2992 {SEGMENT_LINE, {{{3.78125000e+01f, 8.12500076e+01f}}}, D2D1_PATH_SEGMENT_FORCE_ROUND_LINE_JOIN},
2993 {SEGMENT_LINE, {{{4.00000000e+01f, 2.00000000e+01f}}}, D2D1_PATH_SEGMENT_FORCE_ROUND_LINE_JOIN},
2994 {SEGMENT_LINE, {{{4.21875000e+01f, 8.12500076e+01f}}}},
2995 {SEGMENT_LINE, {{{4.87500000e+01f, 1.25000008e+02f}}}, D2D1_PATH_SEGMENT_FORCE_ROUND_LINE_JOIN},
2996 {SEGMENT_LINE, {{{5.96875000e+01f, 1.51250000e+02f}}}, D2D1_PATH_SEGMENT_FORCE_ROUND_LINE_JOIN},
2997 {SEGMENT_LINE, {{{7.50000000e+01f, 1.60000000e+02f}}}, D2D1_PATH_SEGMENT_FORCE_ROUND_LINE_JOIN},
2998 {SEGMENT_LINE, {{{5.96875000e+01f, 1.68750000e+02f}}}},
2999 {SEGMENT_LINE, {{{4.87500000e+01f, 1.95000000e+02f}}}, D2D1_PATH_SEGMENT_FORCE_ROUND_LINE_JOIN},
3000 {SEGMENT_LINE, {{{4.21875000e+01f, 2.38750000e+02f}}}, D2D1_PATH_SEGMENT_FORCE_ROUND_LINE_JOIN},
3001 {SEGMENT_LINE, {{{4.00000000e+01f, 3.00000000e+02f}}}, D2D1_PATH_SEGMENT_FORCE_ROUND_LINE_JOIN},
3002 {SEGMENT_LINE, {{{3.78125000e+01f, 2.38750000e+02f}}}},
3003 {SEGMENT_LINE, {{{3.12500019e+01f, 1.95000000e+02f}}}, D2D1_PATH_SEGMENT_FORCE_ROUND_LINE_JOIN},
3004 {SEGMENT_LINE, {{{2.03125019e+01f, 1.68750000e+02f}}}, D2D1_PATH_SEGMENT_FORCE_ROUND_LINE_JOIN},
3005 {SEGMENT_LINE, {{{5.00000000e+00f, 1.60000000e+02f}}}, D2D1_PATH_SEGMENT_FORCE_ROUND_LINE_JOIN},
3006 /* Figure 25. */
3007 {SEGMENT_LINE, {{{2.50000000e+01f, 1.00000000e+02f}}}},
3008 {SEGMENT_LINE, {{{4.00000000e+01f, 8.00000000e+01f}}}, D2D1_PATH_SEGMENT_FORCE_ROUND_LINE_JOIN},
3009 {SEGMENT_LINE, {{{5.50000000e+01f, 1.00000000e+02f}}}},
3010 {SEGMENT_LINE, {{{6.00000000e+01f, 1.60000000e+02f}}}, D2D1_PATH_SEGMENT_FORCE_ROUND_LINE_JOIN},
3011 {SEGMENT_LINE, {{{5.50000000e+01f, 2.20000000e+02f}}}},
3012 {SEGMENT_LINE, {{{4.00000000e+01f, 2.40000000e+02f}}}, D2D1_PATH_SEGMENT_FORCE_ROUND_LINE_JOIN},
3013 {SEGMENT_LINE, {{{2.50000000e+01f, 2.20000000e+02f}}}},
3014 {SEGMENT_LINE, {{{2.00000000e+01f, 1.60000000e+02f}}}, D2D1_PATH_SEGMENT_FORCE_ROUND_LINE_JOIN},
3015 /* Figure 26. */
3016 {SEGMENT_LINE, {{{2.03125019e+01f, 6.20750000e+02f}}}},
3017 {SEGMENT_LINE, {{{3.12500019e+01f, 6.47000000e+02f}}}, D2D1_PATH_SEGMENT_FORCE_ROUND_LINE_JOIN},
3018 {SEGMENT_LINE, {{{3.78125000e+01f, 6.90750000e+02f}}}, D2D1_PATH_SEGMENT_FORCE_ROUND_LINE_JOIN},
3019 {SEGMENT_LINE, {{{4.00000000e+01f, 7.52000000e+02f}}}, D2D1_PATH_SEGMENT_FORCE_ROUND_LINE_JOIN},
3020 {SEGMENT_LINE, {{{4.21875000e+01f, 6.90750000e+02f}}}},
3021 {SEGMENT_LINE, {{{4.87500000e+01f, 6.47000000e+02f}}}, D2D1_PATH_SEGMENT_FORCE_ROUND_LINE_JOIN},
3022 {SEGMENT_LINE, {{{5.96875000e+01f, 6.20750000e+02f}}}, D2D1_PATH_SEGMENT_FORCE_ROUND_LINE_JOIN},
3023 {SEGMENT_LINE, {{{7.50000000e+01f, 6.12000000e+02f}}}, D2D1_PATH_SEGMENT_FORCE_ROUND_LINE_JOIN},
3024 {SEGMENT_LINE, {{{5.96875000e+01f, 6.03250000e+02f}}}},
3025 {SEGMENT_LINE, {{{4.87500000e+01f, 5.77000000e+02f}}}, D2D1_PATH_SEGMENT_FORCE_ROUND_LINE_JOIN},
3026 {SEGMENT_LINE, {{{4.21875000e+01f, 5.33250000e+02f}}}, D2D1_PATH_SEGMENT_FORCE_ROUND_LINE_JOIN},
3027 {SEGMENT_LINE, {{{4.00000000e+01f, 4.72000000e+02f}}}, D2D1_PATH_SEGMENT_FORCE_ROUND_LINE_JOIN},
3028 {SEGMENT_LINE, {{{3.78125000e+01f, 5.33250000e+02f}}}},
3029 {SEGMENT_LINE, {{{3.12500019e+01f, 5.77000000e+02f}}}, D2D1_PATH_SEGMENT_FORCE_ROUND_LINE_JOIN},
3030 {SEGMENT_LINE, {{{2.03125019e+01f, 6.03250000e+02f}}}, D2D1_PATH_SEGMENT_FORCE_ROUND_LINE_JOIN},
3031 {SEGMENT_LINE, {{{5.00000000e+00f, 6.12000000e+02f}}}, D2D1_PATH_SEGMENT_FORCE_ROUND_LINE_JOIN},
3032 /* Figure 27. */
3033 {SEGMENT_LINE, {{{2.50000000e+01f, 6.72000000e+02f}}}},
3034 {SEGMENT_LINE, {{{4.00000000e+01f, 6.92000000e+02f}}}, D2D1_PATH_SEGMENT_FORCE_ROUND_LINE_JOIN},
3035 {SEGMENT_LINE, {{{5.50000000e+01f, 6.72000000e+02f}}}},
3036 {SEGMENT_LINE, {{{6.00000000e+01f, 6.12000000e+02f}}}, D2D1_PATH_SEGMENT_FORCE_ROUND_LINE_JOIN},
3037 {SEGMENT_LINE, {{{5.50000000e+01f, 5.52000000e+02f}}}},
3038 {SEGMENT_LINE, {{{4.00000000e+01f, 5.32000000e+02f}}}, D2D1_PATH_SEGMENT_FORCE_ROUND_LINE_JOIN},
3039 {SEGMENT_LINE, {{{2.50000000e+01f, 5.52000000e+02f}}}},
3040 {SEGMENT_LINE, {{{2.00000000e+01f, 6.12000000e+02f}}}, D2D1_PATH_SEGMENT_FORCE_ROUND_LINE_JOIN},
3041 /* Figure 28. */
3042 {SEGMENT_LINE, {{{ 75.0f, 300.0f}}}},
3043 {SEGMENT_LINE, {{{ 5.0f, 300.0f}}}},
3045 static const struct expected_geometry_figure expected_figures[] =
3047 /* 0 */
3048 {D2D1_FIGURE_BEGIN_FILLED, D2D1_FIGURE_END_CLOSED, { 15.0f, 20.0f}, 15, &expected_segments[0]},
3049 {D2D1_FIGURE_BEGIN_FILLED, D2D1_FIGURE_END_CLOSED, {155.0f, 300.0f}, 11, &expected_segments[15]},
3050 {D2D1_FIGURE_BEGIN_FILLED, D2D1_FIGURE_END_CLOSED, {165.0f, 20.0f}, 3, &expected_segments[26]},
3051 {D2D1_FIGURE_BEGIN_FILLED, D2D1_FIGURE_END_CLOSED, {225.0f, 60.0f}, 3, &expected_segments[29]},
3052 {D2D1_FIGURE_BEGIN_FILLED, D2D1_FIGURE_END_CLOSED, {215.0f, 220.0f}, 3, &expected_segments[32]},
3053 {D2D1_FIGURE_BEGIN_FILLED, D2D1_FIGURE_END_CLOSED, {195.0f, 180.0f}, 3, &expected_segments[35]},
3054 /* 6 */
3055 {D2D1_FIGURE_BEGIN_FILLED, D2D1_FIGURE_END_CLOSED, { 95.0f, 620.0f}, 15, &expected_segments[38]},
3056 {D2D1_FIGURE_BEGIN_FILLED, D2D1_FIGURE_END_CLOSED, {235.0f, 340.0f}, 11, &expected_segments[53]},
3057 {D2D1_FIGURE_BEGIN_FILLED, D2D1_FIGURE_END_CLOSED, {245.0f, 620.0f}, 3, &expected_segments[64]},
3058 {D2D1_FIGURE_BEGIN_FILLED, D2D1_FIGURE_END_CLOSED, {305.0f, 580.0f}, 3, &expected_segments[67]},
3059 {D2D1_FIGURE_BEGIN_FILLED, D2D1_FIGURE_END_CLOSED, {295.0f, 420.0f}, 3, &expected_segments[70]},
3060 {D2D1_FIGURE_BEGIN_FILLED, D2D1_FIGURE_END_CLOSED, {275.0f, 460.0f}, 3, &expected_segments[73]},
3061 /* 12 */
3062 {D2D1_FIGURE_BEGIN_FILLED, D2D1_FIGURE_END_CLOSED, { 5.0f, 160.0f}, 4, &expected_segments[76]},
3063 {D2D1_FIGURE_BEGIN_FILLED, D2D1_FIGURE_END_CLOSED, { 20.0f, 160.0f}, 4, &expected_segments[80]},
3064 {D2D1_FIGURE_BEGIN_FILLED, D2D1_FIGURE_END_CLOSED, { 5.0f, 612.0f}, 4, &expected_segments[84]},
3065 {D2D1_FIGURE_BEGIN_FILLED, D2D1_FIGURE_END_CLOSED, { 20.0f, 612.0f}, 4, &expected_segments[88]},
3066 /* 16 */
3067 {D2D1_FIGURE_BEGIN_FILLED, D2D1_FIGURE_END_CLOSED,
3068 {1.75251266e+02f, 6.12792168e+01f}, 4, &expected_segments[92]},
3069 {D2D1_FIGURE_BEGIN_FILLED, D2D1_FIGURE_END_CLOSED,
3070 {1.85857864e+02f, 1.03705627e+02f}, 4, &expected_segments[96]},
3071 {D2D1_FIGURE_BEGIN_FILLED, D2D1_FIGURE_END_CLOSED,
3072 {9.53481979e+01f, 3.80891479e+02f}, 4, &expected_segments[100]},
3073 {D2D1_FIGURE_BEGIN_FILLED, D2D1_FIGURE_END_CLOSED,
3074 {1.05954803e+02f, 4.23317871e+02f}, 4, &expected_segments[104]},
3075 /* 20 */
3076 {D2D1_FIGURE_BEGIN_FILLED, D2D1_FIGURE_END_CLOSED, { 5.0f, 160.0f}, 4, &expected_segments[108]},
3077 {D2D1_FIGURE_BEGIN_FILLED, D2D1_FIGURE_END_CLOSED, { 20.0f, 160.0f}, 4, &expected_segments[112]},
3078 {D2D1_FIGURE_BEGIN_FILLED, D2D1_FIGURE_END_CLOSED, { 5.0f, 612.0f}, 4, &expected_segments[116]},
3079 {D2D1_FIGURE_BEGIN_FILLED, D2D1_FIGURE_END_CLOSED, { 20.0f, 612.0f}, 4, &expected_segments[120]},
3080 /* 24 */
3081 {D2D1_FIGURE_BEGIN_FILLED, D2D1_FIGURE_END_CLOSED, { 5.0f, 160.0f}, 16, &expected_segments[124]},
3082 {D2D1_FIGURE_BEGIN_FILLED, D2D1_FIGURE_END_CLOSED, { 20.0f, 160.0f}, 8, &expected_segments[140]},
3083 {D2D1_FIGURE_BEGIN_FILLED, D2D1_FIGURE_END_CLOSED, { 5.0f, 612.0f}, 16, &expected_segments[148]},
3084 {D2D1_FIGURE_BEGIN_FILLED, D2D1_FIGURE_END_CLOSED, { 20.0f, 612.0f}, 8, &expected_segments[164]},
3085 /* 28 */
3086 {D2D1_FIGURE_BEGIN_HOLLOW, D2D1_FIGURE_END_OPEN, { 40.0f, 20.0f}, 2, &expected_segments[172]},
3089 if (!init_test_context(&ctx, d3d11))
3090 return;
3092 rt = ctx.rt;
3093 ID2D1RenderTarget_GetFactory(rt, &factory);
3095 ID2D1RenderTarget_SetDpi(rt, 192.0f, 48.0f);
3096 ID2D1RenderTarget_SetAntialiasMode(rt, D2D1_ANTIALIAS_MODE_ALIASED);
3097 set_color(&color, 0.890f, 0.851f, 0.600f, 1.0f);
3098 hr = ID2D1RenderTarget_CreateSolidColorBrush(rt, &color, NULL, &brush);
3099 ok(SUCCEEDED(hr), "Failed to create brush, hr %#x.\n", hr);
3101 /* Close() when closed. */
3102 hr = ID2D1Factory_CreatePathGeometry(factory, &geometry);
3103 ok(SUCCEEDED(hr), "Failed to create path geometry, hr %#x.\n", hr);
3104 hr = ID2D1PathGeometry_GetFigureCount(geometry, &count);
3105 ok(hr == D2DERR_WRONG_STATE, "Got unexpected hr %#x.\n", hr);
3106 hr = ID2D1PathGeometry_GetSegmentCount(geometry, &count);
3107 ok(hr == D2DERR_WRONG_STATE, "Got unexpected hr %#x.\n", hr);
3108 hr = ID2D1PathGeometry_Open(geometry, &sink);
3109 ok(SUCCEEDED(hr), "Failed to open geometry sink, hr %#x.\n", hr);
3110 hr = ID2D1PathGeometry_GetFigureCount(geometry, &count);
3111 ok(hr == D2DERR_WRONG_STATE, "Got unexpected hr %#x.\n", hr);
3112 hr = ID2D1PathGeometry_GetSegmentCount(geometry, &count);
3113 ok(hr == D2DERR_WRONG_STATE, "Got unexpected hr %#x.\n", hr);
3114 hr = ID2D1GeometrySink_Close(sink);
3115 ok(SUCCEEDED(hr), "Failed to close geometry sink, hr %#x.\n", hr);
3116 hr = ID2D1PathGeometry_GetFigureCount(geometry, &count);
3117 ok(SUCCEEDED(hr), "Failed to get figure count, hr %#x.\n", hr);
3118 ok(!count, "Got unexpected figure count %u.\n", count);
3119 hr = ID2D1PathGeometry_GetSegmentCount(geometry, &count);
3120 ok(SUCCEEDED(hr), "Failed to get segment count, hr %#x.\n", hr);
3121 ok(!count, "Got unexpected segment count %u.\n", count);
3122 hr = ID2D1GeometrySink_Close(sink);
3123 ok(hr == D2DERR_WRONG_STATE, "Got unexpected hr %#x.\n", hr);
3124 ID2D1GeometrySink_Release(sink);
3125 hr = ID2D1PathGeometry_GetFigureCount(geometry, &count);
3126 ok(SUCCEEDED(hr), "Failed to get figure count, hr %#x.\n", hr);
3127 ok(!count, "Got unexpected figure count %u.\n", count);
3128 hr = ID2D1PathGeometry_GetSegmentCount(geometry, &count);
3129 ok(SUCCEEDED(hr), "Failed to get segment count, hr %#x.\n", hr);
3130 ok(!count, "Got unexpected segment count %u.\n", count);
3131 ID2D1PathGeometry_Release(geometry);
3133 /* Open() when closed. */
3134 hr = ID2D1Factory_CreatePathGeometry(factory, &geometry);
3135 ok(SUCCEEDED(hr), "Failed to create path geometry, hr %#x.\n", hr);
3136 hr = ID2D1PathGeometry_Open(geometry, &sink);
3137 ok(SUCCEEDED(hr), "Failed to open geometry sink, hr %#x.\n", hr);
3138 hr = ID2D1GeometrySink_Close(sink);
3139 ok(SUCCEEDED(hr), "Failed to close geometry sink, hr %#x.\n", hr);
3140 ID2D1GeometrySink_Release(sink);
3141 hr = ID2D1PathGeometry_Open(geometry, &sink);
3142 ok(hr == D2DERR_WRONG_STATE, "Got unexpected hr %#x.\n", hr);
3143 hr = ID2D1PathGeometry_GetFigureCount(geometry, &count);
3144 ok(SUCCEEDED(hr), "Failed to get figure count, hr %#x.\n", hr);
3145 ok(!count, "Got unexpected figure count %u.\n", count);
3146 hr = ID2D1PathGeometry_GetSegmentCount(geometry, &count);
3147 ok(SUCCEEDED(hr), "Failed to get segment count, hr %#x.\n", hr);
3148 ok(!count, "Got unexpected segment count %u.\n", count);
3149 ID2D1PathGeometry_Release(geometry);
3151 /* Open() when open. */
3152 hr = ID2D1Factory_CreatePathGeometry(factory, &geometry);
3153 ok(SUCCEEDED(hr), "Failed to create path geometry, hr %#x.\n", hr);
3154 hr = ID2D1PathGeometry_Open(geometry, &sink);
3155 ok(SUCCEEDED(hr), "Failed to open geometry sink, hr %#x.\n", hr);
3156 hr = ID2D1PathGeometry_Open(geometry, &tmp_sink);
3157 ok(hr == D2DERR_WRONG_STATE, "Got unexpected hr %#x.\n", hr);
3158 hr = ID2D1GeometrySink_Close(sink);
3159 ok(SUCCEEDED(hr), "Failed to close geometry sink, hr %#x.\n", hr);
3160 ID2D1GeometrySink_Release(sink);
3161 hr = ID2D1PathGeometry_GetFigureCount(geometry, &count);
3162 ok(SUCCEEDED(hr), "Failed to get figure count, hr %#x.\n", hr);
3163 ok(!count, "Got unexpected figure count %u.\n", count);
3164 hr = ID2D1PathGeometry_GetSegmentCount(geometry, &count);
3165 ok(SUCCEEDED(hr), "Failed to get segment count, hr %#x.\n", hr);
3166 ok(!count, "Got unexpected segment count %u.\n", count);
3167 ID2D1PathGeometry_Release(geometry);
3169 /* BeginFigure() without EndFigure(). */
3170 hr = ID2D1Factory_CreatePathGeometry(factory, &geometry);
3171 ok(SUCCEEDED(hr), "Failed to create path geometry, hr %#x.\n", hr);
3172 hr = ID2D1PathGeometry_Open(geometry, &sink);
3173 ok(SUCCEEDED(hr), "Failed to open geometry sink, hr %#x.\n", hr);
3174 ID2D1GeometrySink_BeginFigure(sink, point, D2D1_FIGURE_BEGIN_FILLED);
3175 hr = ID2D1GeometrySink_Close(sink);
3176 ok(hr == D2DERR_WRONG_STATE, "Got unexpected hr %#x.\n", hr);
3177 ID2D1GeometrySink_EndFigure(sink, D2D1_FIGURE_END_CLOSED);
3178 hr = ID2D1GeometrySink_Close(sink);
3179 ok(hr == D2DERR_WRONG_STATE, "Got unexpected hr %#x.\n", hr);
3180 ID2D1GeometrySink_Release(sink);
3181 hr = ID2D1PathGeometry_GetFigureCount(geometry, &count);
3182 ok(hr == D2DERR_WRONG_STATE, "Got unexpected hr %#x.\n", hr);
3183 hr = ID2D1PathGeometry_GetSegmentCount(geometry, &count);
3184 ok(hr == D2DERR_WRONG_STATE, "Got unexpected hr %#x.\n", hr);
3185 ID2D1PathGeometry_Release(geometry);
3187 /* EndFigure() without BeginFigure(). */
3188 hr = ID2D1Factory_CreatePathGeometry(factory, &geometry);
3189 ok(SUCCEEDED(hr), "Failed to create path geometry, hr %#x.\n", hr);
3190 hr = ID2D1PathGeometry_Open(geometry, &sink);
3191 ok(SUCCEEDED(hr), "Failed to open geometry sink, hr %#x.\n", hr);
3192 ID2D1GeometrySink_EndFigure(sink, D2D1_FIGURE_END_CLOSED);
3193 hr = ID2D1GeometrySink_Close(sink);
3194 ok(hr == D2DERR_WRONG_STATE, "Got unexpected hr %#x.\n", hr);
3195 ID2D1GeometrySink_Release(sink);
3196 hr = ID2D1PathGeometry_GetFigureCount(geometry, &count);
3197 ok(hr == D2DERR_WRONG_STATE, "Got unexpected hr %#x.\n", hr);
3198 hr = ID2D1PathGeometry_GetSegmentCount(geometry, &count);
3199 ok(hr == D2DERR_WRONG_STATE, "Got unexpected hr %#x.\n", hr);
3200 ID2D1PathGeometry_Release(geometry);
3202 /* BeginFigure()/EndFigure() mismatch. */
3203 hr = ID2D1Factory_CreatePathGeometry(factory, &geometry);
3204 ok(SUCCEEDED(hr), "Failed to create path geometry, hr %#x.\n", hr);
3205 hr = ID2D1PathGeometry_Open(geometry, &sink);
3206 ok(SUCCEEDED(hr), "Failed to open geometry sink, hr %#x.\n", hr);
3207 ID2D1GeometrySink_BeginFigure(sink, point, D2D1_FIGURE_BEGIN_FILLED);
3208 ID2D1GeometrySink_BeginFigure(sink, point, D2D1_FIGURE_BEGIN_FILLED);
3209 ID2D1GeometrySink_EndFigure(sink, D2D1_FIGURE_END_CLOSED);
3210 ID2D1GeometrySink_EndFigure(sink, D2D1_FIGURE_END_CLOSED);
3211 hr = ID2D1GeometrySink_Close(sink);
3212 ok(hr == D2DERR_WRONG_STATE, "Got unexpected hr %#x.\n", hr);
3213 ID2D1GeometrySink_EndFigure(sink, D2D1_FIGURE_END_CLOSED);
3214 hr = ID2D1GeometrySink_Close(sink);
3215 ok(hr == D2DERR_WRONG_STATE, "Got unexpected hr %#x.\n", hr);
3216 ID2D1GeometrySink_Release(sink);
3217 ID2D1PathGeometry_Release(geometry);
3219 /* AddLine() outside BeginFigure()/EndFigure(). */
3220 hr = ID2D1Factory_CreatePathGeometry(factory, &geometry);
3221 ok(SUCCEEDED(hr), "Failed to create path geometry, hr %#x.\n", hr);
3222 hr = ID2D1PathGeometry_Open(geometry, &sink);
3223 ok(SUCCEEDED(hr), "Failed to open geometry sink, hr %#x.\n", hr);
3224 ID2D1GeometrySink_AddLine(sink, point);
3225 hr = ID2D1GeometrySink_Close(sink);
3226 ok(hr == D2DERR_WRONG_STATE, "Got unexpected hr %#x.\n", hr);
3227 ID2D1GeometrySink_AddLine(sink, point);
3228 ID2D1GeometrySink_Release(sink);
3229 hr = ID2D1PathGeometry_GetFigureCount(geometry, &count);
3230 ok(hr == D2DERR_WRONG_STATE, "Got unexpected hr %#x.\n", hr);
3231 hr = ID2D1PathGeometry_GetSegmentCount(geometry, &count);
3232 ok(hr == D2DERR_WRONG_STATE, "Got unexpected hr %#x.\n", hr);
3233 ID2D1PathGeometry_Release(geometry);
3235 /* Empty figure. */
3236 hr = ID2D1Factory_CreatePathGeometry(factory, &geometry);
3237 ok(SUCCEEDED(hr), "Failed to create path geometry, hr %#x.\n", hr);
3238 hr = ID2D1PathGeometry_Open(geometry, &sink);
3239 ok(SUCCEEDED(hr), "Failed to open geometry sink, hr %#x.\n", hr);
3240 set_point(&point, 123.0f, 456.0f);
3241 ID2D1GeometrySink_BeginFigure(sink, point, D2D1_FIGURE_BEGIN_FILLED);
3242 ID2D1GeometrySink_EndFigure(sink, D2D1_FIGURE_END_CLOSED);
3243 hr = ID2D1GeometrySink_Close(sink);
3244 ok(SUCCEEDED(hr), "Failed to close geometry sink, hr %#x.\n", hr);
3245 ID2D1GeometrySink_Release(sink);
3246 hr = ID2D1PathGeometry_GetFigureCount(geometry, &count);
3247 ok(SUCCEEDED(hr), "Failed to get figure count, hr %#x.\n", hr);
3248 ok(count == 1, "Got unexpected figure count %u.\n", count);
3249 hr = ID2D1PathGeometry_GetSegmentCount(geometry, &count);
3250 ok(SUCCEEDED(hr), "Failed to get segment count, hr %#x.\n", hr);
3251 ok(count == 1, "Got unexpected segment count %u.\n", count);
3253 set_rect(&rect, 0.0f, 0.0f, 0.0f, 0.0f);
3254 hr = ID2D1PathGeometry_GetBounds(geometry, NULL, &rect);
3255 ok(SUCCEEDED(hr), "Failed to get geometry bounds, hr %#x.\n", hr);
3256 match = compare_rect(&rect, 123.0f, 456.0f, 123.0f, 456.0f, 0);
3257 ok(match, "Got unexpected rectangle {%.8e, %.8e, %.8e, %.8e}.\n",
3258 rect.left, rect.top, rect.right, rect.bottom);
3260 set_matrix_identity(&matrix);
3261 translate_matrix(&matrix, 80.0f, 640.0f);
3262 scale_matrix(&matrix, 2.0f, 0.5f);
3263 hr = ID2D1PathGeometry_GetBounds(geometry, &matrix, &rect);
3264 ok(SUCCEEDED(hr), "Failed to get geometry bounds, hr %#x.\n", hr);
3265 match = compare_rect(&rect, 326.0f, 868.0f, 326.0f, 868.0f, 0);
3266 ok(match, "Got unexpected rectangle {%.8e, %.8e, %.8e, %.8e}.\n",
3267 rect.left, rect.top, rect.right, rect.bottom);
3269 ID2D1PathGeometry_Release(geometry);
3271 /* Degenerate figure. */
3272 hr = ID2D1Factory_CreatePathGeometry(factory, &geometry);
3273 ok(SUCCEEDED(hr), "Failed to create path geometry, hr %#x.\n", hr);
3274 hr = ID2D1PathGeometry_Open(geometry, &sink);
3275 ok(SUCCEEDED(hr), "Failed to open geometry sink, hr %#x.\n", hr);
3276 set_point(&point, 123.0f, 456.0f);
3277 ID2D1GeometrySink_BeginFigure(sink, point, D2D1_FIGURE_BEGIN_FILLED);
3278 quadratic_to(sink, 123.0f, 456.0f, 123.0f, 456.0f);
3279 quadratic_to(sink, 123.0f, 456.0f, 123.0f, 456.0f);
3280 quadratic_to(sink, 123.0f, 456.0f, 123.0f, 456.0f);
3281 ID2D1GeometrySink_EndFigure(sink, D2D1_FIGURE_END_CLOSED);
3282 hr = ID2D1GeometrySink_Close(sink);
3283 ok(SUCCEEDED(hr), "Failed to close geometry sink, hr %#x.\n", hr);
3284 ID2D1GeometrySink_Release(sink);
3285 hr = ID2D1PathGeometry_GetFigureCount(geometry, &count);
3286 ok(SUCCEEDED(hr), "Failed to get figure count, hr %#x.\n", hr);
3287 ok(count == 1, "Got unexpected figure count %u.\n", count);
3288 hr = ID2D1PathGeometry_GetSegmentCount(geometry, &count);
3289 ok(SUCCEEDED(hr), "Failed to get segment count, hr %#x.\n", hr);
3290 ok(count == 4, "Got unexpected segment count %u.\n", count);
3291 ID2D1PathGeometry_Release(geometry);
3293 /* Close right after Open(). */
3294 hr = ID2D1Factory_CreatePathGeometry(factory, &geometry);
3295 ok(SUCCEEDED(hr), "Failed to create path geometry, hr %#x.\n", hr);
3297 /* Not open yet. */
3298 set_rect(&rect, 1.0f, 2.0f, 3.0f, 4.0f);
3299 hr = ID2D1PathGeometry_GetBounds(geometry, NULL, &rect);
3300 ok(hr == D2DERR_WRONG_STATE, "Unexpected hr %#x.\n", hr);
3301 match = compare_rect(&rect, 1.0f, 2.0f, 3.0f, 4.0f, 0);
3302 ok(match, "Got unexpected rectangle {%.8e, %.8e, %.8e, %.8e}.\n",
3303 rect.left, rect.top, rect.right, rect.bottom);
3305 hr = ID2D1PathGeometry_Open(geometry, &sink);
3306 ok(SUCCEEDED(hr), "Failed to open geometry sink, hr %#x.\n", hr);
3308 /* Open, not closed. */
3309 set_rect(&rect, 1.0f, 2.0f, 3.0f, 4.0f);
3310 hr = ID2D1PathGeometry_GetBounds(geometry, NULL, &rect);
3311 ok(hr == D2DERR_WRONG_STATE, "Unexpected hr %#x.\n", hr);
3312 match = compare_rect(&rect, 1.0f, 2.0f, 3.0f, 4.0f, 0);
3313 ok(match, "Got unexpected rectangle {%.8e, %.8e, %.8e, %.8e}.\n",
3314 rect.left, rect.top, rect.right, rect.bottom);
3316 hr = ID2D1GeometrySink_Close(sink);
3317 ok(SUCCEEDED(hr), "Failed to close geometry sink, hr %#x.\n", hr);
3318 ID2D1GeometrySink_Release(sink);
3319 hr = ID2D1PathGeometry_GetFigureCount(geometry, &count);
3320 ok(SUCCEEDED(hr), "Failed to get figure count, hr %#x.\n", hr);
3321 ok(count == 0, "Got unexpected figure count %u.\n", count);
3322 hr = ID2D1PathGeometry_GetSegmentCount(geometry, &count);
3323 ok(SUCCEEDED(hr), "Failed to get segment count, hr %#x.\n", hr);
3324 ok(count == 0, "Got unexpected segment count %u.\n", count);
3326 set_rect(&rect, 0.0f, 0.0f, 0.0f, 0.0f);
3327 hr = ID2D1PathGeometry_GetBounds(geometry, NULL, &rect);
3328 ok(SUCCEEDED(hr), "Failed to get geometry bounds, hr %#x.\n", hr);
3329 ok(rect.left > rect.right && rect.top > rect.bottom,
3330 "Got unexpected rectangle {%.8e, %.8e, %.8e, %.8e}.\n", rect.left, rect.top, rect.right, rect.bottom);
3332 set_matrix_identity(&matrix);
3333 translate_matrix(&matrix, 10.0f, 20.0f);
3334 scale_matrix(&matrix, 10.0f, 20.0f);
3335 set_rect(&rect, 0.0f, 0.0f, 0.0f, 0.0f);
3336 hr = ID2D1PathGeometry_GetBounds(geometry, &matrix, &rect);
3337 ok(SUCCEEDED(hr), "Failed to get geometry bounds, hr %#x.\n", hr);
3338 ok(rect.left > rect.right && rect.top > rect.bottom,
3339 "Got unexpected rectangle {%.8e, %.8e, %.8e, %.8e}.\n", rect.left, rect.top, rect.right, rect.bottom);
3341 ID2D1PathGeometry_Release(geometry);
3343 /* GetBounds() with bezier segments. */
3344 hr = ID2D1Factory_CreatePathGeometry(factory, &geometry);
3345 ok(SUCCEEDED(hr), "Failed to create path geometry, hr %#x.\n", hr);
3346 hr = ID2D1PathGeometry_Open(geometry, &sink);
3347 ok(SUCCEEDED(hr), "Failed to open geometry sink, hr %#x.\n", hr);
3348 fill_geometry_sink_bezier(sink, 0);
3349 hr = ID2D1GeometrySink_Close(sink);
3350 ok(SUCCEEDED(hr), "Failed to close geometry sink, hr %#x.\n", hr);
3351 ID2D1GeometrySink_Release(sink);
3353 set_rect(&rect, 0.0f, 0.0f, 0.0f, 0.0f);
3354 hr = ID2D1PathGeometry_GetBounds(geometry, NULL, &rect);
3355 ok(SUCCEEDED(hr), "Failed to get geometry bounds, hr %#x.\n", hr);
3356 match = compare_rect(&rect, 5.0f, 20.0f, 75.0f, 752.0f, 0);
3357 ok(match, "Got unexpected rectangle {%.8e, %.8e, %.8e, %.8e}.\n",
3358 rect.left, rect.top, rect.right, rect.bottom);
3360 set_matrix_identity(&matrix);
3361 translate_matrix(&matrix, 80.0f, 640.0f);
3362 scale_matrix(&matrix, 2.0f, 0.5f);
3363 set_rect(&rect, 0.0f, 0.0f, 0.0f, 0.0f);
3364 hr = ID2D1PathGeometry_GetBounds(geometry, &matrix, &rect);
3365 ok(SUCCEEDED(hr), "Failed to get geometry bounds, hr %#x.\n", hr);
3366 match = compare_rect(&rect, 90.0f, 650.0f, 230.0f, 1016.0f, 0);
3367 ok(match, "Got unexpected rectangle {%.8e, %.8e, %.8e, %.8e}.\n",
3368 rect.left, rect.top, rect.right, rect.bottom);
3370 ID2D1PathGeometry_Release(geometry);
3372 /* GetBounds() with bezier segments and some hollow components. */
3373 hr = ID2D1Factory_CreatePathGeometry(factory, &geometry);
3374 ok(SUCCEEDED(hr), "Failed to create path geometry, hr %#x.\n", hr);
3375 hr = ID2D1PathGeometry_Open(geometry, &sink);
3376 ok(SUCCEEDED(hr), "Failed to open geometry sink, hr %#x.\n", hr);
3377 fill_geometry_sink_bezier(sink, 2);
3378 hr = ID2D1GeometrySink_Close(sink);
3379 ok(SUCCEEDED(hr), "Failed to close geometry sink, hr %#x.\n", hr);
3380 ID2D1GeometrySink_Release(sink);
3382 set_rect(&rect, 0.0f, 0.0f, 0.0f, 0.0f);
3383 hr = ID2D1PathGeometry_GetBounds(geometry, NULL, &rect);
3384 ok(SUCCEEDED(hr), "Failed to get geometry bounds, hr %#x.\n", hr);
3385 match = compare_rect(&rect, 5.0f, 472.0f, 75.0f, 752.0f, 0);
3386 ok(match, "Got unexpected rectangle {%.8e, %.8e, %.8e, %.8e}.\n",
3387 rect.left, rect.top, rect.right, rect.bottom);
3389 set_matrix_identity(&matrix);
3390 translate_matrix(&matrix, 80.0f, 640.0f);
3391 scale_matrix(&matrix, 2.0f, 0.5f);
3392 set_rect(&rect, 0.0f, 0.0f, 0.0f, 0.0f);
3393 hr = ID2D1PathGeometry_GetBounds(geometry, &matrix, &rect);
3394 ok(SUCCEEDED(hr), "Failed to get geometry bounds, hr %#x.\n", hr);
3395 match = compare_rect(&rect, 90.0f, 876.0f, 230.0f, 1016.0f, 0);
3396 ok(match, "Got unexpected rectangle {%.8e, %.8e, %.8e, %.8e}.\n",
3397 rect.left, rect.top, rect.right, rect.bottom);
3399 ID2D1PathGeometry_Release(geometry);
3401 /* GetBounds() with bezier segments and all hollow components. */
3402 hr = ID2D1Factory_CreatePathGeometry(factory, &geometry);
3403 ok(SUCCEEDED(hr), "Failed to create path geometry, hr %#x.\n", hr);
3404 hr = ID2D1PathGeometry_Open(geometry, &sink);
3405 ok(SUCCEEDED(hr), "Failed to open geometry sink, hr %#x.\n", hr);
3406 fill_geometry_sink_bezier(sink, 4);
3407 hr = ID2D1GeometrySink_Close(sink);
3408 ok(SUCCEEDED(hr), "Failed to close geometry sink, hr %#x.\n", hr);
3409 ID2D1GeometrySink_Release(sink);
3411 set_rect(&rect, 0.0f, 0.0f, 0.0f, 0.0f);
3412 hr = ID2D1PathGeometry_GetBounds(geometry, NULL, &rect);
3413 ok(SUCCEEDED(hr), "Failed to get geometry bounds, hr %#x.\n", hr);
3414 match = compare_rect(&rect, INFINITY, INFINITY, FLT_MAX, FLT_MAX, 0);
3415 ok(match, "Got unexpected rectangle {%.8e, %.8e, %.8e, %.8e}.\n",
3416 rect.left, rect.top, rect.right, rect.bottom);
3418 set_matrix_identity(&matrix);
3419 translate_matrix(&matrix, 80.0f, 640.0f);
3420 scale_matrix(&matrix, 2.0f, 0.5f);
3421 set_rect(&rect, 0.0f, 0.0f, 0.0f, 0.0f);
3422 hr = ID2D1PathGeometry_GetBounds(geometry, &matrix, &rect);
3423 ok(SUCCEEDED(hr), "Failed to get geometry bounds, hr %#x.\n", hr);
3424 match = compare_rect(&rect, INFINITY, INFINITY, FLT_MAX, FLT_MAX, 0);
3425 ok(match, "Got unexpected rectangle {%.8e, %.8e, %.8e, %.8e}.\n",
3426 rect.left, rect.top, rect.right, rect.bottom);
3428 ID2D1PathGeometry_Release(geometry);
3430 hr = ID2D1Factory_CreatePathGeometry(factory, &geometry);
3431 ok(SUCCEEDED(hr), "Failed to create path geometry, hr %#x.\n", hr);
3432 hr = ID2D1PathGeometry_Open(geometry, &sink);
3433 ok(SUCCEEDED(hr), "Failed to open geometry sink, hr %#x.\n", hr);
3434 /* The fillmode that's used is the last one set before the sink is closed. */
3435 ID2D1GeometrySink_SetFillMode(sink, D2D1_FILL_MODE_WINDING);
3436 fill_geometry_sink(sink, 0);
3437 ID2D1GeometrySink_SetFillMode(sink, D2D1_FILL_MODE_ALTERNATE);
3438 hr = ID2D1GeometrySink_Close(sink);
3439 ok(SUCCEEDED(hr), "Failed to close geometry sink, hr %#x.\n", hr);
3440 hr = ID2D1PathGeometry_GetFigureCount(geometry, &count);
3441 ok(SUCCEEDED(hr), "Failed to get figure count, hr %#x.\n", hr);
3442 ok(count == 6, "Got unexpected figure count %u.\n", count);
3443 hr = ID2D1PathGeometry_GetSegmentCount(geometry, &count);
3444 ok(SUCCEEDED(hr), "Failed to get segment count, hr %#x.\n", hr);
3445 /* Intersections don't create extra segments. */
3446 ok(count == 44, "Got unexpected segment count %u.\n", count);
3447 ID2D1GeometrySink_SetFillMode(sink, D2D1_FILL_MODE_WINDING);
3448 ID2D1GeometrySink_Release(sink);
3450 geometry_sink_init(&simplify_sink);
3451 hr = ID2D1PathGeometry_Simplify(geometry, D2D1_GEOMETRY_SIMPLIFICATION_OPTION_LINES,
3452 NULL, 0.0f, &simplify_sink.ID2D1SimplifiedGeometrySink_iface);
3453 ok(SUCCEEDED(hr), "Failed to simplify geometry, hr %#x.\n", hr);
3454 geometry_sink_check(&simplify_sink, D2D1_FILL_MODE_ALTERNATE, 6, &expected_figures[0], 0);
3455 geometry_sink_cleanup(&simplify_sink);
3456 geometry_sink_init(&simplify_sink);
3457 hr = ID2D1PathGeometry_Simplify(geometry, D2D1_GEOMETRY_SIMPLIFICATION_OPTION_CUBICS_AND_LINES,
3458 NULL, 0.0f, &simplify_sink.ID2D1SimplifiedGeometrySink_iface);
3459 ok(SUCCEEDED(hr), "Failed to simplify geometry, hr %#x.\n", hr);
3460 geometry_sink_check(&simplify_sink, D2D1_FILL_MODE_ALTERNATE, 6, &expected_figures[0], 0);
3461 geometry_sink_cleanup(&simplify_sink);
3463 set_matrix_identity(&matrix);
3464 translate_matrix(&matrix, 80.0f, 640.0f);
3465 scale_matrix(&matrix, 1.0f, -1.0f);
3466 hr = ID2D1Factory_CreateTransformedGeometry(factory, (ID2D1Geometry *)geometry, &matrix, &transformed_geometry);
3467 ok(SUCCEEDED(hr), "Failed to create transformed geometry, hr %#x.\n", hr);
3469 geometry_sink_init(&simplify_sink);
3470 hr = ID2D1TransformedGeometry_Simplify(transformed_geometry, D2D1_GEOMETRY_SIMPLIFICATION_OPTION_LINES,
3471 NULL, 0.0f, &simplify_sink.ID2D1SimplifiedGeometrySink_iface);
3472 ok(SUCCEEDED(hr), "Failed to simplify geometry, hr %#x.\n", hr);
3473 geometry_sink_check(&simplify_sink, D2D1_FILL_MODE_ALTERNATE, 6, &expected_figures[6], 0);
3474 geometry_sink_cleanup(&simplify_sink);
3476 ID2D1TransformedGeometry_GetSourceGeometry(transformed_geometry, &tmp_geometry);
3477 ok(tmp_geometry == (ID2D1Geometry *)geometry,
3478 "Got unexpected source geometry %p, expected %p.\n", tmp_geometry, geometry);
3479 ID2D1TransformedGeometry_GetTransform(transformed_geometry, &tmp_matrix);
3480 ok(!memcmp(&tmp_matrix, &matrix, sizeof(matrix)),
3481 "Got unexpected matrix {%.8e, %.8e, %.8e, %.8e, %.8e, %.8e}.\n",
3482 tmp_matrix._11, tmp_matrix._12, tmp_matrix._21,
3483 tmp_matrix._22, tmp_matrix._31, tmp_matrix._32);
3484 geometry_sink_init(&simplify_sink);
3485 hr = ID2D1Geometry_Simplify(tmp_geometry, D2D1_GEOMETRY_SIMPLIFICATION_OPTION_LINES,
3486 &tmp_matrix, 0.0f, &simplify_sink.ID2D1SimplifiedGeometrySink_iface);
3487 ok(SUCCEEDED(hr), "Failed to simplify geometry, hr %#x.\n", hr);
3488 geometry_sink_check(&simplify_sink, D2D1_FILL_MODE_ALTERNATE, 6, &expected_figures[6], 0);
3489 geometry_sink_cleanup(&simplify_sink);
3490 ID2D1Geometry_Release(tmp_geometry);
3492 ID2D1RenderTarget_BeginDraw(rt);
3493 set_color(&color, 0.396f, 0.180f, 0.537f, 1.0f);
3494 ID2D1RenderTarget_Clear(rt, &color);
3495 ID2D1RenderTarget_FillGeometry(rt, (ID2D1Geometry *)geometry, (ID2D1Brush *)brush, NULL);
3496 ID2D1RenderTarget_FillGeometry(rt, (ID2D1Geometry *)transformed_geometry, (ID2D1Brush *)brush, NULL);
3497 hr = ID2D1RenderTarget_EndDraw(rt, NULL, NULL);
3498 ok(SUCCEEDED(hr), "Failed to end draw, hr %#x.\n", hr);
3499 match = compare_surface(&ctx, "3aace1b22aae111cb577614fed16e4eb1650dba5");
3500 ok(match, "Surface does not match.\n");
3502 /* Edge test. */
3503 set_point(&point, 94.0f, 620.0f);
3504 contains = TRUE;
3505 hr = ID2D1TransformedGeometry_FillContainsPoint(transformed_geometry, point, NULL, 0.0f, &contains);
3506 ok(hr == S_OK, "FillContainsPoint failed, hr %#x.\n", hr);
3507 ok(!contains, "Got unexpected contains %#x.\n", contains);
3509 set_point(&point, 95.0f, 620.0f);
3510 contains = FALSE;
3511 hr = ID2D1TransformedGeometry_FillContainsPoint(transformed_geometry, point, NULL, 0.0f, &contains);
3512 ok(hr == S_OK, "FillContainsPoint failed, hr %#x.\n", hr);
3513 ok(contains == TRUE, "Got unexpected contains %#x.\n", contains);
3515 /* With transformation matrix. */
3516 set_matrix_identity(&matrix);
3517 translate_matrix(&matrix, -10.0f, 0.0f);
3518 set_point(&point, 85.0f, 620.0f);
3519 contains = FALSE;
3520 hr = ID2D1TransformedGeometry_FillContainsPoint(transformed_geometry, point, &matrix, 0.0f, &contains);
3521 ok(hr == S_OK, "FillContainsPoint failed, hr %#x.\n", hr);
3522 ok(contains == TRUE, "Got unexpected contains %#x.\n", contains);
3524 ID2D1TransformedGeometry_Release(transformed_geometry);
3525 ID2D1PathGeometry_Release(geometry);
3527 hr = ID2D1Factory_CreatePathGeometry(factory, &geometry);
3528 ok(SUCCEEDED(hr), "Failed to create path geometry, hr %#x.\n", hr);
3529 hr = ID2D1PathGeometry_Open(geometry, &sink);
3530 ok(SUCCEEDED(hr), "Failed to open geometry sink, hr %#x.\n", hr);
3531 fill_geometry_sink(sink, 0);
3532 ID2D1GeometrySink_SetFillMode(sink, D2D1_FILL_MODE_WINDING);
3533 hr = ID2D1GeometrySink_Close(sink);
3534 ok(SUCCEEDED(hr), "Failed to close geometry sink, hr %#x.\n", hr);
3535 hr = ID2D1PathGeometry_GetFigureCount(geometry, &count);
3536 ok(SUCCEEDED(hr), "Failed to get figure count, hr %#x.\n", hr);
3537 ok(count == 6, "Got unexpected figure count %u.\n", count);
3538 hr = ID2D1PathGeometry_GetSegmentCount(geometry, &count);
3539 ok(SUCCEEDED(hr), "Failed to get segment count, hr %#x.\n", hr);
3540 ok(count == 44, "Got unexpected segment count %u.\n", count);
3541 ID2D1GeometrySink_Release(sink);
3543 set_rect(&rect, 0.0f, 0.0f, 0.0f, 0.0f);
3544 hr = ID2D1PathGeometry_GetBounds(geometry, NULL, &rect);
3545 ok(SUCCEEDED(hr), "Failed to get geometry bounds, hr %#x.\n", hr);
3546 match = compare_rect(&rect, 5.0f, 20.0f, 235.0f, 300.0f, 0);
3547 ok(match, "Got unexpected rectangle {%.8e, %.8e, %.8e, %.8e}.\n",
3548 rect.left, rect.top, rect.right, rect.bottom);
3550 set_matrix_identity(&matrix);
3551 translate_matrix(&matrix, 100.0f, 50.0f);
3552 scale_matrix(&matrix, 2.0f, 1.5f);
3553 rotate_matrix(&matrix, M_PI / 4.0f);
3554 set_rect(&rect, 0.0f, 0.0f, 0.0f, 0.0f);
3555 hr = ID2D1PathGeometry_GetBounds(geometry, &matrix, &rect);
3556 ok(SUCCEEDED(hr), "Failed to get geometry bounds, hr %#x.\n", hr);
3557 match = compare_rect(&rect, -3.17192993e+02f, 8.71231079e+01f, 4.04055908e+02f, 6.17453125e+02f, 1);
3558 ok(match, "Got unexpected rectangle {%.8e, %.8e, %.8e, %.8e}.\n",
3559 rect.left, rect.top, rect.right, rect.bottom);
3561 geometry_sink_init(&simplify_sink);
3562 hr = ID2D1PathGeometry_Simplify(geometry, D2D1_GEOMETRY_SIMPLIFICATION_OPTION_LINES,
3563 NULL, 0.0f, &simplify_sink.ID2D1SimplifiedGeometrySink_iface);
3564 ok(SUCCEEDED(hr), "Failed to simplify geometry, hr %#x.\n", hr);
3565 geometry_sink_check(&simplify_sink, D2D1_FILL_MODE_WINDING, 6, &expected_figures[0], 0);
3566 geometry_sink_cleanup(&simplify_sink);
3568 set_matrix_identity(&matrix);
3569 translate_matrix(&matrix, 320.0f, 320.0f);
3570 scale_matrix(&matrix, -1.0f, 1.0f);
3571 hr = ID2D1Factory_CreateTransformedGeometry(factory, (ID2D1Geometry *)geometry, &matrix, &transformed_geometry);
3572 ok(SUCCEEDED(hr), "Failed to create transformed geometry, hr %#x.\n", hr);
3574 ID2D1RenderTarget_BeginDraw(rt);
3575 ID2D1RenderTarget_Clear(rt, &color);
3576 ID2D1RenderTarget_FillGeometry(rt, (ID2D1Geometry *)geometry, (ID2D1Brush *)brush, NULL);
3577 ID2D1RenderTarget_FillGeometry(rt, (ID2D1Geometry *)transformed_geometry, (ID2D1Brush *)brush, NULL);
3578 hr = ID2D1RenderTarget_EndDraw(rt, NULL, NULL);
3579 ok(SUCCEEDED(hr), "Failed to end draw, hr %#x.\n", hr);
3580 match = compare_surface(&ctx, "bfb40a1f007694fa07dbd3b854f3f5d9c3e1d76b");
3581 ok(match, "Surface does not match.\n");
3582 ID2D1TransformedGeometry_Release(transformed_geometry);
3583 ID2D1PathGeometry_Release(geometry);
3585 hr = ID2D1Factory_CreatePathGeometry(factory, &geometry);
3586 ok(SUCCEEDED(hr), "Failed to create path geometry, hr %#x.\n", hr);
3587 hr = ID2D1PathGeometry_Open(geometry, &sink);
3588 ok(SUCCEEDED(hr), "Failed to open geometry sink, hr %#x.\n", hr);
3589 fill_geometry_sink_bezier(sink, 0);
3590 hr = ID2D1GeometrySink_Close(sink);
3591 ok(SUCCEEDED(hr), "Failed to close geometry sink, hr %#x.\n", hr);
3592 hr = ID2D1PathGeometry_GetFigureCount(geometry, &count);
3593 ok(SUCCEEDED(hr), "Failed to get figure count, hr %#x.\n", hr);
3594 ok(count == 4, "Got unexpected figure count %u.\n", count);
3595 hr = ID2D1PathGeometry_GetSegmentCount(geometry, &count);
3596 ok(SUCCEEDED(hr), "Failed to get segment count, hr %#x.\n", hr);
3597 ok(count == 20, "Got unexpected segment count %u.\n", count);
3598 ID2D1GeometrySink_Release(sink);
3600 geometry_sink_init(&simplify_sink);
3601 hr = ID2D1PathGeometry_Simplify(geometry, D2D1_GEOMETRY_SIMPLIFICATION_OPTION_CUBICS_AND_LINES,
3602 NULL, 0.0f, &simplify_sink.ID2D1SimplifiedGeometrySink_iface);
3603 ok(SUCCEEDED(hr), "Failed to simplify geometry, hr %#x.\n", hr);
3604 geometry_sink_check(&simplify_sink, D2D1_FILL_MODE_ALTERNATE, 4, &expected_figures[12], 1);
3605 geometry_sink_cleanup(&simplify_sink);
3606 geometry_sink_init(&simplify_sink);
3607 hr = ID2D1PathGeometry_Simplify(geometry, D2D1_GEOMETRY_SIMPLIFICATION_OPTION_LINES,
3608 NULL, 100.0f, &simplify_sink.ID2D1SimplifiedGeometrySink_iface);
3609 ok(SUCCEEDED(hr), "Failed to simplify geometry, hr %#x.\n", hr);
3610 geometry_sink_check(&simplify_sink, D2D1_FILL_MODE_ALTERNATE, 4, &expected_figures[20], 1);
3611 geometry_sink_cleanup(&simplify_sink);
3612 geometry_sink_init(&simplify_sink);
3613 hr = ID2D1PathGeometry_Simplify(geometry, D2D1_GEOMETRY_SIMPLIFICATION_OPTION_LINES,
3614 NULL, 10.0f, &simplify_sink.ID2D1SimplifiedGeometrySink_iface);
3615 ok(SUCCEEDED(hr), "Failed to simplify geometry, hr %#x.\n", hr);
3616 geometry_sink_check(&simplify_sink, D2D1_FILL_MODE_ALTERNATE, 4, &expected_figures[24], 1);
3617 geometry_sink_cleanup(&simplify_sink);
3619 set_matrix_identity(&matrix);
3620 scale_matrix(&matrix, 0.5f, 2.0f);
3621 translate_matrix(&matrix, 400.0f, -33.0f);
3622 rotate_matrix(&matrix, M_PI / 4.0f);
3623 scale_matrix(&matrix, 2.0f, 0.5f);
3624 hr = ID2D1Factory_CreateTransformedGeometry(factory, (ID2D1Geometry *)geometry, &matrix, &transformed_geometry);
3625 ok(SUCCEEDED(hr), "Failed to create transformed geometry, hr %#x.\n", hr);
3627 geometry_sink_init(&simplify_sink);
3628 hr = ID2D1TransformedGeometry_Simplify(transformed_geometry, D2D1_GEOMETRY_SIMPLIFICATION_OPTION_CUBICS_AND_LINES,
3629 NULL, 0.0f, &simplify_sink.ID2D1SimplifiedGeometrySink_iface);
3630 ok(SUCCEEDED(hr), "Failed to simplify geometry, hr %#x.\n", hr);
3631 geometry_sink_check(&simplify_sink, D2D1_FILL_MODE_ALTERNATE, 4, &expected_figures[16], 4);
3632 geometry_sink_cleanup(&simplify_sink);
3634 ID2D1RenderTarget_BeginDraw(rt);
3635 ID2D1RenderTarget_Clear(rt, &color);
3636 ID2D1RenderTarget_FillGeometry(rt, (ID2D1Geometry *)geometry, (ID2D1Brush *)brush, NULL);
3637 ID2D1RenderTarget_FillGeometry(rt, (ID2D1Geometry *)transformed_geometry, (ID2D1Brush *)brush, NULL);
3638 hr = ID2D1RenderTarget_EndDraw(rt, NULL, NULL);
3639 ok(SUCCEEDED(hr), "Failed to end draw, hr %#x.\n", hr);
3640 match = compare_figure(&ctx, 0, 0, 160, 160, 0xff652e89, 64,
3641 "7xoCngECngECngECngECngECngECngECnQEEnAEEnAEEnAEEnAEEmwEGmgEGmgEGmgEGmQEImAEI"
3642 "lAEECASLAQgKCIEBDQoMew8KD3YQDBByEgwSbhMOEmwUDhRpFBAUZxUQFWUVEhVjFhIWYRYUFl8X"
3643 "FBddFxYWXRYYFlsXGBdaFhoWWRYcFlgVHhVXFSAVVhQiFFUUIxRVEyYTVBIoElQRKhFUECwQUxAu"
3644 "EFIOMg5SDTQNUgs4C1IJPAlRCEAIUAZEBlAESARQAU4BTgJQAkgGUAY/C1ALMhNQEyoTUBMyC1AL"
3645 "PwZQBkgCUAJOAU4BUARIBFAGRAZQCEAIUQk8CVILOAtSDTQNUg4yDlIQLhBTECwQVBEqEVQSKBJU"
3646 "EyYTVBQjFFYUIhRWFSAVVxUeFVgWHBZZFhoWWhcYF1sWGBZcFxYWXhcUF18WFBZhFhIWYxUSFWUV"
3647 "EBVnFBAUaRQOFGsTDhJvEgwSchAMEHYPCg96DQoMggEICgiLAQQIBJQBCJgBCJkBBpoBBpoBBpoB"
3648 "BpsBBJwBBJwBBJwBBJwBBJ0BAp4BAp4BAp4BAp4BAp4BAp4BAp4BAgAA");
3649 ok(match, "Figure does not match.\n");
3650 match = compare_figure(&ctx, 0, 226, 160, 160, 0xff652e89, 64,
3651 "7xoCngECngECngECngECngECngECngECnQEEnAEEnAEEnAEEnAEEmwEGmgEGmgEGmgEGmQEImAEI"
3652 "lAEECASLAQgKCIEBDQoMew8KD3YQDBByEgwSbhMOEmwUDhRpFBAUZxUQFWUVEhVjFhIWYRYUFl8X"
3653 "FBddFxYWXRYYFlsXGBdaFhoWWRYcFlgVHhVXFSAVVhQiFFUUIxRVEyYTVBIoElQRKhFUECwQUxAu"
3654 "EFIOMg5SDTQNUgs4C1IJPAlRCEAIUAZEBlAESARQAU4BTgJQAkgGUAY/C1ALMhNQEyoTUBMyC1AL"
3655 "PwZQBkgCUAJOAU4BUARIBFAGRAZQCEAIUQk8CVILOAtSDTQNUg4yDlIQLhBTECwQVBEqEVQSKBJU"
3656 "EyYTVBQjFFYUIhRWFSAVVxUeFVgWHBZZFhoWWhcYF1sWGBZcFxYWXhcUF18WFBZhFhIWYxUSFWUV"
3657 "EBVnFBAUaRQOFGsTDhJvEgwSchAMEHYPCg96DQoMggEICgiLAQQIBJQBCJgBCJkBBpoBBpoBBpoB"
3658 "BpsBBJwBBJwBBJwBBJwBBJ0BAp4BAp4BAp4BAp4BAp4BAp4BAp4BAgAA");
3659 ok(match, "Figure does not match.\n");
3660 match = compare_figure(&ctx, 160, 0, 320, 160, 0xff652e89, 64,
3661 "gVQBwAIBWgHlAQFYAecBAVYB6QEBVAHrAQEjDCMB7AECHhQeAu0BAxoYGgPvAQMWHhYD8QEDFCAU"
3662 "A/MBBBAkEAT0AQUOJw0F9QEGCioKBvcBBggsCAb4AQgFLgUI+QEJATIBCfsBCAIwAgj8AQcFLAUH"
3663 "/QEFCCgIBf4BBAwiDAT/AQIQHBAClwISlwIBPgGAAgI8Av8BAzwD/QEEPAT7AQY6BvkBBzoH+AEI"
3664 "OAj3AQk4CfYBCTgK9AELNgvzAQw2DPIBDDYM8QEONA7wAQ40DvABDjQO7wEPNA/uAQ80D+4BEDIQ"
3665 "7QERMhHsAREyEewBETIR7AERMhHsAREyEewBETIR7AERMhHsAREyEewBETIR7AERMhHsAREyEewB"
3666 "ETIR7AERMhHsAREyEe0BEDIQ7gEQMw/uAQ80D+4BDzQP7wEONA7wAQ40DvEBDDYM8gEMNgzzAQs2"
3667 "C/QBCzcK9QEJOAn3AQg4CfcBBzoH+QEGOgb7AQU6BfwBBDwE/QEDPAP/AQE+AZkCDpkCAhIYEgKA"
3668 "AgMNIA0D/wEFCSYJBf4BBgYqBgf8AQgDLgMI+wFG+gEIAzADCPkBBwYuBgf3AQYKKgoG9gEFDCgM"
3669 "BfUBBBAlDwTzAQQSIhIE8QEDFh4WA/ABAhkaGQLvAQIcFhwC7QECIBAgAusBASgEKAHpAQFWAecB"
3670 "AVgB5QEBWgHAAgHhUgAA");
3671 ok(match, "Figure does not match.\n");
3672 match = compare_figure(&ctx, 160, 160, 320, 160, 0xff652e89, 64,
3673 "/VUB5QEBWAHnAQFWAekBAVQB6wECIQ8hAe0BAh0VHQLuAQIZGhkD7wEDFh4WA/EBBBMhEwPzAQQQ"
3674 "JQ8F9AEFDCgNBfUBBgoqCgb3AQcHLQcG+QEIBC8ECPkBPAEJ+wEIAy8CCP0BBgYrBQf9AQUJJgkF"
3675 "/wEDDSANBP8BAhEaEQKYAhAXAYACAT4BgAICPQL+AQM8BPwBBTsE+wEGOgb6AQc5B/gBCDgJ9gEJ"
3676 "OAn2AQo3CvQBCzcK8wEMNgzyAQ01DPIBDTUN8AEONA7wAQ40D+4BDzQP7gEQMw/uARAzEO0BEDIR"
3677 "7AERMhHsAREyEewBETIR7AERMhLrAREyEusBETIS6wERMhLrAREyEusBETIS6wERMhHsAREyEewB"
3678 "ETIR7QEQMhHtARAzEO0BEDMP7gEPNA/vAQ40D+8BDjQO8QENNQ3xAQ01DPMBCzYM8wELNwr1AQo3"
3679 "CvUBCTgJ9wEIOAn4AQc5B/kBBjoG+wEFOwT9AQM8BP4BAj0C/wEBPgGYAhAXAYACAhEaEQKAAgMN"
3680 "IA0E/gEFCSYJBf4BBgYrBQf8AQgDLwII+wE8AQn6AQgELwQI+AEHBy0HBvcBBgoqCgb2AQUNJw0F"
3681 "9AEEECQQBfIBBBMhEwPxAQMWHhYD8AECGRoZA+4BAh0VHQLsAQIhDiIB6wEBVAHpAQFWAecBAVgB"
3682 "wAIBwlYA");
3683 ok(match, "Figure does not match.\n");
3684 ID2D1TransformedGeometry_Release(transformed_geometry);
3685 ID2D1PathGeometry_Release(geometry);
3687 hr = ID2D1Factory_CreatePathGeometry(factory, &geometry);
3688 ok(SUCCEEDED(hr), "Failed to create path geometry, hr %#x.\n", hr);
3689 hr = ID2D1PathGeometry_Open(geometry, &sink);
3690 ok(SUCCEEDED(hr), "Failed to open geometry sink, hr %#x.\n", hr);
3691 fill_geometry_sink_bezier(sink, 0);
3692 ID2D1GeometrySink_SetFillMode(sink, D2D1_FILL_MODE_WINDING);
3693 hr = ID2D1GeometrySink_Close(sink);
3694 ok(SUCCEEDED(hr), "Failed to close geometry sink, hr %#x.\n", hr);
3695 hr = ID2D1PathGeometry_GetFigureCount(geometry, &count);
3696 ok(SUCCEEDED(hr), "Failed to get figure count, hr %#x.\n", hr);
3697 ok(count == 4, "Got unexpected figure count %u.\n", count);
3698 hr = ID2D1PathGeometry_GetSegmentCount(geometry, &count);
3699 ok(SUCCEEDED(hr), "Failed to get segment count, hr %#x.\n", hr);
3700 ok(count == 20, "Got unexpected segment count %u.\n", count);
3701 ID2D1GeometrySink_Release(sink);
3703 geometry_sink_init(&simplify_sink);
3704 hr = ID2D1PathGeometry_Simplify(geometry, D2D1_GEOMETRY_SIMPLIFICATION_OPTION_CUBICS_AND_LINES,
3705 NULL, 0.0f, &simplify_sink.ID2D1SimplifiedGeometrySink_iface);
3706 ok(SUCCEEDED(hr), "Failed to simplify geometry, hr %#x.\n", hr);
3707 geometry_sink_check(&simplify_sink, D2D1_FILL_MODE_WINDING, 4, &expected_figures[12], 1);
3708 geometry_sink_cleanup(&simplify_sink);
3709 geometry_sink_init(&simplify_sink);
3710 hr = ID2D1PathGeometry_Simplify(geometry, D2D1_GEOMETRY_SIMPLIFICATION_OPTION_LINES,
3711 NULL, 100.0f, &simplify_sink.ID2D1SimplifiedGeometrySink_iface);
3712 ok(SUCCEEDED(hr), "Failed to simplify geometry, hr %#x.\n", hr);
3713 geometry_sink_check(&simplify_sink, D2D1_FILL_MODE_WINDING, 4, &expected_figures[20], 1);
3714 geometry_sink_cleanup(&simplify_sink);
3715 geometry_sink_init(&simplify_sink);
3716 hr = ID2D1PathGeometry_Simplify(geometry, D2D1_GEOMETRY_SIMPLIFICATION_OPTION_LINES,
3717 NULL, 10.0f, &simplify_sink.ID2D1SimplifiedGeometrySink_iface);
3718 ok(SUCCEEDED(hr), "Failed to simplify geometry, hr %#x.\n", hr);
3719 geometry_sink_check(&simplify_sink, D2D1_FILL_MODE_WINDING, 4, &expected_figures[24], 1);
3720 geometry_sink_cleanup(&simplify_sink);
3722 set_matrix_identity(&matrix);
3723 scale_matrix(&matrix, 0.5f, 2.0f);
3724 translate_matrix(&matrix, 127.0f, 80.0f);
3725 rotate_matrix(&matrix, M_PI / -4.0f);
3726 scale_matrix(&matrix, 2.0f, 0.5f);
3727 hr = ID2D1Factory_CreateTransformedGeometry(factory, (ID2D1Geometry *)geometry, &matrix, &transformed_geometry);
3728 ok(SUCCEEDED(hr), "Failed to create transformed geometry, hr %#x.\n", hr);
3730 ID2D1RenderTarget_BeginDraw(rt);
3731 ID2D1RenderTarget_Clear(rt, &color);
3732 ID2D1RenderTarget_FillGeometry(rt, (ID2D1Geometry *)geometry, (ID2D1Brush *)brush, NULL);
3733 ID2D1RenderTarget_FillGeometry(rt, (ID2D1Geometry *)transformed_geometry, (ID2D1Brush *)brush, NULL);
3734 hr = ID2D1RenderTarget_EndDraw(rt, NULL, NULL);
3735 ok(SUCCEEDED(hr), "Failed to end draw, hr %#x.\n", hr);
3736 match = compare_figure(&ctx, 0, 0, 160, 160, 0xff652e89, 64,
3737 "7xoCngECngECngECngECngECngECngECnQEEnAEEnAEEnAEEnAEEmwEGmgEGmgEGmgEGmQEImAEI"
3738 "lAEQiwEagQEjeyh2LHIwbjNsNmk4ZzplPGM+YUBfQl1DXURbRlpGWUhYSFdKVkpVS1VMVExUTFRM"
3739 "U05STlJOUk5STlFQUFBQUFBQTlRIXD9mMnYqdjJmP1xIVE5QUFBQUFBQUU5STlJOUk5STlNMVExU"
3740 "TFRMVEtWSlZKV0hYSFlGWkZbRFxDXkJfQGE+YzxlOmc4aTZrM28wcix2KHojggEaiwEQlAEImAEI"
3741 "mQEGmgEGmgEGmgEGmwEEnAEEnAEEnAEEnAEEnQECngECngECngECngECngECngECngEC");
3742 ok(match, "Figure does not match.\n");
3743 match = compare_figure(&ctx, 0, 226, 160, 160, 0xff652e89, 64,
3744 "7xoCngECngECngECngECngECngECngECnQEEnAEEnAEEnAEEnAEEmwEGmgEGmgEGmgEGmQEImAEI"
3745 "lAEQiwEagQEjeyh2LHIwbjNsNmk4ZzplPGM+YUBfQl1DXURbRlpGWUhYSFdKVkpVS1VMVExUTFRM"
3746 "U05STlJOUk5STlFQUFBQUFBQTlRIXD9mMnYqdjJmP1xIVE5QUFBQUFBQUU5STlJOUk5STlNMVExU"
3747 "TFRMVEtWSlZKV0hYSFlGWkZbRFxDXkJfQGE+YzxlOmc4aTZrM28wcix2KHojggEaiwEQlAEImAEI"
3748 "mQEGmgEGmgEGmgEGmwEEnAEEnAEEnAEEnAEEnQECngECngECngECngECngECngECngEC");
3749 ok(match, "Figure does not match.\n");
3750 match = compare_figure(&ctx, 160, 0, 320, 160, 0xff652e89, 64,
3751 "4VIBwAIBWgHlAQFYAecBAVYB6QEBVAHrAQIhDiIB7QECHRUdAu4BAhkaGQPvAQMWHhYD8QEEEyET"
3752 "A/MBBBAkEAT1AQUMKA0F9QEGCioKBvcBBwctBwb5AQgELwQI+QEJATIBCfsBRP0BQ/0BQv8BQf8B"
3753 "QIECP4ACQIACQf4BQ/wBRPsBRvoBR/gBSPcBSvYBS/QBTPMBTvIBTvIBT/ABUPABUe4BUu4BUu4B"
3754 "U+0BU+wBVOwBVOwBVOwBVOwBVesBVesBVesBVesBVOwBVOwBVOwBVO0BU+0BU+0BUu4BUu8BUe8B"
3755 "UPEBT/EBTvIBTvMBTPUBS/UBSvcBSfcBSPkBRvsBRP0BQ/4BQf8BQIECP4ACQIACQf4BQv4BQ/wB"
3756 "RPsBCQEyAQn6AQgELwQI+AEHBy0GB/cBBgoqCgb2AQUMKA0F9AEEECUPBPMBBBIiEwPxAQMWHhYD"
3757 "8AECGRoZA+4BAh0VHQLsAQIhDiIB6wEBVAHpAQFWAecBAVgB5QEBWgHAAgEA");
3758 ok(match, "Figure does not match.\n");
3759 match = compare_figure(&ctx, 160, 160, 320, 160, 0xff652e89, 64,
3760 "gVQBXAHjAQFaAeUBAVgB5wEBVgHpAQEpAikB6wECIBAgAu0BAhwWHALvAQIZGhkC8AEDFh4WA/EB"
3761 "BBIiEgTzAQQPJRAE9QEFDCgMBfYBBgoqCgb3AQcGLgYH+QEIAzADCPoBRvsBRPwBRP0BQv8BQIAC"
3762 "QIECPoECQP8BQv0BRPwBRPsBRvkBSPgBSPcBSvUBTPQBTPMBTvIBTvEBUPABUO8BUu4BUu4BUu4B"
3763 "Uu0BVOwBVOwBVOwBVOwBVOwBVOwBVOwBVOwBVOwBVOwBVOwBVOwBVOwBVO0BUu4BUu4BUu8BUPAB"
3764 "UPABUPEBTvIBTvMBTPQBS/YBSvcBSPgBSPkBRvsBRP0BQv8BQIACQIECPoECQP8BQv4BQv0BRPwB"
3765 "RPsBCQEyAQn5AQgFLgUI+AEGCCwIBvcBBgoqCgb1AQUNJw4F9AEEECQQBPMBAxQgFAPxAQMWHhYD"
3766 "7wEDGhgaA+0BAh4UHgLsAQEjDCMB6wEBVAHpAQFWAecBAVgB5QEBWgGiVQAA");
3767 ok(match, "Figure does not match.\n");
3768 ID2D1TransformedGeometry_Release(transformed_geometry);
3769 ID2D1PathGeometry_Release(geometry);
3771 hr = ID2D1Factory_CreatePathGeometry(factory, &geometry);
3772 ok(SUCCEEDED(hr), "Failed to create path geometry, hr %#x.\n", hr);
3773 hr = ID2D1PathGeometry_Open(geometry, &sink);
3774 ok(SUCCEEDED(hr), "Failed to open geometry sink, hr %#x.\n", hr);
3776 set_point(&point, 40.0f, 20.0f);
3777 ID2D1GeometrySink_BeginFigure(sink, point, D2D1_FIGURE_BEGIN_FILLED);
3778 line_to(sink, 75.0f, 300.0f);
3779 line_to(sink, 5.0f, 300.0f);
3780 ID2D1GeometrySink_EndFigure(sink, D2D1_FIGURE_END_CLOSED);
3782 set_point(&point, 40.0f, 290.0f);
3783 ID2D1GeometrySink_BeginFigure(sink, point, D2D1_FIGURE_BEGIN_FILLED);
3784 line_to(sink, 55.0f, 160.0f);
3785 line_to(sink, 25.0f, 160.0f);
3786 ID2D1GeometrySink_EndFigure(sink, D2D1_FIGURE_END_CLOSED);
3788 hr = ID2D1GeometrySink_Close(sink);
3789 ok(SUCCEEDED(hr), "Failed to close geometry sink, hr %#x.\n", hr);
3790 hr = ID2D1PathGeometry_GetFigureCount(geometry, &count);
3791 ok(SUCCEEDED(hr), "Failed to get figure count, hr %#x.\n", hr);
3792 ok(count == 2, "Got unexpected figure count %u.\n", count);
3793 hr = ID2D1PathGeometry_GetSegmentCount(geometry, &count);
3794 ok(SUCCEEDED(hr), "Failed to get segment count, hr %#x.\n", hr);
3795 ok(count == 6, "Got unexpected segment count %u.\n", count);
3796 ID2D1GeometrySink_Release(sink);
3798 ID2D1RenderTarget_BeginDraw(rt);
3799 ID2D1RenderTarget_Clear(rt, &color);
3800 ID2D1RenderTarget_FillGeometry(rt, (ID2D1Geometry *)geometry, (ID2D1Brush *)brush, NULL);
3801 hr = ID2D1RenderTarget_EndDraw(rt, NULL, NULL);
3802 ok(SUCCEEDED(hr), "Failed to end draw, hr %#x.\n", hr);
3803 match = compare_surface(&ctx, "a875e68e0cb9c055927b1b50b879f90b24e38470");
3804 ok(match, "Surface does not match.\n");
3805 ID2D1PathGeometry_Release(geometry);
3807 hr = ID2D1Factory_CreatePathGeometry(factory, &geometry);
3808 ok(SUCCEEDED(hr), "Failed to create path geometry, hr %#x.\n", hr);
3809 hr = ID2D1PathGeometry_Open(geometry, &sink);
3810 ok(SUCCEEDED(hr), "Failed to open geometry sink, hr %#x.\n", hr);
3811 set_point(&point, 40.0f, 20.0f);
3812 ID2D1GeometrySink_BeginFigure(sink, point, D2D1_FIGURE_BEGIN_HOLLOW);
3813 line_to(sink, 75.0f, 300.0f);
3814 line_to(sink, 5.0f, 300.0f);
3815 ID2D1GeometrySink_EndFigure(sink, D2D1_FIGURE_END_OPEN);
3816 hr = ID2D1GeometrySink_Close(sink);
3817 ok(SUCCEEDED(hr), "Failed to close geometry sink, hr %#x.\n", hr);
3818 ID2D1GeometrySink_Release(sink);
3819 hr = ID2D1PathGeometry_GetSegmentCount(geometry, &count);
3820 ok(SUCCEEDED(hr), "Failed to get segment count, hr %#x.\n", hr);
3821 ok(count == 2, "Got unexpected segment count %u.\n", count);
3823 geometry_sink_init(&simplify_sink);
3824 hr = ID2D1PathGeometry_Simplify(geometry, D2D1_GEOMETRY_SIMPLIFICATION_OPTION_LINES,
3825 NULL, 0.0f, &simplify_sink.ID2D1SimplifiedGeometrySink_iface);
3826 ok(SUCCEEDED(hr), "Failed to simplify geometry, hr %#x.\n", hr);
3827 geometry_sink_check(&simplify_sink, D2D1_FILL_MODE_ALTERNATE, 1, &expected_figures[28], 1);
3828 geometry_sink_cleanup(&simplify_sink);
3830 ID2D1PathGeometry_Release(geometry);
3832 ID2D1SolidColorBrush_Release(brush);
3833 ID2D1Factory_Release(factory);
3834 release_test_context(&ctx);
3837 static void test_rectangle_geometry(BOOL d3d11)
3839 ID2D1TransformedGeometry *transformed_geometry;
3840 ID2D1RectangleGeometry *geometry;
3841 struct geometry_sink sink;
3842 D2D1_MATRIX_3X2_F matrix;
3843 D2D1_RECT_F rect, rect2;
3844 ID2D1Factory *factory;
3845 D2D1_POINT_2F point;
3846 BOOL contains;
3847 HRESULT hr;
3848 BOOL match;
3850 static const struct geometry_segment expected_segments[] =
3852 /* Figure 0. */
3853 {SEGMENT_LINE, {{{10.0f, 0.0f}}}},
3854 {SEGMENT_LINE, {{{10.0f, 20.0f}}}},
3855 {SEGMENT_LINE, {{{ 0.0f, 20.0f}}}},
3856 /* Figure 1. */
3857 {SEGMENT_LINE, {{{4.42705116e+01f, 1.82442951e+01f}}}},
3858 {SEGMENT_LINE, {{{7.95376282e+01f, 5.06049728e+01f}}}},
3859 {SEGMENT_LINE, {{{5.52671127e+01f, 6.23606796e+01f}}}},
3860 /* Figure 2. */
3861 {SEGMENT_LINE, {{{25.0f, 15.0f}}}},
3862 {SEGMENT_LINE, {{{25.0f, 55.0f}}}},
3863 {SEGMENT_LINE, {{{25.0f, 55.0f}}}},
3864 /* Figure 3. */
3865 {SEGMENT_LINE, {{{35.0f, 45.0f}}}},
3866 {SEGMENT_LINE, {{{35.0f, 45.0f}}}},
3867 {SEGMENT_LINE, {{{30.0f, 45.0f}}}},
3868 /* Figure 4. */
3869 {SEGMENT_LINE, {{{ 1.07179585e+01f, 2.23205078e+02f}}}},
3870 {SEGMENT_LINE, {{{-5.85640755e+01f, 2.73205078e+02f}}}},
3871 {SEGMENT_LINE, {{{-7.85640717e+01f, 2.29903809e+02f}}}},
3872 /* Figure 5. */
3873 {SEGMENT_LINE, {{{40.0f, 20.0f}}}},
3874 {SEGMENT_LINE, {{{40.0f, 40.0f}}}},
3875 {SEGMENT_LINE, {{{30.0f, 40.0f}}}},
3876 /* Figure 6. */
3877 {SEGMENT_LINE, {{{ 2.14359169e+01f, 0.0f}}}},
3878 {SEGMENT_LINE, {{{-1.17128151e+02f, 0.0f}}}},
3879 {SEGMENT_LINE, {{{-1.57128143e+02f, 0.0f}}}},
3880 /* Figure 7. */
3881 {SEGMENT_LINE, {{{0.0f, 1.11602539e+02f}}}},
3882 {SEGMENT_LINE, {{{0.0f, 1.36602539e+02f}}}},
3883 {SEGMENT_LINE, {{{0.0f, 1.14951904e+02f}}}},
3885 static const struct expected_geometry_figure expected_figures[] =
3887 {D2D1_FIGURE_BEGIN_FILLED, D2D1_FIGURE_END_CLOSED, { 0.0f, 0.0f}, 3, &expected_segments[0]},
3888 {D2D1_FIGURE_BEGIN_FILLED, D2D1_FIGURE_END_CLOSED, {20.0f, 30.0f}, 3, &expected_segments[3]},
3889 {D2D1_FIGURE_BEGIN_FILLED, D2D1_FIGURE_END_CLOSED, {25.0f, 15.0f}, 3, &expected_segments[6]},
3890 {D2D1_FIGURE_BEGIN_FILLED, D2D1_FIGURE_END_CLOSED, {30.0f, 45.0f}, 3, &expected_segments[9]},
3891 {D2D1_FIGURE_BEGIN_FILLED, D2D1_FIGURE_END_CLOSED, {-9.28203964e+00f, 1.79903809e+02f},
3892 3, &expected_segments[12]},
3893 {D2D1_FIGURE_BEGIN_FILLED, D2D1_FIGURE_END_CLOSED, {30.0f, 20.0f}, 3, &expected_segments[15]},
3894 {D2D1_FIGURE_BEGIN_FILLED, D2D1_FIGURE_END_CLOSED, {-1.85640793e+01f, 0.0f}, 3, &expected_segments[18]},
3895 {D2D1_FIGURE_BEGIN_FILLED, D2D1_FIGURE_END_CLOSED, {0.0f, 8.99519043e+01f}, 3, &expected_segments[21]},
3898 hr = D2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED, &IID_ID2D1Factory, NULL, (void **)&factory);
3899 ok(SUCCEEDED(hr), "Failed to create factory, hr %#x.\n", hr);
3901 set_rect(&rect, 0.0f, 0.0f, 0.0f, 0.0f);
3902 hr = ID2D1Factory_CreateRectangleGeometry(factory, &rect, &geometry);
3903 ok(SUCCEEDED(hr), "Failed to create geometry, hr %#x.\n", hr);
3904 ID2D1RectangleGeometry_GetRect(geometry, &rect2);
3905 match = compare_rect(&rect2, 0.0f, 0.0f, 0.0f, 0.0f, 0);
3906 ok(match, "Got unexpected rectangle {%.8e, %.8e, %.8e, %.8e}.\n",
3907 rect2.left, rect2.top, rect2.right, rect2.bottom);
3908 ID2D1RectangleGeometry_Release(geometry);
3910 set_rect(&rect, 50.0f, 0.0f, 40.0f, 100.0f);
3911 hr = ID2D1Factory_CreateRectangleGeometry(factory, &rect, &geometry);
3912 ok(SUCCEEDED(hr), "Failed to create geometry, hr %#x.\n", hr);
3913 ID2D1RectangleGeometry_GetRect(geometry, &rect2);
3914 match = compare_rect(&rect2, 50.0f, 0.0f, 40.0f, 100.0f, 0);
3915 ok(match, "Got unexpected rectangle {%.8e, %.8e, %.8e, %.8e}.\n",
3916 rect2.left, rect2.top, rect2.right, rect2.bottom);
3917 ID2D1RectangleGeometry_Release(geometry);
3919 set_rect(&rect, 0.0f, 100.0f, 40.0f, 50.0f);
3920 hr = ID2D1Factory_CreateRectangleGeometry(factory, &rect, &geometry);
3921 ok(SUCCEEDED(hr), "Failed to create geometry, hr %#x.\n", hr);
3922 ID2D1RectangleGeometry_GetRect(geometry, &rect2);
3923 match = compare_rect(&rect2, 0.0f, 100.0f, 40.0f, 50.0f, 0);
3924 ok(match, "Got unexpected rectangle {%.8e, %.8e, %.8e, %.8e}.\n",
3925 rect2.left, rect2.top, rect2.right, rect2.bottom);
3926 ID2D1RectangleGeometry_Release(geometry);
3928 set_rect(&rect, 50.0f, 100.0f, 40.0f, 50.0f);
3929 hr = ID2D1Factory_CreateRectangleGeometry(factory, &rect, &geometry);
3930 ok(SUCCEEDED(hr), "Failed to create geometry, hr %#x.\n", hr);
3931 ID2D1RectangleGeometry_GetRect(geometry, &rect2);
3932 match = compare_rect(&rect2, 50.0f, 100.0f, 40.0f, 50.0f, 0);
3933 ok(match, "Got unexpected rectangle {%.8e, %.8e, %.8e, %.8e}.\n",
3934 rect2.left, rect2.top, rect2.right, rect2.bottom);
3935 ID2D1RectangleGeometry_Release(geometry);
3937 set_rect(&rect, 0.0f, 0.0f, 10.0f, 20.0f);
3938 hr = ID2D1Factory_CreateRectangleGeometry(factory, &rect, &geometry);
3939 ok(SUCCEEDED(hr), "Failed to create geometry, hr %#x.\n", hr);
3941 /* Edge. */
3942 contains = FALSE;
3943 set_point(&point, 0.0f, 0.0f);
3944 hr = ID2D1RectangleGeometry_FillContainsPoint(geometry, point, NULL, 0.0f, &contains);
3945 ok(SUCCEEDED(hr), "FillContainsPoint() failed, hr %#x.\n", hr);
3946 ok(!!contains, "Got wrong hit test result %d.\n", contains);
3948 /* Within tolerance limit around corner. */
3949 contains = TRUE;
3950 set_point(&point, -D2D1_DEFAULT_FLATTENING_TOLERANCE, 0.0f);
3951 hr = ID2D1RectangleGeometry_FillContainsPoint(geometry, point, NULL, 0.0f, &contains);
3952 ok(SUCCEEDED(hr), "FillContainsPoint() failed, hr %#x.\n", hr);
3953 ok(!contains, "Got wrong hit test result %d.\n", contains);
3955 contains = FALSE;
3956 set_point(&point, -D2D1_DEFAULT_FLATTENING_TOLERANCE + 0.01f, 0.0f);
3957 hr = ID2D1RectangleGeometry_FillContainsPoint(geometry, point, NULL, 0.0f, &contains);
3958 ok(SUCCEEDED(hr), "FillContainsPoint() failed, hr %#x.\n", hr);
3959 ok(!!contains, "Got wrong hit test result %d.\n", contains);
3961 contains = TRUE;
3962 set_point(&point, -D2D1_DEFAULT_FLATTENING_TOLERANCE - 0.01f, 0.0f);
3963 hr = ID2D1RectangleGeometry_FillContainsPoint(geometry, point, NULL, 0.0f, &contains);
3964 ok(SUCCEEDED(hr), "FillContainsPoint() failed, hr %#x.\n", hr);
3965 ok(!contains, "Got wrong hit test result %d.\n", contains);
3967 contains = TRUE;
3968 set_point(&point, -D2D1_DEFAULT_FLATTENING_TOLERANCE, -D2D1_DEFAULT_FLATTENING_TOLERANCE);
3969 hr = ID2D1RectangleGeometry_FillContainsPoint(geometry, point, NULL, 0.0f, &contains);
3970 ok(SUCCEEDED(hr), "FillContainsPoint() failed, hr %#x.\n", hr);
3971 ok(!contains, "Got wrong hit test result %d.\n", contains);
3973 /* Inside. */
3974 contains = FALSE;
3975 set_point(&point, 5.0f, 5.0f);
3976 hr = ID2D1RectangleGeometry_FillContainsPoint(geometry, point, NULL, 0.0f, &contains);
3977 ok(SUCCEEDED(hr), "FillContainsPoint() failed, hr %#x.\n", hr);
3978 ok(!!contains, "Got wrong hit test result %d.\n", contains);
3980 /* Test GetBounds() and Simplify(). */
3981 hr = ID2D1RectangleGeometry_GetBounds(geometry, NULL, &rect);
3982 ok(SUCCEEDED(hr), "Failed to get bounds.\n");
3983 match = compare_rect(&rect, 0.0f, 0.0f, 10.0f, 20.0f, 0);
3984 ok(match, "Got unexpected bounds {%.8e, %.8e, %.8e, %.8e}.\n",
3985 rect.left, rect.top, rect.right, rect.bottom);
3986 geometry_sink_init(&sink);
3987 hr = ID2D1RectangleGeometry_Simplify(geometry, D2D1_GEOMETRY_SIMPLIFICATION_OPTION_CUBICS_AND_LINES,
3988 NULL, 0.0f, &sink.ID2D1SimplifiedGeometrySink_iface);
3989 ok(SUCCEEDED(hr), "Failed to simplify geometry, hr %#x.\n", hr);
3990 geometry_sink_check(&sink, D2D1_FILL_MODE_ALTERNATE, 1, &expected_figures[0], 0);
3991 geometry_sink_cleanup(&sink);
3992 geometry_sink_init(&sink);
3993 hr = ID2D1RectangleGeometry_Simplify(geometry, D2D1_GEOMETRY_SIMPLIFICATION_OPTION_LINES,
3994 NULL, 0.0f, &sink.ID2D1SimplifiedGeometrySink_iface);
3995 ok(SUCCEEDED(hr), "Failed to simplify geometry, hr %#x.\n", hr);
3996 geometry_sink_check(&sink, D2D1_FILL_MODE_ALTERNATE, 1, &expected_figures[0], 0);
3997 geometry_sink_cleanup(&sink);
3999 set_matrix_identity(&matrix);
4000 translate_matrix(&matrix, 20.0f, 30.0f);
4001 scale_matrix(&matrix, 3.0f, 2.0f);
4002 rotate_matrix(&matrix, M_PI / -5.0f);
4003 hr = ID2D1RectangleGeometry_GetBounds(geometry, &matrix, &rect);
4004 ok(SUCCEEDED(hr), "Failed to get bounds.\n");
4005 match = compare_rect(&rect, 2.00000000e+01f, 1.82442951e+01f, 7.95376282e+01f, 6.23606796e+01f, 0);
4006 ok(match, "Got unexpected bounds {%.8e, %.8e, %.8e, %.8e}.\n",
4007 rect.left, rect.top, rect.right, rect.bottom);
4008 geometry_sink_init(&sink);
4009 hr = ID2D1RectangleGeometry_Simplify(geometry, D2D1_GEOMETRY_SIMPLIFICATION_OPTION_CUBICS_AND_LINES,
4010 &matrix, 0.0f, &sink.ID2D1SimplifiedGeometrySink_iface);
4011 ok(SUCCEEDED(hr), "Failed to simplify geometry, hr %#x.\n", hr);
4012 geometry_sink_check(&sink, D2D1_FILL_MODE_ALTERNATE, 1, &expected_figures[1], 1);
4013 geometry_sink_cleanup(&sink);
4015 set_matrix_identity(&matrix);
4016 translate_matrix(&matrix, 25.0f, 15.0f);
4017 scale_matrix(&matrix, 0.0f, 2.0f);
4018 hr = ID2D1RectangleGeometry_GetBounds(geometry, &matrix, &rect);
4019 ok(SUCCEEDED(hr), "Failed to get bounds.\n");
4020 match = compare_rect(&rect, 25.0f, 15.0f, 25.0f, 55.0f, 0);
4021 ok(match, "Got unexpected bounds {%.8e, %.8e, %.8e, %.8e}.\n",
4022 rect.left, rect.top, rect.right, rect.bottom);
4023 geometry_sink_init(&sink);
4024 hr = ID2D1RectangleGeometry_Simplify(geometry, D2D1_GEOMETRY_SIMPLIFICATION_OPTION_LINES,
4025 &matrix, 0.0f, &sink.ID2D1SimplifiedGeometrySink_iface);
4026 ok(SUCCEEDED(hr), "Failed to simplify geometry, hr %#x.\n", hr);
4027 geometry_sink_check(&sink, D2D1_FILL_MODE_ALTERNATE, 1, &expected_figures[2], 0);
4028 geometry_sink_cleanup(&sink);
4030 set_matrix_identity(&matrix);
4031 translate_matrix(&matrix, 30.0f, 45.0f);
4032 scale_matrix(&matrix, 0.5f, 0.0f);
4033 hr = ID2D1RectangleGeometry_GetBounds(geometry, &matrix, &rect);
4034 ok(SUCCEEDED(hr), "Failed to get bounds.\n");
4035 match = compare_rect(&rect, 30.0f, 45.0f, 35.0f, 45.0f, 0);
4036 ok(match, "Got unexpected bounds {%.8e, %.8e, %.8e, %.8e}.\n",
4037 rect.left, rect.top, rect.right, rect.bottom);
4038 geometry_sink_init(&sink);
4039 hr = ID2D1RectangleGeometry_Simplify(geometry, D2D1_GEOMETRY_SIMPLIFICATION_OPTION_LINES,
4040 &matrix, 0.0f, &sink.ID2D1SimplifiedGeometrySink_iface);
4041 ok(SUCCEEDED(hr), "Failed to simplify geometry, hr %#x.\n", hr);
4042 geometry_sink_check(&sink, D2D1_FILL_MODE_ALTERNATE, 1, &expected_figures[3], 0);
4043 geometry_sink_cleanup(&sink);
4045 set_matrix_identity(&matrix);
4046 scale_matrix(&matrix, 4.0f, 5.0f);
4047 rotate_matrix(&matrix, M_PI / 3.0f);
4048 translate_matrix(&matrix, 30.0f, 20.0f);
4049 hr = ID2D1Factory_CreateTransformedGeometry(factory, (ID2D1Geometry *)geometry, &matrix, &transformed_geometry);
4050 ok(SUCCEEDED(hr), "Failed to create transformed geometry, hr %#x.\n", hr);
4052 ID2D1TransformedGeometry_GetBounds(transformed_geometry, NULL, &rect);
4053 ok(SUCCEEDED(hr), "Failed to get bounds.\n");
4054 match = compare_rect(&rect, -7.85640717e+01f, 1.79903809e+02f, 1.07179594e+01f, 2.73205078e+02f, 1);
4055 ok(match, "Got unexpected bounds {%.8e, %.8e, %.8e, %.8e}.\n",
4056 rect.left, rect.top, rect.right, rect.bottom);
4057 geometry_sink_init(&sink);
4058 hr = ID2D1TransformedGeometry_Simplify(transformed_geometry, D2D1_GEOMETRY_SIMPLIFICATION_OPTION_CUBICS_AND_LINES,
4059 NULL, 0.0f, &sink.ID2D1SimplifiedGeometrySink_iface);
4060 ok(SUCCEEDED(hr), "Failed to simplify geometry, hr %#x.\n", hr);
4061 geometry_sink_check(&sink, D2D1_FILL_MODE_ALTERNATE, 1, &expected_figures[4], 1);
4062 geometry_sink_cleanup(&sink);
4063 geometry_sink_init(&sink);
4064 hr = ID2D1TransformedGeometry_Simplify(transformed_geometry, D2D1_GEOMETRY_SIMPLIFICATION_OPTION_LINES,
4065 NULL, 0.0f, &sink.ID2D1SimplifiedGeometrySink_iface);
4066 ok(SUCCEEDED(hr), "Failed to simplify geometry, hr %#x.\n", hr);
4067 geometry_sink_check(&sink, D2D1_FILL_MODE_ALTERNATE, 1, &expected_figures[4], 1);
4068 geometry_sink_cleanup(&sink);
4070 set_matrix_identity(&matrix);
4071 rotate_matrix(&matrix, M_PI / -3.0f);
4072 scale_matrix(&matrix, 0.25f, 0.2f);
4073 ID2D1TransformedGeometry_GetBounds(transformed_geometry, &matrix, &rect);
4074 ok(SUCCEEDED(hr), "Failed to get bounds.\n");
4075 match = compare_rect(&rect, 30.0f, 20.0f, 40.0f, 40.0f, 2);
4076 ok(match, "Got unexpected bounds {%.8e, %.8e, %.8e, %.8e}.\n",
4077 rect.left, rect.top, rect.right, rect.bottom);
4078 geometry_sink_init(&sink);
4079 hr = ID2D1TransformedGeometry_Simplify(transformed_geometry, D2D1_GEOMETRY_SIMPLIFICATION_OPTION_LINES,
4080 &matrix, 0.0f, &sink.ID2D1SimplifiedGeometrySink_iface);
4081 ok(SUCCEEDED(hr), "Failed to simplify geometry, hr %#x.\n", hr);
4082 geometry_sink_check(&sink, D2D1_FILL_MODE_ALTERNATE, 1, &expected_figures[5], 4);
4083 geometry_sink_cleanup(&sink);
4085 set_matrix_identity(&matrix);
4086 scale_matrix(&matrix, 2.0f, 0.0f);
4087 ID2D1TransformedGeometry_GetBounds(transformed_geometry, &matrix, &rect);
4088 ok(SUCCEEDED(hr), "Failed to get bounds.\n");
4089 match = compare_rect(&rect, -1.57128143e+02f, 0.00000000e+00f, 2.14359188e+01f, 0.00000000e+00f, 1);
4090 ok(match, "Got unexpected bounds {%.8e, %.8e, %.8e, %.8e}.\n",
4091 rect.left, rect.top, rect.right, rect.bottom);
4092 geometry_sink_init(&sink);
4093 hr = ID2D1TransformedGeometry_Simplify(transformed_geometry, D2D1_GEOMETRY_SIMPLIFICATION_OPTION_CUBICS_AND_LINES,
4094 &matrix, 0.0f, &sink.ID2D1SimplifiedGeometrySink_iface);
4095 ok(SUCCEEDED(hr), "Failed to simplify geometry, hr %#x.\n", hr);
4096 geometry_sink_check(&sink, D2D1_FILL_MODE_ALTERNATE, 1, &expected_figures[6], 1);
4097 geometry_sink_cleanup(&sink);
4099 set_matrix_identity(&matrix);
4100 scale_matrix(&matrix, 0.0f, 0.5f);
4101 ID2D1TransformedGeometry_GetBounds(transformed_geometry, &matrix, &rect);
4102 ok(SUCCEEDED(hr), "Failed to get bounds.\n");
4103 match = compare_rect(&rect, 0.00000000e+00f, 8.99519043e+01f, 0.00000000e+00, 1.36602539e+02f, 1);
4104 ok(match, "Got unexpected bounds {%.8e, %.8e, %.8e, %.8e}.\n",
4105 rect.left, rect.top, rect.right, rect.bottom);
4106 geometry_sink_init(&sink);
4107 hr = ID2D1TransformedGeometry_Simplify(transformed_geometry, D2D1_GEOMETRY_SIMPLIFICATION_OPTION_CUBICS_AND_LINES,
4108 &matrix, 0.0f, &sink.ID2D1SimplifiedGeometrySink_iface);
4109 ok(SUCCEEDED(hr), "Failed to simplify geometry, hr %#x.\n", hr);
4110 geometry_sink_check(&sink, D2D1_FILL_MODE_ALTERNATE, 1, &expected_figures[7], 1);
4111 geometry_sink_cleanup(&sink);
4113 ID2D1TransformedGeometry_Release(transformed_geometry);
4114 ID2D1RectangleGeometry_Release(geometry);
4115 ID2D1Factory_Release(factory);
4118 static void test_rounded_rectangle_geometry(BOOL d3d11)
4120 ID2D1RoundedRectangleGeometry *geometry;
4121 D2D1_ROUNDED_RECT rect, rect2;
4122 ID2D1Factory *factory;
4123 HRESULT hr;
4125 hr = D2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED, &IID_ID2D1Factory, NULL, (void **)&factory);
4126 ok(SUCCEEDED(hr), "Failed to create factory, hr %#x.\n", hr);
4128 set_rounded_rect(&rect, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f);
4129 hr = ID2D1Factory_CreateRoundedRectangleGeometry(factory, &rect, &geometry);
4130 ok(SUCCEEDED(hr), "Failed to create geometry, hr %#x.\n", hr);
4132 ID2D1RoundedRectangleGeometry_GetRoundedRect(geometry, &rect2);
4133 ok(!memcmp(&rect, &rect2, sizeof(rect)), "Got unexpected rectangle {%.8e, %.8e, %.8e, %.8e, %.8e, %.8e}.\n",
4134 rect2.rect.left, rect2.rect.top, rect2.rect.right, rect2.rect.bottom, rect2.radiusX, rect2.radiusY);
4135 ID2D1RoundedRectangleGeometry_Release(geometry);
4137 /* X radius larger than half width. */
4138 set_rounded_rect(&rect, 0.0f, 0.0f, 50.0f, 40.0f, 30.0f, 5.0f);
4139 hr = ID2D1Factory_CreateRoundedRectangleGeometry(factory, &rect, &geometry);
4140 ID2D1RoundedRectangleGeometry_GetRoundedRect(geometry, &rect2);
4141 ok(!memcmp(&rect, &rect2, sizeof(rect)), "Got unexpected rectangle {%.8e, %.8e, %.8e, %.8e, %.8e, %.8e}.\n",
4142 rect2.rect.left, rect2.rect.top, rect2.rect.right, rect2.rect.bottom, rect2.radiusX, rect2.radiusY);
4143 ID2D1RoundedRectangleGeometry_Release(geometry);
4145 /* Y radius larger than half height. */
4146 set_rounded_rect(&rect, 0.0f, 0.0f, 50.0f, 40.0f, 5.0f, 30.0f);
4147 hr = ID2D1Factory_CreateRoundedRectangleGeometry(factory, &rect, &geometry);
4148 ID2D1RoundedRectangleGeometry_GetRoundedRect(geometry, &rect2);
4149 ok(!memcmp(&rect, &rect2, sizeof(rect)), "Got unexpected rectangle {%.8e, %.8e, %.8e, %.8e, %.8e, %.8e}.\n",
4150 rect2.rect.left, rect2.rect.top, rect2.rect.right, rect2.rect.bottom, rect2.radiusX, rect2.radiusY);
4151 ID2D1RoundedRectangleGeometry_Release(geometry);
4153 /* Both exceed rectangle size. */
4154 set_rounded_rect(&rect, 0.0f, 0.0f, 50.0f, 40.0f, 30.0f, 25.0f);
4155 hr = ID2D1Factory_CreateRoundedRectangleGeometry(factory, &rect, &geometry);
4156 ID2D1RoundedRectangleGeometry_GetRoundedRect(geometry, &rect2);
4157 ok(!memcmp(&rect, &rect2, sizeof(rect)), "Got unexpected rectangle {%.8e, %.8e, %.8e, %.8e, %.8e, %.8e}.\n",
4158 rect2.rect.left, rect2.rect.top, rect2.rect.right, rect2.rect.bottom, rect2.radiusX, rect2.radiusY);
4159 ID2D1RoundedRectangleGeometry_Release(geometry);
4161 ID2D1Factory_Release(factory);
4164 static void test_bitmap_formats(BOOL d3d11)
4166 D2D1_BITMAP_PROPERTIES bitmap_desc;
4167 struct d2d1_test_context ctx;
4168 D2D1_SIZE_U size = {4, 4};
4169 ID2D1RenderTarget *rt;
4170 ID2D1Bitmap *bitmap;
4171 unsigned int i, j;
4172 HRESULT hr;
4174 static const struct
4176 DXGI_FORMAT format;
4177 DWORD mask;
4179 bitmap_formats[] =
4181 {DXGI_FORMAT_R32G32B32A32_FLOAT, 0x8a},
4182 {DXGI_FORMAT_R16G16B16A16_FLOAT, 0x8a},
4183 {DXGI_FORMAT_R16G16B16A16_UNORM, 0x8a},
4184 {DXGI_FORMAT_R8G8B8A8_TYPELESS, 0x00},
4185 {DXGI_FORMAT_R8G8B8A8_UNORM, 0x0a},
4186 {DXGI_FORMAT_R8G8B8A8_UNORM_SRGB, 0x8a},
4187 {DXGI_FORMAT_R8G8B8A8_UINT, 0x00},
4188 {DXGI_FORMAT_R8G8B8A8_SNORM, 0x00},
4189 {DXGI_FORMAT_R8G8B8A8_SINT, 0x00},
4190 {DXGI_FORMAT_A8_UNORM, 0x06},
4191 {DXGI_FORMAT_B8G8R8A8_UNORM, 0x0a},
4192 {DXGI_FORMAT_B8G8R8X8_UNORM, 0x88},
4193 {DXGI_FORMAT_B8G8R8A8_TYPELESS, 0x00},
4194 {DXGI_FORMAT_B8G8R8A8_UNORM_SRGB, 0x8a},
4197 if (!init_test_context(&ctx, d3d11))
4198 return;
4200 rt = ctx.rt;
4201 bitmap_desc.dpiX = 96.0f;
4202 bitmap_desc.dpiY = 96.0f;
4203 for (i = 0; i < ARRAY_SIZE(bitmap_formats); ++i)
4205 for (j = 0; j < 4; ++j)
4207 if ((bitmap_formats[i].mask & (0x80 | (1u << j))) == (0x80 | (1u << j)))
4208 continue;
4210 bitmap_desc.pixelFormat.format = bitmap_formats[i].format;
4211 bitmap_desc.pixelFormat.alphaMode = j;
4212 hr = ID2D1RenderTarget_CreateBitmap(rt, size, NULL, 0, &bitmap_desc, &bitmap);
4213 if (bitmap_formats[i].mask & (1u << j))
4214 ok(hr == S_OK, "Got unexpected hr %#x, for format %#x/%#x.\n",
4215 hr, bitmap_formats[i].format, j);
4216 else
4217 ok(hr == D2DERR_UNSUPPORTED_PIXEL_FORMAT, "Got unexpected hr %#x, for format %#x/%#x.\n",
4218 hr, bitmap_formats[i].format, j);
4219 if (SUCCEEDED(hr))
4220 ID2D1Bitmap_Release(bitmap);
4224 release_test_context(&ctx);
4227 static void test_alpha_mode(BOOL d3d11)
4229 D2D1_RENDER_TARGET_PROPERTIES rt_desc;
4230 D2D1_BITMAP_PROPERTIES bitmap_desc;
4231 ID2D1SolidColorBrush *color_brush;
4232 ID2D1BitmapBrush *bitmap_brush;
4233 struct d2d1_test_context ctx;
4234 ID2D1RenderTarget *rt;
4235 ID2D1Bitmap *bitmap;
4236 D2D1_COLOR_F color;
4237 D2D1_RECT_F rect;
4238 D2D1_SIZE_U size;
4239 ULONG refcount;
4240 HRESULT hr;
4241 BOOL match;
4243 static const DWORD bitmap_data[] =
4245 0x7f7f0000, 0x7f7f7f00, 0x7f007f00, 0x7f007f7f,
4246 0x7f00007f, 0x7f7f007f, 0x7f000000, 0x7f404040,
4247 0x7f7f7f7f, 0x7f7f7f7f, 0x7f7f7f7f, 0x7f000000,
4248 0x7f7f7f7f, 0x7f000000, 0x7f000000, 0x7f000000,
4251 if (!init_test_context(&ctx, d3d11))
4252 return;
4254 rt = ctx.rt;
4255 ID2D1RenderTarget_SetAntialiasMode(rt, D2D1_ANTIALIAS_MODE_ALIASED);
4257 set_size_u(&size, 4, 4);
4258 bitmap_desc.pixelFormat.format = DXGI_FORMAT_B8G8R8A8_UNORM;
4259 bitmap_desc.pixelFormat.alphaMode = D2D1_ALPHA_MODE_IGNORE;
4260 bitmap_desc.dpiX = 96.0f / 40.0f;
4261 bitmap_desc.dpiY = 96.0f / 30.0f;
4262 hr = ID2D1RenderTarget_CreateBitmap(rt, size, bitmap_data, 4 * sizeof(*bitmap_data), &bitmap_desc, &bitmap);
4263 ok(SUCCEEDED(hr), "Failed to create bitmap, hr %#x.\n", hr);
4265 hr = ID2D1RenderTarget_CreateBitmapBrush(rt, bitmap, NULL, NULL, &bitmap_brush);
4266 ok(SUCCEEDED(hr), "Failed to create brush, hr %#x.\n", hr);
4267 ID2D1BitmapBrush_SetInterpolationMode(bitmap_brush, D2D1_BITMAP_INTERPOLATION_MODE_NEAREST_NEIGHBOR);
4268 ID2D1BitmapBrush_SetExtendModeX(bitmap_brush, D2D1_EXTEND_MODE_WRAP);
4269 ID2D1BitmapBrush_SetExtendModeY(bitmap_brush, D2D1_EXTEND_MODE_WRAP);
4271 set_color(&color, 0.0f, 1.0f, 0.0f, 0.75f);
4272 hr = ID2D1RenderTarget_CreateSolidColorBrush(rt, &color, NULL, &color_brush);
4273 ok(SUCCEEDED(hr), "Failed to create brush, hr %#x.\n", hr);
4275 ID2D1RenderTarget_BeginDraw(rt);
4276 ID2D1RenderTarget_Clear(rt, NULL);
4277 hr = ID2D1RenderTarget_EndDraw(rt, NULL, NULL);
4278 ok(SUCCEEDED(hr), "Failed to end draw, hr %#x.\n", hr);
4279 match = compare_surface(&ctx, "48c41aff3a130a17ee210866b2ab7d36763934d5");
4280 ok(match, "Surface does not match.\n");
4282 ID2D1RenderTarget_BeginDraw(rt);
4283 set_color(&color, 1.0f, 0.0f, 0.0f, 0.25f);
4284 ID2D1RenderTarget_Clear(rt, &color);
4285 hr = ID2D1RenderTarget_EndDraw(rt, NULL, NULL);
4286 ok(SUCCEEDED(hr), "Failed to end draw, hr %#x.\n", hr);
4287 match = compare_surface(&ctx, "6487e683730fb5a77c1911388d00b04664c5c4e4");
4288 ok(match, "Surface does not match.\n");
4290 ID2D1RenderTarget_BeginDraw(rt);
4291 set_color(&color, 0.0f, 0.0f, 1.0f, 0.75f);
4292 ID2D1RenderTarget_Clear(rt, &color);
4293 hr = ID2D1RenderTarget_EndDraw(rt, NULL, NULL);
4294 ok(SUCCEEDED(hr), "Failed to end draw, hr %#x.\n", hr);
4295 match = compare_surface(&ctx, "7a35ba09e43cbaf591388ff1ef8de56157630c98");
4296 ok(match, "Surface does not match.\n");
4298 ID2D1RenderTarget_BeginDraw(rt);
4300 set_rect(&rect, 0.0f, 0.0f, 160.0f, 120.0f);
4301 ID2D1RenderTarget_FillRectangle(rt, &rect, (ID2D1Brush *)bitmap_brush);
4302 set_rect(&rect, 160.0f, 0.0f, 320.0f, 120.0f);
4303 ID2D1BitmapBrush_SetOpacity(bitmap_brush, 0.75f);
4304 ID2D1RenderTarget_FillRectangle(rt, &rect, (ID2D1Brush *)bitmap_brush);
4305 set_rect(&rect, 320.0f, 0.0f, 480.0f, 120.0f);
4306 ID2D1BitmapBrush_SetOpacity(bitmap_brush, 0.25f);
4307 ID2D1RenderTarget_FillRectangle(rt, &rect, (ID2D1Brush *)bitmap_brush);
4309 ID2D1Bitmap_Release(bitmap);
4310 bitmap_desc.pixelFormat.alphaMode = D2D1_ALPHA_MODE_PREMULTIPLIED;
4311 hr = ID2D1RenderTarget_CreateBitmap(rt, size, bitmap_data, 4 * sizeof(*bitmap_data), &bitmap_desc, &bitmap);
4312 ok(SUCCEEDED(hr), "Failed to create bitmap, hr %#x.\n", hr);
4313 ID2D1BitmapBrush_SetBitmap(bitmap_brush, bitmap);
4315 set_rect(&rect, 0.0f, 120.0f, 160.0f, 240.0f);
4316 ID2D1BitmapBrush_SetOpacity(bitmap_brush, 1.0f);
4317 ID2D1RenderTarget_FillRectangle(rt, &rect, (ID2D1Brush *)bitmap_brush);
4318 set_rect(&rect, 160.0f, 120.0f, 320.0f, 240.0f);
4319 ID2D1BitmapBrush_SetOpacity(bitmap_brush, 0.75f);
4320 ID2D1RenderTarget_FillRectangle(rt, &rect, (ID2D1Brush *)bitmap_brush);
4321 set_rect(&rect, 320.0f, 120.0f, 480.0f, 240.0f);
4322 ID2D1BitmapBrush_SetOpacity(bitmap_brush, 0.25f);
4323 ID2D1RenderTarget_FillRectangle(rt, &rect, (ID2D1Brush *)bitmap_brush);
4325 set_rect(&rect, 0.0f, 240.0f, 160.0f, 360.0f);
4326 ID2D1RenderTarget_FillRectangle(rt, &rect, (ID2D1Brush *)color_brush);
4327 set_rect(&rect, 160.0f, 240.0f, 320.0f, 360.0f);
4328 ID2D1SolidColorBrush_SetOpacity(color_brush, 0.75f);
4329 ID2D1RenderTarget_FillRectangle(rt, &rect, (ID2D1Brush *)color_brush);
4330 set_rect(&rect, 320.0f, 240.0f, 480.0f, 360.0f);
4331 ID2D1SolidColorBrush_SetOpacity(color_brush, 0.25f);
4332 ID2D1RenderTarget_FillRectangle(rt, &rect, (ID2D1Brush *)color_brush);
4334 hr = ID2D1RenderTarget_EndDraw(rt, NULL, NULL);
4335 ok(SUCCEEDED(hr), "Failed to end draw, hr %#x.\n", hr);
4336 match = compare_surface(&ctx, "14f8ac64b70966c7c3c6281c59aaecdb17c3b16a");
4337 ok(match, "Surface does not match.\n");
4339 rt_desc.type = D2D1_RENDER_TARGET_TYPE_DEFAULT;
4340 rt_desc.pixelFormat.format = DXGI_FORMAT_UNKNOWN;
4341 rt_desc.pixelFormat.alphaMode = D2D1_ALPHA_MODE_IGNORE;
4342 rt_desc.dpiX = 0.0f;
4343 rt_desc.dpiY = 0.0f;
4344 rt_desc.usage = D2D1_RENDER_TARGET_USAGE_NONE;
4345 rt_desc.minLevel = D2D1_FEATURE_LEVEL_DEFAULT;
4346 rt = create_render_target_desc(ctx.surface, &rt_desc, d3d11);
4347 ok(!!rt, "Failed to create render target.\n");
4349 ID2D1RenderTarget_SetAntialiasMode(rt, D2D1_ANTIALIAS_MODE_ALIASED);
4351 ID2D1Bitmap_Release(bitmap);
4352 bitmap_desc.pixelFormat.alphaMode = D2D1_ALPHA_MODE_IGNORE;
4353 hr = ID2D1RenderTarget_CreateBitmap(rt, size, bitmap_data, 4 * sizeof(*bitmap_data), &bitmap_desc, &bitmap);
4354 ok(SUCCEEDED(hr), "Failed to create bitmap, hr %#x.\n", hr);
4355 ID2D1BitmapBrush_SetBitmap(bitmap_brush, bitmap);
4357 ID2D1BitmapBrush_Release(bitmap_brush);
4358 hr = ID2D1RenderTarget_CreateBitmapBrush(rt, bitmap, NULL, NULL, &bitmap_brush);
4359 ok(SUCCEEDED(hr), "Failed to create brush, hr %#x.\n", hr);
4360 ID2D1BitmapBrush_SetInterpolationMode(bitmap_brush, D2D1_BITMAP_INTERPOLATION_MODE_NEAREST_NEIGHBOR);
4361 ID2D1BitmapBrush_SetExtendModeX(bitmap_brush, D2D1_EXTEND_MODE_WRAP);
4362 ID2D1BitmapBrush_SetExtendModeY(bitmap_brush, D2D1_EXTEND_MODE_WRAP);
4364 ID2D1SolidColorBrush_Release(color_brush);
4365 set_color(&color, 0.0f, 1.0f, 0.0f, 0.75f);
4366 hr = ID2D1RenderTarget_CreateSolidColorBrush(rt, &color, NULL, &color_brush);
4367 ok(SUCCEEDED(hr), "Failed to create brush, hr %#x.\n", hr);
4369 ID2D1RenderTarget_BeginDraw(rt);
4370 ID2D1RenderTarget_Clear(rt, NULL);
4371 hr = ID2D1RenderTarget_EndDraw(rt, NULL, NULL);
4372 ok(SUCCEEDED(hr), "Failed to end draw, hr %#x.\n", hr);
4373 match = compare_surface(&ctx, "b44510bf2d2e61a8d7c0ad862de49a471f1fd13f");
4374 ok(match, "Surface does not match.\n");
4376 ID2D1RenderTarget_BeginDraw(rt);
4377 set_color(&color, 1.0f, 0.0f, 0.0f, 0.25f);
4378 ID2D1RenderTarget_Clear(rt, &color);
4379 hr = ID2D1RenderTarget_EndDraw(rt, NULL, NULL);
4380 ok(SUCCEEDED(hr), "Failed to end draw, hr %#x.\n", hr);
4381 match = compare_surface(&ctx, "2184f4a9198fc1de09ac85301b7a03eebadd9b81");
4382 ok(match, "Surface does not match.\n");
4384 ID2D1RenderTarget_BeginDraw(rt);
4385 set_color(&color, 0.0f, 0.0f, 1.0f, 0.75f);
4386 ID2D1RenderTarget_Clear(rt, &color);
4387 hr = ID2D1RenderTarget_EndDraw(rt, NULL, NULL);
4388 ok(SUCCEEDED(hr), "Failed to end draw, hr %#x.\n", hr);
4389 match = compare_surface(&ctx, "6527ec83b4039c895b50f9b3e144fe0cf90d1889");
4390 ok(match, "Surface does not match.\n");
4392 ID2D1RenderTarget_BeginDraw(rt);
4394 set_rect(&rect, 0.0f, 0.0f, 160.0f, 120.0f);
4395 ID2D1RenderTarget_FillRectangle(rt, &rect, (ID2D1Brush *)bitmap_brush);
4396 set_rect(&rect, 160.0f, 0.0f, 320.0f, 120.0f);
4397 ID2D1BitmapBrush_SetOpacity(bitmap_brush, 0.75f);
4398 ID2D1RenderTarget_FillRectangle(rt, &rect, (ID2D1Brush *)bitmap_brush);
4399 set_rect(&rect, 320.0f, 0.0f, 480.0f, 120.0f);
4400 ID2D1BitmapBrush_SetOpacity(bitmap_brush, 0.25f);
4401 ID2D1RenderTarget_FillRectangle(rt, &rect, (ID2D1Brush *)bitmap_brush);
4403 ID2D1Bitmap_Release(bitmap);
4404 bitmap_desc.pixelFormat.alphaMode = D2D1_ALPHA_MODE_PREMULTIPLIED;
4405 hr = ID2D1RenderTarget_CreateBitmap(rt, size, bitmap_data, 4 * sizeof(*bitmap_data), &bitmap_desc, &bitmap);
4406 ok(SUCCEEDED(hr), "Failed to create bitmap, hr %#x.\n", hr);
4407 ID2D1BitmapBrush_SetBitmap(bitmap_brush, bitmap);
4409 set_rect(&rect, 0.0f, 120.0f, 160.0f, 240.0f);
4410 ID2D1BitmapBrush_SetOpacity(bitmap_brush, 1.0f);
4411 ID2D1RenderTarget_FillRectangle(rt, &rect, (ID2D1Brush *)bitmap_brush);
4412 set_rect(&rect, 160.0f, 120.0f, 320.0f, 240.0f);
4413 ID2D1BitmapBrush_SetOpacity(bitmap_brush, 0.75f);
4414 ID2D1RenderTarget_FillRectangle(rt, &rect, (ID2D1Brush *)bitmap_brush);
4415 set_rect(&rect, 320.0f, 120.0f, 480.0f, 240.0f);
4416 ID2D1BitmapBrush_SetOpacity(bitmap_brush, 0.25f);
4417 ID2D1RenderTarget_FillRectangle(rt, &rect, (ID2D1Brush *)bitmap_brush);
4419 set_rect(&rect, 0.0f, 240.0f, 160.0f, 360.0f);
4420 ID2D1RenderTarget_FillRectangle(rt, &rect, (ID2D1Brush *)color_brush);
4421 set_rect(&rect, 160.0f, 240.0f, 320.0f, 360.0f);
4422 ID2D1SolidColorBrush_SetOpacity(color_brush, 0.75f);
4423 ID2D1RenderTarget_FillRectangle(rt, &rect, (ID2D1Brush *)color_brush);
4424 set_rect(&rect, 320.0f, 240.0f, 480.0f, 360.0f);
4425 ID2D1SolidColorBrush_SetOpacity(color_brush, 0.25f);
4426 ID2D1RenderTarget_FillRectangle(rt, &rect, (ID2D1Brush *)color_brush);
4428 hr = ID2D1RenderTarget_EndDraw(rt, NULL, NULL);
4429 ok(SUCCEEDED(hr), "Failed to end draw, hr %#x.\n", hr);
4430 match = compare_surface(&ctx, "465f5a3190d7bde408b3206b4be939fb22f8a3d6");
4431 ok(match, "Surface does not match.\n");
4433 refcount = ID2D1Bitmap_Release(bitmap);
4434 ok(refcount == 1, "Bitmap has %u references left.\n", refcount);
4435 ID2D1SolidColorBrush_Release(color_brush);
4436 ID2D1BitmapBrush_Release(bitmap_brush);
4437 ID2D1RenderTarget_Release(rt);
4438 release_test_context(&ctx);
4441 static void test_shared_bitmap(BOOL d3d11)
4443 IWICBitmap *wic_bitmap1, *wic_bitmap2;
4444 ID2D1GdiInteropRenderTarget *interop;
4445 D2D1_RENDER_TARGET_PROPERTIES desc;
4446 D2D1_BITMAP_PROPERTIES bitmap_desc;
4447 ID2D1RenderTarget *rt1, *rt2, *rt3;
4448 IDXGISurface *surface2;
4449 ID2D1Factory *factory1, *factory2;
4450 IWICImagingFactory *wic_factory;
4451 ID2D1Bitmap *bitmap1, *bitmap2;
4452 DXGI_SURFACE_DESC surface_desc;
4453 D2D1_PIXEL_FORMAT pixel_format;
4454 struct d2d1_test_context ctx;
4455 IDXGISwapChain *swapchain2;
4456 D2D1_SIZE_U size = {4, 4};
4457 IDXGISurface1 *surface3;
4458 IDXGIDevice *device2;
4459 HWND window2;
4460 HRESULT hr;
4462 if (!init_test_context(&ctx, d3d11))
4463 return;
4465 window2 = create_window();
4466 swapchain2 = create_swapchain(ctx.device, window2, TRUE);
4467 hr = IDXGISwapChain_GetBuffer(swapchain2, 0, &IID_IDXGISurface, (void **)&surface2);
4468 ok(SUCCEEDED(hr), "Failed to get buffer, hr %#x.\n", hr);
4470 CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
4471 hr = CoCreateInstance(&CLSID_WICImagingFactory, NULL, CLSCTX_INPROC_SERVER,
4472 &IID_IWICImagingFactory, (void **)&wic_factory);
4473 ok(SUCCEEDED(hr), "Failed to create WIC imaging factory, hr %#x.\n", hr);
4474 hr = IWICImagingFactory_CreateBitmap(wic_factory, 640, 480,
4475 &GUID_WICPixelFormat32bppPBGRA, WICBitmapCacheOnDemand, &wic_bitmap1);
4476 ok(SUCCEEDED(hr), "Failed to create bitmap, hr %#x.\n", hr);
4477 hr = IWICImagingFactory_CreateBitmap(wic_factory, 640, 480,
4478 &GUID_WICPixelFormat32bppPBGRA, WICBitmapCacheOnDemand, &wic_bitmap2);
4479 ok(SUCCEEDED(hr), "Failed to create bitmap, hr %#x.\n", hr);
4480 IWICImagingFactory_Release(wic_factory);
4482 desc.type = D2D1_RENDER_TARGET_TYPE_DEFAULT;
4483 desc.pixelFormat.format = DXGI_FORMAT_UNKNOWN;
4484 desc.pixelFormat.alphaMode = D2D1_ALPHA_MODE_PREMULTIPLIED;
4485 desc.dpiX = 0.0f;
4486 desc.dpiY = 0.0f;
4487 desc.usage = D2D1_RENDER_TARGET_USAGE_NONE;
4488 desc.minLevel = D2D1_FEATURE_LEVEL_DEFAULT;
4490 bitmap_desc.pixelFormat.format = DXGI_FORMAT_B8G8R8A8_UNORM;
4491 bitmap_desc.pixelFormat.alphaMode = D2D1_ALPHA_MODE_PREMULTIPLIED;
4492 bitmap_desc.dpiX = 96.0f;
4493 bitmap_desc.dpiY = 96.0f;
4495 hr = D2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED, &IID_ID2D1Factory, NULL, (void **)&factory1);
4496 ok(SUCCEEDED(hr), "Failed to create factory, hr %#x.\n", hr);
4497 hr = D2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED, &IID_ID2D1Factory, NULL, (void **)&factory2);
4498 ok(SUCCEEDED(hr), "Failed to create factory, hr %#x.\n", hr);
4500 /* DXGI surface render targets with the same device and factory. */
4501 hr = ID2D1Factory_CreateDxgiSurfaceRenderTarget(factory1, ctx.surface, &desc, &rt1);
4502 ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr);
4503 hr = ID2D1RenderTarget_CreateBitmap(rt1, size, NULL, 0, &bitmap_desc, &bitmap1);
4504 check_bitmap_surface(bitmap1, TRUE, 0);
4505 ok(SUCCEEDED(hr), "Failed to create bitmap, hr %#x.\n", hr);
4507 hr = ID2D1Factory_CreateDxgiSurfaceRenderTarget(factory1, surface2, &desc, &rt2);
4508 ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr);
4509 hr = ID2D1RenderTarget_CreateSharedBitmap(rt2, &IID_ID2D1Bitmap, bitmap1, NULL, &bitmap2);
4510 ok(SUCCEEDED(hr), "Failed to create bitmap, hr %#x.\n", hr);
4511 check_bitmap_surface(bitmap2, TRUE, 0);
4512 ID2D1Bitmap_Release(bitmap2);
4513 hr = ID2D1RenderTarget_CreateSharedBitmap(rt2, &IID_IUnknown, bitmap1, NULL, &bitmap2);
4514 ok(hr == E_INVALIDARG, "Got unexpected hr %#x.\n", hr);
4515 ID2D1RenderTarget_Release(rt2);
4517 /* DXGI surface render targets with the same device but different factories. */
4518 hr = ID2D1Factory_CreateDxgiSurfaceRenderTarget(factory2, surface2, &desc, &rt2);
4519 ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr);
4520 hr = ID2D1RenderTarget_CreateSharedBitmap(rt2, &IID_ID2D1Bitmap, bitmap1, NULL, &bitmap2);
4521 ok(hr == D2DERR_WRONG_FACTORY, "Got unexpected hr %#x.\n", hr);
4522 ID2D1RenderTarget_Release(rt2);
4524 /* DXGI surface render targets with different devices but the same factory. */
4525 IDXGISurface_Release(surface2);
4526 IDXGISwapChain_Release(swapchain2);
4527 device2 = create_device(d3d11);
4528 ok(!!device2, "Failed to create device.\n");
4529 swapchain2 = create_swapchain(device2, window2, TRUE);
4530 hr = IDXGISwapChain_GetBuffer(swapchain2, 0, &IID_IDXGISurface, (void **)&surface2);
4531 ok(SUCCEEDED(hr), "Failed to get buffer, hr %#x.\n", hr);
4533 hr = ID2D1Factory_CreateDxgiSurfaceRenderTarget(factory1, surface2, &desc, &rt2);
4534 ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr);
4535 hr = ID2D1RenderTarget_CreateSharedBitmap(rt2, &IID_ID2D1Bitmap, bitmap1, NULL, &bitmap2);
4536 ok(hr == D2DERR_UNSUPPORTED_OPERATION, "Got unexpected hr %#x.\n", hr);
4537 ID2D1RenderTarget_Release(rt2);
4539 /* DXGI surface render targets with different devices and different factories. */
4540 hr = ID2D1Factory_CreateDxgiSurfaceRenderTarget(factory2, surface2, &desc, &rt2);
4541 ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr);
4542 hr = ID2D1RenderTarget_CreateSharedBitmap(rt2, &IID_ID2D1Bitmap, bitmap1, NULL, &bitmap2);
4543 ok(hr == D2DERR_WRONG_FACTORY, "Got unexpected hr %#x.\n", hr);
4544 ID2D1RenderTarget_Release(rt2);
4546 /* DXGI surface render target and WIC bitmap render target, same factory. */
4547 hr = ID2D1Factory_CreateWicBitmapRenderTarget(factory1, wic_bitmap2, &desc, &rt2);
4548 ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr);
4549 hr = ID2D1RenderTarget_CreateSharedBitmap(rt2, &IID_ID2D1Bitmap, bitmap1, NULL, &bitmap2);
4550 ok(hr == D2DERR_UNSUPPORTED_OPERATION, "Got unexpected hr %#x.\n", hr);
4551 ID2D1RenderTarget_Release(rt2);
4553 /* WIC bitmap render targets on different D2D factories. */
4554 ID2D1Bitmap_Release(bitmap1);
4555 ID2D1RenderTarget_Release(rt1);
4556 hr = ID2D1Factory_CreateWicBitmapRenderTarget(factory1, wic_bitmap1, &desc, &rt1);
4557 ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr);
4558 hr = ID2D1RenderTarget_CreateBitmap(rt1, size, NULL, 0, &bitmap_desc, &bitmap1);
4559 ok(SUCCEEDED(hr), "Failed to create bitmap, hr %#x.\n", hr);
4561 hr = ID2D1RenderTarget_QueryInterface(rt1, &IID_ID2D1GdiInteropRenderTarget, (void **)&interop);
4562 ok(SUCCEEDED(hr), "Failed to get interop target, hr %#x.\n", hr);
4563 hr = ID2D1GdiInteropRenderTarget_QueryInterface(interop, &IID_ID2D1RenderTarget, (void **)&rt3);
4564 ok(SUCCEEDED(hr), "Failed to get render target back, %#x.\n", hr);
4565 ok(rt3 == rt1, "Unexpected render target\n");
4566 ID2D1RenderTarget_Release(rt3);
4567 ID2D1GdiInteropRenderTarget_Release(interop);
4569 hr = ID2D1Factory_CreateWicBitmapRenderTarget(factory2, wic_bitmap2, &desc, &rt2);
4570 ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr);
4571 hr = ID2D1RenderTarget_CreateSharedBitmap(rt2, &IID_ID2D1Bitmap, bitmap1, NULL, &bitmap2);
4572 ok(hr == D2DERR_WRONG_FACTORY, "Got unexpected hr %#x.\n", hr);
4573 ID2D1RenderTarget_Release(rt2);
4575 /* WIC bitmap render targets on the same D2D factory. */
4576 hr = ID2D1Factory_CreateWicBitmapRenderTarget(factory1, wic_bitmap2, &desc, &rt2);
4577 ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr);
4578 hr = ID2D1RenderTarget_CreateSharedBitmap(rt2, &IID_ID2D1Bitmap, bitmap1, NULL, &bitmap2);
4579 ok(SUCCEEDED(hr), "Failed to create bitmap, hr %#x.\n", hr);
4580 check_bitmap_surface(bitmap2, FALSE, 0);
4581 ID2D1Bitmap_Release(bitmap2);
4582 ID2D1RenderTarget_Release(rt2);
4584 /* Shared DXGI surface. */
4585 desc.type = D2D1_RENDER_TARGET_TYPE_DEFAULT;
4586 desc.pixelFormat.format = DXGI_FORMAT_B8G8R8A8_UNORM;
4587 desc.pixelFormat.alphaMode = D2D1_ALPHA_MODE_PREMULTIPLIED;
4588 desc.dpiX = 0.0f;
4589 desc.dpiY = 0.0f;
4590 desc.usage = D2D1_RENDER_TARGET_USAGE_NONE;
4591 desc.minLevel = D2D1_FEATURE_LEVEL_DEFAULT;
4593 hr = ID2D1Factory_CreateDxgiSurfaceRenderTarget(factory1, surface2, &desc, &rt2);
4594 ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr);
4596 bitmap_desc.pixelFormat.format = DXGI_FORMAT_B8G8R8A8_UNORM;
4597 bitmap_desc.pixelFormat.alphaMode = D2D1_ALPHA_MODE_PREMULTIPLIED;
4598 bitmap_desc.dpiX = 0.0f;
4599 bitmap_desc.dpiY = 0.0f;
4601 hr = ID2D1RenderTarget_CreateSharedBitmap(rt2, &IID_IDXGISurface, surface2, &bitmap_desc, &bitmap2);
4602 ok(SUCCEEDED(hr) || broken(hr == E_INVALIDARG) /* vista */, "Failed to create bitmap, hr %#x.\n", hr);
4604 if (SUCCEEDED(hr))
4606 static const struct bitmap_format_test
4608 D2D1_PIXEL_FORMAT original;
4609 D2D1_PIXEL_FORMAT result;
4610 HRESULT hr;
4612 bitmap_format_tests[] =
4614 { { DXGI_FORMAT_UNKNOWN, D2D1_ALPHA_MODE_PREMULTIPLIED },
4615 { DXGI_FORMAT_B8G8R8A8_UNORM, D2D1_ALPHA_MODE_PREMULTIPLIED } },
4617 { { DXGI_FORMAT_UNKNOWN, D2D1_ALPHA_MODE_IGNORE },
4618 { DXGI_FORMAT_B8G8R8A8_UNORM, D2D1_ALPHA_MODE_IGNORE } },
4620 { { DXGI_FORMAT_UNKNOWN, D2D1_ALPHA_MODE_UNKNOWN }, { 0 }, WINCODEC_ERR_UNSUPPORTEDPIXELFORMAT },
4622 { { DXGI_FORMAT_B8G8R8A8_UNORM, D2D1_ALPHA_MODE_UNKNOWN }, { 0 }, WINCODEC_ERR_UNSUPPORTEDPIXELFORMAT },
4624 { { DXGI_FORMAT_B8G8R8A8_UNORM, D2D1_ALPHA_MODE_IGNORE },
4625 { DXGI_FORMAT_B8G8R8A8_UNORM, D2D1_ALPHA_MODE_IGNORE } },
4627 { { DXGI_FORMAT_UNKNOWN, D2D1_ALPHA_MODE_STRAIGHT }, { 0 }, WINCODEC_ERR_UNSUPPORTEDPIXELFORMAT },
4628 { { DXGI_FORMAT_B8G8R8A8_UNORM, D2D1_ALPHA_MODE_STRAIGHT }, { 0 }, WINCODEC_ERR_UNSUPPORTEDPIXELFORMAT },
4630 unsigned int i;
4632 size = ID2D1Bitmap_GetPixelSize(bitmap2);
4633 hr = IDXGISurface_GetDesc(surface2, &surface_desc);
4634 ok(SUCCEEDED(hr), "Failed to get surface description, hr %#x.\n", hr);
4635 ok(size.width == surface_desc.Width && size.height == surface_desc.Height, "Got wrong bitmap size.\n");
4637 check_bitmap_surface(bitmap2, TRUE, D2D1_BITMAP_OPTIONS_TARGET | D2D1_BITMAP_OPTIONS_CANNOT_DRAW);
4639 ID2D1Bitmap_Release(bitmap2);
4641 /* IDXGISurface1 is supported too. */
4642 if (IDXGISurface_QueryInterface(surface2, &IID_IDXGISurface1, (void **)&surface3) == S_OK)
4644 hr = ID2D1RenderTarget_CreateSharedBitmap(rt2, &IID_IDXGISurface1, surface3, &bitmap_desc, &bitmap2);
4645 ok(SUCCEEDED(hr), "Failed to create bitmap, hr %#x.\n", hr);
4647 ID2D1Bitmap_Release(bitmap2);
4648 IDXGISurface1_Release(surface3);
4651 for (i = 0; i < ARRAY_SIZE(bitmap_format_tests); ++i)
4653 bitmap_desc.pixelFormat = bitmap_format_tests[i].original;
4655 hr = ID2D1RenderTarget_CreateSharedBitmap(rt2, &IID_IDXGISurface, surface2, &bitmap_desc, &bitmap2);
4656 todo_wine_if(i == 2 || i == 3 || i == 5 || i == 6)
4657 ok(hr == bitmap_format_tests[i].hr, "%u: unexpected hr %#x.\n", i, hr);
4659 if (SUCCEEDED(bitmap_format_tests[i].hr))
4661 pixel_format = ID2D1Bitmap_GetPixelFormat(bitmap2);
4662 ok(pixel_format.format == bitmap_format_tests[i].result.format, "%u: unexpected pixel format %#x.\n",
4663 i, pixel_format.format);
4664 ok(pixel_format.alphaMode == bitmap_format_tests[i].result.alphaMode, "%u: unexpected alpha mode %d.\n",
4665 i, pixel_format.alphaMode);
4667 ID2D1Bitmap_Release(bitmap2);
4672 ID2D1RenderTarget_Release(rt2);
4674 ID2D1Bitmap_Release(bitmap1);
4675 ID2D1RenderTarget_Release(rt1);
4676 ID2D1Factory_Release(factory2);
4677 ID2D1Factory_Release(factory1);
4678 IWICBitmap_Release(wic_bitmap2);
4679 IWICBitmap_Release(wic_bitmap1);
4680 IDXGISurface_Release(surface2);
4681 IDXGISwapChain_Release(swapchain2);
4682 IDXGIDevice_Release(device2);
4683 release_test_context(&ctx);
4684 DestroyWindow(window2);
4685 CoUninitialize();
4688 static void test_bitmap_updates(BOOL d3d11)
4690 D2D1_BITMAP_PROPERTIES bitmap_desc;
4691 struct d2d1_test_context ctx;
4692 ID2D1RenderTarget *rt;
4693 D2D1_RECT_U dst_rect;
4694 ID2D1Bitmap *bitmap;
4695 D2D1_COLOR_F color;
4696 D2D1_RECT_F rect;
4697 D2D1_SIZE_U size;
4698 HRESULT hr;
4699 BOOL match;
4701 static const DWORD bitmap_data[] =
4703 0xffff0000, 0xffffff00, 0xff00ff00, 0xff00ffff,
4704 0xff0000ff, 0xffff00ff, 0xff000000, 0xff7f7f7f,
4705 0xffffffff, 0xffffffff, 0xffffffff, 0xff000000,
4706 0xffffffff, 0xff000000, 0xff000000, 0xff000000,
4709 if (!init_test_context(&ctx, d3d11))
4710 return;
4712 rt = ctx.rt;
4713 ID2D1RenderTarget_SetAntialiasMode(rt, D2D1_ANTIALIAS_MODE_ALIASED);
4715 ID2D1RenderTarget_BeginDraw(rt);
4716 set_color(&color, 0.0f, 0.0f, 1.0f, 1.0f);
4717 ID2D1RenderTarget_Clear(rt, &color);
4719 set_size_u(&size, 4, 4);
4720 bitmap_desc.pixelFormat.format = DXGI_FORMAT_B8G8R8A8_UNORM;
4721 bitmap_desc.pixelFormat.alphaMode = D2D1_ALPHA_MODE_PREMULTIPLIED;
4722 bitmap_desc.dpiX = 96.0f;
4723 bitmap_desc.dpiY = 96.0f;
4724 hr = ID2D1RenderTarget_CreateBitmap(rt, size, NULL, 0, &bitmap_desc, &bitmap);
4725 ok(SUCCEEDED(hr), "Failed to create bitmap, hr %#x.\n", hr);
4727 set_rect(&rect, 0.0f, 0.0f, 320.0f, 240.0f);
4728 ID2D1RenderTarget_DrawBitmap(rt, bitmap, &rect, 1.0f,
4729 D2D1_BITMAP_INTERPOLATION_MODE_NEAREST_NEIGHBOR, NULL);
4731 ID2D1Bitmap_Release(bitmap);
4733 bitmap_desc.pixelFormat.alphaMode = D2D1_ALPHA_MODE_IGNORE;
4734 hr = ID2D1RenderTarget_CreateBitmap(rt, size, NULL, 0, &bitmap_desc, &bitmap);
4735 ok(SUCCEEDED(hr), "Failed to create bitmap, hr %#x.\n", hr);
4737 set_rect(&rect, 0.0f, 240.0f, 320.0f, 480.0f);
4738 ID2D1RenderTarget_DrawBitmap(rt, bitmap, &rect, 1.0f,
4739 D2D1_BITMAP_INTERPOLATION_MODE_NEAREST_NEIGHBOR, NULL);
4741 set_rect_u(&dst_rect, 1, 1, 3, 3);
4742 hr = ID2D1Bitmap_CopyFromMemory(bitmap, &dst_rect, bitmap_data, 4 * sizeof(*bitmap_data));
4743 ok(SUCCEEDED(hr), "Failed to update bitmap, hr %#x.\n", hr);
4744 set_rect_u(&dst_rect, 0, 3, 3, 4);
4745 hr = ID2D1Bitmap_CopyFromMemory(bitmap, &dst_rect, &bitmap_data[6], 4 * sizeof(*bitmap_data));
4746 ok(SUCCEEDED(hr), "Failed to update bitmap, hr %#x.\n", hr);
4747 set_rect_u(&dst_rect, 0, 0, 4, 1);
4748 hr = ID2D1Bitmap_CopyFromMemory(bitmap, &dst_rect, &bitmap_data[10], 4 * sizeof(*bitmap_data));
4749 ok(SUCCEEDED(hr), "Failed to update bitmap, hr %#x.\n", hr);
4750 set_rect_u(&dst_rect, 0, 1, 1, 3);
4751 hr = ID2D1Bitmap_CopyFromMemory(bitmap, &dst_rect, &bitmap_data[2], sizeof(*bitmap_data));
4752 ok(SUCCEEDED(hr), "Failed to update bitmap, hr %#x.\n", hr);
4753 set_rect_u(&dst_rect, 4, 4, 3, 1);
4754 hr = ID2D1Bitmap_CopyFromMemory(bitmap, &dst_rect, bitmap_data, sizeof(*bitmap_data));
4755 ok(SUCCEEDED(hr), "Failed to update bitmap, hr %#x.\n", hr);
4756 set_rect(&rect, 320.0f, 240.0f, 640.0f, 480.0f);
4757 ID2D1RenderTarget_DrawBitmap(rt, bitmap, &rect, 1.0f,
4758 D2D1_BITMAP_INTERPOLATION_MODE_NEAREST_NEIGHBOR, NULL);
4760 hr = ID2D1Bitmap_CopyFromMemory(bitmap, NULL, bitmap_data, 4 * sizeof(*bitmap_data));
4761 ok(SUCCEEDED(hr), "Failed to update bitmap, hr %#x.\n", hr);
4762 set_rect(&rect, 320.0f, 0.0f, 640.0f, 240.0f);
4763 ID2D1RenderTarget_DrawBitmap(rt, bitmap, &rect, 1.0f,
4764 D2D1_BITMAP_INTERPOLATION_MODE_NEAREST_NEIGHBOR, NULL);
4766 hr = ID2D1RenderTarget_EndDraw(rt, NULL, NULL);
4767 ok(SUCCEEDED(hr), "Failed to end draw, hr %#x.\n", hr);
4769 match = compare_surface(&ctx, "cb8136c91fbbdc76bb83b8c09edc1907b0a5d0a6");
4770 ok(match, "Surface does not match.\n");
4772 ID2D1Bitmap_Release(bitmap);
4773 release_test_context(&ctx);
4776 static void test_opacity_brush(BOOL d3d11)
4778 ID2D1BitmapBrush *bitmap_brush, *opacity_brush;
4779 D2D1_BITMAP_PROPERTIES bitmap_desc;
4780 ID2D1RectangleGeometry *geometry;
4781 ID2D1SolidColorBrush *color_brush;
4782 struct d2d1_test_context ctx;
4783 D2D1_MATRIX_3X2_F matrix;
4784 ID2D1RenderTarget *rt;
4785 ID2D1Factory *factory;
4786 ID2D1Bitmap *bitmap;
4787 D2D1_COLOR_F color;
4788 D2D1_RECT_F rect;
4789 D2D1_SIZE_U size;
4790 ULONG refcount;
4791 HRESULT hr;
4792 BOOL match;
4794 static const DWORD bitmap_data[] =
4796 0xffff0000, 0x40ffff00, 0x4000ff00, 0xff00ffff,
4797 0x7f0000ff, 0x00ff00ff, 0x00000000, 0x7f7f7f7f,
4798 0x7fffffff, 0x00ffffff, 0x00ffffff, 0x7f000000,
4799 0xffffffff, 0x40000000, 0x40000000, 0xff000000,
4802 if (!init_test_context(&ctx, d3d11))
4803 return;
4805 rt = ctx.rt;
4806 ID2D1RenderTarget_GetFactory(rt, &factory);
4808 ID2D1RenderTarget_SetDpi(rt, 192.0f, 48.0f);
4809 ID2D1RenderTarget_SetAntialiasMode(rt, D2D1_ANTIALIAS_MODE_ALIASED);
4811 set_color(&color, 0.0f, 1.0f, 0.0f, 0.8f);
4812 hr = ID2D1RenderTarget_CreateSolidColorBrush(rt, &color, NULL, &color_brush);
4813 ok(SUCCEEDED(hr), "Failed to create color brush, hr %#x.\n", hr);
4815 set_size_u(&size, 4, 4);
4816 bitmap_desc.pixelFormat.format = DXGI_FORMAT_B8G8R8A8_UNORM;
4817 bitmap_desc.pixelFormat.alphaMode = D2D1_ALPHA_MODE_PREMULTIPLIED;
4818 bitmap_desc.dpiX = 96.0f;
4819 bitmap_desc.dpiY = 96.0f;
4820 hr = ID2D1RenderTarget_CreateBitmap(rt, size, bitmap_data, 4 * sizeof(*bitmap_data), &bitmap_desc, &bitmap);
4821 ok(SUCCEEDED(hr), "Failed to create bitmap, hr %#x.\n", hr);
4822 hr = ID2D1RenderTarget_CreateBitmapBrush(rt, bitmap, NULL, NULL, &opacity_brush);
4823 ok(SUCCEEDED(hr), "Failed to create bitmap brush, hr %#x.\n", hr);
4824 ID2D1BitmapBrush_SetInterpolationMode(opacity_brush, D2D1_BITMAP_INTERPOLATION_MODE_NEAREST_NEIGHBOR);
4825 refcount = ID2D1Bitmap_Release(bitmap);
4826 ok(refcount == 1, "Got unexpected refcount %u.\n", refcount);
4828 set_size_u(&size, 1, 1);
4829 bitmap_desc.pixelFormat.format = DXGI_FORMAT_B8G8R8A8_UNORM;
4830 bitmap_desc.pixelFormat.alphaMode = D2D1_ALPHA_MODE_IGNORE;
4831 bitmap_desc.dpiX = 96.0f;
4832 bitmap_desc.dpiY = 96.0f;
4833 hr = ID2D1RenderTarget_CreateBitmap(rt, size, &bitmap_data[2], sizeof(*bitmap_data), &bitmap_desc, &bitmap);
4834 ok(SUCCEEDED(hr), "Failed to create bitmap, hr %#x.\n", hr);
4835 hr = ID2D1RenderTarget_CreateBitmapBrush(rt, bitmap, NULL, NULL, &bitmap_brush);
4836 ok(SUCCEEDED(hr), "Failed to create bitmap brush, hr %#x.\n", hr);
4837 ID2D1BitmapBrush_SetInterpolationMode(bitmap_brush, D2D1_BITMAP_INTERPOLATION_MODE_NEAREST_NEIGHBOR);
4838 refcount = ID2D1Bitmap_Release(bitmap);
4839 ok(refcount == 1, "Got unexpected refcount %u.\n", refcount);
4841 ID2D1RenderTarget_BeginDraw(rt);
4843 set_color(&color, 0.0f, 0.0f, 1.0f, 1.0f);
4844 ID2D1RenderTarget_Clear(rt, &color);
4846 set_rect(&rect, 40.0f, 120.0f, 120.0f, 360.0f);
4847 ID2D1RenderTarget_FillRectangle(rt, &rect, (ID2D1Brush *)color_brush);
4849 set_matrix_identity(&matrix);
4850 translate_matrix(&matrix, 120.0f, 120.0f);
4851 scale_matrix(&matrix, 20.0f, 60.0f);
4852 ID2D1BitmapBrush_SetTransform(opacity_brush, &matrix);
4853 set_rect(&rect, 120.0f, 120.0f, 200.0f, 360.0f);
4854 ID2D1RenderTarget_FillRectangle(rt, &rect, (ID2D1Brush *)opacity_brush);
4856 set_rect(&rect, 200.0f, 120.0f, 280.0f, 360.0f);
4857 ID2D1RenderTarget_FillRectangle(rt, &rect, (ID2D1Brush *)bitmap_brush);
4859 set_matrix_identity(&matrix);
4860 translate_matrix(&matrix, 40.0f, 360.0f);
4861 scale_matrix(&matrix, 20.0f, 60.0f);
4862 ID2D1BitmapBrush_SetTransform(opacity_brush, &matrix);
4863 set_rect(&rect, 40.0f, 360.0f, 120.0f, 600.0f);
4864 ID2D1Factory_CreateRectangleGeometry(factory, &rect, &geometry);
4865 ID2D1RenderTarget_FillGeometry(rt, (ID2D1Geometry *)geometry,
4866 (ID2D1Brush *)opacity_brush, (ID2D1Brush *)color_brush);
4867 ID2D1RectangleGeometry_Release(geometry);
4869 set_matrix_identity(&matrix);
4870 translate_matrix(&matrix, 120.0f, 360.0f);
4871 scale_matrix(&matrix, 20.0f, 60.0f);
4872 ID2D1BitmapBrush_SetTransform(opacity_brush, &matrix);
4873 set_rect(&rect, 120.0f, 360.0f, 200.0f, 600.0f);
4874 ID2D1Factory_CreateRectangleGeometry(factory, &rect, &geometry);
4875 ID2D1RenderTarget_FillGeometry(rt, (ID2D1Geometry *)geometry,
4876 (ID2D1Brush *)color_brush, (ID2D1Brush *)opacity_brush);
4877 ID2D1RectangleGeometry_Release(geometry);
4879 set_matrix_identity(&matrix);
4880 translate_matrix(&matrix, 200.0f, 360.0f);
4881 scale_matrix(&matrix, 20.0f, 60.0f);
4882 ID2D1BitmapBrush_SetTransform(opacity_brush, &matrix);
4883 set_rect(&rect, 200.0f, 360.0f, 280.0f, 600.0f);
4884 ID2D1Factory_CreateRectangleGeometry(factory, &rect, &geometry);
4885 ID2D1RenderTarget_FillGeometry(rt, (ID2D1Geometry *)geometry,
4886 (ID2D1Brush *)bitmap_brush, (ID2D1Brush *)opacity_brush);
4888 hr = ID2D1RenderTarget_EndDraw(rt, NULL, NULL);
4889 ok(hr == D2DERR_INCOMPATIBLE_BRUSH_TYPES, "Got unexpected hr %#x.\n", hr);
4890 match = compare_surface(&ctx, "7141c6c7b3decb91196428efb1856bcbf9872935");
4891 ok(match, "Surface does not match.\n");
4892 ID2D1RenderTarget_BeginDraw(rt);
4894 ID2D1RenderTarget_FillGeometry(rt, (ID2D1Geometry *)geometry,
4895 (ID2D1Brush *)bitmap_brush, (ID2D1Brush *)opacity_brush);
4896 ID2D1RectangleGeometry_Release(geometry);
4898 ID2D1SolidColorBrush_SetOpacity(color_brush, 0.5f);
4899 set_matrix_identity(&matrix);
4900 translate_matrix(&matrix, 40.0f, 600.0f);
4901 scale_matrix(&matrix, 20.0f, 60.0f);
4902 ID2D1BitmapBrush_SetTransform(opacity_brush, &matrix);
4903 set_rect(&rect, 40.0f, 600.0f, 120.0f, 840.0f);
4904 ID2D1Factory_CreateRectangleGeometry(factory, &rect, &geometry);
4905 ID2D1RenderTarget_FillGeometry(rt, (ID2D1Geometry *)geometry,
4906 (ID2D1Brush *)opacity_brush, (ID2D1Brush *)color_brush);
4907 ID2D1RectangleGeometry_Release(geometry);
4909 ID2D1BitmapBrush_SetOpacity(opacity_brush, 0.8f);
4910 set_matrix_identity(&matrix);
4911 translate_matrix(&matrix, 120.0f, 600.0f);
4912 scale_matrix(&matrix, 20.0f, 60.0f);
4913 ID2D1BitmapBrush_SetTransform(opacity_brush, &matrix);
4914 set_rect(&rect, 120.0f, 600.0f, 200.0f, 840.0f);
4915 ID2D1Factory_CreateRectangleGeometry(factory, &rect, &geometry);
4916 ID2D1RenderTarget_FillGeometry(rt, (ID2D1Geometry *)geometry,
4917 (ID2D1Brush *)opacity_brush, (ID2D1Brush *)bitmap_brush);
4918 ID2D1RectangleGeometry_Release(geometry);
4920 set_matrix_identity(&matrix);
4921 translate_matrix(&matrix, 200.0f, 600.0f);
4922 scale_matrix(&matrix, 20.0f, 60.0f);
4923 ID2D1BitmapBrush_SetTransform(opacity_brush, &matrix);
4924 set_rect(&rect, 200.0f, 600.0f, 280.0f, 840.0f);
4925 ID2D1Factory_CreateRectangleGeometry(factory, &rect, &geometry);
4926 ID2D1RenderTarget_FillGeometry(rt, (ID2D1Geometry *)geometry,
4927 (ID2D1Brush *)bitmap_brush, (ID2D1Brush *)opacity_brush);
4928 ID2D1RectangleGeometry_Release(geometry);
4930 hr = ID2D1RenderTarget_EndDraw(rt, NULL, NULL);
4931 ok(SUCCEEDED(hr), "Failed to end draw, hr %#x.\n", hr);
4932 match = compare_surface(&ctx, "c3a5802d1750efa3e9122c1a92f6064df3872732");
4933 ok(match, "Surface does not match.\n");
4935 ID2D1BitmapBrush_Release(bitmap_brush);
4936 ID2D1BitmapBrush_Release(opacity_brush);
4937 ID2D1SolidColorBrush_Release(color_brush);
4938 ID2D1Factory_Release(factory);
4939 release_test_context(&ctx);
4942 static void test_create_target(BOOL d3d11)
4944 struct d2d1_test_context ctx;
4945 ID2D1Factory *factory;
4946 ID2D1RenderTarget *rt;
4947 HRESULT hr;
4948 static const struct
4950 float dpi_x, dpi_y;
4951 float rt_dpi_x, rt_dpi_y;
4952 HRESULT hr;
4954 create_dpi_tests[] =
4956 { 0.0f, 0.0f, 96.0f, 96.0f, S_OK },
4957 { 192.0f, 0.0f, 96.0f, 96.0f, E_INVALIDARG },
4958 { 0.0f, 192.0f, 96.0f, 96.0f, E_INVALIDARG },
4959 { 192.0f, -10.0f, 96.0f, 96.0f, E_INVALIDARG },
4960 { -10.0f, 192.0f, 96.0f, 96.0f, E_INVALIDARG },
4961 { 48.0f, 96.0f, 48.0f, 96.0f, S_OK },
4963 unsigned int i;
4965 if (!init_test_context(&ctx, d3d11))
4966 return;
4968 hr = D2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED, &IID_ID2D1Factory, NULL, (void **)&factory);
4969 ok(SUCCEEDED(hr), "Failed to create factory, hr %#x.\n", hr);
4971 for (i = 0; i < ARRAY_SIZE(create_dpi_tests); ++i)
4973 ID2D1GdiInteropRenderTarget *interop;
4974 D2D1_RENDER_TARGET_PROPERTIES desc;
4975 ID2D1RenderTarget *rt2;
4976 float dpi_x, dpi_y;
4977 IUnknown *unk;
4979 desc.type = D2D1_RENDER_TARGET_TYPE_DEFAULT;
4980 desc.pixelFormat.format = DXGI_FORMAT_UNKNOWN;
4981 desc.pixelFormat.alphaMode = D2D1_ALPHA_MODE_PREMULTIPLIED;
4982 desc.dpiX = create_dpi_tests[i].dpi_x;
4983 desc.dpiY = create_dpi_tests[i].dpi_y;
4984 desc.usage = D2D1_RENDER_TARGET_USAGE_NONE;
4985 desc.minLevel = D2D1_FEATURE_LEVEL_DEFAULT;
4987 hr = ID2D1Factory_CreateDxgiSurfaceRenderTarget(factory, ctx.surface, &desc, &rt);
4988 ok(hr == create_dpi_tests[i].hr, "Wrong return code, hr %#x, expected %#x, test %u.\n", hr,
4989 create_dpi_tests[i].hr, i);
4991 if (FAILED(hr))
4992 continue;
4994 hr = ID2D1RenderTarget_QueryInterface(rt, &IID_IUnknown, (void **)&unk);
4995 ok(SUCCEEDED(hr), "Failed to get IUnknown, hr %#x.\n", hr);
4996 ok(unk == (IUnknown *)rt, "Expected same interface pointer.\n");
4997 IUnknown_Release(unk);
4999 hr = ID2D1RenderTarget_QueryInterface(rt, &IID_ID2D1GdiInteropRenderTarget, (void **)&interop);
5000 ok(SUCCEEDED(hr), "Failed to get interop target, hr %#x.\n", hr);
5001 hr = ID2D1GdiInteropRenderTarget_QueryInterface(interop, &IID_ID2D1RenderTarget, (void **)&rt2);
5002 ok(SUCCEEDED(hr), "Failed to get render target back, %#x.\n", hr);
5003 ok(rt2 == rt, "Unexpected render target\n");
5004 ID2D1RenderTarget_Release(rt2);
5005 ID2D1GdiInteropRenderTarget_Release(interop);
5007 ID2D1RenderTarget_GetDpi(rt, &dpi_x, &dpi_y);
5008 ok(dpi_x == create_dpi_tests[i].rt_dpi_x, "Wrong dpi_x %.8e, expected %.8e, test %u\n",
5009 dpi_x, create_dpi_tests[i].rt_dpi_x, i);
5010 ok(dpi_y == create_dpi_tests[i].rt_dpi_y, "Wrong dpi_y %.8e, expected %.8e, test %u\n",
5011 dpi_y, create_dpi_tests[i].rt_dpi_y, i);
5013 ID2D1RenderTarget_Release(rt);
5016 ID2D1Factory_Release(factory);
5017 release_test_context(&ctx);
5020 static void test_draw_text_layout(BOOL d3d11)
5022 static const struct
5024 D2D1_TEXT_ANTIALIAS_MODE aa_mode;
5025 DWRITE_RENDERING_MODE rendering_mode;
5026 HRESULT hr;
5028 antialias_mode_tests[] =
5030 { D2D1_TEXT_ANTIALIAS_MODE_DEFAULT, DWRITE_RENDERING_MODE_ALIASED },
5031 { D2D1_TEXT_ANTIALIAS_MODE_ALIASED, DWRITE_RENDERING_MODE_ALIASED },
5032 { D2D1_TEXT_ANTIALIAS_MODE_ALIASED, DWRITE_RENDERING_MODE_DEFAULT },
5033 { D2D1_TEXT_ANTIALIAS_MODE_ALIASED, DWRITE_RENDERING_MODE_OUTLINE },
5034 { D2D1_TEXT_ANTIALIAS_MODE_GRAYSCALE, DWRITE_RENDERING_MODE_DEFAULT },
5035 { D2D1_TEXT_ANTIALIAS_MODE_GRAYSCALE, DWRITE_RENDERING_MODE_OUTLINE },
5036 { D2D1_TEXT_ANTIALIAS_MODE_GRAYSCALE, DWRITE_RENDERING_MODE_CLEARTYPE_NATURAL },
5037 { D2D1_TEXT_ANTIALIAS_MODE_GRAYSCALE, DWRITE_RENDERING_MODE_CLEARTYPE_NATURAL_SYMMETRIC },
5038 { D2D1_TEXT_ANTIALIAS_MODE_GRAYSCALE, DWRITE_RENDERING_MODE_CLEARTYPE_GDI_NATURAL },
5039 { D2D1_TEXT_ANTIALIAS_MODE_GRAYSCALE, DWRITE_RENDERING_MODE_CLEARTYPE_GDI_CLASSIC },
5040 { D2D1_TEXT_ANTIALIAS_MODE_CLEARTYPE, DWRITE_RENDERING_MODE_DEFAULT },
5041 { D2D1_TEXT_ANTIALIAS_MODE_CLEARTYPE, DWRITE_RENDERING_MODE_CLEARTYPE_NATURAL },
5042 { D2D1_TEXT_ANTIALIAS_MODE_CLEARTYPE, DWRITE_RENDERING_MODE_CLEARTYPE_NATURAL_SYMMETRIC },
5043 { D2D1_TEXT_ANTIALIAS_MODE_CLEARTYPE, DWRITE_RENDERING_MODE_CLEARTYPE_GDI_NATURAL },
5044 { D2D1_TEXT_ANTIALIAS_MODE_CLEARTYPE, DWRITE_RENDERING_MODE_CLEARTYPE_GDI_CLASSIC },
5045 { D2D1_TEXT_ANTIALIAS_MODE_CLEARTYPE, DWRITE_RENDERING_MODE_OUTLINE, E_INVALIDARG },
5046 { D2D1_TEXT_ANTIALIAS_MODE_GRAYSCALE, DWRITE_RENDERING_MODE_ALIASED, E_INVALIDARG },
5047 { D2D1_TEXT_ANTIALIAS_MODE_CLEARTYPE, DWRITE_RENDERING_MODE_ALIASED, E_INVALIDARG },
5048 { D2D1_TEXT_ANTIALIAS_MODE_ALIASED, DWRITE_RENDERING_MODE_CLEARTYPE_NATURAL, E_INVALIDARG },
5049 { D2D1_TEXT_ANTIALIAS_MODE_ALIASED, DWRITE_RENDERING_MODE_CLEARTYPE_NATURAL_SYMMETRIC, E_INVALIDARG },
5050 { D2D1_TEXT_ANTIALIAS_MODE_ALIASED, DWRITE_RENDERING_MODE_CLEARTYPE_GDI_NATURAL, E_INVALIDARG },
5051 { D2D1_TEXT_ANTIALIAS_MODE_ALIASED, DWRITE_RENDERING_MODE_CLEARTYPE_GDI_CLASSIC, E_INVALIDARG },
5053 D2D1_RENDER_TARGET_PROPERTIES desc;
5054 ID2D1Factory *factory, *factory2;
5055 ID2D1RenderTarget *rt, *rt2;
5056 HRESULT hr;
5057 IDWriteFactory *dwrite_factory;
5058 IDWriteTextFormat *text_format;
5059 IDWriteTextLayout *text_layout;
5060 struct d2d1_test_context ctx;
5061 D2D1_POINT_2F origin;
5062 DWRITE_TEXT_RANGE range;
5063 D2D1_COLOR_F color;
5064 ID2D1SolidColorBrush *brush, *brush2;
5065 ID2D1RectangleGeometry *geometry;
5066 D2D1_RECT_F rect;
5067 unsigned int i;
5069 if (!init_test_context(&ctx, d3d11))
5070 return;
5073 hr = D2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED, &IID_ID2D1Factory, NULL, (void **)&factory);
5074 ok(SUCCEEDED(hr), "Failed to create factory, hr %#x.\n", hr);
5076 hr = D2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED, &IID_ID2D1Factory, NULL, (void **)&factory2);
5077 ok(SUCCEEDED(hr), "Failed to create factory, hr %#x.\n", hr);
5078 ok(factory != factory2, "got same factory\n");
5080 desc.type = D2D1_RENDER_TARGET_TYPE_DEFAULT;
5081 desc.pixelFormat.format = DXGI_FORMAT_UNKNOWN;
5082 desc.pixelFormat.alphaMode = D2D1_ALPHA_MODE_PREMULTIPLIED;
5083 desc.dpiX = 0.0f;
5084 desc.dpiY = 0.0f;
5085 desc.usage = D2D1_RENDER_TARGET_USAGE_NONE;
5086 desc.minLevel = D2D1_FEATURE_LEVEL_DEFAULT;
5088 hr = ID2D1Factory_CreateDxgiSurfaceRenderTarget(factory, ctx.surface, &desc, &rt);
5089 ok(SUCCEEDED(hr), "Failed to create a target, hr %#x.\n", hr);
5091 hr = ID2D1Factory_CreateDxgiSurfaceRenderTarget(factory2, ctx.surface, &desc, &rt2);
5092 ok(SUCCEEDED(hr), "Failed to create a target, hr %#x.\n", hr);
5094 hr = DWriteCreateFactory(DWRITE_FACTORY_TYPE_SHARED, &IID_IDWriteFactory, (IUnknown **)&dwrite_factory);
5095 ok(SUCCEEDED(hr), "Failed to create factory, hr %#x.\n", hr);
5097 hr = IDWriteFactory_CreateTextFormat(dwrite_factory, L"Tahoma", NULL, DWRITE_FONT_WEIGHT_NORMAL,
5098 DWRITE_FONT_STYLE_NORMAL, DWRITE_FONT_STRETCH_NORMAL, 10.0f, L"", &text_format);
5099 ok(SUCCEEDED(hr), "Failed to create text format, hr %#x.\n", hr);
5101 hr = IDWriteFactory_CreateTextLayout(dwrite_factory, L"text", 4, text_format, 100.0f, 100.0f, &text_layout);
5102 ok(SUCCEEDED(hr), "Failed to create text layout, hr %#x.\n", hr);
5104 set_color(&color, 0.0f, 0.0f, 0.0f, 0.0f);
5105 hr = ID2D1RenderTarget_CreateSolidColorBrush(rt, &color, NULL, &brush);
5106 ok(SUCCEEDED(hr), "Failed to create brush, hr %#x.\n", hr);
5108 hr = ID2D1RenderTarget_CreateSolidColorBrush(rt2, &color, NULL, &brush2);
5109 ok(SUCCEEDED(hr), "Failed to create brush, hr %#x.\n", hr);
5111 /* effect brush is created from different factory */
5112 range.startPosition = 0;
5113 range.length = 4;
5114 hr = IDWriteTextLayout_SetDrawingEffect(text_layout, (IUnknown*)brush2, range);
5115 ok(SUCCEEDED(hr), "Failed to set drawing effect, hr %#x.\n", hr);
5117 ID2D1RenderTarget_BeginDraw(rt);
5119 origin.x = origin.y = 0.0f;
5120 ID2D1RenderTarget_DrawTextLayout(rt, origin, text_layout, (ID2D1Brush*)brush, D2D1_DRAW_TEXT_OPTIONS_NONE);
5122 hr = ID2D1RenderTarget_EndDraw(rt, NULL, NULL);
5123 todo_wine
5124 ok(hr == D2DERR_WRONG_FACTORY, "Unexpected hr %#x.\n", hr);
5126 /* Effect is d2d resource, but not a brush. */
5127 set_rect(&rect, 0.0f, 0.0f, 10.0f, 10.0f);
5128 hr = ID2D1Factory_CreateRectangleGeometry(factory, &rect, &geometry);
5129 ok(SUCCEEDED(hr), "Failed to geometry, hr %#x.\n", hr);
5131 range.startPosition = 0;
5132 range.length = 4;
5133 hr = IDWriteTextLayout_SetDrawingEffect(text_layout, (IUnknown*)geometry, range);
5134 ok(SUCCEEDED(hr), "Failed to set drawing effect, hr %#x.\n", hr);
5135 ID2D1RectangleGeometry_Release(geometry);
5137 ID2D1RenderTarget_BeginDraw(rt);
5139 origin.x = origin.y = 0.0f;
5140 ID2D1RenderTarget_DrawTextLayout(rt, origin, text_layout, (ID2D1Brush*)brush, D2D1_DRAW_TEXT_OPTIONS_NONE);
5142 hr = ID2D1RenderTarget_EndDraw(rt, NULL, NULL);
5143 ok(SUCCEEDED(hr), "EndDraw() failed, hr %#x.\n", hr);
5145 for (i = 0; i < ARRAY_SIZE(antialias_mode_tests); ++i)
5147 IDWriteRenderingParams *rendering_params;
5149 ID2D1RenderTarget_SetTextAntialiasMode(rt, antialias_mode_tests[i].aa_mode);
5151 hr = IDWriteFactory_CreateCustomRenderingParams(dwrite_factory, 2.0f, 1.0f, 0.0f, DWRITE_PIXEL_GEOMETRY_FLAT,
5152 antialias_mode_tests[i].rendering_mode, &rendering_params);
5153 ok(SUCCEEDED(hr), "Failed to create custom rendering params, hr %#x.\n", hr);
5155 ID2D1RenderTarget_SetTextRenderingParams(rt, rendering_params);
5157 ID2D1RenderTarget_BeginDraw(rt);
5159 ID2D1RenderTarget_DrawTextLayout(rt, origin, text_layout, (ID2D1Brush *)brush, D2D1_DRAW_TEXT_OPTIONS_NONE);
5161 hr = ID2D1RenderTarget_EndDraw(rt, NULL, NULL);
5162 ok(hr == antialias_mode_tests[i].hr, "%u: unexpected hr %#x.\n", i, hr);
5164 IDWriteRenderingParams_Release(rendering_params);
5167 IDWriteTextFormat_Release(text_format);
5168 IDWriteTextLayout_Release(text_layout);
5169 IDWriteFactory_Release(dwrite_factory);
5170 ID2D1RenderTarget_Release(rt);
5171 ID2D1RenderTarget_Release(rt2);
5173 ID2D1Factory_Release(factory);
5174 ID2D1Factory_Release(factory2);
5175 release_test_context(&ctx);
5178 static void create_target_dibsection(HDC hdc, UINT32 width, UINT32 height)
5180 char bmibuf[FIELD_OFFSET(BITMAPINFO, bmiColors[256])];
5181 BITMAPINFO *bmi = (BITMAPINFO*)bmibuf;
5182 HBITMAP hbm;
5184 memset(bmi, 0, sizeof(bmibuf));
5185 bmi->bmiHeader.biSize = sizeof(bmi->bmiHeader);
5186 bmi->bmiHeader.biHeight = -height;
5187 bmi->bmiHeader.biWidth = width;
5188 bmi->bmiHeader.biBitCount = 32;
5189 bmi->bmiHeader.biPlanes = 1;
5190 bmi->bmiHeader.biCompression = BI_RGB;
5192 hbm = CreateDIBSection(hdc, bmi, DIB_RGB_COLORS, NULL, NULL, 0);
5193 ok(hbm != NULL, "Failed to create a dib section.\n");
5195 DeleteObject(SelectObject(hdc, hbm));
5198 static void test_dc_target(BOOL d3d11)
5200 static const D2D1_PIXEL_FORMAT invalid_formats[] =
5202 { DXGI_FORMAT_UNKNOWN, D2D1_ALPHA_MODE_PREMULTIPLIED },
5203 { DXGI_FORMAT_B8G8R8A8_UNORM, D2D1_ALPHA_MODE_UNKNOWN },
5204 { DXGI_FORMAT_R8G8B8A8_UNORM, D2D1_ALPHA_MODE_PREMULTIPLIED },
5206 D2D1_TEXT_ANTIALIAS_MODE text_aa_mode;
5207 ID2D1GdiInteropRenderTarget *interop;
5208 D2D1_RENDER_TARGET_PROPERTIES desc;
5209 D2D1_MATRIX_3X2_F matrix, matrix2;
5210 ID2D1DCRenderTarget *rt, *rt2;
5211 struct d2d1_test_context ctx;
5212 D2D1_ANTIALIAS_MODE aa_mode;
5213 ID2D1SolidColorBrush *brush;
5214 ID2D1RenderTarget *rt3;
5215 ID2D1Factory *factory;
5216 FLOAT dpi_x, dpi_y;
5217 D2D1_COLOR_F color;
5218 D2D1_SIZE_U sizeu;
5219 D2D1_SIZE_F size;
5220 D2D1_TAG t1, t2;
5221 unsigned int i;
5222 HDC hdc, hdc2;
5223 D2D_RECT_F r;
5224 COLORREF clr;
5225 HRESULT hr;
5226 RECT rect;
5228 if (!init_test_context(&ctx, d3d11))
5229 return;
5230 release_test_context(&ctx);
5232 hr = D2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED, &IID_ID2D1Factory, NULL, (void **)&factory);
5233 ok(SUCCEEDED(hr), "Failed to create factory, hr %#x.\n", hr);
5235 for (i = 0; i < ARRAY_SIZE(invalid_formats); ++i)
5237 desc.type = D2D1_RENDER_TARGET_TYPE_DEFAULT;
5238 desc.pixelFormat = invalid_formats[i];
5239 desc.dpiX = 96.0f;
5240 desc.dpiY = 96.0f;
5241 desc.usage = D2D1_RENDER_TARGET_USAGE_NONE;
5242 desc.minLevel = D2D1_FEATURE_LEVEL_DEFAULT;
5244 hr = ID2D1Factory_CreateDCRenderTarget(factory, &desc, &rt);
5245 ok(hr == D2DERR_UNSUPPORTED_PIXEL_FORMAT, "Got unexpected hr %#x.\n", hr);
5248 desc.type = D2D1_RENDER_TARGET_TYPE_DEFAULT;
5249 desc.pixelFormat.format = DXGI_FORMAT_B8G8R8A8_UNORM;
5250 desc.pixelFormat.alphaMode = D2D1_ALPHA_MODE_PREMULTIPLIED;
5251 desc.dpiX = 96.0f;
5252 desc.dpiY = 96.0f;
5253 desc.usage = D2D1_RENDER_TARGET_USAGE_NONE;
5254 desc.minLevel = D2D1_FEATURE_LEVEL_DEFAULT;
5255 hr = ID2D1Factory_CreateDCRenderTarget(factory, &desc, &rt);
5256 ok(SUCCEEDED(hr), "Failed to create target, hr %#x.\n", hr);
5258 hr = ID2D1DCRenderTarget_QueryInterface(rt, &IID_ID2D1GdiInteropRenderTarget, (void **)&interop);
5259 ok(SUCCEEDED(hr), "Failed to get interop target, hr %#x.\n", hr);
5260 hr = ID2D1GdiInteropRenderTarget_QueryInterface(interop, &IID_ID2D1RenderTarget, (void **)&rt3);
5261 ok(SUCCEEDED(hr), "Failed to get render target back, %#x.\n", hr);
5262 ok(rt3 == (ID2D1RenderTarget *)rt, "Unexpected render target\n");
5263 ID2D1RenderTarget_Release(rt3);
5264 hr = ID2D1GdiInteropRenderTarget_QueryInterface(interop, &IID_ID2D1DCRenderTarget, (void **)&rt2);
5265 ok(SUCCEEDED(hr), "Failed to get render target back, %#x.\n", hr);
5266 ok(rt2 == rt, "Unexpected render target\n");
5267 ID2D1DCRenderTarget_Release(rt2);
5268 ID2D1GdiInteropRenderTarget_Release(interop);
5270 size = ID2D1DCRenderTarget_GetSize(rt);
5271 ok(size.width == 0.0f, "got width %.08e.\n", size.width);
5272 ok(size.height == 0.0f, "got height %.08e.\n", size.height);
5274 sizeu = ID2D1DCRenderTarget_GetPixelSize(rt);
5275 ok(sizeu.width == 0, "got width %u.\n", sizeu.width);
5276 ok(sizeu.height == 0, "got height %u.\n", sizeu.height);
5278 /* object creation methods work without BindDC() */
5279 set_color(&color, 0.0f, 0.0f, 0.0f, 0.0f);
5280 hr = ID2D1DCRenderTarget_CreateSolidColorBrush(rt, &color, NULL, &brush);
5281 ok(SUCCEEDED(hr), "Failed to create a brush, hr %#x.\n", hr);
5282 ID2D1SolidColorBrush_Release(brush);
5284 ID2D1DCRenderTarget_BeginDraw(rt);
5285 hr = ID2D1DCRenderTarget_EndDraw(rt, NULL, NULL);
5286 ok(hr == D2DERR_WRONG_STATE, "Got unexpected hr %#x.\n", hr);
5288 ID2D1DCRenderTarget_Release(rt);
5290 /* BindDC() */
5291 hr = ID2D1Factory_CreateDCRenderTarget(factory, &desc, &rt);
5292 ok(SUCCEEDED(hr), "Failed to create target, hr %#x.\n", hr);
5294 aa_mode = ID2D1DCRenderTarget_GetAntialiasMode(rt);
5295 ok(aa_mode == D2D1_ANTIALIAS_MODE_PER_PRIMITIVE, "Got wrong default aa mode %d.\n", aa_mode);
5296 text_aa_mode = ID2D1DCRenderTarget_GetTextAntialiasMode(rt);
5297 ok(text_aa_mode == D2D1_TEXT_ANTIALIAS_MODE_DEFAULT, "Got wrong default text aa mode %d.\n", text_aa_mode);
5299 ID2D1DCRenderTarget_GetDpi(rt, &dpi_x, &dpi_y);
5300 ok(dpi_x == 96.0f && dpi_y == 96.0f, "Got dpi_x %f, dpi_y %f.\n", dpi_x, dpi_y);
5302 hdc = CreateCompatibleDC(NULL);
5303 ok(hdc != NULL, "Failed to create an HDC.\n");
5305 create_target_dibsection(hdc, 16, 16);
5307 SetRect(&rect, 0, 0, 32, 32);
5308 hr = ID2D1DCRenderTarget_BindDC(rt, NULL, &rect);
5309 ok(hr == E_INVALIDARG, "BindDC() returned %#x.\n", hr);
5311 /* Target properties are retained during BindDC() */
5312 ID2D1DCRenderTarget_SetTags(rt, 1, 2);
5313 ID2D1DCRenderTarget_SetAntialiasMode(rt, D2D1_ANTIALIAS_MODE_ALIASED);
5314 ID2D1DCRenderTarget_SetTextAntialiasMode(rt, D2D1_TEXT_ANTIALIAS_MODE_CLEARTYPE);
5316 set_matrix_identity(&matrix);
5317 translate_matrix(&matrix, 200.0f, 600.0f);
5318 ID2D1DCRenderTarget_SetTransform(rt, &matrix);
5320 hr = ID2D1DCRenderTarget_BindDC(rt, hdc, &rect);
5321 ok(hr == S_OK, "BindDC() returned %#x.\n", hr);
5323 ID2D1DCRenderTarget_GetTags(rt, &t1, &t2);
5324 ok(t1 == 1 && t2 == 2, "Got wrong tags.\n");
5326 aa_mode = ID2D1DCRenderTarget_GetAntialiasMode(rt);
5327 ok(aa_mode == D2D1_ANTIALIAS_MODE_ALIASED, "Got wrong aa mode %d.\n", aa_mode);
5329 text_aa_mode = ID2D1DCRenderTarget_GetTextAntialiasMode(rt);
5330 ok(text_aa_mode == D2D1_TEXT_ANTIALIAS_MODE_CLEARTYPE, "Got wrong text aa mode %d.\n", text_aa_mode);
5332 ID2D1DCRenderTarget_GetTransform(rt, &matrix2);
5333 ok(!memcmp(&matrix, &matrix2, sizeof(matrix)), "Got wrong target transform.\n");
5335 set_matrix_identity(&matrix);
5336 ID2D1DCRenderTarget_SetTransform(rt, &matrix);
5338 /* target size comes from specified dimensions, not from selected bitmap size */
5339 size = ID2D1DCRenderTarget_GetSize(rt);
5340 ok(size.width == 32.0f, "got width %.08e.\n", size.width);
5341 ok(size.height == 32.0f, "got height %.08e.\n", size.height);
5343 /* clear one HDC to red, switch to another one, partially fill it and test contents */
5344 ID2D1DCRenderTarget_BeginDraw(rt);
5346 set_color(&color, 1.0f, 0.0f, 0.0f, 1.0f);
5347 ID2D1DCRenderTarget_Clear(rt, &color);
5349 hr = ID2D1DCRenderTarget_EndDraw(rt, NULL, NULL);
5350 ok(SUCCEEDED(hr), "EndDraw() failed, hr %#x.\n", hr);
5352 clr = GetPixel(hdc, 0, 0);
5353 ok(clr == RGB(255, 0, 0), "Unexpected color 0x%08x.\n", clr);
5355 hdc2 = CreateCompatibleDC(NULL);
5356 ok(hdc2 != NULL, "Failed to create an HDC.\n");
5358 create_target_dibsection(hdc2, 16, 16);
5360 hr = ID2D1DCRenderTarget_BindDC(rt, hdc2, &rect);
5361 ok(hr == S_OK, "BindDC() returned %#x.\n", hr);
5363 clr = GetPixel(hdc2, 0, 0);
5364 ok(clr == 0, "Unexpected color 0x%08x.\n", clr);
5366 set_color(&color, 0.0f, 1.0f, 0.0f, 1.0f);
5367 hr = ID2D1DCRenderTarget_CreateSolidColorBrush(rt, &color, NULL, &brush);
5368 ok(SUCCEEDED(hr), "Failed to create brush, hr %#x.\n", hr);
5370 ID2D1DCRenderTarget_BeginDraw(rt);
5372 r.left = r.top = 0.0f;
5373 r.bottom = 16.0f;
5374 r.right = 8.0f;
5375 ID2D1DCRenderTarget_FillRectangle(rt, &r, (ID2D1Brush*)brush);
5377 hr = ID2D1DCRenderTarget_EndDraw(rt, NULL, NULL);
5378 ok(SUCCEEDED(hr), "EndDraw() failed, hr %#x.\n", hr);
5380 ID2D1SolidColorBrush_Release(brush);
5382 clr = GetPixel(hdc2, 0, 0);
5383 ok(clr == RGB(0, 255, 0), "Unexpected color 0x%08x.\n", clr);
5385 clr = GetPixel(hdc2, 10, 0);
5386 ok(clr == 0, "Unexpected color 0x%08x.\n", clr);
5388 /* Invalid DC. */
5389 hr = ID2D1DCRenderTarget_BindDC(rt, (HDC)0xdeadbeef, &rect);
5390 todo_wine
5391 ok(hr == E_INVALIDARG, "BindDC() returned %#x.\n", hr);
5393 ID2D1DCRenderTarget_BeginDraw(rt);
5395 set_color(&color, 1.0f, 0.0f, 0.0f, 1.0f);
5396 ID2D1DCRenderTarget_Clear(rt, &color);
5398 hr = ID2D1DCRenderTarget_EndDraw(rt, NULL, NULL);
5399 ok(SUCCEEDED(hr), "EndDraw() failed, hr %#x.\n", hr);
5401 clr = GetPixel(hdc2, 0, 0);
5402 todo_wine
5403 ok(clr == RGB(255, 0, 0), "Unexpected color 0x%08x.\n", clr);
5405 hr = ID2D1DCRenderTarget_BindDC(rt, NULL, &rect);
5406 ok(hr == E_INVALIDARG, "BindDC() returned %#x.\n", hr);
5408 ID2D1DCRenderTarget_BeginDraw(rt);
5410 set_color(&color, 0.0f, 0.0f, 1.0f, 1.0f);
5411 ID2D1DCRenderTarget_Clear(rt, &color);
5413 hr = ID2D1DCRenderTarget_EndDraw(rt, NULL, NULL);
5414 ok(SUCCEEDED(hr), "EndDraw() failed, hr %#x.\n", hr);
5416 clr = GetPixel(hdc2, 0, 0);
5417 todo_wine
5418 ok(clr == RGB(0, 0, 255), "Unexpected color 0x%08x.\n", clr);
5420 DeleteDC(hdc);
5421 DeleteDC(hdc2);
5422 ID2D1DCRenderTarget_Release(rt);
5423 ID2D1Factory_Release(factory);
5426 static void test_hwnd_target(BOOL d3d11)
5428 D2D1_HWND_RENDER_TARGET_PROPERTIES hwnd_rt_desc;
5429 ID2D1GdiInteropRenderTarget *interop;
5430 D2D1_RENDER_TARGET_PROPERTIES desc;
5431 ID2D1HwndRenderTarget *rt, *rt2;
5432 struct d2d1_test_context ctx;
5433 ID2D1RenderTarget *rt3;
5434 ID2D1Factory *factory;
5435 D2D1_SIZE_U size;
5436 HRESULT hr;
5438 if (!init_test_context(&ctx, d3d11))
5439 return;
5440 release_test_context(&ctx);
5442 hr = D2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED, &IID_ID2D1Factory, NULL, (void **)&factory);
5443 ok(SUCCEEDED(hr), "Failed to create factory, hr %#x.\n", hr);
5445 desc.type = D2D1_RENDER_TARGET_TYPE_DEFAULT;
5446 desc.pixelFormat.format = DXGI_FORMAT_B8G8R8A8_UNORM;
5447 desc.pixelFormat.alphaMode = D2D1_ALPHA_MODE_PREMULTIPLIED;
5448 desc.dpiX = 0.0f;
5449 desc.dpiY = 0.0f;
5450 desc.usage = D2D1_RENDER_TARGET_USAGE_NONE;
5451 desc.minLevel = D2D1_FEATURE_LEVEL_DEFAULT;
5453 hwnd_rt_desc.hwnd = NULL;
5454 hwnd_rt_desc.pixelSize.width = 64;
5455 hwnd_rt_desc.pixelSize.height = 64;
5456 hwnd_rt_desc.presentOptions = D2D1_PRESENT_OPTIONS_NONE;
5458 hr = ID2D1Factory_CreateHwndRenderTarget(factory, &desc, &hwnd_rt_desc, &rt);
5459 ok(FAILED(hr), "Target creation should fail, hr %#x.\n", hr);
5461 hwnd_rt_desc.hwnd = (HWND)0xdeadbeef;
5462 hr = ID2D1Factory_CreateHwndRenderTarget(factory, &desc, &hwnd_rt_desc, &rt);
5463 ok(FAILED(hr), "Target creation should fail, hr %#x.\n", hr);
5465 hwnd_rt_desc.hwnd = CreateWindowA("static", "d2d_test", 0, 0, 0, 0, 0, 0, 0, 0, 0);
5466 ok(!!hwnd_rt_desc.hwnd, "Failed to create target window.\n");
5467 hr = ID2D1Factory_CreateHwndRenderTarget(factory, &desc, &hwnd_rt_desc, &rt);
5468 ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr);
5470 hr = ID2D1HwndRenderTarget_QueryInterface(rt, &IID_ID2D1GdiInteropRenderTarget, (void **)&interop);
5471 ok(SUCCEEDED(hr), "Failed to get interop target, hr %#x.\n", hr);
5472 hr = ID2D1GdiInteropRenderTarget_QueryInterface(interop, &IID_ID2D1RenderTarget, (void **)&rt3);
5473 ok(SUCCEEDED(hr), "Failed to get render target back, %#x.\n", hr);
5474 ok(rt3 == (ID2D1RenderTarget *)rt, "Unexpected render target\n");
5475 ID2D1RenderTarget_Release(rt3);
5476 hr = ID2D1GdiInteropRenderTarget_QueryInterface(interop, &IID_ID2D1HwndRenderTarget, (void **)&rt2);
5477 ok(SUCCEEDED(hr), "Failed to get render target back, %#x.\n", hr);
5478 ok(rt2 == rt, "Unexpected render target\n");
5479 ID2D1HwndRenderTarget_Release(rt2);
5480 ID2D1GdiInteropRenderTarget_Release(interop);
5482 size.width = 128;
5483 size.height = 64;
5484 hr = ID2D1HwndRenderTarget_Resize(rt, &size);
5485 ok(SUCCEEDED(hr), "Failed to resize render target, hr %#x.\n", hr);
5487 ID2D1HwndRenderTarget_Release(rt);
5489 DestroyWindow(hwnd_rt_desc.hwnd);
5490 ID2D1Factory_Release(factory);
5493 #define test_compatible_target_size(r) test_compatible_target_size_(__LINE__, r)
5494 static void test_compatible_target_size_(unsigned int line, ID2D1RenderTarget *rt)
5496 static const D2D1_SIZE_F size_1_0 = { 1.0f, 0.0f };
5497 static const D2D1_SIZE_F size_1_1 = { 1.0f, 1.0f };
5498 static const D2D1_SIZE_U px_size_1_1 = { 1, 1 };
5499 static const D2D1_SIZE_U zero_px_size;
5500 static const D2D1_SIZE_F zero_size;
5501 static const struct size_test
5503 const D2D1_SIZE_U *pixel_size;
5504 const D2D1_SIZE_F *size;
5506 size_tests[] =
5508 { &zero_px_size, NULL },
5509 { &zero_px_size, &zero_size },
5510 { NULL, &zero_size },
5511 { NULL, &size_1_0 },
5512 { &px_size_1_1, &size_1_1 },
5514 float dpi_x, dpi_y, rt_dpi_x, rt_dpi_y;
5515 D2D1_SIZE_U pixel_size, expected_size;
5516 ID2D1BitmapRenderTarget *bitmap_rt;
5517 ID2D1DeviceContext *context;
5518 unsigned int i;
5519 HRESULT hr;
5521 ID2D1RenderTarget_GetDpi(rt, &rt_dpi_x, &rt_dpi_y);
5523 for (i = 0; i < ARRAY_SIZE(size_tests); ++i)
5525 hr = ID2D1RenderTarget_CreateCompatibleRenderTarget(rt, size_tests[i].size, size_tests[i].pixel_size,
5526 NULL, D2D1_COMPATIBLE_RENDER_TARGET_OPTIONS_NONE, &bitmap_rt);
5527 ok_(__FILE__, line)(SUCCEEDED(hr), "%u: Failed to create render target, hr %#x.\n", i, hr);
5529 if (size_tests[i].pixel_size)
5531 expected_size = *size_tests[i].pixel_size;
5533 else if (size_tests[i].size)
5535 expected_size.width = ceilf((size_tests[i].size->width * rt_dpi_x) / 96.0f);
5536 expected_size.height = ceilf((size_tests[i].size->height * rt_dpi_y) / 96.0f);
5538 else
5540 expected_size = ID2D1RenderTarget_GetPixelSize(rt);
5543 pixel_size = ID2D1BitmapRenderTarget_GetPixelSize(bitmap_rt);
5544 ok_(__FILE__, line)(!memcmp(&pixel_size, &expected_size, sizeof(pixel_size)),
5545 "%u: unexpected target size %ux%u.\n", i, pixel_size.width, pixel_size.height);
5547 ID2D1BitmapRenderTarget_GetDpi(bitmap_rt, &dpi_x, &dpi_y);
5548 if (size_tests[i].pixel_size && size_tests[i].size && size_tests[i].size->width != 0.0f
5549 && size_tests[i].size->height != 0.0f)
5551 ok_(__FILE__, line)(dpi_x == pixel_size.width * 96.0f / size_tests[i].size->width
5552 && dpi_y == pixel_size.height * 96.0f / size_tests[i].size->height,
5553 "%u: unexpected target dpi %.8ex%.8e.\n", i, dpi_x, dpi_y);
5555 else
5556 ok_(__FILE__, line)(dpi_x == rt_dpi_x && dpi_y == rt_dpi_y,
5557 "%u: unexpected target dpi %.8ex%.8e.\n", i, dpi_x, dpi_y);
5558 ID2D1BitmapRenderTarget_Release(bitmap_rt);
5561 pixel_size.height = pixel_size.width = 0;
5562 hr = ID2D1RenderTarget_CreateCompatibleRenderTarget(rt, NULL, &pixel_size, NULL,
5563 D2D1_COMPATIBLE_RENDER_TARGET_OPTIONS_NONE, &bitmap_rt);
5564 ok_(__FILE__, line)(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr);
5566 if (SUCCEEDED(ID2D1BitmapRenderTarget_QueryInterface(bitmap_rt, &IID_ID2D1DeviceContext, (void **)&context)))
5568 ID2D1Bitmap *bitmap;
5570 pixel_size = ID2D1DeviceContext_GetPixelSize(context);
5571 ok_(__FILE__, line)(!pixel_size.width && !pixel_size.height, "Unexpected target size %ux%u.\n",
5572 pixel_size.width, pixel_size.height);
5574 ID2D1DeviceContext_GetTarget(context, (ID2D1Image **)&bitmap);
5575 pixel_size = ID2D1Bitmap_GetPixelSize(bitmap);
5576 ok_(__FILE__, line)(!pixel_size.width && !pixel_size.height, "Unexpected target size %ux%u.\n",
5577 pixel_size.width, pixel_size.height);
5578 ID2D1Bitmap_Release(bitmap);
5580 ID2D1DeviceContext_Release(context);
5583 ID2D1BitmapRenderTarget_Release(bitmap_rt);
5586 static void test_bitmap_target(BOOL d3d11)
5588 D2D1_HWND_RENDER_TARGET_PROPERTIES hwnd_rt_desc;
5589 ID2D1GdiInteropRenderTarget *interop;
5590 D2D1_SIZE_U pixel_size, pixel_size2;
5591 D2D1_RENDER_TARGET_PROPERTIES desc;
5592 ID2D1BitmapRenderTarget *rt, *rt2;
5593 ID2D1HwndRenderTarget *hwnd_rt;
5594 ID2D1Bitmap *bitmap, *bitmap2;
5595 struct d2d1_test_context ctx;
5596 ID2D1DCRenderTarget *dc_rt;
5597 D2D1_SIZE_F size, size2;
5598 ID2D1RenderTarget *rt3;
5599 ID2D1Factory *factory;
5600 float dpi[2], dpi2[2];
5601 D2D1_COLOR_F color;
5602 ULONG refcount;
5603 HRESULT hr;
5605 if (!init_test_context(&ctx, d3d11))
5606 return;
5607 release_test_context(&ctx);
5609 hr = D2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED, &IID_ID2D1Factory, NULL, (void **)&factory);
5610 ok(SUCCEEDED(hr), "Failed to create factory, hr %#x.\n", hr);
5612 desc.type = D2D1_RENDER_TARGET_TYPE_DEFAULT;
5613 desc.pixelFormat.format = DXGI_FORMAT_B8G8R8A8_UNORM;
5614 desc.pixelFormat.alphaMode = D2D1_ALPHA_MODE_PREMULTIPLIED;
5615 desc.dpiX = 96.0f;
5616 desc.dpiY = 192.0f;
5617 desc.usage = D2D1_RENDER_TARGET_USAGE_NONE;
5618 desc.minLevel = D2D1_FEATURE_LEVEL_DEFAULT;
5620 hwnd_rt_desc.hwnd = CreateWindowA("static", "d2d_test", 0, 0, 0, 0, 0, 0, 0, 0, 0);
5621 ok(!!hwnd_rt_desc.hwnd, "Failed to create target window.\n");
5622 hwnd_rt_desc.pixelSize.width = 64;
5623 hwnd_rt_desc.pixelSize.height = 64;
5624 hwnd_rt_desc.presentOptions = D2D1_PRESENT_OPTIONS_NONE;
5626 hr = ID2D1Factory_CreateHwndRenderTarget(factory, &desc, &hwnd_rt_desc, &hwnd_rt);
5627 ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr);
5629 test_compatible_target_size((ID2D1RenderTarget *)hwnd_rt);
5631 hr = ID2D1HwndRenderTarget_CreateCompatibleRenderTarget(hwnd_rt, NULL, NULL, NULL,
5632 D2D1_COMPATIBLE_RENDER_TARGET_OPTIONS_NONE, &rt);
5633 ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr);
5635 hr = ID2D1BitmapRenderTarget_QueryInterface(rt, &IID_ID2D1GdiInteropRenderTarget, (void **)&interop);
5636 ok(SUCCEEDED(hr), "Failed to get interop target, hr %#x.\n", hr);
5637 hr = ID2D1GdiInteropRenderTarget_QueryInterface(interop, &IID_ID2D1RenderTarget, (void **)&rt3);
5638 ok(SUCCEEDED(hr), "Failed to get render target back, %#x.\n", hr);
5639 ok(rt3 == (ID2D1RenderTarget *)rt, "Unexpected render target\n");
5640 ID2D1RenderTarget_Release(rt3);
5641 hr = ID2D1GdiInteropRenderTarget_QueryInterface(interop, &IID_ID2D1BitmapRenderTarget, (void **)&rt2);
5642 ok(SUCCEEDED(hr), "Failed to get render target back, %#x.\n", hr);
5643 ok(rt2 == rt, "Unexpected render target\n");
5644 ID2D1BitmapRenderTarget_Release(rt2);
5645 ID2D1GdiInteropRenderTarget_Release(interop);
5647 /* See if parent target is referenced. */
5648 ID2D1HwndRenderTarget_AddRef(hwnd_rt);
5649 refcount = ID2D1HwndRenderTarget_Release(hwnd_rt);
5650 ok(refcount == 1, "Target should not have been referenced, got %u.\n", refcount);
5652 /* Size was not specified, should match parent. */
5653 pixel_size = ID2D1HwndRenderTarget_GetPixelSize(hwnd_rt);
5654 pixel_size2 = ID2D1BitmapRenderTarget_GetPixelSize(rt);
5655 ok(!memcmp(&pixel_size, &pixel_size2, sizeof(pixel_size)), "Got target pixel size mismatch.\n");
5657 size = ID2D1HwndRenderTarget_GetSize(hwnd_rt);
5658 size2 = ID2D1BitmapRenderTarget_GetSize(rt);
5659 ok(!memcmp(&size, &size2, sizeof(size)), "Got target DIP size mismatch.\n");
5661 ID2D1HwndRenderTarget_GetDpi(hwnd_rt, dpi, dpi + 1);
5662 ID2D1BitmapRenderTarget_GetDpi(rt, dpi2, dpi2 + 1);
5663 ok(!memcmp(dpi, dpi2, sizeof(dpi)), "Got dpi mismatch.\n");
5665 ID2D1BitmapRenderTarget_Release(rt);
5667 /* Pixel size specified. */
5668 set_size_u(&pixel_size, 32, 32);
5669 hr = ID2D1HwndRenderTarget_CreateCompatibleRenderTarget(hwnd_rt, NULL, &pixel_size, NULL,
5670 D2D1_COMPATIBLE_RENDER_TARGET_OPTIONS_NONE, &rt);
5671 ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr);
5673 pixel_size2 = ID2D1BitmapRenderTarget_GetPixelSize(rt);
5674 ok(!memcmp(&pixel_size, &pixel_size2, sizeof(pixel_size)), "Got target pixel size mismatch.\n");
5676 ID2D1BitmapRenderTarget_GetDpi(rt, dpi2, dpi2 + 1);
5677 ok(!memcmp(dpi, dpi2, sizeof(dpi)), "Got dpi mismatch.\n");
5679 ID2D1BitmapRenderTarget_Release(rt);
5681 /* Both pixel size and DIP size are specified. */
5682 set_size_u(&pixel_size, 128, 128);
5683 hr = ID2D1HwndRenderTarget_CreateCompatibleRenderTarget(hwnd_rt, &size, &pixel_size, NULL,
5684 D2D1_COMPATIBLE_RENDER_TARGET_OPTIONS_NONE, &rt);
5685 ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr);
5687 /* Doubled pixel size dimensions with the same DIP size give doubled dpi. */
5688 ID2D1BitmapRenderTarget_GetDpi(rt, dpi2, dpi2 + 1);
5689 ok(dpi[0] == dpi2[0] / 2.0f && dpi[1] == dpi2[1] / 2.0f, "Got dpi mismatch.\n");
5691 ID2D1BitmapRenderTarget_Release(rt);
5693 /* DIP size is specified, fractional. */
5694 set_size_f(&size, 70.1f, 70.4f);
5695 hr = ID2D1HwndRenderTarget_CreateCompatibleRenderTarget(hwnd_rt, &size, NULL, NULL,
5696 D2D1_COMPATIBLE_RENDER_TARGET_OPTIONS_NONE, &rt);
5697 ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr);
5699 ID2D1BitmapRenderTarget_GetDpi(rt, dpi2, dpi2 + 1);
5701 pixel_size = ID2D1BitmapRenderTarget_GetPixelSize(rt);
5702 ok(pixel_size.width == ceilf(size.width * dpi[0] / 96.0f)
5703 && pixel_size.height == ceilf(size.height * dpi[1] / 96.0f), "Wrong pixel size %ux%u\n",
5704 pixel_size.width, pixel_size.height);
5706 dpi[0] *= (pixel_size.width / size.width) * (96.0f / dpi[0]);
5707 dpi[1] *= (pixel_size.height / size.height) * (96.0f / dpi[1]);
5709 ok(compare_float(dpi[0], dpi2[0], 1) && compare_float(dpi[1], dpi2[1], 1), "Got dpi mismatch.\n");
5711 ID2D1HwndRenderTarget_Release(hwnd_rt);
5713 /* Check if GetBitmap() returns same instance. */
5714 hr = ID2D1BitmapRenderTarget_GetBitmap(rt, &bitmap);
5715 ok(SUCCEEDED(hr), "GetBitmap() failed, hr %#x.\n", hr);
5716 hr = ID2D1BitmapRenderTarget_GetBitmap(rt, &bitmap2);
5717 ok(SUCCEEDED(hr), "GetBitmap() failed, hr %#x.\n", hr);
5718 ok(bitmap == bitmap2, "Got different bitmap instances.\n");
5720 /* Draw something, see if bitmap instance is retained. */
5721 ID2D1BitmapRenderTarget_BeginDraw(rt);
5722 set_color(&color, 1.0f, 1.0f, 0.0f, 1.0f);
5723 ID2D1BitmapRenderTarget_Clear(rt, &color);
5724 hr = ID2D1BitmapRenderTarget_EndDraw(rt, NULL, NULL);
5725 ok(SUCCEEDED(hr), "EndDraw() failed, hr %#x.\n", hr);
5727 ID2D1Bitmap_Release(bitmap2);
5728 hr = ID2D1BitmapRenderTarget_GetBitmap(rt, &bitmap2);
5729 ok(SUCCEEDED(hr), "GetBitmap() failed, hr %#x.\n", hr);
5730 ok(bitmap == bitmap2, "Got different bitmap instances.\n");
5732 ID2D1Bitmap_Release(bitmap);
5733 ID2D1Bitmap_Release(bitmap2);
5735 refcount = ID2D1BitmapRenderTarget_Release(rt);
5736 ok(!refcount, "Target should be released, got %u.\n", refcount);
5738 DestroyWindow(hwnd_rt_desc.hwnd);
5740 /* Compatible target created from a DC target without associated HDC */
5741 desc.type = D2D1_RENDER_TARGET_TYPE_DEFAULT;
5742 desc.pixelFormat.format = DXGI_FORMAT_B8G8R8A8_UNORM;
5743 desc.pixelFormat.alphaMode = D2D1_ALPHA_MODE_PREMULTIPLIED;
5744 desc.dpiX = 192.0f;
5745 desc.dpiY = 96.0f;
5746 desc.usage = D2D1_RENDER_TARGET_USAGE_NONE;
5747 desc.minLevel = D2D1_FEATURE_LEVEL_DEFAULT;
5748 hr = ID2D1Factory_CreateDCRenderTarget(factory, &desc, &dc_rt);
5749 ok(SUCCEEDED(hr), "Failed to create target, hr %#x.\n", hr);
5751 test_compatible_target_size((ID2D1RenderTarget *)dc_rt);
5753 hr = ID2D1DCRenderTarget_CreateCompatibleRenderTarget(dc_rt, NULL, NULL, NULL,
5754 D2D1_COMPATIBLE_RENDER_TARGET_OPTIONS_NONE, &rt);
5755 ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr);
5757 pixel_size = ID2D1BitmapRenderTarget_GetPixelSize(rt);
5758 ok(pixel_size.width == 0 && pixel_size.height == 0, "Got wrong size\n");
5760 hr = ID2D1BitmapRenderTarget_GetBitmap(rt, &bitmap);
5761 ok(SUCCEEDED(hr), "GetBitmap() failed, hr %#x.\n", hr);
5762 pixel_size = ID2D1Bitmap_GetPixelSize(bitmap);
5763 ok(pixel_size.width == 0 && pixel_size.height == 0, "Got wrong size\n");
5764 ID2D1Bitmap_Release(bitmap);
5766 ID2D1BitmapRenderTarget_Release(rt);
5767 ID2D1DCRenderTarget_Release(dc_rt);
5769 ID2D1Factory_Release(factory);
5772 static void test_desktop_dpi(BOOL d3d11)
5774 ID2D1Factory *factory;
5775 float dpi_x, dpi_y;
5776 HRESULT hr;
5778 hr = D2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED, &IID_ID2D1Factory, NULL, (void **)&factory);
5779 ok(SUCCEEDED(hr), "Failed to create factory, hr %#x.\n", hr);
5781 dpi_x = dpi_y = 0.0f;
5782 ID2D1Factory_GetDesktopDpi(factory, &dpi_x, &dpi_y);
5783 ok(dpi_x > 0.0f && dpi_y > 0.0f, "Got wrong dpi %f x %f.\n", dpi_x, dpi_y);
5785 ID2D1Factory_Release(factory);
5788 static void test_stroke_style(BOOL d3d11)
5790 static const struct
5792 D2D1_DASH_STYLE dash_style;
5793 UINT32 dash_count;
5794 float dashes[6];
5796 dash_style_tests[] =
5798 {D2D1_DASH_STYLE_SOLID, 0},
5799 {D2D1_DASH_STYLE_DASH, 2, {2.0f, 2.0f}},
5800 {D2D1_DASH_STYLE_DOT, 2, {0.0f, 2.0f}},
5801 {D2D1_DASH_STYLE_DASH_DOT, 4, {2.0f, 2.0f, 0.0f, 2.0f}},
5802 {D2D1_DASH_STYLE_DASH_DOT_DOT, 6, {2.0f, 2.0f, 0.0f, 2.0f, 0.0f, 2.0f}},
5804 D2D1_STROKE_STYLE_PROPERTIES desc;
5805 ID2D1StrokeStyle *style;
5806 ID2D1Factory *factory;
5807 UINT32 count;
5808 HRESULT hr;
5809 D2D1_CAP_STYLE cap_style;
5810 D2D1_LINE_JOIN line_join;
5811 float miter_limit, dash_offset;
5812 D2D1_DASH_STYLE dash_style;
5813 unsigned int i;
5814 float dashes[2];
5816 hr = D2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED, &IID_ID2D1Factory, NULL, (void **)&factory);
5817 ok(SUCCEEDED(hr), "Failed to create factory, hr %#x.\n", hr);
5819 desc.startCap = D2D1_CAP_STYLE_SQUARE;
5820 desc.endCap = D2D1_CAP_STYLE_ROUND;
5821 desc.dashCap = D2D1_CAP_STYLE_TRIANGLE;
5822 desc.lineJoin = D2D1_LINE_JOIN_BEVEL;
5823 desc.miterLimit = 1.5f;
5824 desc.dashStyle = D2D1_DASH_STYLE_DOT;
5825 desc.dashOffset = -1.0f;
5827 hr = ID2D1Factory_CreateStrokeStyle(factory, &desc, NULL, 0, &style);
5828 ok(SUCCEEDED(hr), "Failed to create stroke style, %#x.\n", hr);
5830 cap_style = ID2D1StrokeStyle_GetStartCap(style);
5831 ok(cap_style == D2D1_CAP_STYLE_SQUARE, "Unexpected cap style %d.\n", cap_style);
5832 cap_style = ID2D1StrokeStyle_GetEndCap(style);
5833 ok(cap_style == D2D1_CAP_STYLE_ROUND, "Unexpected cap style %d.\n", cap_style);
5834 cap_style = ID2D1StrokeStyle_GetDashCap(style);
5835 ok(cap_style == D2D1_CAP_STYLE_TRIANGLE, "Unexpected cap style %d.\n", cap_style);
5836 line_join = ID2D1StrokeStyle_GetLineJoin(style);
5837 ok(line_join == D2D1_LINE_JOIN_BEVEL, "Unexpected line joind %d.\n", line_join);
5838 miter_limit = ID2D1StrokeStyle_GetMiterLimit(style);
5839 ok(miter_limit == 1.5f, "Unexpected miter limit %f.\n", miter_limit);
5840 dash_style = ID2D1StrokeStyle_GetDashStyle(style);
5841 ok(dash_style == D2D1_DASH_STYLE_DOT, "Unexpected dash style %d.\n", dash_style);
5842 dash_offset = ID2D1StrokeStyle_GetDashOffset(style);
5843 ok(dash_offset == -1.0f, "Unexpected dash offset %f.\n", dash_offset);
5845 /* Custom dash pattern, no dashes data specified. */
5846 desc.startCap = D2D1_CAP_STYLE_SQUARE;
5847 desc.endCap = D2D1_CAP_STYLE_ROUND;
5848 desc.dashCap = D2D1_CAP_STYLE_TRIANGLE;
5849 desc.lineJoin = D2D1_LINE_JOIN_BEVEL;
5850 desc.miterLimit = 1.5f;
5851 desc.dashStyle = D2D1_DASH_STYLE_CUSTOM;
5852 desc.dashOffset = 0.0f;
5854 ID2D1StrokeStyle_Release(style);
5856 hr = ID2D1Factory_CreateStrokeStyle(factory, &desc, NULL, 0, &style);
5857 ok(hr == E_INVALIDARG, "Unexpected return value, %#x.\n", hr);
5859 hr = ID2D1Factory_CreateStrokeStyle(factory, &desc, dashes, 0, &style);
5860 ok(hr == E_INVALIDARG, "Unexpected return value, %#x.\n", hr);
5862 hr = ID2D1Factory_CreateStrokeStyle(factory, &desc, dashes, 1, &style);
5863 ok(hr == S_OK, "Unexpected return value, %#x.\n", hr);
5864 ID2D1StrokeStyle_Release(style);
5866 /* Builtin style, dashes are specified. */
5867 desc.dashStyle = D2D1_DASH_STYLE_DOT;
5868 hr = ID2D1Factory_CreateStrokeStyle(factory, &desc, dashes, 1, &style);
5869 ok(hr == E_INVALIDARG, "Unexpected return value, %#x.\n", hr);
5871 /* Invalid style. */
5872 desc.dashStyle = 100;
5873 hr = ID2D1Factory_CreateStrokeStyle(factory, &desc, NULL, 0, &style);
5874 ok(hr == E_INVALIDARG, "Unexpected return value, %#x.\n", hr);
5876 /* Test returned dash pattern for builtin styles. */
5877 desc.startCap = D2D1_CAP_STYLE_SQUARE;
5878 desc.endCap = D2D1_CAP_STYLE_ROUND;
5879 desc.dashCap = D2D1_CAP_STYLE_TRIANGLE;
5880 desc.lineJoin = D2D1_LINE_JOIN_BEVEL;
5881 desc.miterLimit = 1.5f;
5882 desc.dashOffset = 0.0f;
5884 for (i = 0; i < ARRAY_SIZE(dash_style_tests); ++i)
5886 float dashes[10];
5887 UINT dash_count;
5889 desc.dashStyle = dash_style_tests[i].dash_style;
5891 hr = ID2D1Factory_CreateStrokeStyle(factory, &desc, NULL, 0, &style);
5892 ok(SUCCEEDED(hr), "Failed to create stroke style, %#x.\n", hr);
5894 dash_count = ID2D1StrokeStyle_GetDashesCount(style);
5895 ok(dash_count == dash_style_tests[i].dash_count, "%u: unexpected dash count %u, expected %u.\n",
5896 i, dash_count, dash_style_tests[i].dash_count);
5897 ok(dash_count < ARRAY_SIZE(dashes), "%u: unexpectedly large dash count %u.\n", i, dash_count);
5898 if (dash_count == dash_style_tests[i].dash_count)
5900 unsigned int j;
5902 ID2D1StrokeStyle_GetDashes(style, dashes, dash_count);
5903 ok(!memcmp(dashes, dash_style_tests[i].dashes, sizeof(*dashes) * dash_count),
5904 "%u: unexpected dash array.\n", i);
5906 /* Ask for more dashes than style actually has. */
5907 memset(dashes, 0xcc, sizeof(dashes));
5908 ID2D1StrokeStyle_GetDashes(style, dashes, ARRAY_SIZE(dashes));
5909 ok(!memcmp(dashes, dash_style_tests[i].dashes, sizeof(*dashes) * dash_count),
5910 "%u: unexpected dash array.\n", i);
5912 for (j = dash_count; j < ARRAY_SIZE(dashes); ++j)
5913 ok(dashes[j] == 0.0f, "%u: unexpected dash value at %u.\n", i, j);
5916 ID2D1StrokeStyle_Release(style);
5919 /* NULL dashes array, non-zero length. */
5920 memset(&desc, 0, sizeof(desc));
5921 hr = ID2D1Factory_CreateStrokeStyle(factory, &desc, NULL, 1, &style);
5922 ok(SUCCEEDED(hr), "Failed to create stroke style, %#x.\n", hr);
5924 count = ID2D1StrokeStyle_GetDashesCount(style);
5925 ok(count == 0, "Unexpected dashes count %u.\n", count);
5927 ID2D1StrokeStyle_Release(style);
5929 ID2D1Factory_Release(factory);
5932 static void test_gradient(BOOL d3d11)
5934 ID2D1GradientStopCollection *gradient;
5935 D2D1_GRADIENT_STOP stops[3], stops2[3];
5936 struct d2d1_test_context ctx;
5937 ID2D1RenderTarget *rt;
5938 D2D1_COLOR_F color;
5939 unsigned int i;
5940 UINT32 count;
5941 HRESULT hr;
5943 if (!init_test_context(&ctx, d3d11))
5944 return;
5946 rt = ctx.rt;
5947 stops2[0].position = 0.5f;
5948 set_color(&stops2[0].color, 1.0f, 1.0f, 0.0f, 1.0f);
5949 stops2[1] = stops2[0];
5950 hr = ID2D1RenderTarget_CreateGradientStopCollection(rt, stops2, 2, D2D1_GAMMA_2_2,
5951 D2D1_EXTEND_MODE_CLAMP, &gradient);
5952 ok(SUCCEEDED(hr), "Failed to create stop collection, hr %#x.\n", hr);
5954 count = ID2D1GradientStopCollection_GetGradientStopCount(gradient);
5955 ok(count == 2, "Unexpected stop count %u.\n", count);
5957 /* Request more stops than collection has. */
5958 stops[0].position = 123.4f;
5959 set_color(&stops[0].color, 1.0f, 0.5f, 0.4f, 1.0f);
5960 color = stops[0].color;
5961 stops[2] = stops[1] = stops[0];
5962 ID2D1GradientStopCollection_GetGradientStops(gradient, stops, ARRAY_SIZE(stops));
5963 ok(!memcmp(stops, stops2, sizeof(*stops) * count), "Unexpected gradient stops array.\n");
5964 for (i = count; i < ARRAY_SIZE(stops); ++i)
5966 ok(stops[i].position == 123.4f, "%u: unexpected stop position %f.\n", i, stops[i].position);
5967 ok(!memcmp(&stops[i].color, &color, sizeof(color)), "%u: unexpected stop color.\n", i);
5970 ID2D1GradientStopCollection_Release(gradient);
5972 release_test_context(&ctx);
5975 static void test_draw_geometry(BOOL d3d11)
5977 ID2D1TransformedGeometry *transformed_geometry[4];
5978 ID2D1RectangleGeometry *rect_geometry[2];
5979 D2D1_POINT_2F point = {0.0f, 0.0f};
5980 D2D1_ROUNDED_RECT rounded_rect;
5981 struct d2d1_test_context ctx;
5982 ID2D1SolidColorBrush *brush;
5983 ID2D1PathGeometry *geometry;
5984 D2D1_MATRIX_3X2_F matrix;
5985 ID2D1GeometrySink *sink;
5986 ID2D1RenderTarget *rt;
5987 ID2D1Factory *factory;
5988 D2D1_POINT_2F p0, p1;
5989 D2D1_ELLIPSE ellipse;
5990 D2D1_COLOR_F color;
5991 D2D1_RECT_F rect;
5992 HRESULT hr;
5993 BOOL match;
5995 if (!init_test_context(&ctx, d3d11))
5996 return;
5998 rt = ctx.rt;
5999 ID2D1RenderTarget_GetFactory(rt, &factory);
6001 ID2D1RenderTarget_SetDpi(rt, 192.0f, 48.0f);
6002 ID2D1RenderTarget_SetAntialiasMode(rt, D2D1_ANTIALIAS_MODE_ALIASED);
6003 set_color(&color, 0.890f, 0.851f, 0.600f, 1.0f);
6004 hr = ID2D1RenderTarget_CreateSolidColorBrush(rt, &color, NULL, &brush);
6005 ok(SUCCEEDED(hr), "Failed to create brush, hr %#x.\n", hr);
6007 ID2D1RenderTarget_BeginDraw(rt);
6008 set_color(&color, 0.396f, 0.180f, 0.537f, 1.0f);
6009 ID2D1RenderTarget_Clear(rt, &color);
6011 set_point(&p0, 40.0f, 160.0f);
6012 ID2D1RenderTarget_DrawLine(rt, p0, p0, (ID2D1Brush *)brush, 10.0f, NULL);
6013 set_point(&p0, 100.0f, 160.0f);
6014 set_point(&p1, 140.0f, 160.0f);
6015 ID2D1RenderTarget_DrawLine(rt, p0, p1, (ID2D1Brush *)brush, 10.0f, NULL);
6016 set_point(&p0, 200.0f, 80.0f);
6017 set_point(&p1, 200.0f, 240.0f);
6018 ID2D1RenderTarget_DrawLine(rt, p0, p1, (ID2D1Brush *)brush, 10.0f, NULL);
6019 set_point(&p0, 260.0f, 240.0f);
6020 set_point(&p1, 300.0f, 80.0f);
6021 ID2D1RenderTarget_DrawLine(rt, p0, p1, (ID2D1Brush *)brush, 10.0f, NULL);
6023 set_rect(&rect, 40.0f, 480.0f, 40.0f, 480.0f);
6024 ID2D1RenderTarget_DrawRectangle(rt, &rect, (ID2D1Brush *)brush, 10.0f, NULL);
6025 set_rect(&rect, 100.0f, 480.0f, 140.0f, 480.0f);
6026 ID2D1RenderTarget_DrawRectangle(rt, &rect, (ID2D1Brush *)brush, 10.0f, NULL);
6027 set_rect(&rect, 200.0f, 400.0f, 200.0f, 560.0f);
6028 ID2D1RenderTarget_DrawRectangle(rt, &rect, (ID2D1Brush *)brush, 10.0f, NULL);
6029 set_rect(&rect, 260.0f, 560.0f, 300.0f, 400.0f);
6030 ID2D1RenderTarget_DrawRectangle(rt, &rect, (ID2D1Brush *)brush, 10.0f, NULL);
6032 set_ellipse(&ellipse, 40.0f, 800.0f, 0.0f, 0.0f);
6033 ID2D1RenderTarget_DrawEllipse(rt, &ellipse, (ID2D1Brush *)brush, 10.0f, NULL);
6034 set_ellipse(&ellipse, 120.0f, 800.0f, 20.0f, 0.0f);
6035 ID2D1RenderTarget_DrawEllipse(rt, &ellipse, (ID2D1Brush *)brush, 10.0f, NULL);
6036 set_ellipse(&ellipse, 200.0f, 800.0f, 0.0f, 80.0f);
6037 ID2D1RenderTarget_DrawEllipse(rt, &ellipse, (ID2D1Brush *)brush, 10.0f, NULL);
6038 set_ellipse(&ellipse, 280.0f, 800.0f, 20.0f, 80.0f);
6039 ID2D1RenderTarget_DrawEllipse(rt, &ellipse, (ID2D1Brush *)brush, 10.0f, NULL);
6041 hr = ID2D1RenderTarget_EndDraw(rt, NULL, NULL);
6042 ok(SUCCEEDED(hr), "Failed to end draw, hr %#x.\n", hr);
6044 match = compare_figure(&ctx, 0, 0, 160, 160, 0xff652e89, 0, "");
6045 ok(match, "Figure does not match.\n");
6046 match = compare_figure(&ctx, 160, 0, 160, 160, 0xff652e89, 0, "yGBQUFBQUFBQUFDoYQAA");
6047 ok(match, "Figure does not match.\n");
6048 match = compare_figure(&ctx, 320, 0, 160, 160, 0xff652e89, 0,
6049 "xjIUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEU"
6050 "jAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEU"
6051 "jAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEU"
6052 "jAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEU"
6053 "jAEUjAEUjAEUjAEUxjIA");
6054 ok(match, "Figure does not match.\n");
6055 match = compare_figure(&ctx, 480, 0, 160, 160, 0xff652e89, 2,
6056 "zjECnQETjAEVigEVigEVigEVigEVigEVigEVigEVigEVigEVigEVigEVigEVigEVigEVigEVigEV"
6057 "igEVigEVigEVigEVigEVigEVigEVigEVigEVigEVigEVigEVigEVigEVigEVigEVigEVigEVigEV"
6058 "igEVigEVigEVigEVigEVigEVigEVigEVigEVigEVigEVigEVigEVigEVigEVigEVigEVigEVigEV"
6059 "igEVigEVigEVigEVigEVigEVigEVigEVigEVigEVigEVigEVigEVigEVigEVigEVigEVigEVigEV"
6060 "igEVigEVigEVigEVjAETnQECzjEA");
6061 ok(match, "Figure does not match.\n");
6063 match = compare_figure(&ctx, 0, 160, 160, 160, 0xff652e89, 0, "5mAUjAEUjAEUjAEUjAEUhmIA");
6064 ok(match, "Figure does not match.\n");
6065 match = compare_figure(&ctx, 160, 160, 160, 160, 0xff652e89, 0, "vmBkPGQ8ZDxkPGTeYQAA");
6066 ok(match, "Figure does not match.\n");
6067 match = compare_figure(&ctx, 320, 160, 160, 160, 0xff652e89, 0,
6068 "5i4UjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEU"
6069 "jAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEU"
6070 "jAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEU"
6071 "jAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEU"
6072 "jAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUhjAA");
6073 ok(match, "Figure does not match.\n");
6074 match = compare_figure(&ctx, 480, 160, 160, 160, 0xff652e89, 0,
6075 "vi5kPGQ8ZDxkPGQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwU"
6076 "PBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8"
6077 "FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwU"
6078 "PBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8"
6079 "FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwU"
6080 "PBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8ZDxkPGQ8ZDxk3i8A");
6081 ok(match, "Figure does not match.\n");
6083 match = compare_figure(&ctx, 0, 320, 160, 160, 0xff652e89, 0, "iGIQjgEUjAEUjgEQiGIA");
6084 todo_wine ok(match, "Figure does not match.\n");
6085 match = compare_figure(&ctx, 160, 320, 160, 160, 0xff652e89, 0, "yGBQSGA+ZDxkPmDgYQAA");
6086 todo_wine ok(match, "Figure does not match.\n");
6087 match = compare_figure(&ctx, 320, 320, 160, 160, 0xff652e89, 0,
6088 "iDAQjgEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEU"
6089 "jAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEU"
6090 "jAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEU"
6091 "jAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEU"
6092 "jAEUjAEUjAEUjAEUjAEUjAEUjAEUjgEQiDAA");
6093 todo_wine ok(match, "Figure does not match.\n");
6094 match = compare_figure(&ctx, 480, 320, 160, 160, 0xff652e89, 10,
6095 "hDAYgwEieyh1LnAybBcIF2gWDhZkFhIWYRUWFV4VGhVbFRwVWRUeFVcVIBVVFCQUUxQmFFEUKBRP"
6096 "FSgVTRUqFUwULBRLFC4USRQwFEgUMBRHFDIURhQyFEUUNBREFDQUQxQ2FEIUNhRBFDgUQBQ4FEAU"
6097 "OBQ/FDoUPhQ6FD4UOhQ+FDoUPhQ6FD0UPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8"
6098 "FDwUPBQ8FDwUPBQ8FD0UOhQ+FDoUPhQ6FD4UOhQ+FDoUPxQ4FEAUOBRAFDgUQRQ2FEIUNhRDFDQU"
6099 "RBQ0FEUUMhRGFDIURxQwFEgUMBRJFC4USxQsFEwVKhVNFSgVTxQoFFEUJhRTFCQUVRUgFVcVHhVZ"
6100 "FRwVWxUaFV4VFhVhFhIWZBYOFmgXCBdsMnAudSh7IoMBGIQw");
6101 todo_wine ok(match, "Figure does not match.\n");
6103 ID2D1RenderTarget_BeginDraw(rt);
6104 set_color(&color, 0.396f, 0.180f, 0.537f, 1.0f);
6105 ID2D1RenderTarget_Clear(rt, &color);
6107 set_rounded_rect(&rounded_rect, 40.0f, 160.0f, 40.0f, 160.0f, 10.0f, 10.0f);
6108 ID2D1RenderTarget_DrawRoundedRectangle(rt, &rounded_rect, (ID2D1Brush *)brush, 10.0f, NULL);
6109 set_rounded_rect(&rounded_rect, 100.0f, 160.0f, 140.0f, 160.0f, 10.0f, 10.0f);
6110 ID2D1RenderTarget_DrawRoundedRectangle(rt, &rounded_rect, (ID2D1Brush *)brush, 10.0f, NULL);
6111 set_rounded_rect(&rounded_rect, 200.0f, 80.0f, 200.0f, 240.0f, 10.0f, 10.0f);
6112 ID2D1RenderTarget_DrawRoundedRectangle(rt, &rounded_rect, (ID2D1Brush *)brush, 10.0f, NULL);
6113 set_rounded_rect(&rounded_rect, 260.0f, 240.0f, 300.0f, 80.0f, 10.0f, 10.0f);
6114 ID2D1RenderTarget_DrawRoundedRectangle(rt, &rounded_rect, (ID2D1Brush *)brush, 10.0f, NULL);
6116 set_rounded_rect(&rounded_rect, 40.0f, 480.0f, 40.0f, 480.0f, 10.0f, 20.0f);
6117 ID2D1RenderTarget_DrawRoundedRectangle(rt, &rounded_rect, (ID2D1Brush *)brush, 10.0f, NULL);
6118 set_rounded_rect(&rounded_rect, 100.0f, 480.0f, 140.0f, 480.0f, 10.0f, 20.0f);
6119 ID2D1RenderTarget_DrawRoundedRectangle(rt, &rounded_rect, (ID2D1Brush *)brush, 10.0f, NULL);
6120 set_rounded_rect(&rounded_rect, 200.0f, 400.0f, 200.0f, 560.0f, 10.0f, 20.0f);
6121 ID2D1RenderTarget_DrawRoundedRectangle(rt, &rounded_rect, (ID2D1Brush *)brush, 10.0f, NULL);
6122 set_rounded_rect(&rounded_rect, 260.0f, 560.0f, 300.0f, 400.0f, 10.0f, 20.0f);
6123 ID2D1RenderTarget_DrawRoundedRectangle(rt, &rounded_rect, (ID2D1Brush *)brush, 10.0f, NULL);
6125 set_rounded_rect(&rounded_rect, 40.0f, 800.0f, 40.0f, 800.0f, 10.0f, 5.0f);
6126 ID2D1RenderTarget_DrawRoundedRectangle(rt, &rounded_rect, (ID2D1Brush *)brush, 10.0f, NULL);
6127 set_rounded_rect(&rounded_rect, 100.0f, 800.0f, 140.0f, 800.0f, 10.0f, 5.0f);
6128 ID2D1RenderTarget_DrawRoundedRectangle(rt, &rounded_rect, (ID2D1Brush *)brush, 10.0f, NULL);
6129 set_rounded_rect(&rounded_rect, 200.0f, 720.0f, 200.0f, 880.0f, 10.0f, 5.0f);
6130 ID2D1RenderTarget_DrawRoundedRectangle(rt, &rounded_rect, (ID2D1Brush *)brush, 10.0f, NULL);
6131 set_rounded_rect(&rounded_rect, 260.0f, 880.0f, 300.0f, 720.0f, 10.0f, 5.0f);
6132 ID2D1RenderTarget_DrawRoundedRectangle(rt, &rounded_rect, (ID2D1Brush *)brush, 10.0f, NULL);
6134 hr = ID2D1RenderTarget_EndDraw(rt, NULL, NULL);
6135 ok(SUCCEEDED(hr), "Failed to end draw, hr %#x.\n", hr);
6137 match = compare_figure(&ctx, 0, 0, 160, 160, 0xff652e89, 0, "iGIQjgEUjAEUjgEQiGIA");
6138 todo_wine ok(match, "Figure does not match.\n");
6139 match = compare_figure(&ctx, 160, 0, 160, 160, 0xff652e89, 0, "yGBQSGA+ZDxkPmDgYQAA");
6140 todo_wine ok(match, "Figure does not match.\n");
6141 match = compare_figure(&ctx, 320, 0, 160, 160, 0xff652e89, 0,
6142 "iDAQjgEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEU"
6143 "jAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEU"
6144 "jAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEU"
6145 "jAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEU"
6146 "jAEUjAEUjAEUjAEUjAEUjAEUjAEUjgEQiDAA");
6147 todo_wine ok(match, "Figure does not match.\n");
6148 match = compare_figure(&ctx, 480, 0, 160, 160, 0xff652e89, 0,
6149 "3C4oaUZVUExYRlxCHCgcPxU4FT0UPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwU"
6150 "PBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8"
6151 "FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwU"
6152 "PBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8"
6153 "FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwU"
6154 "PBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FD0VOBU/YEJcRlhMUFVG7S8A");
6155 todo_wine ok(match, "Figure does not match.\n");
6157 match = compare_figure(&ctx, 0, 160, 160, 160, 0xff652e89, 0, "iGIQjgEUjAEUjgEQiGIA");
6158 todo_wine ok(match, "Figure does not match.\n");
6159 match = compare_figure(&ctx, 160, 160, 160, 160, 0xff652e89, 0, "yGBQSGA+ZDxkPmDgYQAA");
6160 todo_wine ok(match, "Figure does not match.\n");
6161 match = compare_figure(&ctx, 320, 160, 160, 160, 0xff652e89, 0,
6162 "iDAQjgEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEU"
6163 "jAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEU"
6164 "jAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEU"
6165 "jAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEU"
6166 "jAEUjAEUjAEUjAEUjAEUjAEUjAEUjgEQiDAA");
6167 todo_wine ok(match, "Figure does not match.\n");
6168 match = compare_figure(&ctx, 480, 160, 160, 160, 0xff652e89, 8,
6169 "3C4obT5dSFRQTlRKGCgYRhYwFkMVNBVBFTYVPxU5FD4UOhQ9FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwU"
6170 "PBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8"
6171 "FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwU"
6172 "PBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8"
6173 "FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwU"
6174 "PBQ8FDwUPRQ6FD4UOhQ/FTYVQRU0FUMWMBZGWEpVTVBTSltA8C8A");
6175 todo_wine ok(match, "Figure does not match.\n");
6177 match = compare_figure(&ctx, 0, 320, 160, 160, 0xff652e89, 0, "iGIQjgEUjAEUjgEQiGIA");
6178 todo_wine ok(match, "Figure does not match.\n");
6179 match = compare_figure(&ctx, 160, 320, 160, 160, 0xff652e89, 0, "yGBQSGA+ZDxkPmDgYQAA");
6180 todo_wine ok(match, "Figure does not match.\n");
6181 match = compare_figure(&ctx, 320, 320, 160, 160, 0xff652e89, 0,
6182 "iDAQjgEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEU"
6183 "jAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEU"
6184 "jAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEU"
6185 "jAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEU"
6186 "jAEUjAEUjAEUjAEUjAEUjAEUjAEUjgEQiDAA");
6187 todo_wine ok(match, "Figure does not match.\n");
6188 match = compare_figure(&ctx, 480, 320, 160, 160, 0xff652e89, 0,
6189 "3C4oZU5NWERgP2I9HigePBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwU"
6190 "PBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8"
6191 "FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwU"
6192 "PBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8"
6193 "FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwU"
6194 "PBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8ZD1iP2BEWE1O6S8A");
6195 todo_wine ok(match, "Figure does not match.\n");
6197 ID2D1RenderTarget_BeginDraw(rt);
6198 set_color(&color, 0.396f, 0.180f, 0.537f, 1.0f);
6199 ID2D1RenderTarget_Clear(rt, &color);
6201 set_rounded_rect(&rounded_rect, 40.0f, 160.0f, 40.0f, 160.0f, 1000.0f, 1000.0f);
6202 ID2D1RenderTarget_DrawRoundedRectangle(rt, &rounded_rect, (ID2D1Brush *)brush, 10.0f, NULL);
6203 set_rounded_rect(&rounded_rect, 100.0f, 160.0f, 140.0f, 160.0f, 1000.0f, 1000.0f);
6204 ID2D1RenderTarget_DrawRoundedRectangle(rt, &rounded_rect, (ID2D1Brush *)brush, 10.0f, NULL);
6205 set_rounded_rect(&rounded_rect, 200.0f, 80.0f, 200.0f, 240.0f, 1000.0f, 1000.0f);
6206 ID2D1RenderTarget_DrawRoundedRectangle(rt, &rounded_rect, (ID2D1Brush *)brush, 10.0f, NULL);
6207 set_rounded_rect(&rounded_rect, 260.0f, 240.0f, 300.0f, 80.0f, 1000.0f, 1000.0f);
6208 ID2D1RenderTarget_DrawRoundedRectangle(rt, &rounded_rect, (ID2D1Brush *)brush, 10.0f, NULL);
6210 set_rounded_rect(&rounded_rect, 40.0f, 480.0f, 40.0f, 480.0f, 10.0f, 1000.0f);
6211 ID2D1RenderTarget_DrawRoundedRectangle(rt, &rounded_rect, (ID2D1Brush *)brush, 10.0f, NULL);
6212 set_rounded_rect(&rounded_rect, 100.0f, 480.0f, 140.0f, 480.0f, 10.0f, 1000.0f);
6213 ID2D1RenderTarget_DrawRoundedRectangle(rt, &rounded_rect, (ID2D1Brush *)brush, 10.0f, NULL);
6214 set_rounded_rect(&rounded_rect, 200.0f, 400.0f, 200.0f, 560.0f, 10.0f, 1000.0f);
6215 ID2D1RenderTarget_DrawRoundedRectangle(rt, &rounded_rect, (ID2D1Brush *)brush, 10.0f, NULL);
6216 set_rounded_rect(&rounded_rect, 260.0f, 560.0f, 300.0f, 400.0f, 10.0f, 1000.0f);
6217 ID2D1RenderTarget_DrawRoundedRectangle(rt, &rounded_rect, (ID2D1Brush *)brush, 10.0f, NULL);
6219 set_rounded_rect(&rounded_rect, 40.0f, 800.0f, 40.0f, 800.0f, 1000.0f, 10.0f);
6220 ID2D1RenderTarget_DrawRoundedRectangle(rt, &rounded_rect, (ID2D1Brush *)brush, 10.0f, NULL);
6221 set_rounded_rect(&rounded_rect, 100.0f, 800.0f, 140.0f, 800.0f, 1000.0f, 10.0f);
6222 ID2D1RenderTarget_DrawRoundedRectangle(rt, &rounded_rect, (ID2D1Brush *)brush, 10.0f, NULL);
6223 set_rounded_rect(&rounded_rect, 200.0f, 720.0f, 200.0f, 880.0f, 1000.0f, 10.0f);
6224 ID2D1RenderTarget_DrawRoundedRectangle(rt, &rounded_rect, (ID2D1Brush *)brush, 10.0f, NULL);
6225 set_rounded_rect(&rounded_rect, 260.0f, 880.0f, 300.0f, 720.0f, 1000.0f, 10.0f);
6226 ID2D1RenderTarget_DrawRoundedRectangle(rt, &rounded_rect, (ID2D1Brush *)brush, 10.0f, NULL);
6228 hr = ID2D1RenderTarget_EndDraw(rt, NULL, NULL);
6229 ok(SUCCEEDED(hr), "Failed to end draw, hr %#x.\n", hr);
6231 match = compare_figure(&ctx, 0, 0, 160, 160, 0xff652e89, 0, "iGIQjgEUjAEUjgEQiGIA");
6232 todo_wine ok(match, "Figure does not match.\n");
6233 match = compare_figure(&ctx, 160, 0, 160, 160, 0xff652e89, 0, "yGBQSGA+ZDxkPmDgYQAA");
6234 todo_wine ok(match, "Figure does not match.\n");
6235 match = compare_figure(&ctx, 320, 0, 160, 160, 0xff652e89, 0,
6236 "iDAQjgEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEU"
6237 "jAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEU"
6238 "jAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEU"
6239 "jAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEU"
6240 "jAEUjAEUjAEUjAEUjAEUjAEUjAEUjgEQiDAA");
6241 todo_wine ok(match, "Figure does not match.\n");
6242 match = compare_figure(&ctx, 480, 0, 160, 160, 0xff652e89, 16,
6243 "hDAYgwEieyh1LnAybBcIF2gWDhZkFhIWYRUWFV4WGRVbFRwVWRUeFVcVIBVVFSMUUxQmFFEVJxRP"
6244 "FSgVTRUqFUwULBRLFC4USRUvFEgUMBRHFDIURhQyFEUUNBREFDQUQxQ2FEIUNhRBFDgUQBQ4FEAU"
6245 "OBQ/FTkUPhQ6FD4UOhQ+FDoUPhQ6FD0UPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8"
6246 "FDwUPBQ8FDwUPBQ8FD0UOhQ+FDoUPhQ6FD4UOhQ+FDoUPxQ4FEAUOBRAFDgUQRQ2FEIUNhRDFDQU"
6247 "RBQ0FEUUMhRGFDIURxQwFEgUMBRJFC4USxQsFEwVKhVNFSgVTxQoFFEUJhRTFCQUVRUgFVcVHhVZ"
6248 "FRwVWxUaFV4VFhVhFhIWZBYOFmgWChZsMnAudCp6IoMBGIQw");
6249 todo_wine ok(match, "Figure does not match.\n");
6251 match = compare_figure(&ctx, 0, 160, 160, 160, 0xff652e89, 0, "iGIQjgEUjAEUjgEQiGIA");
6252 todo_wine ok(match, "Figure does not match.\n");
6253 match = compare_figure(&ctx, 160, 160, 160, 160, 0xff652e89, 0, "yGBQSGA+ZDxkPmDgYQAA");
6254 todo_wine ok(match, "Figure does not match.\n");
6255 match = compare_figure(&ctx, 320, 160, 160, 160, 0xff652e89, 0,
6256 "iDAQjgEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEU"
6257 "jAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEU"
6258 "jAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEU"
6259 "jAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEU"
6260 "jAEUjAEUjAEUjAEUjAEUjAEUjAEUjgEQiDAA");
6261 todo_wine ok(match, "Figure does not match.\n");
6262 match = compare_figure(&ctx, 480, 160, 160, 160, 0xff652e89, 16,
6263 "3C4obzpjQF5EWkhXFSAVVRQkFFMUJhRRFCgUTxQqFE0VKhVMFCwUSxQuFEoULhVIFDAUSBQwFUYU"
6264 "MhRGFDIURRQ0FEQUNBRDFTQVQhQ2FEIUNhRCFDYUQRQ4FEAUOBRAFDgUQBQ4FD8UOhQ+FDoUPhQ6"
6265 "FD4UOhQ+FDoUPhQ6FD0VOxQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwU"
6266 "PBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBU7FD0UOhQ+FDoUPhQ6FD4UOhQ+FDoUPhQ6FD8UOBRA"
6267 "FDgUQBQ4FEAUOBRBFDYUQhQ2FEIUNhRCFTQVQxQ0FEQUNBRFFDIURhQyFEYVMBVHFDAUSBUuFUkU"
6268 "LhRLFCwUTBUrFE0UKhRPFCgUURQmFFMUJBRVSldIWUZdQWI78i8A");
6269 todo_wine ok(match, "Figure does not match.\n");
6271 match = compare_figure(&ctx, 0, 320, 160, 160, 0xff652e89, 0, "iGIQjgEUjAEUjgEQiGIA");
6272 todo_wine ok(match, "Figure does not match.\n");
6273 match = compare_figure(&ctx, 160, 320, 160, 160, 0xff652e89, 0, "yGBQSGA+ZDxkPmDgYQAA");
6274 todo_wine ok(match, "Figure does not match.\n");
6275 match = compare_figure(&ctx, 320, 320, 160, 160, 0xff652e89, 0,
6276 "iDAQjgEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEU"
6277 "jAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEU"
6278 "jAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEU"
6279 "jAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEU"
6280 "jAEUjAEUjAEUjAEUjAEUjAEUjAEUjgEQiDAA");
6281 todo_wine ok(match, "Figure does not match.\n");
6282 match = compare_figure(&ctx, 480, 320, 160, 160, 0xff652e89, 8,
6283 "9i80ZERWUExYRV5AHCocPRY4FjwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwU"
6284 "PBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8"
6285 "FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwU"
6286 "PBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8"
6287 "FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwU"
6288 "PBQ8FDwUPBQ8FDwUPBQ8FToVPRssG0BeRFpLUFVGYzT2LwAA");
6289 todo_wine ok(match, "Figure does not match.\n");
6291 hr = ID2D1Factory_CreatePathGeometry(factory, &geometry);
6292 ok(SUCCEEDED(hr), "Failed to create path geometry, hr %#x.\n", hr);
6293 hr = ID2D1PathGeometry_Open(geometry, &sink);
6294 ok(SUCCEEDED(hr), "Failed to open geometry sink, hr %#x.\n", hr);
6296 set_point(&point, 40.0f, 160.0f);
6297 ID2D1GeometrySink_BeginFigure(sink, point, D2D1_FIGURE_BEGIN_FILLED);
6298 ID2D1GeometrySink_EndFigure(sink, D2D1_FIGURE_END_OPEN);
6300 set_point(&point, 120.0f, 160.0f);
6301 ID2D1GeometrySink_BeginFigure(sink, point, D2D1_FIGURE_BEGIN_FILLED);
6302 line_to(sink, 120.0f, 160.0f);
6303 ID2D1GeometrySink_EndFigure(sink, D2D1_FIGURE_END_OPEN);
6305 set_point(&point, 200.0f, 160.0f);
6306 ID2D1GeometrySink_BeginFigure(sink, point, D2D1_FIGURE_BEGIN_FILLED);
6307 ID2D1GeometrySink_EndFigure(sink, D2D1_FIGURE_END_CLOSED);
6309 set_point(&point, 280.0f, 160.0f);
6310 ID2D1GeometrySink_BeginFigure(sink, point, D2D1_FIGURE_BEGIN_FILLED);
6311 line_to(sink, 280.0f, 160.0f);
6312 ID2D1GeometrySink_EndFigure(sink, D2D1_FIGURE_END_CLOSED);
6314 set_point(&point, 20.0f, 480.0f);
6315 ID2D1GeometrySink_BeginFigure(sink, point, D2D1_FIGURE_BEGIN_FILLED);
6316 line_to(sink, 60.0f, 480.0f);
6317 ID2D1GeometrySink_EndFigure(sink, D2D1_FIGURE_END_OPEN);
6319 set_point(&point, 120.0f, 400.0f);
6320 ID2D1GeometrySink_BeginFigure(sink, point, D2D1_FIGURE_BEGIN_FILLED);
6321 line_to(sink, 120.0f, 560.0f);
6322 line_to(sink, 120.0f, 400.0f);
6323 line_to(sink, 120.0f, 560.0f);
6324 ID2D1GeometrySink_EndFigure(sink, D2D1_FIGURE_END_OPEN);
6326 set_point(&point, 180.0f, 480.0f);
6327 ID2D1GeometrySink_BeginFigure(sink, point, D2D1_FIGURE_BEGIN_FILLED);
6328 line_to(sink, 220.0f, 480.0f);
6329 ID2D1GeometrySink_EndFigure(sink, D2D1_FIGURE_END_CLOSED);
6331 set_point(&point, 280.0f, 400.0f);
6332 ID2D1GeometrySink_BeginFigure(sink, point, D2D1_FIGURE_BEGIN_FILLED);
6333 line_to(sink, 280.0f, 560.0f);
6334 line_to(sink, 280.0f, 400.0f);
6335 line_to(sink, 280.0f, 560.0f);
6336 ID2D1GeometrySink_EndFigure(sink, D2D1_FIGURE_END_CLOSED);
6338 set_point(&point, 20.0f, 880.0f);
6339 ID2D1GeometrySink_BeginFigure(sink, point, D2D1_FIGURE_BEGIN_FILLED);
6340 line_to(sink, 40.0f, 720.0f);
6341 line_to(sink, 60.0f, 880.0f);
6342 ID2D1GeometrySink_EndFigure(sink, D2D1_FIGURE_END_OPEN);
6344 set_point(&point, 100.0f, 720.0f);
6345 ID2D1GeometrySink_BeginFigure(sink, point, D2D1_FIGURE_BEGIN_FILLED);
6346 line_to(sink, 120.0f, 880.0f);
6347 line_to(sink, 140.0f, 720.0f);
6348 ID2D1GeometrySink_EndFigure(sink, D2D1_FIGURE_END_OPEN);
6350 set_point(&point, 180.0f, 880.0f);
6351 ID2D1GeometrySink_BeginFigure(sink, point, D2D1_FIGURE_BEGIN_FILLED);
6352 line_to(sink, 200.0f, 720.0f);
6353 line_to(sink, 220.0f, 880.0f);
6354 ID2D1GeometrySink_EndFigure(sink, D2D1_FIGURE_END_CLOSED);
6356 set_point(&point, 260.0f, 720.0f);
6357 ID2D1GeometrySink_BeginFigure(sink, point, D2D1_FIGURE_BEGIN_FILLED);
6358 line_to(sink, 280.0f, 880.0f);
6359 line_to(sink, 300.0f, 720.0f);
6360 ID2D1GeometrySink_EndFigure(sink, D2D1_FIGURE_END_CLOSED);
6362 ID2D1GeometrySink_SetFillMode(sink, D2D1_FILL_MODE_ALTERNATE);
6363 hr = ID2D1GeometrySink_Close(sink);
6364 ok(SUCCEEDED(hr), "Failed to close geometry sink, hr %#x.\n", hr);
6365 ID2D1GeometrySink_Release(sink);
6367 ID2D1RenderTarget_BeginDraw(rt);
6368 ID2D1RenderTarget_Clear(rt, &color);
6369 ID2D1RenderTarget_DrawGeometry(rt, (ID2D1Geometry *)geometry, (ID2D1Brush *)brush, 5.0f, NULL);
6370 hr = ID2D1RenderTarget_EndDraw(rt, NULL, NULL);
6371 ok(SUCCEEDED(hr), "Failed to end draw, hr %#x.\n", hr);
6372 ID2D1PathGeometry_Release(geometry);
6374 match = compare_figure(&ctx, 0, 0, 160, 160, 0xff652e89, 0, "");
6375 ok(match, "Figure does not match.\n");
6376 match = compare_figure(&ctx, 160, 0, 160, 160, 0xff652e89, 0, "");
6377 ok(match, "Figure does not match.\n");
6378 match = compare_figure(&ctx, 320, 0, 160, 160, 0xff652e89, 0, "");
6379 ok(match, "Figure does not match.\n");
6380 match = compare_figure(&ctx, 480, 0, 160, 160, 0xff652e89, 0, "q2MKlgEKq2MA");
6381 todo_wine ok(match, "Figure does not match.\n");
6383 match = compare_figure(&ctx, 0, 160, 160, 160, 0xff652e89, 0, "iGNQUFCIYwAA");
6384 ok(match, "Figure does not match.\n");
6385 match = compare_figure(&ctx, 160, 160, 160, 160, 0xff652e89, 0,
6386 "qyIKlgEKlgEKlgEKlgEKlgEKlgEKlgEKlgEKlgEKlgEKlgEKlgEKlgEKlgEKlgEKlgEKlgEKlgEK"
6387 "lgEKlgEKlgEKlgEKlgEKlgEKlgEKlgEKlgEKlgEKlgEKlgEKlgEKlgEKlgEKlgEKlgEKlgEKlgEK"
6388 "lgEKlgEKlgEKlgEKlgEKlgEKlgEKlgEKlgEKlgEKlgEKlgEKlgEKlgEKlgEKQQpLCkEKSwqWAQqW"
6389 "AQqWAQqWAQqWAQqWAQqWAQqWAQqWAQqWAQqWAQqWAQqWAQqWAQqWAQqWAQqWAQqWAQqWAQqWAQqW"
6390 "AQqWAQqWAQqWAQqWAQqWAQqWAQqWAQqWAQqWAQqWAQqWAQqWAQqWAQqWAQqWAQqWAQqWAQqWAQqW"
6391 "AQqWAQqWAQqWAQqWAQqWAQqWAQqWAQqWAQqWAQqWAQrLIwAA");
6392 ok(match, "Figure does not match.\n");
6393 match = compare_figure(&ctx, 320, 160, 160, 160, 0xff652e89, 0, "4GLAAuBi");
6394 ok(match, "Figure does not match.\n");
6395 match = compare_figure(&ctx, 480, 160, 160, 160, 0xff652e89, 0,
6396 "qyIKlgEKlgEKlgEKlgEKlgEKlgEKlgEKlgEKlgEKlgEKlgEKlgEKlgEKlgEKlgEKlgEKlgEKlgEK"
6397 "lgEKlgEKlgEKlgEKlgEKlgEKlgEKlgEKlgEKlgEKlgEKlgEKlgEKlgEKlgEKlgEKlgEKlgEKlgEK"
6398 "lgEKlgEKlgEKlgEKlgEKlgEKlgEKlgEKlgEKlgEKlgEKlgEKlgEKlgEKSwpBCksKQQqWAQqWAQqW"
6399 "AQqWAQqWAQqWAQqWAQqWAQqWAQqWAQqWAQqWAQqWAQqWAQqWAQqWAQqWAQqWAQqWAQqWAQqWAQqW"
6400 "AQqWAQqWAQqWAQqWAQqWAQqWAQqWAQqWAQqWAQqWAQqWAQqWAQqWAQqWAQqWAQqWAQqWAQqWAQqW"
6401 "AQqWAQqWAQqWAQqWAQqWAQqWAQqWAQqWAQqWAQqWAQrLIwAA");
6402 ok(match, "Figure does not match.\n");
6404 match = compare_figure(&ctx, 0, 320, 160, 160, 0xff652e89, 0,
6405 "rycCngECnQEEnAEEmwEGmgEGmQEImAEIlwEKlgEKlQEMlAEMkwEOkgEOkQEQkAEQjwESjgESjQEU"
6406 "jAEUiwEKAgqKAQoCCokBCgQKiAEKBAqHAQoGCoYBCgYKhQEKCAqEAQoICoMBCgoKggEKCgqBAQoM"
6407 "CoABCgwKfwoOCn4KDgp9ChAKfAoQCnsKEgp6ChIKeQoUCngKFAp3ChYKdgoWCnUKGAp0ChgKcwoa"
6408 "CnIKGgpxChwKcAocCm8KHgpuCh4KbQogCmwKIAprCiIKagoiCmkKJApoCiQKZwomCmYKJgplCigK"
6409 "ZAooCmMKKgpiCioKYQosCmAKLApfCi4KXgouCl0KMApcCjAKWwoyCloKMgpZCjQKWAo0ClcKNgpW"
6410 "CjYKVQo4ClQKOApTCjoKUgo6ClEKPApQCjwKTwo+Ck4KPgpNCkAKTApACksKQgpKCkIKSQpECkgK"
6411 "RApHCkYKozIA");
6412 ok(match, "Figure does not match.\n");
6413 match = compare_figure(&ctx, 160, 320, 160, 160, 0xff652e89, 0,
6414 "ozIKRgpHCkQKSApECkkKQgpKCkIKSwpACkwKQApNCj4KTgo+Ck8KPApQCjwKUQo6ClIKOgpTCjgK"
6415 "VAo4ClUKNgpWCjYKVwo0ClgKNApZCjIKWgoyClsKMApcCjAKXQouCl4KLgpfCiwKYAosCmEKKgpi"
6416 "CioKYwooCmQKKAplCiYKZgomCmcKJApoCiQKaQoiCmoKIgprCiAKbAogCm0KHgpuCh4KbwocCnAK"
6417 "HApxChoKcgoaCnMKGAp0ChgKdQoWCnYKFgp3ChQKeAoUCnkKEgp6ChIKewoQCnwKEAp9Cg4KfgoO"
6418 "Cn8KDAqAAQoMCoEBCgoKggEKCgqDAQoICoQBCggKhQEKBgqGAQoGCocBCgQKiAEKBAqJAQoCCooB"
6419 "CgIKiwEUjAEUjQESjgESjwEQkAEQkQEOkgEOkwEMlAEMlQEKlgEKlwEImAEImQEGmgEGmwEEnAEE"
6420 "nQECngECrycA");
6421 ok(match, "Figure does not match.\n");
6422 match = compare_figure(&ctx, 320, 320, 160, 160, 0xff652e89, 0,
6423 "rycCngECnQEEnAEEmwEGmgEGmQEImAEIlwEKlgEKlQEMlAEMkwEOkgEOkQEQkAEQjwESjgESjQEU"
6424 "jAEUiwEKAgqKAQoCCokBCgQKiAEKBAqHAQoGCoYBCgYKhQEKCAqEAQoICoMBCgoKggEKCgqBAQoM"
6425 "CoABCgwKfwoOCn4KDgp9ChAKfAoQCnsKEgp6ChIKeQoUCngKFAp3ChYKdgoWCnUKGAp0ChgKcwoa"
6426 "CnIKGgpxChwKcAocCm8KHgpuCh4KbQogCmwKIAprCiIKagoiCmkKJApoCiQKZwomCmYKJgplCigK"
6427 "ZAooCmMKKgpiCioKYQosCmAKLApfCi4KXgouCl0KMApcCjAKWwoyCloKMgpZCjQKWAo0ClcKNgpW"
6428 "CjYKVQo4ClQKOApTCjoKUgo6ClEKPApQCjwKTwo+Ck4KPgpNCkAKTApACksKQgpKCkIKSQpECkgK"
6429 "RApHWkZagzEA");
6430 ok(match, "Figure does not match.\n");
6431 match = compare_figure(&ctx, 480, 320, 160, 160, 0xff652e89, 0,
6432 "gzFaRlpHCkQKSApECkkKQgpKCkIKSwpACkwKQApNCj4KTgo+Ck8KPApQCjwKUQo6ClIKOgpTCjgK"
6433 "VAo4ClUKNgpWCjYKVwo0ClgKNApZCjIKWgoyClsKMApcCjAKXQouCl4KLgpfCiwKYAosCmEKKgpi"
6434 "CioKYwooCmQKKAplCiYKZgomCmcKJApoCiQKaQoiCmoKIgprCiAKbAogCm0KHgpuCh4KbwocCnAK"
6435 "HApxChoKcgoaCnMKGAp0ChgKdQoWCnYKFgp3ChQKeAoUCnkKEgp6ChIKewoQCnwKEAp9Cg4KfgoO"
6436 "Cn8KDAqAAQoMCoEBCgoKggEKCgqDAQoICoQBCggKhQEKBgqGAQoGCocBCgQKiAEKBAqJAQoCCooB"
6437 "CgIKiwEUjAEUjQESjgESjwEQkAEQkQEOkgEOkwEMlAEMlQEKlgEKlwEImAEImQEGmgEGmwEEnAEE"
6438 "nQECngECrycA");
6439 ok(match, "Figure does not match.\n");
6441 set_rect(&rect, 20.0f, 80.0f, 60.0f, 240.0f);
6442 hr = ID2D1Factory_CreateRectangleGeometry(factory, &rect, &rect_geometry[0]);
6443 ok(SUCCEEDED(hr), "Failed to create geometry, hr %#x.\n", hr);
6445 set_rect(&rect, -1.0f, -1.0f, 1.0f, 1.0f);
6446 hr = ID2D1Factory_CreateRectangleGeometry(factory, &rect, &rect_geometry[1]);
6447 ok(SUCCEEDED(hr), "Failed to create geometry, hr %#x.\n", hr);
6449 set_matrix_identity(&matrix);
6450 translate_matrix(&matrix, 160.0f, 640.0f);
6451 scale_matrix(&matrix, 40.0f, 160.0f);
6452 rotate_matrix(&matrix, M_PI / -5.0f);
6453 hr = ID2D1Factory_CreateTransformedGeometry(factory,
6454 (ID2D1Geometry *)rect_geometry[1], &matrix, &transformed_geometry[0]);
6455 ok(SUCCEEDED(hr), "Failed to create geometry, hr %#x.\n", hr);
6457 set_matrix_identity(&matrix);
6458 scale_matrix(&matrix, 0.5f, 1.0f);
6459 translate_matrix(&matrix, -80.0f, 0.0f);
6460 hr = ID2D1Factory_CreateTransformedGeometry(factory,
6461 (ID2D1Geometry *)transformed_geometry[0], &matrix, &transformed_geometry[1]);
6462 ok(SUCCEEDED(hr), "Failed to create geometry, hr %#x.\n", hr);
6464 set_matrix_identity(&matrix);
6465 rotate_matrix(&matrix, M_PI / 2.0f);
6466 translate_matrix(&matrix, 80.0f, -320.0f);
6467 scale_matrix(&matrix, 2.0f, 0.25f);
6468 hr = ID2D1Factory_CreateTransformedGeometry(factory,
6469 (ID2D1Geometry *)transformed_geometry[1], &matrix, &transformed_geometry[2]);
6470 ok(SUCCEEDED(hr), "Failed to create geometry, hr %#x.\n", hr);
6472 ID2D1RenderTarget_BeginDraw(rt);
6473 ID2D1RenderTarget_Clear(rt, &color);
6474 ID2D1RenderTarget_DrawGeometry(rt, (ID2D1Geometry *)rect_geometry[0], (ID2D1Brush *)brush, 10.0f, NULL);
6475 ID2D1RenderTarget_DrawGeometry(rt, (ID2D1Geometry *)transformed_geometry[0], (ID2D1Brush *)brush, 10.0f, NULL);
6476 ID2D1RenderTarget_DrawGeometry(rt, (ID2D1Geometry *)transformed_geometry[1], (ID2D1Brush *)brush, 5.0f, NULL);
6477 ID2D1RenderTarget_DrawGeometry(rt, (ID2D1Geometry *)transformed_geometry[2], (ID2D1Brush *)brush, 15.0f, NULL);
6478 hr = ID2D1RenderTarget_EndDraw(rt, NULL, NULL);
6479 ok(SUCCEEDED(hr), "Failed to end draw, hr %#x.\n", hr);
6480 ID2D1TransformedGeometry_Release(transformed_geometry[2]);
6481 ID2D1TransformedGeometry_Release(transformed_geometry[1]);
6482 ID2D1TransformedGeometry_Release(transformed_geometry[0]);
6483 ID2D1RectangleGeometry_Release(rect_geometry[1]);
6484 ID2D1RectangleGeometry_Release(rect_geometry[0]);
6486 match = compare_figure(&ctx, 0, 0, 160, 160, 0xff652e89, 0,
6487 "vi5kPGQ8ZDxkPGQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwU"
6488 "PBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8"
6489 "FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwU"
6490 "PBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8"
6491 "FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwU"
6492 "PBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8ZDxkPGQ8ZDxk3i8A");
6493 ok(match, "Figure does not match.\n");
6494 match = compare_figure(&ctx, 160, 0, 320, 160, 0xff652e89, 32,
6495 "8XYGtQIOrAIXpAIfmwIokwIwigI4gwJA+gFJ8gFR6QEzAiXhATMKJdgBMxMl0AEzGyXHATMkJb8B"
6496 "MysmtgEzNCWvATM8JaYBM0UlngEzTSWVATNWJY0BM14lhAEzZyV8M28lczN4JWszgAElYjOIASZa"
6497 "M5ABJVgtmQElWCWhASVYJaEBJVgloQElWCWhASVYJaEBJVgloQElWCWhASVYJaEBJVglmQEtWCWQ"
6498 "ATNaJogBM2IlgAEzayV4M3MlbzN8JWczhAElXjONASVWM5UBJU0zngElRTOmASU8M68BJTQztgEm"
6499 "KzO/ASUkM8cBJRsz0AElEzPYASUKM+EBJQIz6QFR8gFJ+gFAgwI4igIwkwIomwIfpAIXrAIOtQIG"
6500 "8XYA");
6501 ok(match, "Figure does not match.\n");
6502 match = compare_figure(&ctx, 0, 160, 160, 320, 0xff652e89, 32,
6503 "ujEBngECnQEDnQEEmwEFmgEHmQEHmAEIlwEKlgEKlQELlAENkwENkgEOkQEQjwERjwESjQETjAEU"
6504 "jAEKAQqKAQoCCokBCgMKiQEKBAqHAQoFCoYBCgYKhgEKBwqEAQoICoMBCgkKgwEKCgqBAQoLCoAB"
6505 "Cg0KfgsNCn4KDgp9ChAKewsQCnsKEQp6ChMKeAoUCngKFAp3ChYKdQoXCnUKGApzChkKcgoaCnIK"
6506 "GwpwChwKbwodCm4LHgptCh8KbAogCmsLIQpqCiIKaQokCmcKJQpnCiUKZgonCmQKKApkCigKYwoq"
6507 "CmEKKwphCisKYAotCl4KLgpdCy8KXAowClsKMQpaCzIKWQozClgKNApXCjYKVgo2ClUKNwpUCjkK"
6508 "Uwo5ClIKOwpQCjwKTws8Ck8KPgpNCj8KTAs/CkwKQQpKCkIKSQtCCkkKRApHCkUKRgpHCkUKRwpE"
6509 "CkgKQwpKCkIKSgpBCksKQApNCj4LTQo+Ck4KPQpQCjsLUAo7ClIKOQpTCjgLUwo4ClUKNgpWCjUK"
6510 "Vwo1ClgKMwpZCjQKWAo0ClkKMwpZCjQKWQozClkKMwpZCjQKWQozClkKMwpZCjQKWQozClkKNApY"
6511 "CjQKWQozClkKNApZCjMKWQozClkKNApZCjMKWQozClkKNApZCjMKWQo0ClgKNApZCjMKWQo0ClkK"
6512 "MwpZCjMKWQo0ClkKMwpZCjMKWQo0ClkKMwpZCjQKWAo0ClkKMwpYCjUKVwo1ClYKNgpVCjgKUws4"
6513 "ClMKOQpSCjsKUAs7ClAKPQpOCj4KTQs+Ck0KQApLCkEKSgpCCkoKQwpICkQKRwpFCkcKRgpFCkcK"
6514 "RApJCkILSQpCCkoKQQpMCj8LTAo/Ck0KPgpPCjwLTwo8ClAKOwpSCjkKUwo5ClQKNwpVCjYKVgo2"
6515 "ClcKNApYCjMKWQoyC1oKMQpbCjAKXAovC10KLgpeCi0KYAorCmEKKwphCioKYwooCmQKKApkCicK"
6516 "ZgolCmcKJQpnCiQKaQoiCmoKIQtrCiAKbAofCm0KHgtuCh0KbwocCnAKGwpyChoKcgoZCnMKGAp1"
6517 "ChcKdQoWCncKFAp4ChQKeAoTCnoKEQp7ChALewoQCn0KDgp+Cg0LfgoNCoABCgsKgQEKCgqDAQoJ"
6518 "CoMBCggKhAEKBwqGAQoGCoYBCgUKhwEKBAqJAQoDCokBCgIKigEKAQqMARSMARONARKPARGPARCR"
6519 "AQ6SAQ2TAQ2UAQuVAQqWAQqXAQiYAQeZAQeaAQWbAQSdAQOdAQKeAQG6MQAA");
6520 ok(match, "Figure does not match.\n");
6521 match = compare_figure(&ctx, 160, 160, 320, 320, 0xff652e89, 64,
6522 "82ICvQIEugIHuAIJtgIKtAINsgIPsAIRrQITrAIVqQIYpwIZpgIbowIeoQIgnwIhnQIkmwImmAIp"
6523 "lgIVARSVAhUDFJICFQUVkAIVBxSPAhUJFIwCFQwUigIVDRWHAhYPFIYCFRIUhAIVFBSBAhUWFf8B"
6524 "FRgU/gEVGhT7ARUcFfkBFR4U9wEWIBT1ARUjFPMBFSQV8AEVJxTvARUpFOwBFisU6gEVLRXoARUv"
6525 "FOYBFjEU5AEVMxXiARU1FOABFTgU3gEVOhTbARY7FdkBFT4U2AEVQBTVARZCFNMBFUQV0QEVRhTP"
6526 "ARVJFM0BFUoVygEWTBTJARVPFMcBFVEUxAEVUxXCARVVFMEBFVcUvgEVWRW8ARVbFbkBFl0UuAEV"
6527 "YBS2ARVhFbMBFWQUsgEVZhSwARVoFK0BFWoVqwEVbBSpARZuFKcBFXAVpQEVchWiARV1FKEBFXcU"
6528 "nwEVeBWcARV7FJsBFX0UmAEWfxSWARWBARWUARWDARSSARWGARSQARWHARWOARWJARWLARWMARSK"
6529 "ARWOARSHARaPARWFARWSARSEARWUARSBARWXARR/FZgBFX0VmgEUexWdARR5FZ4BFXYWoAEVdBWj"
6530 "ARRzFaUBFHAVpwEVbhWpARRtFasBFGoVrgEUaBWvARVmFbEBFGcUsgEUZxSxARVmFbEBFWYUsgEU"
6531 "ZxSyARRnFLEBFWYVsQEUZxSyARRnFLIBFGcUsQEVZhWxARRnFLIBFGcUsQEVZhWxARVmFLIBFGcU"
6532 "sgEUZxSxARVmFbEBFGcUsgEUZxSyARRmFbEBFWYVsQEUZxSyARRnFLEBFWYVsQEUZxSyARRnFLIB"
6533 "FGcUsQEVZhWxARRnFLIBFGcUsgEUZhWxARVmFbEBFGcUsgEUZxSxARVmFa8BFWgUrgEVahSrARVt"
6534 "FKkBFW4VpwEVcBSlARVzFKMBFXQVoAEWdhWeARV5FJ0BFXsUmgEVfRWYARV/FJcBFYEBFJQBFYQB"
6535 "FJIBFYUBFY8BFocBFI4BFYoBFIwBFYsBFYkBFY4BFYcBFZABFIYBFZIBFIMBFZQBFYEBFZYBFH8W"
6536 "mAEUfRWbARR7FZwBFXgVnwEUdxWhARR1FaIBFXIVpQEVcBWnARRuFqkBFGwVqwEVahWtARRoFbAB"
6537 "FGYVsgEUZBWzARVhFbYBFGAVuAEUXRa5ARVbFbwBFVkVvgEUVxXBARRVFcIBFVMVxAEUURXHARRP"
6538 "FckBFEwWygEVShXNARRJFc8BFEYV0QEVRBXTARRCFtUBFEAV2AEUPhXZARU7FtsBFDoV3gEUOBXg"
6539 "ARQ1FeIBFTMV5AEUMRbmARQvFegBFS0V6gEUKxbsARQpFe8BFCcV8AEVJBXzARQjFfUBFCAW9wEU"
6540 "HhX5ARUcFfsBFBoV/gEUGBX/ARUWFYECFBQVhAIUEhWGAhQPFocCFQ0VigIUDBWMAhQJFY8CFAcV"
6541 "kAIVBRWSAhQDFZUCFAEVlgIpmAImmwIknQIhnwIgoQIeowIbpgIZpwIYqQIVrAITrQIRsAIPsgIN"
6542 "tAIKtgIJuAIHugIEvQIC82IA");
6543 ok(match, "Figure does not match.\n");
6545 hr = ID2D1Factory_CreatePathGeometry(factory, &geometry);
6546 ok(SUCCEEDED(hr), "Failed to create path geometry, hr %#x.\n", hr);
6547 hr = ID2D1PathGeometry_Open(geometry, &sink);
6548 ok(SUCCEEDED(hr), "Failed to open geometry sink, hr %#x.\n", hr);
6550 set_point(&point, 20.0f, 80.0f);
6551 ID2D1GeometrySink_BeginFigure(sink, point, D2D1_FIGURE_BEGIN_HOLLOW);
6552 quadratic_to(sink, 40.0f, 80.0f, 60.0f, 80.0f);
6553 quadratic_to(sink, 60.0f, 160.0f, 60.0f, 240.0f);
6554 quadratic_to(sink, 40.0f, 240.0f, 20.0f, 240.0f);
6555 quadratic_to(sink, 20.0f, 160.0f, 20.0f, 80.0f);
6556 ID2D1GeometrySink_EndFigure(sink, D2D1_FIGURE_END_CLOSED);
6558 set_point(&point, 100.0f, 80.0f);
6559 ID2D1GeometrySink_BeginFigure(sink, point, D2D1_FIGURE_BEGIN_HOLLOW);
6560 quadratic_to(sink, 105.0f, 80.0f, 140.0f, 80.0f);
6561 quadratic_to(sink, 140.0f, 100.0f, 140.0f, 240.0f);
6562 quadratic_to(sink, 135.0f, 240.0f, 100.0f, 240.0f);
6563 quadratic_to(sink, 100.0f, 220.0f, 100.0f, 80.0f);
6564 ID2D1GeometrySink_EndFigure(sink, D2D1_FIGURE_END_CLOSED);
6566 set_point(&point, 180.0f, 80.0f);
6567 ID2D1GeometrySink_BeginFigure(sink, point, D2D1_FIGURE_BEGIN_HOLLOW);
6568 quadratic_to(sink, 215.0f, 80.0f, 220.0f, 80.0f);
6569 quadratic_to(sink, 220.0f, 220.0f, 220.0f, 240.0f);
6570 quadratic_to(sink, 185.0f, 240.0f, 180.0f, 240.0f);
6571 quadratic_to(sink, 180.0f, 100.0f, 180.0f, 80.0f);
6572 ID2D1GeometrySink_EndFigure(sink, D2D1_FIGURE_END_CLOSED);
6574 set_point(&point, 260.0f, 80.0f);
6575 ID2D1GeometrySink_BeginFigure(sink, point, D2D1_FIGURE_BEGIN_HOLLOW);
6576 quadratic_to(sink, 280.0f, 80.0f, 300.0f, 80.0f);
6577 quadratic_to(sink, 300.0f, 160.0f, 300.0f, 240.0f);
6578 quadratic_to(sink, 280.0f, 240.0f, 260.0f, 240.0f);
6579 quadratic_to(sink, 260.0f, 160.0f, 260.0f, 80.0f);
6580 ID2D1GeometrySink_EndFigure(sink, D2D1_FIGURE_END_OPEN);
6582 set_point(&point, 20.0f, 400.0f);
6583 ID2D1GeometrySink_BeginFigure(sink, point, D2D1_FIGURE_BEGIN_HOLLOW);
6584 quadratic_to(sink, 40.0f, 420.0f, 60.0f, 400.0f);
6585 quadratic_to(sink, 55.0f, 480.0f, 60.0f, 560.0f);
6586 quadratic_to(sink, 40.0f, 540.0f, 20.0f, 560.0f);
6587 quadratic_to(sink, 25.0f, 480.0f, 20.0f, 400.0f);
6588 ID2D1GeometrySink_EndFigure(sink, D2D1_FIGURE_END_CLOSED);
6590 set_point(&point, 100.0f, 400.0f);
6591 ID2D1GeometrySink_BeginFigure(sink, point, D2D1_FIGURE_BEGIN_HOLLOW);
6592 quadratic_to(sink, 105.0f, 420.0f, 140.0f, 400.0f);
6593 quadratic_to(sink, 135.0f, 420.0f, 140.0f, 560.0f);
6594 quadratic_to(sink, 135.0f, 540.0f, 100.0f, 560.0f);
6595 quadratic_to(sink, 105.0f, 540.0f, 100.0f, 400.0f);
6596 ID2D1GeometrySink_EndFigure(sink, D2D1_FIGURE_END_CLOSED);
6598 set_point(&point, 180.0f, 400.0f);
6599 ID2D1GeometrySink_BeginFigure(sink, point, D2D1_FIGURE_BEGIN_HOLLOW);
6600 quadratic_to(sink, 215.0f, 420.0f, 220.0f, 400.0f);
6601 quadratic_to(sink, 215.0f, 540.0f, 220.0f, 560.0f);
6602 quadratic_to(sink, 185.0f, 540.0f, 180.0f, 560.0f);
6603 quadratic_to(sink, 185.0f, 420.0f, 180.0f, 400.0f);
6604 ID2D1GeometrySink_EndFigure(sink, D2D1_FIGURE_END_CLOSED);
6606 set_point(&point, 260.0f, 400.0f);
6607 ID2D1GeometrySink_BeginFigure(sink, point, D2D1_FIGURE_BEGIN_HOLLOW);
6608 quadratic_to(sink, 280.0f, 420.0f, 300.0f, 400.0f);
6609 quadratic_to(sink, 295.0f, 480.0f, 300.0f, 560.0f);
6610 quadratic_to(sink, 280.0f, 540.0f, 260.0f, 560.0f);
6611 quadratic_to(sink, 265.0f, 480.0f, 260.0f, 400.0f);
6612 ID2D1GeometrySink_EndFigure(sink, D2D1_FIGURE_END_OPEN);
6614 set_point(&point, 20.0f, 720.0f);
6615 ID2D1GeometrySink_BeginFigure(sink, point, D2D1_FIGURE_BEGIN_HOLLOW);
6616 quadratic_to(sink, 40.0f, 700.0f, 60.0f, 720.0f);
6617 quadratic_to(sink, 65.0f, 800.0f, 60.0f, 880.0f);
6618 quadratic_to(sink, 40.0f, 900.0f, 20.0f, 880.0f);
6619 quadratic_to(sink, 15.0f, 800.0f, 20.0f, 720.0f);
6620 ID2D1GeometrySink_EndFigure(sink, D2D1_FIGURE_END_CLOSED);
6622 set_point(&point, 100.0f, 720.0f);
6623 ID2D1GeometrySink_BeginFigure(sink, point, D2D1_FIGURE_BEGIN_HOLLOW);
6624 quadratic_to(sink, 105.0f, 700.0f, 140.0f, 720.0f);
6625 quadratic_to(sink, 145.0f, 740.0f, 140.0f, 880.0f);
6626 quadratic_to(sink, 135.0f, 900.0f, 100.0f, 880.0f);
6627 quadratic_to(sink, 95.0f, 860.0f, 100.0f, 720.0f);
6628 ID2D1GeometrySink_EndFigure(sink, D2D1_FIGURE_END_CLOSED);
6630 set_point(&point, 180.0f, 720.0f);
6631 ID2D1GeometrySink_BeginFigure(sink, point, D2D1_FIGURE_BEGIN_HOLLOW);
6632 quadratic_to(sink, 215.0f, 700.0f, 220.0f, 720.0f);
6633 quadratic_to(sink, 225.0f, 860.0f, 220.0f, 880.0f);
6634 quadratic_to(sink, 185.0f, 900.0f, 180.0f, 880.0f);
6635 quadratic_to(sink, 175.0f, 740.0f, 180.0f, 720.0f);
6636 ID2D1GeometrySink_EndFigure(sink, D2D1_FIGURE_END_CLOSED);
6638 set_point(&point, 260.0f, 720.0f);
6639 ID2D1GeometrySink_BeginFigure(sink, point, D2D1_FIGURE_BEGIN_HOLLOW);
6640 quadratic_to(sink, 280.0f, 700.0f, 300.0f, 720.0f);
6641 quadratic_to(sink, 305.0f, 800.0f, 300.0f, 880.0f);
6642 quadratic_to(sink, 280.0f, 900.0f, 260.0f, 880.0f);
6643 quadratic_to(sink, 255.0f, 800.0f, 260.0f, 720.0f);
6644 ID2D1GeometrySink_EndFigure(sink, D2D1_FIGURE_END_OPEN);
6646 hr = ID2D1GeometrySink_Close(sink);
6647 ok(SUCCEEDED(hr), "Failed to close geometry sink, hr %#x.\n", hr);
6648 ID2D1GeometrySink_Release(sink);
6650 ID2D1RenderTarget_BeginDraw(rt);
6651 ID2D1RenderTarget_Clear(rt, &color);
6652 ID2D1RenderTarget_DrawGeometry(rt, (ID2D1Geometry *)geometry, (ID2D1Brush *)brush, 10.0f, NULL);
6653 hr = ID2D1RenderTarget_EndDraw(rt, NULL, NULL);
6654 ok(SUCCEEDED(hr), "Failed to end draw, hr %#x.\n", hr);
6655 ID2D1PathGeometry_Release(geometry);
6657 match = compare_figure(&ctx, 0, 0, 160, 160, 0xff652e89, 0,
6658 "vi5kPGQ8ZDxkPGQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwU"
6659 "PBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8"
6660 "FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwU"
6661 "PBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8"
6662 "FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwU"
6663 "PBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8ZDxkPGQ8ZDxk3i8A");
6664 ok(match, "Figure does not match.\n");
6665 match = compare_figure(&ctx, 160, 0, 160, 160, 0xff652e89, 0,
6666 "vi5kPGQ8ZDxkPGQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwU"
6667 "PBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8"
6668 "FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwU"
6669 "PBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8"
6670 "FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwU"
6671 "PBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8ZDxkPGQ8ZDxk3i8A");
6672 ok(match, "Figure does not match.\n");
6673 match = compare_figure(&ctx, 320, 0, 160, 160, 0xff652e89, 0,
6674 "vi5kPGQ8ZDxkPGQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwU"
6675 "PBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8"
6676 "FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwU"
6677 "PBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8"
6678 "FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwU"
6679 "PBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8ZDxkPGQ8ZDxk3i8A");
6680 ok(match, "Figure does not match.\n");
6681 match = compare_figure(&ctx, 480, 0, 160, 160, 0xff652e89, 0,
6682 "yC5aRlpGWjxkPGQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwU"
6683 "PBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8"
6684 "FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwU"
6685 "PBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8"
6686 "FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwU"
6687 "PBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8ZDxkPGQ8ZDxk3i8A");
6688 ok(match, "Figure does not match.\n");
6690 match = compare_figure(&ctx, 0, 160, 160, 160, 0xff652e89, 64,
6691 "3SoDYAM6B1gHOgtQCzoPSA87EkASPBc2FzwcLBw8IiAiPWI+Yj5iPhQBOAEUPhQKJgoUPxQ4FEAU"
6692 "OBRAFDgUQBQ4FEAUOBRBFDYUQhQ2FEIUNhRCFDYUQhQ2FEIUNhRDFDQURBQ0FEQUNBREFDQURBQ0"
6693 "FEQUNBREFDQURBQ0FEQUNBREFDQURRQyFEYUMhRGFDIURhQyFEYUMhRGFDIURhQyFEYUMhRGFDIU"
6694 "RhQyFEYUMhRGFDIURhQyFEYUMhRGFDIURhQyFEYUMhRGFDIURhQyFEYUMhRGFDIURhQyFEYUMhRG"
6695 "FDIURRQ0FEQUNBREFDQURBQ0FEQUNBREFDQURBQ0FEQUNBREFDQURBQ0FEMUNhRCFDYUQhQ2FEIU"
6696 "NhRCFDYUQhQ2FEEUOBRAFDgUQBQ4FEAUOBRAFDgUPxQKJgoUPhQBOAEUPmI+Yj5iPSIgIjwcLBw8"
6697 "FzYXPBJAEjsPSA86C1ALOgdYBzoDYAPdKgAA");
6698 ok(match, "Figure does not match.\n");
6699 match = compare_figure(&ctx, 160, 160, 160, 160, 0xff652e89, 1024,
6700 "uxUBnwECngEDnQEEnAEFmwEGmwEGmgEHmQEImAEJlwEKlgELlQEMlQEMlAENkwEOkgEPkQEQkAER"
6701 "VQQ2Ek0KOBJFEDkTPRY6FDUcOxUrJDwYHi09Yj5iP2BAQwkUQDgUFEAUOBRAFDcUQRQ3FEEUNxRC"
6702 "FDYUQhQ2FEIUNhRCFDUUQxQ1FEMUNRRDFDUUQxQ1FEQUNBREFDQURBQ0FEQUNBREFDQURBQ0FEQU"
6703 "NBREFDQURBQ0FEQUNBRFFDMURRQzFEUUMxRFFDMURRQzFEUUMxRFFDMURRQzFEUUMxRFFDMURRQ0"
6704 "FEQUNBRFFDMURRQzFEUUMxRFFDMURRQzFEUUMxRFFDMURRQzFEUUMxRFFDMURRQ0FEQUNBREFDQU"
6705 "RBQ0FEQUNBREFDQURBQ0FEQUNBREFDQURBQ0FEQUNRRDFDUUQxQ1FEMUNRRDFDUUQhQ2FEIUNhRC"
6706 "FDYUQhQ3FEEUNxRBFDcUQBQ4FEAUFDhAFAlDQGA/Yj5iPS0eGDwkKxU7HDUUOhY9EzkQRRI4Ck0S"
6707 "NgRVEZABEJEBD5IBDpMBDZQBDJUBDJUBC5YBCpcBCZgBCJkBB5oBBpsBBpsBBZwBBJ0BA54BAp8B"
6708 "AbsV");
6709 ok(match, "Figure does not match.\n");
6710 match = compare_figure(&ctx, 320, 160, 160, 160, 0xff652e89, 1024,
6711 "pBYBngECnQEDnAEEmwEFmgEGmQEGmQEHmAEIlwEJlgEKlQELlAEMkwEMkwENkgEOkQEPkAEQNgRV"
6712 "ETcKTRI4EEUSOhY9EzscNRQ8JCsVPS0eGD5iPmI/YEAUCUNAFBQ4QBQ4FEEUNxRBFDcUQRQ3FEEU"
6713 "NhRCFDYUQhQ2FEMUNRRDFDUUQxQ1FEMUNRRDFDUUQxQ0FEQUNBREFDQURBQ0FEQUNBREFDQURBQ0"
6714 "FEQUNBREFDQURBQ0FEQUMxRFFDMURRQzFEUUMxRFFDMURRQzFEUUMxRFFDMURRQzFEUUMxREFDQU"
6715 "RBQ0FEQUMxRFFDMURRQzFEUUMxRFFDMURRQzFEUUMxRFFDMURRQzFEUUMxREFDQURBQ0FEQUNBRE"
6716 "FDQURBQ0FEQUNBREFDQURBQ0FEQUNBREFDQUQxQ1FEMUNRRDFDUUQxQ1FEMUNRRDFDYUQhQ2FEIU"
6717 "NhRBFDcUQRQ3FEEUNxRBFDgUQDgUFEBDCRRAYD9iPmI+GB4tPRUrJDwUNRw7Ez0WOhJFEDgSTQo3"
6718 "EVUENhCQAQ+RAQ6SAQ2TAQyTAQyUAQuVAQqWAQmXAQiYAQeZAQaZAQaaAQWbAQScAQOdAQKeAQGk"
6719 "FgAA");
6720 ok(match, "Figure does not match.\n");
6721 match = compare_figure(&ctx, 480, 160, 160, 160, 0xff652e89, 64,
6722 "wCsDmQEHlQELkQEPSwJAEkgLNhc8HCwcPCIgIj1iPmI+Yj4UATgBFD4UCiYKFD8UOBRAFDgUQBQ4"
6723 "FEAUOBRAFDgUQRQ2FEIUNhRCFDYUQhQ2FEIUNhRCFDYUQxQ0FEQUNBREFDQURBQ0FEQUNBREFDQU"
6724 "RBQ0FEQUNBREFDQURBQ0FEUUMhRGFDIURhQyFEYUMhRGFDIURhQyFEYUMhRGFDIURhQyFEYUMhRG"
6725 "FDIURhQyFEYUMhRGFDIURhQyFEYUMhRGFDIURhQyFEYUMhRGFDIURhQyFEYUMhRGFDIURhQyFEUU"
6726 "NBREFDQURBQ0FEQUNBREFDQURBQ0FEQUNBREFDQURBQ0FEQUNBRDFDYUQhQ2FEIUNhRCFDYUQhQ2"
6727 "FEIUNhRBFDgUQBQ4FEAUOBRAFDgUQBQ4FD8UCiYKFD4UATgBFD5iPmI+Yj0iICI8HCwcPBc2FzwS"
6728 "QBI7D0gPOgtQCzoHWAc6A2AD3SoA");
6729 ok(match, "Figure does not match.\n");
6731 match = compare_figure(&ctx, 0, 320, 160, 160, 0xff652e89, 64,
6732 "3SkmcThiRFdOTVhEICAgPhwsHDwXNhc8FDwUOxQ+FDoUPhQ6FD4UOhQ+FDoUPhQ5FEAUOBRAFDgU"
6733 "QBQ4FEAUOBRAFDcUQhQ2FEIUNhRCFDYUQhQ2FEIUNhRCFDUURBQ0FEQUNBREFDQURBQ0FEQUNBRE"
6734 "FDQURBQ0FEQUNBREFDQURBQzFEYUMhRGFDIURhQyFEYUMhRGFDIURhQyFEYUMhRGFDIURhQyFEYU"
6735 "MhRGFDIURhQyFEYUMhRGFDIURhQyFEYUMhRGFDIURhQyFEYUMhRGFDIURhQyFEYUMhRGFDIURhQz"
6736 "FEQUNBREFDQURBQ0FEQUNBREFDQURBQ0FEQUNBREFDQURBQ0FEQUNRRCFDYUQhQ2FEIUNhRCFDYU"
6737 "QhQ2FEIUNxRAFDgUQBQ4FEAUOBRAFDgUQBQ5FD4UOhQ+FDoUPhQ6FD4UOhQ+FDsUPBQ8FzYXPBws"
6738 "HD4gICBEWE1OV0RiOHEm3SkA");
6739 ok(match, "Figure does not match.\n");
6740 match = compare_figure(&ctx, 160, 320, 160, 160, 0xff652e89, 1024,
6741 "zykoczhkRVhQTlpEFx4tPRUrJDwUNRw7FDwVOxQ+FDoUPhQ5FEAUOBRAFDgUQBQ4FEAUOBRBFDcU"
6742 "QRQ3FEEUNhRCFDYUQhQ2FEIUNhRDFDUUQxQ1FEMUNRRDFDUUQxQ0FEQUNBREFDQURBQ0FEQUNBRE"
6743 "FDQURBQ0FEQUNBREFDQURBQ0FEQUMxRFFDMURRQzFEUUMxRFFDMURRQzFEUUMxRFFDMURRQzFEUU"
6744 "MxRFFDMURBQ0FEQUMxRFFDMURRQzFEUUMxRFFDMURRQzFEUUMxRFFDMURRQzFEUUMxRFFDMURBQ0"
6745 "FEQUNBREFDQURBQ0FEQUNBREFDQURBQ0FEQUNBREFDQURBQ0FEMUNRRDFDUUQxQ1FEMUNRRDFDYU"
6746 "QhQ2FEIUNhRCFDYUQRQ3FEEUNxRBFDgUQBQ4FEAUOBRAFDgUQBQ5FD4UOhQ+FDsVPBQ7HDUUPCQr"
6747 "FT0tHhdEWk5QWEVkOHMozykA");
6748 ok(match, "Figure does not match.\n");
6749 match = compare_figure(&ctx, 320, 320, 160, 160, 0xff652e89, 1024,
6750 "6SkobThfRVNQSFpALR4XPSQrFTscNRQ7FTwUOhQ+FDoUPhQ5FEAUOBRAFDgUQBQ4FEAUNxRBFDcU"
6751 "QRQ3FEEUNxRCFDYUQhQ2FEIUNRRDFDUUQxQ1FEMUNRRDFDUUQxQ1FEQUNBREFDQURBQ0FEQUNBRE"
6752 "FDQURBQ0FEQUNBREFDQURBQ0FEQUNBRFFDMURRQzFEUUMxRFFDMURRQzFEUUMxRFFDMURRQzFEUU"
6753 "MxRFFDQURBQ0FEQUNBRFFDMURRQzFEUUMxRFFDMURRQzFEUUMxRFFDMURRQzFEUUMxRFFDQURBQ0"
6754 "FEQUNBREFDQURBQ0FEQUNBREFDQURBQ0FEQUNBREFDQURBQ1FEMUNRRDFDUUQxQ1FEMUNRRDFDUU"
6755 "QhQ2FEIUNhRCFDcUQRQ3FEEUNxRBFDcUQBQ4FEAUOBRAFDgUQBQ5FD4UOhQ+FDoUPBU7FDUcOxUr"
6756 "JD0XHi1AWkhQU0VfOG0o6SkA");
6757 ok(match, "Figure does not match.\n");
6758 match = compare_figure(&ctx, 480, 320, 160, 160, 0xff652e89, 64,
6759 "3SkmcThiRFdOTVhGHiAgRhQsHDwXNhc8FDwUOxQ+FDoUPhQ6FD4UOhQ+FDoUPhQ5FEAUOBRAFDgU"
6760 "QBQ4FEAUOBRAFDcUQhQ2FEIUNhRCFDYUQhQ2FEIUNhRCFDUURBQ0FEQUNBREFDQURBQ0FEQUNBRE"
6761 "FDQURBQ0FEQUNBREFDQURBQzFEYUMhRGFDIURhQyFEYUMhRGFDIURhQyFEYUMhRGFDIURhQyFEYU"
6762 "MhRGFDIURhQyFEYUMhRGFDIURhQyFEYUMhRGFDIURhQyFEYUMhRGFDIURhQyFEYUMhRGFDIURhQz"
6763 "FEQUNBREFDQURBQ0FEQUNBREFDQURBQ0FEQUNBREFDQURBQ0FEQUNRRCFDYUQhQ2FEIUNhRCFDYU"
6764 "QhQ2FEIUNxRAFDgUQBQ4FEAUOBRAFDgUQBQ5FD4UOhQ+FDoUPhQ6FD4UOhQ+FDsUPBQ8FzYXPBws"
6765 "HD4gICBEWE1OV0RiOHEm3SkA");
6766 ok(match, "Figure does not match.\n");
6768 hr = ID2D1Factory_CreatePathGeometry(factory, &geometry);
6769 ok(SUCCEEDED(hr), "Failed to create path geometry, hr %#x.\n", hr);
6770 hr = ID2D1PathGeometry_Open(geometry, &sink);
6771 ok(SUCCEEDED(hr), "Failed to open geometry sink, hr %#x.\n", hr);
6773 set_point(&point, -0.402914f, 0.915514f);
6774 ID2D1GeometrySink_BeginFigure(sink, point, D2D1_FIGURE_BEGIN_HOLLOW);
6775 quadratic_to(sink, -0.310379f, 0.882571f, -0.116057f, 0.824000f);
6776 quadratic_to(sink, 0.008350f, 0.693614f, -0.052343f, 0.448886f);
6777 quadratic_to(sink, -0.154236f, 0.246072f, -0.279229f, 0.025343f);
6778 quadratic_to(sink, -0.370064f, -0.588586f, -0.383029f, -0.924114f);
6779 quadratic_to(sink, -0.295479f, -0.958764f, -0.017086f, -0.988400f);
6780 quadratic_to(sink, 0.208836f, -0.954157f, 0.272200f, -0.924114f);
6781 quadratic_to(sink, 0.295614f, -0.569071f, 0.230143f, 0.022886f);
6782 quadratic_to(sink, 0.101664f, 0.220643f, 0.012057f, 0.451571f);
6783 quadratic_to(sink, -0.028764f, 0.709014f, 0.104029f, 0.833943f);
6784 quadratic_to(sink, 0.319414f, 0.913057f, 0.403229f, 0.942628f);
6785 quadratic_to(sink, 0.317721f, 1.023450f, -0.017086f, 1.021771f);
6786 quadratic_to(sink, -0.310843f, 1.007472f, -0.402914f, 0.915514f);
6787 ID2D1GeometrySink_EndFigure(sink, D2D1_FIGURE_END_CLOSED);
6789 hr = ID2D1GeometrySink_Close(sink);
6790 ok(SUCCEEDED(hr), "Failed to close geometry sink, hr %#x.\n", hr);
6791 ID2D1GeometrySink_Release(sink);
6793 set_matrix_identity(&matrix);
6794 translate_matrix(&matrix, 40.0f, 160.0f);
6795 scale_matrix(&matrix, 20.0f, 80.0f);
6796 hr = ID2D1Factory_CreateTransformedGeometry(factory,
6797 (ID2D1Geometry *)geometry, &matrix, &transformed_geometry[0]);
6798 ok(SUCCEEDED(hr), "Failed to create geometry, hr %#x.\n", hr);
6800 set_matrix_identity(&matrix);
6801 translate_matrix(&matrix, 160.0f, 640.0f);
6802 scale_matrix(&matrix, 40.0f, 160.0f);
6803 rotate_matrix(&matrix, M_PI / -5.0f);
6804 hr = ID2D1Factory_CreateTransformedGeometry(factory,
6805 (ID2D1Geometry *)geometry, &matrix, &transformed_geometry[1]);
6806 ok(SUCCEEDED(hr), "Failed to create geometry, hr %#x.\n", hr);
6807 ID2D1PathGeometry_Release(geometry);
6809 set_matrix_identity(&matrix);
6810 scale_matrix(&matrix, 0.5f, 1.0f);
6811 translate_matrix(&matrix, -80.0f, 0.0f);
6812 hr = ID2D1Factory_CreateTransformedGeometry(factory,
6813 (ID2D1Geometry *)transformed_geometry[1], &matrix, &transformed_geometry[2]);
6814 ok(SUCCEEDED(hr), "Failed to create geometry, hr %#x.\n", hr);
6816 set_matrix_identity(&matrix);
6817 rotate_matrix(&matrix, M_PI / 2.0f);
6818 translate_matrix(&matrix, 80.0f, -320.0f);
6819 scale_matrix(&matrix, 2.0f, 0.25f);
6820 hr = ID2D1Factory_CreateTransformedGeometry(factory,
6821 (ID2D1Geometry *)transformed_geometry[2], &matrix, &transformed_geometry[3]);
6822 ok(SUCCEEDED(hr), "Failed to create geometry, hr %#x.\n", hr);
6824 ID2D1RenderTarget_BeginDraw(rt);
6825 ID2D1RenderTarget_Clear(rt, &color);
6826 ID2D1RenderTarget_DrawGeometry(rt, (ID2D1Geometry *)transformed_geometry[0], (ID2D1Brush *)brush, 2.0f, NULL);
6827 ID2D1RenderTarget_DrawGeometry(rt, (ID2D1Geometry *)transformed_geometry[1], (ID2D1Brush *)brush, 10.0f, NULL);
6828 ID2D1RenderTarget_DrawGeometry(rt, (ID2D1Geometry *)transformed_geometry[2], (ID2D1Brush *)brush, 5.0f, NULL);
6829 ID2D1RenderTarget_DrawGeometry(rt, (ID2D1Geometry *)transformed_geometry[3], (ID2D1Brush *)brush, 15.0f, NULL);
6830 hr = ID2D1RenderTarget_EndDraw(rt, NULL, NULL);
6831 ok(SUCCEEDED(hr), "Failed to end draw, hr %#x.\n", hr);
6832 ID2D1TransformedGeometry_Release(transformed_geometry[3]);
6833 ID2D1TransformedGeometry_Release(transformed_geometry[2]);
6834 ID2D1TransformedGeometry_Release(transformed_geometry[1]);
6835 ID2D1TransformedGeometry_Release(transformed_geometry[0]);
6837 match = compare_figure(&ctx, 0, 0, 160, 160, 0xff652e89, 128,
6838 "yjIJkQEHBwaIAQUSBYMBBBYEggEEFgSCAQQWBIIBBBYEggEEFgSCAQQWBIIBBBYEggEEFgSCAQQW"
6839 "BIIBBBYEggEEFgSDAQQVBIMBBBUEgwEEFQSDAQQVBIMBBBUEgwEEFQSDAQQVBIMBBBUEgwEEFQSD"
6840 "AQQVBIQBBBQEhAEEFASEAQQTBIUBBBMEhQEEEwSFAQQTBIUBBBMEhQEEEwSGAQQSBIYBBBIEhgEE"
6841 "EgSGAQQSBIYBBBIEhgEEEgSGAQQRBIgBBBAEiAEEEASIAQQQBIkBBA4EigEEDgSLAQQMBIwBBAwE"
6842 "jQEECgSOAQQJBJABBAgEkAEFBgSSAQQGBJMBBAQElAEEBASVAQQDBJUBBAIElwEEAQSXAQiZAQeZ"
6843 "AQaaAQaaAQaaAQabAQWbAQWbAQWbAQWaAQeZAQeZAQeZAQiXAQQBBJYBBAMElQEEAwWRAQUGBY0B"
6844 "BQwFhwEFEgSCAQUXBYABBBoFfgUYBIIBBhEFiAEUpTEA");
6845 ok(match, "Figure does not match.\n");
6846 match = compare_figure(&ctx, 160, 0, 320, 160, 0xff652e89, 512,
6847 "yJIBArkCDa4CGKMCIZoCK5ECM4gCO4ECQ/gBS/EBUesBLAYl5QEsDiPeASwWIdkBLBwh0wEsISHO"
6848 "ASsgKMsBKR4vyAEnHDPIASUaNMsBIxg1mQEFMCIUN54BCygiDzijAREhIgY9qAEYGWGuAR4RXbMB"
6849 "JAhbuQGAAcABesYBc84Ba9YBTvQBP4MCOIoCNI4CM5ACMZICL5QCLZYCK5kCKJsCJ54CI6MCHq8C"
6850 "EraSAQAA");
6851 ok(match, "Figure does not match.\n");
6852 match = compare_figure(&ctx, 0, 160, 160, 320, 0xff652e89, 512,
6853 "xWkCmwEFmAEJlQELlAENkgEOkQEPjwESjQETjAEVigELAQqJAQsCCogBCwQKhwEKBQqGAQoGCoYB"
6854 "CgcKhAEKCAqEAQoIC4IBCgoKggEKCgqBAQoMCoABCgwKfwoNCn8KDgp9Cg8KfQoPCnwKEQp7ChEK"
6855 "egoSCnoKEwp4ChQKeAoUCncLFQp2ChYKdgoWCnYKFwp2ChYKdgoWCncKFgp2ChYKdgoWCncKFQt2"
6856 "ChYKdwoVCncKFQp4ChUKdwoVCncKFQp4ChUKdwoVCngKFAp4ChUKeAoUCngKFAp4CxMKeQoUCngK"
6857 "FAp5ChMKeQoUCnkKEwp5ChMKegoSC3kKEwp6ChIKegoSCnoLEgp6ChIKegoSCnsKEQp7ChEKfAoQ"
6858 "CnwKEAp9Cg8KfQoPCn4KDgp+Cg4KfwoOCn4KDgp/Cg0KfwoNCoABCgwKgAEKDAqBAQoLCoEBCgsK"
6859 "gQELCgqCAQoKCoIBCwkKgwEKCQqDAQoJCoQBCggKhAEKCQqEAQsHCoUBCwYKhgELBQqHAQsECogB"
6860 "CwMKiQELAgqLAQoBCowBFI0BE44BE44BEo8BEZABEJEBD5IBDpMBDpMBDZMBDZQBDJQBDZQBDJQB"
6861 "DBUCfgwSBH4MEQV/DA4GgAEMDAiAAQ0KCYEBDAgLgQENBQ2BAQ0EDoIBDQEPgwEdgwEdgwEdgwEc"
6862 "hAEKAgQCCoUBCgYKhgEKBgqGAQoFC4YBCgUKhwEKBAqIAQoECogBCgMKiQEKAwqIAQoDCokBCgMK"
6863 "iQEKAgqJAQoCCooBCgIKiQEKAgqKAQoBCosBCgEKigEKAQqLARSMARSLARSMAROMARONARKOARGO"
6864 "ARGPARCQAQ6RAQ2YAQTEZAAA");
6865 ok(match, "Figure does not match.\n");
6866 match = compare_figure(&ctx, 160, 160, 320, 320, 0xff652e89, 1024,
6867 "ytABA7gCCbICD60CFKkCF6cCGqMCHqACIZ0CJJoCJpgCKZUCFgIUkgIWBBWPAhYHFI4CFQoUjAIV"
6868 "DBSKAhUNFYgCFQ8UhwIVERSFAhUTFIMCFRQVgQIUFxSAAhQZFP4BFBoV/AEUHBT7ARQeFPkBFB8V"
6869 "9wEUIRT2ARQjFPQBFSMV8gEVJRTxARUnFPABFCgV7gEUKhTtARQsFOwBFCwV7AEULBTsARUsFOwB"
6870 "FSsV7AEULBTtARQsFO0BFCsU7QEVKxTtARUqFe0BFSoU7gEUKxTuARQqFe4BFCoU7wEUKhTuARUp"
6871 "FO8BFSkU7wEVKBXvARUoFPABFCkU8AEUKBTxARQoFPEBFCcV8QEUJxTxARUnFPEBFSYU8gEVJhTy"
6872 "ARUlFfIBFSUU8wEUJRXzARQlFPQBFCUU9AEUJBT1ARQkFPUBFCMU9gEUIhT2ARUhFPcBFSAU+AEV"
6873 "HxT5ARUeFPoBFR4U+gEVHRT7ARUcFPwBFRsU/QEVGhT+ARUZFP8BFBkUgAIUGBSBAhQXFIICFBcU"
6874 "ggIUFhSDAhQVFIQCFBQUhQIUExSGAhQSFIcCFBIUhwIUERSIAhUPFIkCFg0UigIXCxSNAhYJFI8C"
6875 "FggUkAIXBRSSAhcDFJQCFwEUlgIrlwIpmgImnAIkngIjnwIhoQIfowIepAIcpgIbpgIaqAIZqAIZ"
6876 "qAIYKwP7ARgnBf0BGCMI/QEZHgz+ARgbD/8BGBcSgAIYEhaAAhoNGIICGggcgwIaBB+DAjyEAjyF"
6877 "AjqGAjmIAjiIAiECFIkCFAIIBBSKAhQNFIsCFAwUjAIUCxSNAhQKFI4CFAkUjwIUBxWQAhQGFZEC"
6878 "FAUVkQIUBRWRAhQFFZECFQMVkwIUAxWTAhQDFZMCFAIVlAIVARWVAiqVAimWAimWAiiYAiaZAiaZ"
6879 "AiWaAiScAiKdAiGeAh+hAhyjAhmuAg3GxgEA");
6880 ok(match, "Figure does not match.\n");
6882 ID2D1SolidColorBrush_Release(brush);
6883 ID2D1Factory_Release(factory);
6884 release_test_context(&ctx);
6887 static void test_fill_geometry(BOOL d3d11)
6889 ID2D1TransformedGeometry *transformed_geometry[4];
6890 ID2D1RectangleGeometry *rect_geometry[2];
6891 D2D1_POINT_2F point = {0.0f, 0.0f};
6892 D2D1_ROUNDED_RECT rounded_rect;
6893 struct d2d1_test_context ctx;
6894 ID2D1SolidColorBrush *brush;
6895 ID2D1PathGeometry *geometry;
6896 D2D1_MATRIX_3X2_F matrix;
6897 ID2D1GeometrySink *sink;
6898 ID2D1RenderTarget *rt;
6899 ID2D1Factory *factory;
6900 D2D1_ELLIPSE ellipse;
6901 D2D1_COLOR_F color;
6902 D2D1_RECT_F rect;
6903 HRESULT hr;
6904 BOOL match;
6906 if (!init_test_context(&ctx, d3d11))
6907 return;
6909 rt = ctx.rt;
6910 ID2D1RenderTarget_GetFactory(rt, &factory);
6912 ID2D1RenderTarget_SetDpi(rt, 192.0f, 48.0f);
6913 ID2D1RenderTarget_SetAntialiasMode(rt, D2D1_ANTIALIAS_MODE_ALIASED);
6914 set_color(&color, 0.890f, 0.851f, 0.600f, 1.0f);
6915 hr = ID2D1RenderTarget_CreateSolidColorBrush(rt, &color, NULL, &brush);
6916 ok(SUCCEEDED(hr), "Failed to create brush, hr %#x.\n", hr);
6918 ID2D1RenderTarget_BeginDraw(rt);
6919 set_color(&color, 0.396f, 0.180f, 0.537f, 1.0f);
6920 ID2D1RenderTarget_Clear(rt, &color);
6922 set_rect(&rect, 40.0f, 480.0f, 40.0f, 480.0f);
6923 ID2D1RenderTarget_FillRectangle(rt, &rect, (ID2D1Brush *)brush);
6924 set_rect(&rect, 100.0f, 480.0f, 140.0f, 480.0f);
6925 ID2D1RenderTarget_FillRectangle(rt, &rect, (ID2D1Brush *)brush);
6926 set_rect(&rect, 200.0f, 400.0f, 200.0f, 560.0f);
6927 ID2D1RenderTarget_FillRectangle(rt, &rect, (ID2D1Brush *)brush);
6928 set_rect(&rect, 260.0f, 560.0f, 300.0f, 400.0f);
6929 ID2D1RenderTarget_FillRectangle(rt, &rect, (ID2D1Brush *)brush);
6931 set_ellipse(&ellipse, 40.0f, 800.0f, 0.0f, 0.0f);
6932 ID2D1RenderTarget_FillEllipse(rt, &ellipse, (ID2D1Brush *)brush);
6933 set_ellipse(&ellipse, 120.0f, 800.0f, 20.0f, 0.0f);
6934 ID2D1RenderTarget_FillEllipse(rt, &ellipse, (ID2D1Brush *)brush);
6935 set_ellipse(&ellipse, 200.0f, 800.0f, 0.0f, 80.0f);
6936 ID2D1RenderTarget_FillEllipse(rt, &ellipse, (ID2D1Brush *)brush);
6937 set_ellipse(&ellipse, 280.0f, 800.0f, 20.0f, 80.0f);
6938 ID2D1RenderTarget_FillEllipse(rt, &ellipse, (ID2D1Brush *)brush);
6940 hr = ID2D1RenderTarget_EndDraw(rt, NULL, NULL);
6941 ok(SUCCEEDED(hr), "Failed to end draw, hr %#x.\n", hr);
6943 match = compare_figure(&ctx, 0, 160, 160, 160, 0xff652e89, 0, "gMgB");
6944 ok(match, "Figure does not match.\n");
6945 match = compare_figure(&ctx, 160, 160, 160, 160, 0xff652e89, 0, "gMgB");
6946 ok(match, "Figure does not match.\n");
6947 match = compare_figure(&ctx, 320, 160, 160, 160, 0xff652e89, 0, "gMgB");
6948 ok(match, "Figure does not match.\n");
6949 match = compare_figure(&ctx, 480, 160, 160, 160, 0xff652e89, 0,
6950 "qDJQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQ"
6951 "UFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQ"
6952 "UFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFCoMgAA");
6953 ok(match, "Figure does not match.\n");
6955 match = compare_figure(&ctx, 0, 320, 160, 160, 0xff652e89, 0, "gMgB");
6956 ok(match, "Figure does not match.\n");
6957 match = compare_figure(&ctx, 160, 320, 160, 160, 0xff652e89, 0, "gMgB");
6958 ok(match, "Figure does not match.\n");
6959 match = compare_figure(&ctx, 320, 320, 160, 160, 0xff652e89, 0, "gMgB");
6960 ok(match, "Figure does not match.\n");
6961 match = compare_figure(&ctx, 480, 320, 160, 160, 0xff652e89, 8,
6962 "yjIMjwEWhwEcggEgfiR6KHYscy5xMG40azZpOGc6ZTxjPmI+YUBfQl1EXERbRlpGWUhYSFdKVkpV"
6963 "TFRMVExTTlJOUk5STlJOUVBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUU5STlJOUk5STlNMVExUTFVK"
6964 "VkpXSFhIWUZaRltEXERdQl9AYT5iPmM8ZTpnOGk2azRuMHEucyx2KHokfiCCARyHARaPAQzKMgAA");
6965 ok(match, "Figure does not match.\n");
6967 ID2D1RenderTarget_BeginDraw(rt);
6968 set_color(&color, 0.396f, 0.180f, 0.537f, 1.0f);
6969 ID2D1RenderTarget_Clear(rt, &color);
6971 set_rounded_rect(&rounded_rect, 40.0f, 160.0f, 40.0f, 160.0f, 10.0f, 10.0f);
6972 ID2D1RenderTarget_FillRoundedRectangle(rt, &rounded_rect, (ID2D1Brush *)brush);
6973 set_rounded_rect(&rounded_rect, 100.0f, 160.0f, 140.0f, 160.0f, 10.0f, 10.0f);
6974 ID2D1RenderTarget_FillRoundedRectangle(rt, &rounded_rect, (ID2D1Brush *)brush);
6975 set_rounded_rect(&rounded_rect, 200.0f, 80.0f, 200.0f, 240.0f, 10.0f, 10.0f);
6976 ID2D1RenderTarget_FillRoundedRectangle(rt, &rounded_rect, (ID2D1Brush *)brush);
6977 set_rounded_rect(&rounded_rect, 260.0f, 240.0f, 300.0f, 80.0f, 10.0f, 10.0f);
6978 ID2D1RenderTarget_FillRoundedRectangle(rt, &rounded_rect, (ID2D1Brush *)brush);
6980 set_rounded_rect(&rounded_rect, 40.0f, 480.0f, 40.0f, 480.0f, 10.0f, 20.0f);
6981 ID2D1RenderTarget_FillRoundedRectangle(rt, &rounded_rect, (ID2D1Brush *)brush);
6982 set_rounded_rect(&rounded_rect, 100.0f, 480.0f, 140.0f, 480.0f, 10.0f, 20.0f);
6983 ID2D1RenderTarget_FillRoundedRectangle(rt, &rounded_rect, (ID2D1Brush *)brush);
6984 set_rounded_rect(&rounded_rect, 200.0f, 400.0f, 200.0f, 560.0f, 10.0f, 20.0f);
6985 ID2D1RenderTarget_FillRoundedRectangle(rt, &rounded_rect, (ID2D1Brush *)brush);
6986 set_rounded_rect(&rounded_rect, 260.0f, 560.0f, 300.0f, 400.0f, 10.0f, 20.0f);
6987 ID2D1RenderTarget_FillRoundedRectangle(rt, &rounded_rect, (ID2D1Brush *)brush);
6989 set_rounded_rect(&rounded_rect, 40.0f, 800.0f, 40.0f, 800.0f, 10.0f, 5.0f);
6990 ID2D1RenderTarget_FillRoundedRectangle(rt, &rounded_rect, (ID2D1Brush *)brush);
6991 set_rounded_rect(&rounded_rect, 100.0f, 800.0f, 140.0f, 800.0f, 10.0f, 5.0f);
6992 ID2D1RenderTarget_FillRoundedRectangle(rt, &rounded_rect, (ID2D1Brush *)brush);
6993 set_rounded_rect(&rounded_rect, 200.0f, 720.0f, 200.0f, 880.0f, 10.0f, 5.0f);
6994 ID2D1RenderTarget_FillRoundedRectangle(rt, &rounded_rect, (ID2D1Brush *)brush);
6995 set_rounded_rect(&rounded_rect, 260.0f, 880.0f, 300.0f, 720.0f, 10.0f, 5.0f);
6996 ID2D1RenderTarget_FillRoundedRectangle(rt, &rounded_rect, (ID2D1Brush *)brush);
6998 hr = ID2D1RenderTarget_EndDraw(rt, NULL, NULL);
6999 ok(SUCCEEDED(hr), "Failed to end draw, hr %#x.\n", hr);
7001 match = compare_figure(&ctx, 0, 0, 160, 160, 0xff652e89, 0, "gMgB");
7002 ok(match, "Figure does not match.\n");
7003 match = compare_figure(&ctx, 160, 0, 160, 160, 0xff652e89, 0, "gMgB");
7004 ok(match, "Figure does not match.\n");
7005 match = compare_figure(&ctx, 320, 0, 160, 160, 0xff652e89, 0, "gMgB");
7006 ok(match, "Figure does not match.\n");
7007 match = compare_figure(&ctx, 480, 0, 160, 160, 0xff652e89, 0,
7008 "szI6YURZSlROUVBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQ"
7009 "UFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQ"
7010 "UFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUU5USllEYTqzMgAA");
7011 ok(match, "Figure does not match.\n");
7013 match = compare_figure(&ctx, 0, 160, 160, 160, 0xff652e89, 0, "gMgB");
7014 ok(match, "Figure does not match.\n");
7015 match = compare_figure(&ctx, 160, 160, 160, 160, 0xff652e89, 0, "gMgB");
7016 ok(match, "Figure does not match.\n");
7017 match = compare_figure(&ctx, 320, 160, 160, 160, 0xff652e89, 0, "gMgB");
7018 ok(match, "Figure does not match.\n");
7019 match = compare_figure(&ctx, 480, 160, 160, 160, 0xff652e89, 2,
7020 "tjI0aDxhQlxGWEpVTFNOUk5RUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQ"
7021 "UFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQ"
7022 "UFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFFOUk5TTFVKWEZcQmA+ZzS2MgAA");
7023 ok(match, "Figure does not match.\n");
7025 match = compare_figure(&ctx, 0, 320, 160, 160, 0xff652e89, 0, "gMgB");
7026 ok(match, "Figure does not match.\n");
7027 match = compare_figure(&ctx, 160, 320, 160, 160, 0xff652e89, 0, "gMgB");
7028 ok(match, "Figure does not match.\n");
7029 match = compare_figure(&ctx, 320, 320, 160, 160, 0xff652e89, 0, "gMgB");
7030 ok(match, "Figure does not match.\n");
7031 match = compare_figure(&ctx, 480, 320, 160, 160, 0xff652e89, 0,
7032 "sDJAWkxSUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQ"
7033 "UFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQ"
7034 "UFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFJMWkCwMgAA");
7035 ok(match, "Figure does not match.\n");
7037 ID2D1RenderTarget_BeginDraw(rt);
7038 set_color(&color, 0.396f, 0.180f, 0.537f, 1.0f);
7039 ID2D1RenderTarget_Clear(rt, &color);
7041 set_rounded_rect(&rounded_rect, 40.0f, 160.0f, 40.0f, 160.0f, 1000.0f, 1000.0f);
7042 ID2D1RenderTarget_FillRoundedRectangle(rt, &rounded_rect, (ID2D1Brush *)brush);
7043 set_rounded_rect(&rounded_rect, 100.0f, 160.0f, 140.0f, 160.0f, 1000.0f, 1000.0f);
7044 ID2D1RenderTarget_FillRoundedRectangle(rt, &rounded_rect, (ID2D1Brush *)brush);
7045 set_rounded_rect(&rounded_rect, 200.0f, 80.0f, 200.0f, 240.0f, 1000.0f, 1000.0f);
7046 ID2D1RenderTarget_FillRoundedRectangle(rt, &rounded_rect, (ID2D1Brush *)brush);
7047 set_rounded_rect(&rounded_rect, 260.0f, 240.0f, 300.0f, 80.0f, 1000.0f, 1000.0f);
7048 ID2D1RenderTarget_FillRoundedRectangle(rt, &rounded_rect, (ID2D1Brush *)brush);
7050 set_rounded_rect(&rounded_rect, 40.0f, 480.0f, 40.0f, 480.0f, 10.0f, 1000.0f);
7051 ID2D1RenderTarget_FillRoundedRectangle(rt, &rounded_rect, (ID2D1Brush *)brush);
7052 set_rounded_rect(&rounded_rect, 100.0f, 480.0f, 140.0f, 480.0f, 10.0f, 1000.0f);
7053 ID2D1RenderTarget_FillRoundedRectangle(rt, &rounded_rect, (ID2D1Brush *)brush);
7054 set_rounded_rect(&rounded_rect, 200.0f, 400.0f, 200.0f, 560.0f, 10.0f, 1000.0f);
7055 ID2D1RenderTarget_FillRoundedRectangle(rt, &rounded_rect, (ID2D1Brush *)brush);
7056 set_rounded_rect(&rounded_rect, 260.0f, 560.0f, 300.0f, 400.0f, 10.0f, 1000.0f);
7057 ID2D1RenderTarget_FillRoundedRectangle(rt, &rounded_rect, (ID2D1Brush *)brush);
7059 set_rounded_rect(&rounded_rect, 40.0f, 800.0f, 40.0f, 800.0f, 1000.0f, 10.0f);
7060 ID2D1RenderTarget_FillRoundedRectangle(rt, &rounded_rect, (ID2D1Brush *)brush);
7061 set_rounded_rect(&rounded_rect, 100.0f, 800.0f, 140.0f, 800.0f, 1000.0f, 10.0f);
7062 ID2D1RenderTarget_FillRoundedRectangle(rt, &rounded_rect, (ID2D1Brush *)brush);
7063 set_rounded_rect(&rounded_rect, 200.0f, 720.0f, 200.0f, 880.0f, 1000.0f, 10.0f);
7064 ID2D1RenderTarget_FillRoundedRectangle(rt, &rounded_rect, (ID2D1Brush *)brush);
7065 set_rounded_rect(&rounded_rect, 260.0f, 880.0f, 300.0f, 720.0f, 1000.0f, 10.0f);
7066 ID2D1RenderTarget_FillRoundedRectangle(rt, &rounded_rect, (ID2D1Brush *)brush);
7068 hr = ID2D1RenderTarget_EndDraw(rt, NULL, NULL);
7069 ok(SUCCEEDED(hr), "Failed to end draw, hr %#x.\n", hr);
7071 match = compare_figure(&ctx, 0, 0, 160, 160, 0xff652e89, 0, "gMgB");
7072 ok(match, "Figure does not match.\n");
7073 match = compare_figure(&ctx, 160, 0, 160, 160, 0xff652e89, 0, "gMgB");
7074 ok(match, "Figure does not match.\n");
7075 match = compare_figure(&ctx, 320, 0, 160, 160, 0xff652e89, 0, "gMgB");
7076 ok(match, "Figure does not match.\n");
7077 match = compare_figure(&ctx, 480, 0, 160, 160, 0xff652e89, 10,
7078 "yjIMjwEWhwEcggEgfiR6KHYscy5xMG40azZpOGc6ZTxjPmI+YUBfQl1EXERbRlpGWUhYSFdKVkpV"
7079 "TFRMVExTTlJOUk5STlJOUVBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUU5STlJOUk5STlNMVExUTFVK"
7080 "VkpXSFhIWUZaRltEXERdQl9AYT5iPmM8ZTpnOGk2azRuMHEucyx2KHokfiCCARyHARaPAQzKMgAA");
7081 ok(match, "Figure does not match.\n");
7083 match = compare_figure(&ctx, 0, 160, 160, 160, 0xff652e89, 0, "gMgB");
7084 ok(match, "Figure does not match.\n");
7085 match = compare_figure(&ctx, 160, 160, 160, 160, 0xff652e89, 0, "gMgB");
7086 ok(match, "Figure does not match.\n");
7087 match = compare_figure(&ctx, 320, 160, 160, 160, 0xff652e89, 0, "gMgB");
7088 ok(match, "Figure does not match.\n");
7089 match = compare_figure(&ctx, 480, 160, 160, 160, 0xff652e89, 10,
7090 "uTIucDJsNmk4ZzplPGM+YUBgQF9CXkJdRFxEW0ZaRllIWEhXSlZKVkpWSlVMVExUTFRMU05STlJO"
7091 "Uk5STlJOUk9QUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFFPUU5STlJOUk5STlJOU0xU"
7092 "TFRMVExVSlZKVkpWSldIWEhZRlpGW0RcRF1CXkJfQGBAYT5jPGU6ZzhpNmwycC65MgAA");
7093 ok(match, "Figure does not match.\n");
7095 match = compare_figure(&ctx, 0, 320, 160, 160, 0xff652e89, 0, "gMgB");
7096 ok(match, "Figure does not match.\n");
7097 match = compare_figure(&ctx, 160, 320, 160, 160, 0xff652e89, 0, "gMgB");
7098 ok(match, "Figure does not match.\n");
7099 match = compare_figure(&ctx, 320, 320, 160, 160, 0xff652e89, 0, "gMgB");
7100 ok(match, "Figure does not match.\n");
7101 match = compare_figure(&ctx, 480, 320, 160, 160, 0xff652e89, 10,
7102 "vzIiczhhRldMUlBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQ"
7103 "UFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQ"
7104 "UFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUkxXRmA6cSS+MgAA");
7105 ok(match, "Figure does not match.\n");
7107 hr = ID2D1Factory_CreatePathGeometry(factory, &geometry);
7108 ok(SUCCEEDED(hr), "Failed to create path geometry, hr %#x.\n", hr);
7109 hr = ID2D1PathGeometry_Open(geometry, &sink);
7110 ok(SUCCEEDED(hr), "Failed to open geometry sink, hr %#x.\n", hr);
7112 set_point(&point, 40.0f, 160.0f);
7113 ID2D1GeometrySink_BeginFigure(sink, point, D2D1_FIGURE_BEGIN_FILLED);
7114 ID2D1GeometrySink_EndFigure(sink, D2D1_FIGURE_END_OPEN);
7116 set_point(&point, 120.0f, 160.0f);
7117 ID2D1GeometrySink_BeginFigure(sink, point, D2D1_FIGURE_BEGIN_FILLED);
7118 line_to(sink, 120.0f, 160.0f);
7119 ID2D1GeometrySink_EndFigure(sink, D2D1_FIGURE_END_OPEN);
7121 set_point(&point, 200.0f, 160.0f);
7122 ID2D1GeometrySink_BeginFigure(sink, point, D2D1_FIGURE_BEGIN_FILLED);
7123 ID2D1GeometrySink_EndFigure(sink, D2D1_FIGURE_END_CLOSED);
7125 set_point(&point, 280.0f, 160.0f);
7126 ID2D1GeometrySink_BeginFigure(sink, point, D2D1_FIGURE_BEGIN_FILLED);
7127 line_to(sink, 280.0f, 160.0f);
7128 ID2D1GeometrySink_EndFigure(sink, D2D1_FIGURE_END_CLOSED);
7130 set_point(&point, 20.0f, 480.0f);
7131 ID2D1GeometrySink_BeginFigure(sink, point, D2D1_FIGURE_BEGIN_FILLED);
7132 line_to(sink, 60.0f, 480.0f);
7133 ID2D1GeometrySink_EndFigure(sink, D2D1_FIGURE_END_OPEN);
7135 set_point(&point, 120.0f, 400.0f);
7136 ID2D1GeometrySink_BeginFigure(sink, point, D2D1_FIGURE_BEGIN_FILLED);
7137 line_to(sink, 120.0f, 560.0f);
7138 line_to(sink, 120.0f, 400.0f);
7139 line_to(sink, 120.0f, 560.0f);
7140 ID2D1GeometrySink_EndFigure(sink, D2D1_FIGURE_END_OPEN);
7142 set_point(&point, 180.0f, 480.0f);
7143 ID2D1GeometrySink_BeginFigure(sink, point, D2D1_FIGURE_BEGIN_FILLED);
7144 line_to(sink, 220.0f, 480.0f);
7145 ID2D1GeometrySink_EndFigure(sink, D2D1_FIGURE_END_CLOSED);
7147 set_point(&point, 280.0f, 400.0f);
7148 ID2D1GeometrySink_BeginFigure(sink, point, D2D1_FIGURE_BEGIN_FILLED);
7149 line_to(sink, 280.0f, 560.0f);
7150 line_to(sink, 280.0f, 400.0f);
7151 line_to(sink, 280.0f, 560.0f);
7152 ID2D1GeometrySink_EndFigure(sink, D2D1_FIGURE_END_CLOSED);
7154 set_point(&point, 20.0f, 880.0f);
7155 ID2D1GeometrySink_BeginFigure(sink, point, D2D1_FIGURE_BEGIN_FILLED);
7156 line_to(sink, 40.0f, 720.0f);
7157 line_to(sink, 60.0f, 880.0f);
7158 ID2D1GeometrySink_EndFigure(sink, D2D1_FIGURE_END_OPEN);
7160 set_point(&point, 100.0f, 720.0f);
7161 ID2D1GeometrySink_BeginFigure(sink, point, D2D1_FIGURE_BEGIN_FILLED);
7162 line_to(sink, 120.0f, 880.0f);
7163 line_to(sink, 140.0f, 720.0f);
7164 ID2D1GeometrySink_EndFigure(sink, D2D1_FIGURE_END_OPEN);
7166 set_point(&point, 180.0f, 880.0f);
7167 ID2D1GeometrySink_BeginFigure(sink, point, D2D1_FIGURE_BEGIN_FILLED);
7168 line_to(sink, 200.0f, 720.0f);
7169 line_to(sink, 220.0f, 880.0f);
7170 ID2D1GeometrySink_EndFigure(sink, D2D1_FIGURE_END_CLOSED);
7172 set_point(&point, 260.0f, 720.0f);
7173 ID2D1GeometrySink_BeginFigure(sink, point, D2D1_FIGURE_BEGIN_FILLED);
7174 line_to(sink, 280.0f, 880.0f);
7175 line_to(sink, 300.0f, 720.0f);
7176 ID2D1GeometrySink_EndFigure(sink, D2D1_FIGURE_END_CLOSED);
7178 ID2D1GeometrySink_SetFillMode(sink, D2D1_FILL_MODE_ALTERNATE);
7179 hr = ID2D1GeometrySink_Close(sink);
7180 ok(SUCCEEDED(hr), "Failed to close geometry sink, hr %#x.\n", hr);
7181 ID2D1GeometrySink_Release(sink);
7183 ID2D1RenderTarget_BeginDraw(rt);
7184 ID2D1RenderTarget_Clear(rt, &color);
7185 ID2D1RenderTarget_FillGeometry(rt, (ID2D1Geometry *)geometry, (ID2D1Brush *)brush, NULL);
7186 hr = ID2D1RenderTarget_EndDraw(rt, NULL, NULL);
7187 ok(SUCCEEDED(hr), "Failed to end draw, hr %#x.\n", hr);
7188 ID2D1PathGeometry_Release(geometry);
7190 match = compare_figure(&ctx, 0, 0, 160, 160, 0xff652e89, 0, "gMgB");
7191 ok(match, "Figure does not match.\n");
7192 match = compare_figure(&ctx, 160, 0, 160, 160, 0xff652e89, 0, "gMgB");
7193 ok(match, "Figure does not match.\n");
7194 match = compare_figure(&ctx, 320, 0, 160, 160, 0xff652e89, 0, "gMgB");
7195 ok(match, "Figure does not match.\n");
7196 match = compare_figure(&ctx, 480, 0, 160, 160, 0xff652e89, 0, "gMgB");
7197 ok(match, "Figure does not match.\n");
7199 match = compare_figure(&ctx, 0, 160, 160, 160, 0xff652e89, 0, "gMgB");
7200 ok(match, "Figure does not match.\n");
7201 match = compare_figure(&ctx, 160, 160, 160, 160, 0xff652e89, 0, "gMgB");
7202 ok(match, "Figure does not match.\n");
7203 match = compare_figure(&ctx, 320, 160, 160, 160, 0xff652e89, 0, "gMgB");
7204 ok(match, "Figure does not match.\n");
7205 match = compare_figure(&ctx, 480, 160, 160, 160, 0xff652e89, 0, "gMgB");
7206 ok(match, "Figure does not match.\n");
7208 match = compare_figure(&ctx, 0, 320, 160, 160, 0xff652e89, 0,
7209 "7zMCngECnQEEnAEEmwEGmgEGmQEImAEIlwEKlgEKlQEMlAEMkwEOkgEOkQEQkAEQjwESjgESjQEU"
7210 "jAEUiwEWigEWiQEYiAEYhwEahgEahQEchAEcgwEeggEegQEggAEgfyJ+In0kfCR7JnomeSh4KHcq"
7211 "dip1LHQscy5yLnEwcDBvMm4ybTRsNGs2ajZpOGg4ZzpmOmU8ZDxjPmI+YUBgQF9CXkJdRFxEW0Za"
7212 "RllIWEhXSlZKVUxUTFNOUk5RUKgy");
7213 ok(match, "Figure does not match.\n");
7214 match = compare_figure(&ctx, 160, 320, 160, 160, 0xff652e89, 0,
7215 "qDJQUU5STlNMVExVSlZKV0hYSFlGWkZbRFxEXUJeQl9AYEBhPmI+YzxkPGU6ZjpnOGg4aTZqNms0"
7216 "bDRtMm4ybzBwMHEuci5zLHQsdSp2KncoeCh5JnomeyR8JH0ifiJ/IIABIIEBHoIBHoMBHIQBHIUB"
7217 "GoYBGocBGIgBGIkBFooBFosBFIwBFI0BEo4BEo8BEJABEJEBDpIBDpMBDJQBDJUBCpYBCpcBCJgB"
7218 "CJkBBpoBBpsBBJwBBJ0BAp4BAu8z");
7219 ok(match, "Figure does not match.\n");
7220 match = compare_figure(&ctx, 320, 320, 160, 160, 0xff652e89, 0,
7221 "7zMCngECnQEEnAEEmwEGmgEGmQEImAEIlwEKlgEKlQEMlAEMkwEOkgEOkQEQkAEQjwESjgESjQEU"
7222 "jAEUiwEWigEWiQEYiAEYhwEahgEahQEchAEcgwEeggEegQEggAEgfyJ+In0kfCR7JnomeSh4KHcq"
7223 "dip1LHQscy5yLnEwcDBvMm4ybTRsNGs2ajZpOGg4ZzpmOmU8ZDxjPmI+YUBgQF9CXkJdRFxEW0Za"
7224 "RllIWEhXSlZKVUxUTFNOUk5RUKgy");
7225 ok(match, "Figure does not match.\n");
7226 match = compare_figure(&ctx, 480, 320, 160, 160, 0xff652e89, 0,
7227 "qDJQUU5STlNMVExVSlZKV0hYSFlGWkZbRFxEXUJeQl9AYEBhPmI+YzxkPGU6ZjpnOGg4aTZqNms0"
7228 "bDRtMm4ybzBwMHEuci5zLHQsdSp2KncoeCh5JnomeyR8JH0ifiJ/IIABIIEBHoIBHoMBHIQBHIUB"
7229 "GoYBGocBGIgBGIkBFooBFosBFIwBFI0BEo4BEo8BEJABEJEBDpIBDpMBDJQBDJUBCpYBCpcBCJgB"
7230 "CJkBBpoBBpsBBJwBBJ0BAp4BAu8z");
7231 ok(match, "Figure does not match.\n");
7233 set_rect(&rect, 20.0f, 80.0f, 60.0f, 240.0f);
7234 hr = ID2D1Factory_CreateRectangleGeometry(factory, &rect, &rect_geometry[0]);
7235 ok(SUCCEEDED(hr), "Failed to create geometry, hr %#x.\n", hr);
7237 set_rect(&rect, -1.0f, -1.0f, 1.0f, 1.0f);
7238 hr = ID2D1Factory_CreateRectangleGeometry(factory, &rect, &rect_geometry[1]);
7239 ok(SUCCEEDED(hr), "Failed to create geometry, hr %#x.\n", hr);
7241 set_matrix_identity(&matrix);
7242 translate_matrix(&matrix, 160.0f, 640.0f);
7243 scale_matrix(&matrix, 40.0f, 160.0f);
7244 rotate_matrix(&matrix, M_PI / -5.0f);
7245 hr = ID2D1Factory_CreateTransformedGeometry(factory,
7246 (ID2D1Geometry *)rect_geometry[1], &matrix, &transformed_geometry[0]);
7247 ok(SUCCEEDED(hr), "Failed to create geometry, hr %#x.\n", hr);
7249 set_matrix_identity(&matrix);
7250 scale_matrix(&matrix, 0.5f, 1.0f);
7251 translate_matrix(&matrix, -80.0f, 0.0f);
7252 hr = ID2D1Factory_CreateTransformedGeometry(factory,
7253 (ID2D1Geometry *)transformed_geometry[0], &matrix, &transformed_geometry[1]);
7254 ok(SUCCEEDED(hr), "Failed to create geometry, hr %#x.\n", hr);
7256 set_matrix_identity(&matrix);
7257 rotate_matrix(&matrix, M_PI / 2.0f);
7258 translate_matrix(&matrix, 80.0f, -320.0f);
7259 scale_matrix(&matrix, 2.0f, 0.25f);
7260 hr = ID2D1Factory_CreateTransformedGeometry(factory,
7261 (ID2D1Geometry *)transformed_geometry[1], &matrix, &transformed_geometry[2]);
7262 ok(SUCCEEDED(hr), "Failed to create geometry, hr %#x.\n", hr);
7264 ID2D1RenderTarget_BeginDraw(rt);
7265 ID2D1RenderTarget_Clear(rt, &color);
7266 ID2D1RenderTarget_FillGeometry(rt, (ID2D1Geometry *)rect_geometry[0], (ID2D1Brush *)brush, NULL);
7267 ID2D1RenderTarget_FillGeometry(rt, (ID2D1Geometry *)transformed_geometry[0], (ID2D1Brush *)brush, NULL);
7268 ID2D1RenderTarget_FillGeometry(rt, (ID2D1Geometry *)transformed_geometry[1], (ID2D1Brush *)brush, NULL);
7269 ID2D1RenderTarget_FillGeometry(rt, (ID2D1Geometry *)transformed_geometry[2], (ID2D1Brush *)brush, NULL);
7270 hr = ID2D1RenderTarget_EndDraw(rt, NULL, NULL);
7271 ok(SUCCEEDED(hr), "Failed to end draw, hr %#x.\n", hr);
7272 ID2D1TransformedGeometry_Release(transformed_geometry[2]);
7273 ID2D1TransformedGeometry_Release(transformed_geometry[1]);
7274 ID2D1TransformedGeometry_Release(transformed_geometry[0]);
7275 ID2D1RectangleGeometry_Release(rect_geometry[1]);
7276 ID2D1RectangleGeometry_Release(rect_geometry[0]);
7278 match = compare_figure(&ctx, 0, 0, 160, 160, 0xff652e89, 0,
7279 "qDJQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQ"
7280 "UFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQ"
7281 "UFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFCoMgAA");
7282 ok(match, "Figure does not match.\n");
7283 match = compare_figure(&ctx, 160, 0, 320, 160, 0xff652e89, 32,
7284 "sIMBA7cCDK8CFKYCHZ4CJJYCLY4CNYUCPv0BRvQBT+wBV+MBYNsBaNIBccoBecEBgQG6AYkBsQGS"
7285 "AakBmgGgAaMBmAGrAY8BtAGHAbwBfsUBfcYBfcYBfcUBfsUBfcYBfcYBfcYBfcYBfcUBfr0BhgG0"
7286 "AY8BrAGXAaMBoAGbAagBkgGwAYsBuAGCAcEBeskBcdIBadoBYOMBWOsBT/QBR/wBPoUCNowCLpUC"
7287 "Jp0CHaYCFa4CDLcCBK+DAQAA");
7288 ok(match, "Figure does not match.\n");
7289 match = compare_figure(&ctx, 0, 160, 160, 320, 0xff652e89, 32,
7290 "+D0BngEDnQEDnAEEmwEGmgEGmQEHmAEJlwEJlgELlAEMkwENkwEOkQEPkAEQkAERjgESjQETjQEU"
7291 "iwEVigEXiQEXiAEYhwEahgEahQEbhAEdggEeggEegQEgfyF/In0jfCR8JXomeSd5KHcpdip2K3Qs"
7292 "cy5xL3EvcDFuMm4ybTRrNWs1ajdoOGg5ZjplO2U8Yz1iPmFAYEBfQV5DXUNcRVpGWkZZSFdJV0lW"
7293 "S1RMVExTTlFPUFFPUU5STVRMVEtVSldJV0hYR1pGWkVcQ11CXkJfQGA/YT9iPWM+Yj5jPWM+Yz1j"
7294 "PWM+Yz1jPmI+Yz1jPmI+Yz1jPmM9Yz1jPmM9Yz5iPmM9Yz5iPmM9Yz5jPWM9Yz5jPWM+Yj5jPWM+"
7295 "Yj5jPWI/YT9gQF9CXkJdRFtFW0VaR1hIV0lXSlVLVExUTVJOUVBQUE9RTlNNU0xUS1ZKVklXSFlG"
7296 "WkZaRVxDXUNeQV9AYEBhPmI9Yz1kO2U6ZjpnOGg3ajVrNWs0bTJuMm4xcC9xL3Eucyx0LHUqdil3"
7297 "KXgneSZ6JXwkfCN9In8hfyCBAR6CAR6CAR2EARuFARuFARqHARiIAReJAReKARWLARSNARONARKO"
7298 "ARGQARCQAQ+RAQ6TAQ2TAQyUAQuWAQqWAQmYAQeZAQaaAQabAQScAQOdAQOeAQH4PQAA");
7299 ok(match, "Figure does not match.\n");
7300 match = compare_figure(&ctx, 160, 160, 320, 320, 0xff652e89, 32,
7301 "sXkBvgIDvAIEugIHuAIJtgILswINsgIPrwISrQITrAIVqQIYpwIapQIbowIeoQIgngIjnAIkmwIm"
7302 "mAIplgIqlQIskgIvkAIxjQIzjAI1igI3hwI5hgI7hAI9gQJA/wFB/QFE+wFG+QFI9gFK9QFM8wFO"
7303 "8AFQ7wFS7AFV6gFX6AFY5gFb5AFd4gFf3wFh3gFj2wFm2QFn2AFp1QFs0wFu0QFvzwFyzQF0ygF3"
7304 "yAF4xwF6xAF9wgF+wAGBAb4BgwG8AYUBuQGHAbgBiQG2AYsBswGOAbEBjwGvAZIBrQGUAasBlQGp"
7305 "AZgBpwGaAaUBnAGiAZ4BoQGgAZ4BowGcAaUBmgGmAZgBqQGWAasBlAGsAZIBrwGQAbEBjQG0AYsB"
7306 "tQGKAbcBhwG6AYUBvAGDAb0BgQHAAX/CAXzEAXvGAXvGAXvGAXvFAXvGAXvGAXvGAXvFAXvGAXvG"
7307 "AXvFAXvGAXvGAXvGAXvFAXvGAXvGAXvFAXzFAXvGAXvGAXvFAXvGAXvGAXvGAXvFAXvGAXvGAXvF"
7308 "AXzFAXvGAXvGAXvFAXvGAXvGAXvGAXvEAXzCAX/AAYEBvgGCAbwBhQG6AYcBtwGKAbUBiwG0AY0B"
7309 "sQGQAa8BkgGtAZMBqwGWAakBmAGmAZoBpQGcAaMBngGgAaEBngGiAZ0BpAGaAacBmAGpAZUBqwGU"
7310 "Aa0BkgGvAY8BsQGOAbMBjAG1AYkBuAGHAbkBhQG8AYMBvgGBAcABfsIBfcQBe8YBeMgBd8oBdM0B"
7311 "cs8BcNABbtMBbNUBatcBZ9kBZtsBY94BYd8BYOEBXeQBW+YBWOgBV+oBVewBUu8BUPABT/IBTPUB"
7312 "SvYBSPkBRvsBRP0BQf8BQIECPoMCO4YCOYcCN4oCNYwCM40CMZACL5ICLZQCKpYCKZgCJpsCJJ0C"
7313 "Ip4CIKECHqMCHKQCGqcCGKkCFawCE60CEq8CD7ICDbMCDLUCCbgCB7oCBLwCA74CAbF5");
7314 ok(match, "Figure does not match.\n");
7316 hr = ID2D1Factory_CreatePathGeometry(factory, &geometry);
7317 ok(SUCCEEDED(hr), "Failed to create path geometry, hr %#x.\n", hr);
7318 hr = ID2D1PathGeometry_Open(geometry, &sink);
7319 ok(SUCCEEDED(hr), "Failed to open geometry sink, hr %#x.\n", hr);
7321 set_point(&point, 20.0f, 80.0f);
7322 ID2D1GeometrySink_BeginFigure(sink, point, D2D1_FIGURE_BEGIN_FILLED);
7323 quadratic_to(sink, 40.0f, 80.0f, 60.0f, 80.0f);
7324 quadratic_to(sink, 60.0f, 160.0f, 60.0f, 240.0f);
7325 quadratic_to(sink, 40.0f, 240.0f, 20.0f, 240.0f);
7326 quadratic_to(sink, 20.0f, 160.0f, 20.0f, 80.0f);
7327 ID2D1GeometrySink_EndFigure(sink, D2D1_FIGURE_END_CLOSED);
7329 set_point(&point, 100.0f, 80.0f);
7330 ID2D1GeometrySink_BeginFigure(sink, point, D2D1_FIGURE_BEGIN_FILLED);
7331 quadratic_to(sink, 105.0f, 80.0f, 140.0f, 80.0f);
7332 quadratic_to(sink, 140.0f, 100.0f, 140.0f, 240.0f);
7333 quadratic_to(sink, 135.0f, 240.0f, 100.0f, 240.0f);
7334 quadratic_to(sink, 100.0f, 220.0f, 100.0f, 80.0f);
7335 ID2D1GeometrySink_EndFigure(sink, D2D1_FIGURE_END_CLOSED);
7337 set_point(&point, 180.0f, 80.0f);
7338 ID2D1GeometrySink_BeginFigure(sink, point, D2D1_FIGURE_BEGIN_FILLED);
7339 quadratic_to(sink, 215.0f, 80.0f, 220.0f, 80.0f);
7340 quadratic_to(sink, 220.0f, 220.0f, 220.0f, 240.0f);
7341 quadratic_to(sink, 185.0f, 240.0f, 180.0f, 240.0f);
7342 quadratic_to(sink, 180.0f, 100.0f, 180.0f, 80.0f);
7343 ID2D1GeometrySink_EndFigure(sink, D2D1_FIGURE_END_CLOSED);
7345 set_point(&point, 260.0f, 80.0f);
7346 ID2D1GeometrySink_BeginFigure(sink, point, D2D1_FIGURE_BEGIN_FILLED);
7347 quadratic_to(sink, 280.0f, 80.0f, 300.0f, 80.0f);
7348 quadratic_to(sink, 300.0f, 160.0f, 300.0f, 240.0f);
7349 quadratic_to(sink, 280.0f, 240.0f, 260.0f, 240.0f);
7350 quadratic_to(sink, 260.0f, 160.0f, 260.0f, 80.0f);
7351 ID2D1GeometrySink_EndFigure(sink, D2D1_FIGURE_END_OPEN);
7353 set_point(&point, 20.0f, 400.0f);
7354 ID2D1GeometrySink_BeginFigure(sink, point, D2D1_FIGURE_BEGIN_FILLED);
7355 quadratic_to(sink, 40.0f, 420.0f, 60.0f, 400.0f);
7356 quadratic_to(sink, 55.0f, 480.0f, 60.0f, 560.0f);
7357 quadratic_to(sink, 40.0f, 540.0f, 20.0f, 560.0f);
7358 quadratic_to(sink, 25.0f, 480.0f, 20.0f, 400.0f);
7359 ID2D1GeometrySink_EndFigure(sink, D2D1_FIGURE_END_CLOSED);
7361 set_point(&point, 100.0f, 400.0f);
7362 ID2D1GeometrySink_BeginFigure(sink, point, D2D1_FIGURE_BEGIN_FILLED);
7363 quadratic_to(sink, 105.0f, 420.0f, 140.0f, 400.0f);
7364 quadratic_to(sink, 135.0f, 420.0f, 140.0f, 560.0f);
7365 quadratic_to(sink, 135.0f, 540.0f, 100.0f, 560.0f);
7366 quadratic_to(sink, 105.0f, 540.0f, 100.0f, 400.0f);
7367 ID2D1GeometrySink_EndFigure(sink, D2D1_FIGURE_END_CLOSED);
7369 set_point(&point, 180.0f, 400.0f);
7370 ID2D1GeometrySink_BeginFigure(sink, point, D2D1_FIGURE_BEGIN_FILLED);
7371 quadratic_to(sink, 215.0f, 420.0f, 220.0f, 400.0f);
7372 quadratic_to(sink, 215.0f, 540.0f, 220.0f, 560.0f);
7373 quadratic_to(sink, 185.0f, 540.0f, 180.0f, 560.0f);
7374 quadratic_to(sink, 185.0f, 420.0f, 180.0f, 400.0f);
7375 ID2D1GeometrySink_EndFigure(sink, D2D1_FIGURE_END_CLOSED);
7377 set_point(&point, 260.0f, 400.0f);
7378 ID2D1GeometrySink_BeginFigure(sink, point, D2D1_FIGURE_BEGIN_FILLED);
7379 quadratic_to(sink, 280.0f, 420.0f, 300.0f, 400.0f);
7380 quadratic_to(sink, 295.0f, 480.0f, 300.0f, 560.0f);
7381 quadratic_to(sink, 280.0f, 540.0f, 260.0f, 560.0f);
7382 quadratic_to(sink, 265.0f, 480.0f, 260.0f, 400.0f);
7383 ID2D1GeometrySink_EndFigure(sink, D2D1_FIGURE_END_OPEN);
7385 set_point(&point, 20.0f, 720.0f);
7386 ID2D1GeometrySink_BeginFigure(sink, point, D2D1_FIGURE_BEGIN_FILLED);
7387 quadratic_to(sink, 40.0f, 700.0f, 60.0f, 720.0f);
7388 quadratic_to(sink, 65.0f, 800.0f, 60.0f, 880.0f);
7389 quadratic_to(sink, 40.0f, 900.0f, 20.0f, 880.0f);
7390 quadratic_to(sink, 15.0f, 800.0f, 20.0f, 720.0f);
7391 ID2D1GeometrySink_EndFigure(sink, D2D1_FIGURE_END_CLOSED);
7393 set_point(&point, 100.0f, 720.0f);
7394 ID2D1GeometrySink_BeginFigure(sink, point, D2D1_FIGURE_BEGIN_FILLED);
7395 quadratic_to(sink, 105.0f, 700.0f, 140.0f, 720.0f);
7396 quadratic_to(sink, 145.0f, 740.0f, 140.0f, 880.0f);
7397 quadratic_to(sink, 135.0f, 900.0f, 100.0f, 880.0f);
7398 quadratic_to(sink, 95.0f, 860.0f, 100.0f, 720.0f);
7399 ID2D1GeometrySink_EndFigure(sink, D2D1_FIGURE_END_CLOSED);
7401 set_point(&point, 180.0f, 720.0f);
7402 ID2D1GeometrySink_BeginFigure(sink, point, D2D1_FIGURE_BEGIN_FILLED);
7403 quadratic_to(sink, 215.0f, 700.0f, 220.0f, 720.0f);
7404 quadratic_to(sink, 225.0f, 860.0f, 220.0f, 880.0f);
7405 quadratic_to(sink, 185.0f, 900.0f, 180.0f, 880.0f);
7406 quadratic_to(sink, 175.0f, 740.0f, 180.0f, 720.0f);
7407 ID2D1GeometrySink_EndFigure(sink, D2D1_FIGURE_END_CLOSED);
7409 set_point(&point, 260.0f, 720.0f);
7410 ID2D1GeometrySink_BeginFigure(sink, point, D2D1_FIGURE_BEGIN_FILLED);
7411 quadratic_to(sink, 280.0f, 700.0f, 300.0f, 720.0f);
7412 quadratic_to(sink, 305.0f, 800.0f, 300.0f, 880.0f);
7413 quadratic_to(sink, 280.0f, 900.0f, 260.0f, 880.0f);
7414 quadratic_to(sink, 255.0f, 800.0f, 260.0f, 720.0f);
7415 ID2D1GeometrySink_EndFigure(sink, D2D1_FIGURE_END_OPEN);
7417 hr = ID2D1GeometrySink_Close(sink);
7418 ok(SUCCEEDED(hr), "Failed to close geometry sink, hr %#x.\n", hr);
7419 ID2D1GeometrySink_Release(sink);
7421 ID2D1RenderTarget_BeginDraw(rt);
7422 ID2D1RenderTarget_Clear(rt, &color);
7423 ID2D1RenderTarget_FillGeometry(rt, (ID2D1Geometry *)geometry, (ID2D1Brush *)brush, NULL);
7424 hr = ID2D1RenderTarget_EndDraw(rt, NULL, NULL);
7425 ok(SUCCEEDED(hr), "Failed to end draw, hr %#x.\n", hr);
7426 ID2D1PathGeometry_Release(geometry);
7428 match = compare_figure(&ctx, 0, 0, 160, 160, 0xff652e89, 0,
7429 "qDJQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQ"
7430 "UFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQ"
7431 "UFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFCoMgAA");
7432 ok(match, "Figure does not match.\n");
7433 match = compare_figure(&ctx, 160, 0, 160, 160, 0xff652e89, 0,
7434 "qDJQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQ"
7435 "UFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQ"
7436 "UFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFCoMgAA");
7437 match = compare_figure(&ctx, 320, 0, 160, 160, 0xff652e89, 0,
7438 "qDJQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQ"
7439 "UFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQ"
7440 "UFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFCoMgAA");
7441 ok(match, "Figure does not match.\n");
7442 match = compare_figure(&ctx, 480, 0, 160, 160, 0xff652e89, 0,
7443 "qDJQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQ"
7444 "UFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQ"
7445 "UFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFCoMgAA");
7446 ok(match, "Figure does not match.\n");
7448 match = compare_figure(&ctx, 0, 160, 160, 160, 0xff652e89, 16,
7449 "qDICTAJQB0IHUQs4C1IRLBFSGxgbUk5STlNMVExUTFRMVExVSlZKVkpWSlZKVkpXSFhIWEhYSFhI"
7450 "WEhYSFhIWEhYSFlGWkZaRlpGWkZaRlpGWkZaRlpGWkZaRlpGWkZaRlpGWkZaRlpGWkZaRlpGWkZa"
7451 "RllIWEhYSFhIWEhYSFhIWEhYSFhIV0pWSlZKVkpWSlZKVUxUTFRMVExUTFNOUk5SGxgbUhEsEVIL"
7452 "OAtRB0IHUAJMAqgy");
7453 ok(match, "Figure does not match.\n");
7454 match = compare_figure(&ctx, 160, 160, 160, 160, 0xff652e89, 16,
7455 "qDIBSwRQAkMKUQQ5EVIIKxtTDRkmVExUTFRMVEtVS1VLVkpWSlZKVklXSVdJV0lXSVhIWEhYSFhI"
7456 "WEhYSFhIWEhYSFhIWUdZR1lHWUdZR1lHWUdZR1lHWUdZSFhIWUdZR1lHWUdZR1lHWUdZR1lHWUdZ"
7457 "SFhIWEhYSFhIWEhYSFhIWEhYSFhJV0lXSVdJV0lWSlZKVkpWS1VLVUtUTFRMVExUJhkNUxsrCFIR"
7458 "OQRRCkMCUARLAagy");
7459 ok(match, "Figure does not match.\n");
7460 match = compare_figure(&ctx, 320, 160, 160, 160, 0xff652e89, 16,
7461 "qDIESwFRCkMCUhE5BFIbKwhTJhkNVExUTFRMVUtVS1VLVUpWSlZKV0lXSVdJV0lXSVdIWEhYSFhI"
7462 "WEhYSFhIWEhYSFhIWEdZR1lHWUdZR1lHWUdZR1lHWUdYSFhIWEdZR1lHWUdZR1lHWUdZR1lHWUdY"
7463 "SFhIWEhYSFhIWEhYSFhIWEhYSFdJV0lXSVdJV0lXSlZKVkpVS1VLVUtVTFRMVExUDRkmUwgrG1IE"
7464 "ORFSAkMKUQFLBKgy");
7465 ok(match, "Figure does not match.\n");
7466 match = compare_figure(&ctx, 480, 160, 160, 160, 0xff652e89, 16,
7467 "qDICTAJQB0IHUQs4C1IRLBFSGxgbUk5STlNMVExUTFRMVExVSlZKVkpWSlZKVkpXSFhIWEhYSFhI"
7468 "WEhYSFhIWEhYSFlGWkZaRlpGWkZaRlpGWkZaRlpGWkZaRlpGWkZaRlpGWkZaRlpGWkZaRlpGWkZa"
7469 "RllIWEhYSFhIWEhYSFhIWEhYSFhIV0pWSlZKVkpWSlZKVUxUTFRMVExUTFNOUk5SGxgbUhEsEVIL"
7470 "OAtRB0IHUAJMAqgy");
7471 ok(match, "Figure does not match.\n");
7473 match = compare_figure(&ctx, 0, 320, 160, 160, 0xff652e89, 16,
7474 "pCwYfixuOGNCWUxSUFBQT1JOUk5STlJOUk1UTFRMVExUTFRLVkpWSlZKVkpWSlZJWEhYSFhIWEhY"
7475 "SFhIWEhYSFhIWEdaRlpGWkZaRlpGWkZaRlpGWkZaRlpGWkZaRlpGWkZaRlpGWkZaRlpGWkZaRlpG"
7476 "WkdYSFhIWEhYSFhIWEhYSFhIWEhYSVZKVkpWSlZKVkpWS1RMVExUTFRMVE1STlJOUk5STlJPUFBQ"
7477 "UkxZQmM4bix+GKQs");
7478 ok(match, "Figure does not match.\n");
7479 match = compare_figure(&ctx, 160, 320, 160, 160, 0xff652e89, 16,
7480 "liwZgQErcTllQ1xLVFBQUU9STlJNVExUTFRMVExVS1VLVUpWSlZKVkpXSVdJV0lXSVdIWEhYSFhI"
7481 "WEhYSFhIWEhYSFhIWEdZR1lHWUdZR1lHWUdZR1lHWUdZR1hIWEdZR1lHWUdZR1lHWUdZR1lHWUdZ"
7482 "R1hIWEhYSFhIWEhYSFhIWEhYSFhIV0lXSVdJV0lXSlZKVkpWSlVLVUtVTFRMVExUTFRNUk5ST1FQ"
7483 "UFRLXENlOXErgQEZliwA");
7484 ok(match, "Figure does not match.\n");
7485 match = compare_figure(&ctx, 320, 320, 160, 160, 0xff652e89, 16,
7486 "sSwZeytrOV9DVktRUE9RTlJOUk1UTFRMVExUS1VLVUtVS1ZKVkpWSVdJV0lXSVdJV0lYSFhIWEhY"
7487 "SFhIWEhYSFhIWEhYSFlHWUdZR1lHWUdZR1lHWUdZR1lIWEhYSFlHWUdZR1lHWUdZR1lHWUdZR1lI"
7488 "WEhYSFhIWEhYSFhIWEhYSFhIWElXSVdJV0lXSVdJVkpWSlZLVUtVS1VLVExUTFRMVE1STlJOUU9Q"
7489 "UUtWQ185ayt7GbEs");
7490 ok(match, "Figure does not match.\n");
7491 match = compare_figure(&ctx, 480, 320, 160, 160, 0xff652e89, 16,
7492 "pCwYfixuOGNCWUxSUFBQT1JOUk5STlJOUk1UTFRMVExUTFRLVkpWSlZKVkpWSlZJWEhYSFhIWEhY"
7493 "SFhIWEhYSFhIWEdaRlpGWkZaRlpGWkZaRlpGWkZaRlpGWkZaRlpGWkZaRlpGWkZaRlpGWkZaRlpG"
7494 "WkdYSFhIWEhYSFhIWEhYSFhIWEhYSVZKVkpWSlZKVkpWS1RMVExUTFRMVE1STlJOUk5STlJPUFBQ"
7495 "UkxZQmM4bix+GKQs");
7496 ok(match, "Figure does not match.\n");
7498 hr = ID2D1Factory_CreatePathGeometry(factory, &geometry);
7499 ok(SUCCEEDED(hr), "Failed to create path geometry, hr %#x.\n", hr);
7500 hr = ID2D1PathGeometry_Open(geometry, &sink);
7501 ok(SUCCEEDED(hr), "Failed to open geometry sink, hr %#x.\n", hr);
7503 set_point(&point, -0.402914f, 0.915514f);
7504 ID2D1GeometrySink_BeginFigure(sink, point, D2D1_FIGURE_BEGIN_FILLED);
7505 quadratic_to(sink, -0.310379f, 0.882571f, -0.116057f, 0.824000f);
7506 quadratic_to(sink, 0.008350f, 0.693614f, -0.052343f, 0.448886f);
7507 quadratic_to(sink, -0.154236f, 0.246072f, -0.279229f, 0.025343f);
7508 quadratic_to(sink, -0.370064f, -0.588586f, -0.383029f, -0.924114f);
7509 quadratic_to(sink, -0.295479f, -0.958764f, -0.017086f, -0.988400f);
7510 quadratic_to(sink, 0.208836f, -0.954157f, 0.272200f, -0.924114f);
7511 quadratic_to(sink, 0.295614f, -0.569071f, 0.230143f, 0.022886f);
7512 quadratic_to(sink, 0.101664f, 0.220643f, 0.012057f, 0.451571f);
7513 quadratic_to(sink, -0.028764f, 0.709014f, 0.104029f, 0.833943f);
7514 quadratic_to(sink, 0.319414f, 0.913057f, 0.403229f, 0.942628f);
7515 quadratic_to(sink, 0.317721f, 1.023450f, -0.017086f, 1.021771f);
7516 quadratic_to(sink, -0.310843f, 1.007472f, -0.402914f, 0.915514f);
7517 ID2D1GeometrySink_EndFigure(sink, D2D1_FIGURE_END_CLOSED);
7519 hr = ID2D1GeometrySink_Close(sink);
7520 ok(SUCCEEDED(hr), "Failed to close geometry sink, hr %#x.\n", hr);
7521 ID2D1GeometrySink_Release(sink);
7523 set_matrix_identity(&matrix);
7524 translate_matrix(&matrix, 40.0f, 160.0f);
7525 scale_matrix(&matrix, 20.0f, 80.0f);
7526 hr = ID2D1Factory_CreateTransformedGeometry(factory,
7527 (ID2D1Geometry *)geometry, &matrix, &transformed_geometry[0]);
7528 ok(SUCCEEDED(hr), "Failed to create geometry, hr %#x.\n", hr);
7530 set_matrix_identity(&matrix);
7531 translate_matrix(&matrix, 160.0f, 640.0f);
7532 scale_matrix(&matrix, 40.0f, 160.0f);
7533 rotate_matrix(&matrix, M_PI / -5.0f);
7534 hr = ID2D1Factory_CreateTransformedGeometry(factory,
7535 (ID2D1Geometry *)geometry, &matrix, &transformed_geometry[1]);
7536 ok(SUCCEEDED(hr), "Failed to create geometry, hr %#x.\n", hr);
7537 ID2D1PathGeometry_Release(geometry);
7539 set_matrix_identity(&matrix);
7540 scale_matrix(&matrix, 0.5f, 1.0f);
7541 translate_matrix(&matrix, -80.0f, 0.0f);
7542 hr = ID2D1Factory_CreateTransformedGeometry(factory,
7543 (ID2D1Geometry *)transformed_geometry[1], &matrix, &transformed_geometry[2]);
7544 ok(SUCCEEDED(hr), "Failed to create geometry, hr %#x.\n", hr);
7546 set_matrix_identity(&matrix);
7547 rotate_matrix(&matrix, M_PI / 2.0f);
7548 translate_matrix(&matrix, 80.0f, -320.0f);
7549 scale_matrix(&matrix, 2.0f, 0.25f);
7550 hr = ID2D1Factory_CreateTransformedGeometry(factory,
7551 (ID2D1Geometry *)transformed_geometry[2], &matrix, &transformed_geometry[3]);
7552 ok(SUCCEEDED(hr), "Failed to create geometry, hr %#x.\n", hr);
7554 ID2D1RenderTarget_BeginDraw(rt);
7555 ID2D1RenderTarget_Clear(rt, &color);
7556 ID2D1RenderTarget_FillGeometry(rt, (ID2D1Geometry *)transformed_geometry[0], (ID2D1Brush *)brush, NULL);
7557 ID2D1RenderTarget_FillGeometry(rt, (ID2D1Geometry *)transformed_geometry[1], (ID2D1Brush *)brush, NULL);
7558 ID2D1RenderTarget_FillGeometry(rt, (ID2D1Geometry *)transformed_geometry[2], (ID2D1Brush *)brush, NULL);
7559 ID2D1RenderTarget_FillGeometry(rt, (ID2D1Geometry *)transformed_geometry[3], (ID2D1Brush *)brush, NULL);
7560 hr = ID2D1RenderTarget_EndDraw(rt, NULL, NULL);
7561 ok(SUCCEEDED(hr), "Failed to end draw, hr %#x.\n", hr);
7562 ID2D1TransformedGeometry_Release(transformed_geometry[3]);
7563 ID2D1TransformedGeometry_Release(transformed_geometry[2]);
7564 ID2D1TransformedGeometry_Release(transformed_geometry[1]);
7565 ID2D1TransformedGeometry_Release(transformed_geometry[0]);
7567 match = compare_figure(&ctx, 0, 0, 160, 160, 0xff652e89, 32,
7568 "6DMNjgEWiAEahgEahgEahgEahgEahgEahgEahgEahgEahgEahgEahwEZhwEZhwEZhwEZhwEZhwEZ"
7569 "hwEZhwEZhwEZiAEYiAEYiAEYiAEYiAEXiQEXiQEXiQEXigEWigEWigEWigEWigEWigEWigEWiwEU"
7570 "jAEUjAEUjAEUjQESjgESjwEQkAEQkQEOkgENlAEMlQEKlgEKlwEImAEImQEHmQEGmwEFmwEEnQED"
7571 "nQECngECngECnwEBnwEBnwEBnwEBnwEBnwECnQEDnQEDnQEEmwEFmgEHmQEHlwELkQERjAEXhgEd"
7572 "hAEfgwEchgEXjwEMqTEA");
7573 ok(match, "Figure does not match.\n");
7574 match = compare_figure(&ctx, 160, 0, 320, 160, 0xff652e89, 32,
7575 "h58BBrYCDq0CF6QCIJwCKJMCMIwCNoUCPf8BQ/kBSPQBTu4BTe8BTPEBSfUBRvgBQf0BPYECOYUC"
7576 "NIoCMI4CK+UBAS0W/AEHIwiPAgsaBZcCEAwIngIepAIaqAIWrAITsAIRsgIPtQIMtwILugIHwAIB"
7577 "ypwB");
7578 ok(match, "Figure does not match.\n");
7579 match = compare_figure(&ctx, 0, 160, 160, 320, 0xff652e89, 32,
7580 "wW4DnAEEmwEFmgEHmAEIlwEKlQELlAEMkwEOkQEPkAEQkAERjgESjgETjAEUjAEUiwEWigEWiQEX"
7581 "iQEYhwEZhwEZhgEbhQEbhAEchAEdggEeggEeggEfgAEggAEggAEhgAEggAEggQEggAEggAEggQEg"
7582 "gAEggQEfgQEfggEfgQEfgQEfggEfgQEfggEeggEfggEeggEegwEdgwEeggEegwEdgwEegwEdgwEd"
7583 "hAEchAEdhAEchAEchAEdhAEchAEchQEbhQEbhgEahgEahwEZhwEZiAEYiAEYiQEYiAEYiQEXiQEX"
7584 "igEWigEWiwEViwEViwEVjAEUjAEUjQETjQETjgESjgETjgESjwERkAEQkQEPkwENlAEMlQELlgEK"
7585 "lwEKlwEJmAEImQEHmgEGmwEFnAEEnQEEnQEDnQEDngECngEDngECngECnwECngECnwECngECngED"
7586 "ngECEgGLAQMQAosBAw4EjAEDCwaMAQQJBo0BBQYIjQEHAgqNARKOARKPARCQARCQARCQAQ+RAQ6S"
7587 "AQ6SAQ2TAQ2SAQ2TAQ2TAQyTAQyUAQyUAQuUAQuVAQuUAQuVAQqWAQmWAQqWAQmXAQiXAQiYAQeY"
7588 "AQeZAQWbAQSDZwAA");
7589 ok(match, "Figure does not match.\n");
7590 match = compare_figure(&ctx, 160, 160, 320, 320, 0xff652e89, 32,
7591 "g90BBLkCCLYCC7ICDrACEa0CFKoCF6cCGqQCHKMCHqECIJ8CIpwCJJsCJpkCKJcCKZYCK5QCLZIC"
7592 "L5ACMI8CMo0CNIsCNYoCN4gCOYcCOYYCO4QCPYICPoECQIACQYACQIECQIACQIECQIECQIECP4IC"
7593 "P4ICP4ECP4ICP4ICPoMCPoMCPoMCPYQCPYMCPYQCPYQCPYQCPIUCPIUCPIUCO4YCO4YCOoYCO4YC"
7594 "OocCOocCOocCOYgCOYgCOIkCOIkCN4oCNosCNYwCNI0CM44CMo4CM44CMo8CMZACMJECL5ICLpMC"
7595 "LZQCLJUCK5YCK5YCKpcCKZgCKJkCJ5oCJpsCJpsCJZwCJJ4CIqACIKICH6MCHaUCG6cCGakCF6wC"
7596 "Fa0CE68CEbECD7MCDrQCDLYCCrgCCbkCB7sCBrsCBbwCBbwCBL0CBL0CBL0CBL0CA70CBL0CBL0C"
7597 "BLwCBSUBlgIFIQSXAgYbCJcCBxcKmQIIEQ6ZAgoMEJoCDQUTnAIknAIjnQIingIhnwIgoAIfoQIe"
7598 "ogIdowIcpAIbpQIapQIZpgIZpgIZpwIYpwIXqAIXqAIXqQIVqgIVqgIUqwITrQISrQIRrgIQsAIO"
7599 "sQIMswILtQIIhs4B");
7600 ok(match, "Figure does not match.\n");
7602 hr = ID2D1Factory_CreatePathGeometry(factory, &geometry);
7603 ok(SUCCEEDED(hr), "Failed to create path geometry, hr %#x.\n", hr);
7604 hr = ID2D1PathGeometry_Open(geometry, &sink);
7605 ok(SUCCEEDED(hr), "Failed to open geometry sink, hr %#x.\n", hr);
7607 set_point(&point, -0.402914f, 0.915514f);
7608 ID2D1GeometrySink_BeginFigure(sink, point, D2D1_FIGURE_BEGIN_HOLLOW);
7609 quadratic_to(sink, -0.310379f, 0.882571f, -0.116057f, 0.824000f);
7610 quadratic_to(sink, 0.008350f, 0.693614f, -0.052343f, 0.448886f);
7611 quadratic_to(sink, -0.154236f, 0.246072f, -0.279229f, 0.025343f);
7612 quadratic_to(sink, -0.370064f, -0.588586f, -0.383029f, -0.924114f);
7613 quadratic_to(sink, -0.295479f, -0.958764f, -0.017086f, -0.988400f);
7614 quadratic_to(sink, 0.208836f, -0.954157f, 0.272200f, -0.924114f);
7615 quadratic_to(sink, 0.295614f, -0.569071f, 0.230143f, 0.022886f);
7616 quadratic_to(sink, 0.101664f, 0.220643f, 0.012057f, 0.451571f);
7617 quadratic_to(sink, -0.028764f, 0.709014f, 0.104029f, 0.833943f);
7618 quadratic_to(sink, 0.319414f, 0.913057f, 0.403229f, 0.942628f);
7619 quadratic_to(sink, 0.317721f, 1.023450f, -0.017086f, 1.021771f);
7620 quadratic_to(sink, -0.310843f, 1.007472f, -0.402914f, 0.915514f);
7621 ID2D1GeometrySink_EndFigure(sink, D2D1_FIGURE_END_CLOSED);
7623 hr = ID2D1GeometrySink_Close(sink);
7624 ok(SUCCEEDED(hr), "Failed to close geometry sink, hr %#x.\n", hr);
7625 ID2D1GeometrySink_Release(sink);
7627 set_matrix_identity(&matrix);
7628 translate_matrix(&matrix, 40.0f, 160.0f);
7629 scale_matrix(&matrix, 20.0f, 80.0f);
7630 hr = ID2D1Factory_CreateTransformedGeometry(factory,
7631 (ID2D1Geometry *)geometry, &matrix, &transformed_geometry[0]);
7632 ok(SUCCEEDED(hr), "Failed to create geometry, hr %#x.\n", hr);
7634 set_matrix_identity(&matrix);
7635 translate_matrix(&matrix, 160.0f, 640.0f);
7636 scale_matrix(&matrix, 40.0f, 160.0f);
7637 rotate_matrix(&matrix, M_PI / -5.0f);
7638 hr = ID2D1Factory_CreateTransformedGeometry(factory,
7639 (ID2D1Geometry *)geometry, &matrix, &transformed_geometry[1]);
7640 ok(SUCCEEDED(hr), "Failed to create geometry, hr %#x.\n", hr);
7641 ID2D1PathGeometry_Release(geometry);
7643 set_matrix_identity(&matrix);
7644 scale_matrix(&matrix, 0.5f, 1.0f);
7645 translate_matrix(&matrix, -80.0f, 0.0f);
7646 hr = ID2D1Factory_CreateTransformedGeometry(factory,
7647 (ID2D1Geometry *)transformed_geometry[1], &matrix, &transformed_geometry[2]);
7648 ok(SUCCEEDED(hr), "Failed to create geometry, hr %#x.\n", hr);
7650 set_matrix_identity(&matrix);
7651 rotate_matrix(&matrix, M_PI / 2.0f);
7652 translate_matrix(&matrix, 80.0f, -320.0f);
7653 scale_matrix(&matrix, 2.0f, 0.25f);
7654 hr = ID2D1Factory_CreateTransformedGeometry(factory,
7655 (ID2D1Geometry *)transformed_geometry[2], &matrix, &transformed_geometry[3]);
7656 ok(SUCCEEDED(hr), "Failed to create geometry, hr %#x.\n", hr);
7658 ID2D1RenderTarget_BeginDraw(rt);
7659 ID2D1RenderTarget_Clear(rt, &color);
7660 ID2D1RenderTarget_FillGeometry(rt, (ID2D1Geometry *)transformed_geometry[0], (ID2D1Brush *)brush, NULL);
7661 ID2D1RenderTarget_FillGeometry(rt, (ID2D1Geometry *)transformed_geometry[1], (ID2D1Brush *)brush, NULL);
7662 ID2D1RenderTarget_FillGeometry(rt, (ID2D1Geometry *)transformed_geometry[2], (ID2D1Brush *)brush, NULL);
7663 ID2D1RenderTarget_FillGeometry(rt, (ID2D1Geometry *)transformed_geometry[3], (ID2D1Brush *)brush, NULL);
7664 hr = ID2D1RenderTarget_EndDraw(rt, NULL, NULL);
7665 ok(SUCCEEDED(hr), "Failed to end draw, hr %#x.\n", hr);
7666 ID2D1TransformedGeometry_Release(transformed_geometry[3]);
7667 ID2D1TransformedGeometry_Release(transformed_geometry[2]);
7668 ID2D1TransformedGeometry_Release(transformed_geometry[1]);
7669 ID2D1TransformedGeometry_Release(transformed_geometry[0]);
7671 match = compare_figure(&ctx, 0, 0, 160, 160, 0xff652e89, 0, "gMgB");
7672 ok(match, "Figure does not match.\n");
7673 match = compare_figure(&ctx, 160, 0, 320, 160, 0xff652e89, 0, "gJAD");
7674 ok(match, "Figure does not match.\n");
7675 match = compare_figure(&ctx, 0, 160, 160, 320, 0xff652e89, 0, "gJAD");
7676 ok(match, "Figure does not match.\n");
7677 match = compare_figure(&ctx, 160, 160, 320, 320, 0xff652e89, 0, "gKAG");
7678 ok(match, "Figure does not match.\n");
7680 ID2D1SolidColorBrush_Release(brush);
7681 ID2D1Factory_Release(factory);
7682 release_test_context(&ctx);
7685 static void test_gdi_interop(BOOL d3d11)
7687 ID2D1GdiInteropRenderTarget *interop;
7688 D2D1_RENDER_TARGET_PROPERTIES desc;
7689 IWICImagingFactory *wic_factory;
7690 struct d2d1_test_context ctx;
7691 IWICBitmapLock *wic_lock;
7692 IWICBitmap *wic_bitmap;
7693 ID2D1RenderTarget *rt;
7694 ID2D1Factory *factory;
7695 D2D1_COLOR_F color;
7696 HRESULT hr;
7697 BOOL match;
7698 RECT rect;
7699 HDC dc;
7701 if (!init_test_context(&ctx, d3d11))
7702 return;
7704 hr = D2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED, &IID_ID2D1Factory, NULL, (void **)&factory);
7705 ok(SUCCEEDED(hr), "Failed to create factory, hr %#x.\n", hr);
7707 CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
7708 hr = CoCreateInstance(&CLSID_WICImagingFactory, NULL, CLSCTX_INPROC_SERVER,
7709 &IID_IWICImagingFactory, (void **)&wic_factory);
7710 ok(SUCCEEDED(hr), "Failed to create WIC imaging factory, hr %#x.\n", hr);
7711 hr = IWICImagingFactory_CreateBitmap(wic_factory, 16, 16,
7712 &GUID_WICPixelFormat32bppPBGRA, WICBitmapCacheOnDemand, &wic_bitmap);
7713 ok(SUCCEEDED(hr), "Failed to create bitmap, hr %#x.\n", hr);
7714 IWICImagingFactory_Release(wic_factory);
7716 /* WIC target, default usage */
7717 desc.type = D2D1_RENDER_TARGET_TYPE_DEFAULT;
7718 desc.pixelFormat.format = DXGI_FORMAT_UNKNOWN;
7719 desc.pixelFormat.alphaMode = D2D1_ALPHA_MODE_PREMULTIPLIED;
7720 desc.dpiX = 0.0f;
7721 desc.dpiY = 0.0f;
7722 desc.usage = D2D1_RENDER_TARGET_USAGE_NONE;
7723 desc.minLevel = D2D1_FEATURE_LEVEL_DEFAULT;
7725 hr = ID2D1Factory_CreateWicBitmapRenderTarget(factory, wic_bitmap, &desc, &rt);
7726 ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr);
7728 hr = ID2D1RenderTarget_QueryInterface(rt, &IID_ID2D1GdiInteropRenderTarget, (void **)&interop);
7729 ok(SUCCEEDED(hr), "Failed to get gdi interop interface, hr %#x.\n", hr);
7731 ID2D1RenderTarget_BeginDraw(rt);
7732 dc = (void *)0xdeadbeef;
7733 hr = ID2D1GdiInteropRenderTarget_GetDC(interop, D2D1_DC_INITIALIZE_MODE_COPY, &dc);
7734 ok(FAILED(hr), "GetDC() was expected to fail, hr %#x.\n", hr);
7735 todo_wine
7736 ok(dc == NULL, "Expected NULL dc, got %p.\n", dc);
7737 ID2D1GdiInteropRenderTarget_Release(interop);
7738 hr = ID2D1RenderTarget_EndDraw(rt, NULL, NULL);
7739 ok(SUCCEEDED(hr), "Failed to end draw, hr %#x.\n", hr);
7741 ID2D1RenderTarget_Release(rt);
7743 /* WIC target, gdi compatible */
7744 desc.usage = D2D1_RENDER_TARGET_USAGE_GDI_COMPATIBLE;
7746 hr = ID2D1Factory_CreateWicBitmapRenderTarget(factory, wic_bitmap, &desc, &rt);
7747 ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr);
7749 hr = ID2D1RenderTarget_QueryInterface(rt, &IID_ID2D1GdiInteropRenderTarget, (void **)&interop);
7750 ok(SUCCEEDED(hr), "Failed to get gdi interop interface, hr %#x.\n", hr);
7752 ID2D1RenderTarget_BeginDraw(rt);
7753 dc = NULL;
7754 hr = ID2D1GdiInteropRenderTarget_GetDC(interop, D2D1_DC_INITIALIZE_MODE_COPY, &dc);
7755 ok(SUCCEEDED(hr), "GetDC() was expected to succeed, hr %#x.\n", hr);
7756 ok(dc != NULL, "Expected NULL dc, got %p.\n", dc);
7757 ID2D1GdiInteropRenderTarget_ReleaseDC(interop, NULL);
7758 hr = ID2D1RenderTarget_EndDraw(rt, NULL, NULL);
7759 ok(SUCCEEDED(hr), "EndDraw() failed, hr %#x.\n", hr);
7761 ID2D1RenderTarget_BeginDraw(rt);
7762 set_color(&color, 1.0f, 0.0f, 0.0f, 1.0f);
7763 ID2D1RenderTarget_Clear(rt, &color);
7764 hr = ID2D1RenderTarget_EndDraw(rt, NULL, NULL);
7765 ok(SUCCEEDED(hr), "EndDraw() failed, hr %#x.\n", hr);
7767 match = compare_wic_bitmap(wic_bitmap, "54034063dbc1c1bb61cb60ec57e4498678dc2b13");
7768 ok(match, "Bitmap does not match.\n");
7770 /* Do solid fill using GDI */
7771 ID2D1RenderTarget_BeginDraw(rt);
7773 hr = ID2D1GdiInteropRenderTarget_GetDC(interop, D2D1_DC_INITIALIZE_MODE_COPY, &dc);
7774 ok(SUCCEEDED(hr), "GetDC() was expected to succeed, hr %#x.\n", hr);
7776 SetRect(&rect, 0, 0, 16, 16);
7777 FillRect(dc, &rect, GetStockObject(BLACK_BRUSH));
7778 ID2D1GdiInteropRenderTarget_ReleaseDC(interop, NULL);
7780 hr = ID2D1RenderTarget_EndDraw(rt, NULL, NULL);
7781 ok(SUCCEEDED(hr), "EndDraw() failed, hr %#x.\n", hr);
7783 match = compare_wic_bitmap(wic_bitmap, "60cacbf3d72e1e7834203da608037b1bf83b40e8");
7784 ok(match, "Bitmap does not match.\n");
7786 /* Bitmap is locked at BeginDraw(). */
7787 hr = IWICBitmap_Lock(wic_bitmap, NULL, WICBitmapLockRead, &wic_lock);
7788 ok(SUCCEEDED(hr), "Expected bitmap to be unlocked, hr %#x.\n", hr);
7789 IWICBitmapLock_Release(wic_lock);
7791 ID2D1RenderTarget_BeginDraw(rt);
7792 hr = IWICBitmap_Lock(wic_bitmap, NULL, WICBitmapLockRead, &wic_lock);
7793 todo_wine
7794 ok(hr == WINCODEC_ERR_ALREADYLOCKED, "Expected bitmap to be locked, hr %#x.\n", hr);
7795 if (SUCCEEDED(hr))
7796 IWICBitmapLock_Release(wic_lock);
7797 hr = ID2D1RenderTarget_EndDraw(rt, NULL, NULL);
7798 ok(SUCCEEDED(hr), "EndDraw() failed, hr %#x.\n", hr);
7800 /* Lock before BeginDraw(). */
7801 hr = IWICBitmap_Lock(wic_bitmap, NULL, WICBitmapLockRead, &wic_lock);
7802 ok(SUCCEEDED(hr), "Expected bitmap to be unlocked, hr %#x.\n", hr);
7803 ID2D1RenderTarget_BeginDraw(rt);
7804 hr = ID2D1RenderTarget_EndDraw(rt, NULL, NULL);
7805 todo_wine
7806 ok(hr == WINCODEC_ERR_ALREADYLOCKED, "Unexpected hr %#x.\n", hr);
7807 IWICBitmapLock_Release(wic_lock);
7809 ID2D1GdiInteropRenderTarget_Release(interop);
7810 ID2D1RenderTarget_Release(rt);
7812 IWICBitmap_Release(wic_bitmap);
7813 ID2D1Factory_Release(factory);
7814 release_test_context(&ctx);
7817 static void test_layer(BOOL d3d11)
7819 ID2D1Factory *factory, *layer_factory;
7820 struct d2d1_test_context ctx;
7821 ID2D1RenderTarget *rt;
7822 ID2D1Layer *layer;
7823 D2D1_SIZE_F size;
7824 HRESULT hr;
7826 if (!init_test_context(&ctx, d3d11))
7827 return;
7829 rt = ctx.rt;
7830 ID2D1RenderTarget_GetFactory(rt, &factory);
7832 ID2D1RenderTarget_SetDpi(rt, 192.0f, 48.0f);
7833 ID2D1RenderTarget_SetAntialiasMode(rt, D2D1_ANTIALIAS_MODE_ALIASED);
7835 hr = ID2D1RenderTarget_CreateLayer(rt, NULL, &layer);
7836 ok(SUCCEEDED(hr), "Failed to create layer, hr %#x.\n", hr);
7837 ID2D1Layer_GetFactory(layer, &layer_factory);
7838 ok(layer_factory == factory, "Got unexpected layer factory %p, expected %p.\n", layer_factory, factory);
7839 ID2D1Factory_Release(layer_factory);
7840 size = ID2D1Layer_GetSize(layer);
7841 ok(size.width == 0.0f, "Got unexpected width %.8e.\n", size.width);
7842 ok(size.height == 0.0f, "Got unexpected height %.8e.\n", size.height);
7843 ID2D1Layer_Release(layer);
7845 set_size_f(&size, 800.0f, 600.0f);
7846 hr = ID2D1RenderTarget_CreateLayer(rt, &size, &layer);
7847 ok(SUCCEEDED(hr), "Failed to create layer, hr %#x.\n", hr);
7848 size = ID2D1Layer_GetSize(layer);
7849 ok(size.width == 800.0f, "Got unexpected width %.8e.\n", size.width);
7850 ok(size.height == 600.0f, "Got unexpected height %.8e.\n", size.height);
7851 ID2D1Layer_Release(layer);
7853 ID2D1Factory_Release(factory);
7854 release_test_context(&ctx);
7857 static void test_bezier_intersect(BOOL d3d11)
7859 D2D1_POINT_2F point = {0.0f, 0.0f};
7860 struct d2d1_test_context ctx;
7861 ID2D1SolidColorBrush *brush;
7862 ID2D1PathGeometry *geometry;
7863 ID2D1GeometrySink *sink;
7864 ID2D1RenderTarget *rt;
7865 ID2D1Factory *factory;
7866 D2D1_COLOR_F color;
7867 HRESULT hr;
7868 BOOL match;
7870 if (!init_test_context(&ctx, d3d11))
7871 return;
7873 rt = ctx.rt;
7874 ID2D1RenderTarget_GetFactory(rt, &factory);
7876 ID2D1RenderTarget_SetDpi(rt, 192.0f, 48.0f);
7877 ID2D1RenderTarget_SetAntialiasMode(rt, D2D1_ANTIALIAS_MODE_ALIASED);
7878 set_color(&color, 0.890f, 0.851f, 0.600f, 1.0f);
7879 hr = ID2D1RenderTarget_CreateSolidColorBrush(rt, &color, NULL, &brush);
7880 ok(SUCCEEDED(hr), "Failed to create brush, hr %#x.\n", hr);
7882 hr = ID2D1Factory_CreatePathGeometry(factory, &geometry);
7883 ok(SUCCEEDED(hr), "Failed to create path geometry, hr %#x.\n", hr);
7884 hr = ID2D1PathGeometry_Open(geometry, &sink);
7885 ok(SUCCEEDED(hr), "Failed to open geometry sink, hr %#x.\n", hr);
7887 set_point(&point, 160.0f, 720.0f);
7888 ID2D1GeometrySink_BeginFigure(sink, point, D2D1_FIGURE_BEGIN_FILLED);
7889 cubic_to(sink, 119.0f, 720.0f, 83.0f, 600.0f, 80.0f, 474.0f);
7890 cubic_to(sink, 78.0f, 349.0f, 108.0f, 245.0f, 135.0f, 240.0f);
7891 cubic_to(sink, 163.0f, 235.0f, 180.0f, 318.0f, 176.0f, 370.0f);
7892 cubic_to(sink, 171.0f, 422.0f, 149.0f, 422.0f, 144.0f, 370.0f);
7893 cubic_to(sink, 140.0f, 318.0f, 157.0f, 235.0f, 185.0f, 240.0f);
7894 cubic_to(sink, 212.0f, 245.0f, 242.0f, 349.0f, 240.0f, 474.0f);
7895 cubic_to(sink, 238.0f, 600.0f, 201.0f, 720.0f, 160.0f, 720.0f);
7896 ID2D1GeometrySink_EndFigure(sink, D2D1_FIGURE_END_CLOSED);
7898 set_point(&point, 160.0f, 240.0f);
7899 ID2D1GeometrySink_BeginFigure(sink, point, D2D1_FIGURE_BEGIN_FILLED);
7900 line_to(sink, 240.0f, 240.0f);
7901 line_to(sink, 240.0f, 720.0f);
7902 line_to(sink, 160.0f, 720.0f);
7903 ID2D1GeometrySink_EndFigure(sink, D2D1_FIGURE_END_CLOSED);
7905 hr = ID2D1GeometrySink_Close(sink);
7906 ok(SUCCEEDED(hr), "Failed to close geometry sink, hr %#x.\n", hr);
7907 ID2D1GeometrySink_Release(sink);
7909 ID2D1RenderTarget_BeginDraw(rt);
7910 set_color(&color, 0.396f, 0.180f, 0.537f, 1.0f);
7911 ID2D1RenderTarget_Clear(rt, &color);
7912 ID2D1RenderTarget_FillGeometry(rt, (ID2D1Geometry *)geometry, (ID2D1Brush *)brush, NULL);
7913 hr = ID2D1RenderTarget_EndDraw(rt, NULL, NULL);
7914 ok(SUCCEEDED(hr), "Failed to end draw, hr %#x.\n", hr);
7915 ID2D1PathGeometry_Release(geometry);
7917 match = compare_figure(&ctx, 160, 120, 320, 240, 0xff652e89, 2048,
7918 "aRQjIxRpYiIcHCJiXSwXFyxdWTQTEzRZVTsQEDtVUkIMDEJST0cKCkdPTUsICEtNSlEFBVFKSFUD"
7919 "A1VIRlkBAVlGRFsBAVtEQlwCAlxCQFwEBFxAPl0FBV0+PF0HB108Ol4ICF46OV0KCl05N14LC143"
7920 "Nl4MDF42NF8NDV80M14PD14zMV8QEF8xMF8REV8wL18SEl8vLWATE2AtLGAUFGAsK2EUFGErKWIV"
7921 "FWIpKGIWFmIoJ2IXF2InJmIYGGImJWMYGGMlJGMZGWMkI2MaGmMjImQaGmQiIWQbG2QhIGQcHGQg"
7922 "H2UcHGUfHmUdHWUeHWYdHWYdHGcdHWccG2ceHmcbGmgeHmgaGWgfH2gZGWgfH2gZGGkfH2kYF2kg"
7923 "IGkXFmogIGoWFmogIGoWFWsgIGsVFGshIWsUE2whIWwTE2whIWwTEm0hIW0SEW4hIW4REW4hIW4R"
7924 "EG8hIW8QD3AhIXAPD3AhIXAPDnEhIXEODnEhIXEODXIhIXINDHQgIHQMDHQgIHQMC3UgIHULC3Yf"
7925 "H3YLCncfH3cKCngeHngKCXkeHnkJCXodHXoJCXscHHsJCHwcHHwICH0bG30IB38aGn8HB4ABGRmA"
7926 "AQcHgQEYGIEBBwaEARYWhAEGBoUBFRWFAQYFiAETE4gBBQWKARERigEFBYwBDw+MAQUEkAEMDJAB"
7927 "BASTAQkJkwEEBJwBnAEEA50BnQEDA50BnQEDA50BnQEDA50BnQEDAp4BngECAp4BngECAp4BngEC"
7928 "Ap4BngECAp4BngECAZ8BnwEBAZ8BnwEBAZ8BnwEBAZ8BnwEBAZ8BnwEBAZ8BnwEBAZ8BnwGhAaAB"
7929 "oAGgAaABoAGgAaABoAGgAaABoAGgAaABoAGgAaABoAGgAaABoAGgAaABoAGgAaABoAGgAaABoAGg"
7930 "AaABoAGgAaABoAGgAaABoAGhAZ8BoQGfAZ8BAQGfAZ8BAQGfAZ8BAQGfAZ8BAQGfAZ8BAQKeAZ8B"
7931 "AQKeAZ4BAgKeAZ4BAgKeAZ4BAgOdAZ4BAgOdAZ4BAgOdAZ0BAwScAZ0BAwScAZ0BAwScAZ0BAwSc"
7932 "AZwBBAWbAZwBBAWbAZwBBAWbAZsBBQaaAZsBBQaaAZoBBgeZAZoBBgeZAZoBBgeZAZkBBwiYAZkB"
7933 "BwiYAZgBCAmXAZgBCAmXAZgBCAmXAZcBCQqWAZcBCQqWAZYBCguVAZYBCguVAZUBCwyUAZUBCw2T"
7934 "AZQBDA2TAZQBDA6SAZMBDQ6SAZMBDQ+RAZIBDg+RAZIBDhCQAZEBDxCQAZABEBGPAZABEBKOAY8B"
7935 "ERONAY4BEhONAY4BEhSMAY0BExWLAYwBFBWLAYwBFBaKAYsBFReJAYoBFheJAYoBFhiIAYkBFxmH"
7936 "AYgBGBqGAYcBGRuFAYYBGhuFAYUBGxyEAYUBGx2DAYQBHB6CAYMBHR+BAYIBHiCAAYEBHyF/gAEg"
7937 "In5/ISJ+fiIjfX0jJHx8JCV7eyUmenomJ3l5Jyh4eCgpd3cpK3V2Kix0dSstc3QsLnJzLS9xci4w"
7938 "cHAwMm5vMTNtbjI0bG0zNWtrNTdpajY4aGk3OmZnOTtlZjo8ZGQ8PmJjPT9hYj5BX2BAQl5eQkRc"
7939 "XUNGWltFR1lZR0lXWEhLVVZKTVNUTE9RUk5RT1BQUk5OUlRMTFRWSkpWWUdIWFtFRVteQkNdYEBA"
7940 "YGI+PmJlOztlaDg4aGs1NWtuMjJuci4vcXUrK3V6JiZ6fiIifoMBHR2DAYsBFRWLAZUBCwuVAQAA");
7941 ok(match, "Figure does not match.\n");
7943 hr = ID2D1Factory_CreatePathGeometry(factory, &geometry);
7944 ok(SUCCEEDED(hr), "Failed to create path geometry, hr %#x.\n", hr);
7945 hr = ID2D1PathGeometry_Open(geometry, &sink);
7946 ok(SUCCEEDED(hr), "Failed to open geometry sink, hr %#x.\n", hr);
7948 set_point(&point, 240.0f, 720.0f);
7949 ID2D1GeometrySink_BeginFigure(sink, point, D2D1_FIGURE_BEGIN_FILLED);
7950 cubic_to(sink, 152.0f, 720.0f, 80.0f, 613.0f, 80.0f, 480.0f);
7951 cubic_to(sink, 80.0f, 347.0f, 152.0f, 240.0f, 240.0f, 240.0f);
7952 cubic_to(sink, 152.0f, 339.0f, 134.0f, 528.0f, 200.0f, 660.0f);
7953 cubic_to(sink, 212.0f, 683.0f, 225.0f, 703.0f, 240.0f, 720.0f);
7954 ID2D1GeometrySink_EndFigure(sink, D2D1_FIGURE_END_CLOSED);
7956 hr = ID2D1GeometrySink_Close(sink);
7957 ok(SUCCEEDED(hr), "Failed to close geometry sink, hr %#x.\n", hr);
7958 ID2D1GeometrySink_Release(sink);
7960 ID2D1RenderTarget_BeginDraw(rt);
7961 ID2D1RenderTarget_Clear(rt, &color);
7962 ID2D1RenderTarget_FillGeometry(rt, (ID2D1Geometry *)geometry, (ID2D1Brush *)brush, NULL);
7963 hr = ID2D1RenderTarget_EndDraw(rt, NULL, NULL);
7964 ok(SUCCEEDED(hr), "Failed to end draw, hr %#x.\n", hr);
7965 ID2D1PathGeometry_Release(geometry);
7967 match = compare_figure(&ctx, 160, 120, 320, 240, 0xff652e89, 2048,
7968 "pQIZkgIrhAI5/QE/9gFH7wFO6wFS5wFW4gFb3gFf2wFi2AFl1gFn1AFp0gFszwFuzQFxywFyyQF1"
7969 "xwF2xgF4xAF5xAF6wgF8wAF+vwF+vwF/vQGBAbwBggG7AYMBugGEAbkBhQG4AYYBtwGHAbcBiAG1"
7970 "AYkBtAGKAbQBigGzAYsBswGMAbEBjQGxAY0BsQGOAa8BjwGvAZABrgGQAa4BkQGtAZEBrQGSAawB"
7971 "kgGsAZMBqwGTAasBlAGrAZQBqgGVAakBlQGqAZUBqQGWAagBlwGoAZYBqAGXAagBlwGnAZgBpwGY"
7972 "AaYBmQGmAZkBpgGZAaUBmgGlAZoBpQGaAaUBmgGkAZsBpAGbAaQBmwGkAZsBpAGcAaMBnAGjAZwB"
7973 "owGcAaMBnAGjAZ0BogGdAaIBnQGiAZ4BoQGeAaEBngGiAZ4BoQGeAaEBnwGgAZ8BoQGeAaEBnwGh"
7974 "AZ4BoQGfAaABnwGhAZ8BoAGgAaABnwGgAaABoAGfAaABoAGgAaABnwGgAaABoAGgAaABnwGgAaAB"
7975 "oAGgAaABnwGhAZ8BoQGfAaABoAGgAaABoAGfAaEBnwGhAZ8BoQGfAaEBnwGhAZ8BoQGfAaABoAGg"
7976 "AaABoAGgAaEBnwGhAZ8BoQGfAaEBnwGhAaABoAGgAaABoAGgAaABoAGgAaEBoAGgAaABoAGgAaAB"
7977 "oQGgAaABoAGgAaABoQGfAaEBoAGhAZ8BoQGfAaIBnwGhAZ8BogGfAaEBnwGiAZ8BogGeAaIBnwGi"
7978 "AZ4BogGfAaIBngGjAZ4BowGdAaMBngGjAZ4BowGdAaQBnQGkAZ0BpAGcAaUBnAGlAZwBpQGcAaUB"
7979 "mwGmAZsBpgGbAaYBmwGmAZsBpgGbAacBmgGnAZkBqAGZAagBmQGpAZgBqQGZAagBmQGpAZgBqQGY"
7980 "AaoBlwGqAZcBqwGWAasBlgGsAZUBrQGVAawBlQGtAZQBrgGUAa0BlAGuAZMBrwGTAa8BkgGwAZEB"
7981 "sQGRAbEBkAGyAZABsgGPAbMBjwG0AY4BtAGNAbUBjQG2AYwBtgGLAbgBigG4AYoBuQGJAboBhwG7"
7982 "AYcBvAGGAb0BhQG+AYQBvwGDAcABggHBAYIBwgGAAcMBf8QBfsYBfMgBe8gBesoBeMwBd80BddAB"
7983 "c9EBcdQBb9YBbNkBatsBaN0BZeEBYuQBX+gBW+0BVvEBUvUBTvwBR4QCQIoCOZgCK6oCGQIA");
7984 ok(match, "Figure does not match.\n");
7986 ID2D1SolidColorBrush_Release(brush);
7987 ID2D1Factory_Release(factory);
7988 release_test_context(&ctx);
7991 static void test_create_device(BOOL d3d11)
7993 D2D1_CREATION_PROPERTIES properties = {0};
7994 struct d2d1_test_context ctx;
7995 ID2D1Factory1 *factory;
7996 ID2D1Factory *factory2;
7997 ID2D1Device *device;
7998 ULONG refcount;
7999 HRESULT hr;
8001 if (!init_test_context(&ctx, d3d11))
8002 return;
8004 if (FAILED(D2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED, &IID_ID2D1Factory1, NULL, (void **)&factory)))
8006 win_skip("ID2D1Factory1 is not supported.\n");
8007 release_test_context(&ctx);
8008 return;
8011 hr = ID2D1Factory1_CreateDevice(factory, ctx.device, &device);
8012 ok(SUCCEEDED(hr), "Failed to get ID2D1Device, hr %#x.\n", hr);
8014 ID2D1Device_GetFactory(device, &factory2);
8015 ok(factory2 == (ID2D1Factory *)factory, "Got unexpected factory %p, expected %p.\n", factory2, factory);
8016 ID2D1Factory_Release(factory2);
8017 ID2D1Device_Release(device);
8019 if (pD2D1CreateDevice)
8021 hr = pD2D1CreateDevice(ctx.device, NULL, &device);
8022 ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
8023 ID2D1Device_Release(device);
8025 hr = pD2D1CreateDevice(ctx.device, &properties, &device);
8026 ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
8027 ID2D1Device_Release(device);
8029 else
8030 win_skip("D2D1CreateDevice() is unavailable.\n");
8032 release_test_context(&ctx);
8034 refcount = ID2D1Factory1_Release(factory);
8035 ok(!refcount, "Factory has %u references left.\n", refcount);
8038 #define check_rt_bitmap_surface(r, s, o) check_rt_bitmap_surface_(__LINE__, r, s, o)
8039 static void check_rt_bitmap_surface_(unsigned int line, ID2D1RenderTarget *rt, BOOL has_surface, DWORD options)
8041 ID2D1BitmapRenderTarget *compatible_rt;
8042 D2D1_BITMAP_PROPERTIES bitmap_desc;
8043 IWICImagingFactory *wic_factory;
8044 ID2D1Bitmap *bitmap, *bitmap2;
8045 ID2D1DeviceContext *context;
8046 ID2D1DCRenderTarget *dc_rt;
8047 IWICBitmap *wic_bitmap;
8048 ID2D1Image *target;
8049 D2D1_SIZE_U size;
8050 HRESULT hr;
8052 static const DWORD bitmap_data[] =
8054 0x7f7f0000,
8057 /* Raw data bitmap. */
8058 set_size_u(&size, 1, 1);
8059 bitmap_desc.pixelFormat.format = DXGI_FORMAT_B8G8R8A8_UNORM;
8060 bitmap_desc.pixelFormat.alphaMode = D2D1_ALPHA_MODE_IGNORE;
8061 bitmap_desc.dpiX = 96.0f;
8062 bitmap_desc.dpiY = 96.0f;
8063 hr = ID2D1RenderTarget_CreateBitmap(rt, size, bitmap_data, sizeof(*bitmap_data), &bitmap_desc, &bitmap);
8064 ok_(__FILE__, line)(SUCCEEDED(hr), "Failed to create bitmap, hr %#x.\n", hr);
8066 check_bitmap_surface_(line, bitmap, has_surface, options);
8068 ID2D1Bitmap_Release(bitmap);
8070 /* Zero sized bitmaps. */
8071 set_size_u(&size, 0, 0);
8072 hr = ID2D1RenderTarget_CreateBitmap(rt, size, NULL, 0, &bitmap_desc, &bitmap);
8073 ok_(__FILE__, line)(SUCCEEDED(hr), "Failed to create bitmap, hr %#x.\n", hr);
8074 check_bitmap_surface_(line, bitmap, has_surface, options);
8075 ID2D1Bitmap_Release(bitmap);
8077 set_size_u(&size, 2, 0);
8078 hr = ID2D1RenderTarget_CreateBitmap(rt, size, NULL, 0, &bitmap_desc, &bitmap);
8079 ok_(__FILE__, line)(SUCCEEDED(hr), "Failed to create bitmap, hr %#x.\n", hr);
8080 check_bitmap_surface_(line, bitmap, has_surface, options);
8081 ID2D1Bitmap_Release(bitmap);
8083 set_size_u(&size, 0, 2);
8084 hr = ID2D1RenderTarget_CreateBitmap(rt, size, NULL, 0, &bitmap_desc, &bitmap);
8085 ok_(__FILE__, line)(SUCCEEDED(hr), "Failed to create bitmap, hr %#x.\n", hr);
8086 check_bitmap_surface_(line, bitmap, has_surface, options);
8087 ID2D1Bitmap_Release(bitmap);
8089 /* WIC bitmap. */
8090 CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
8092 hr = CoCreateInstance(&CLSID_WICImagingFactory, NULL, CLSCTX_INPROC_SERVER,
8093 &IID_IWICImagingFactory, (void **)&wic_factory);
8094 ok_(__FILE__, line)(SUCCEEDED(hr), "Failed to create WIC imaging factory, hr %#x.\n", hr);
8096 hr = IWICImagingFactory_CreateBitmap(wic_factory, 16, 16,
8097 &GUID_WICPixelFormat32bppPBGRA, WICBitmapCacheOnDemand, &wic_bitmap);
8098 ok_(__FILE__, line)(SUCCEEDED(hr), "Failed to create WIC bitmap, hr %#x.\n", hr);
8099 IWICImagingFactory_Release(wic_factory);
8101 hr = ID2D1RenderTarget_CreateBitmapFromWicBitmap(rt, (IWICBitmapSource *)wic_bitmap, NULL, &bitmap);
8102 ok_(__FILE__, line)(SUCCEEDED(hr), "Failed to create bitmap from WIC source, hr %#x.\n", hr);
8104 check_bitmap_surface_(line, bitmap, has_surface, options);
8106 ID2D1Bitmap_Release(bitmap);
8108 CoUninitialize();
8110 /* Compatible target follows its parent. */
8111 hr = ID2D1RenderTarget_QueryInterface(rt, &IID_ID2D1DeviceContext, (void **)&context);
8112 ok_(__FILE__, line)(SUCCEEDED(hr), "Failed to get device context, hr %#x.\n", hr);
8114 dc_rt = NULL;
8115 ID2D1RenderTarget_QueryInterface(rt, &IID_ID2D1DCRenderTarget, (void **)&dc_rt);
8117 bitmap = NULL;
8118 target = NULL;
8119 ID2D1DeviceContext_GetTarget(context, &target);
8120 if (target && FAILED(ID2D1Image_QueryInterface(target, &IID_ID2D1Bitmap, (void **)&bitmap)))
8122 ID2D1Image_Release(target);
8123 target = NULL;
8125 if (bitmap)
8127 D2D1_PIXEL_FORMAT rt_format, bitmap_format;
8129 rt_format = ID2D1RenderTarget_GetPixelFormat(rt);
8130 bitmap_format = ID2D1Bitmap_GetPixelFormat(bitmap);
8131 ok_(__FILE__, line)(!memcmp(&rt_format, &bitmap_format, sizeof(rt_format)), "Unexpected bitmap format.\n");
8133 ID2D1Bitmap_Release(bitmap);
8136 /* Pixel format is not defined until target is set, for DC target it's specified on creation. */
8137 if (target || dc_rt)
8139 ID2D1Device *device, *device2;
8140 ID2D1DeviceContext *context2;
8142 ID2D1DeviceContext_GetDevice(context, &device);
8144 hr = ID2D1RenderTarget_CreateCompatibleRenderTarget(rt, NULL, NULL, NULL,
8145 D2D1_COMPATIBLE_RENDER_TARGET_OPTIONS_NONE, &compatible_rt);
8146 ok_(__FILE__, line)(SUCCEEDED(hr), "Failed to create compatible render target, hr %#x.\n", hr);
8148 hr = ID2D1BitmapRenderTarget_QueryInterface(compatible_rt, &IID_ID2D1DeviceContext, (void **)&context2);
8149 ok_(__FILE__, line)(SUCCEEDED(hr), "Failed to get device context, hr %#x.\n", hr);
8151 ID2D1DeviceContext_GetDevice(context2, &device2);
8152 ok_(__FILE__, line)(device == device2, "Unexpected device.\n");
8154 ID2D1Device_Release(device);
8155 ID2D1Device_Release(device2);
8157 hr = ID2D1BitmapRenderTarget_CreateBitmap(compatible_rt, size,
8158 bitmap_data, sizeof(*bitmap_data), &bitmap_desc, &bitmap);
8159 ok_(__FILE__, line)(SUCCEEDED(hr), "Failed to create bitmap, hr %#x.\n", hr);
8160 check_bitmap_surface_(line, bitmap, has_surface, options);
8161 ID2D1Bitmap_Release(bitmap);
8163 hr = ID2D1BitmapRenderTarget_GetBitmap(compatible_rt, &bitmap);
8164 ok_(__FILE__, line)(SUCCEEDED(hr), "Failed to get compatible target bitmap, hr %#x.\n", hr);
8166 bitmap2 = NULL;
8167 ID2D1DeviceContext_GetTarget(context2, (ID2D1Image **)&bitmap2);
8168 ok_(__FILE__, line)(bitmap2 == bitmap, "Unexpected bitmap.\n");
8170 check_bitmap_surface_(line, bitmap, has_surface, D2D1_BITMAP_OPTIONS_TARGET);
8171 ID2D1Bitmap_Release(bitmap2);
8172 ID2D1Bitmap_Release(bitmap);
8174 ID2D1BitmapRenderTarget_Release(compatible_rt);
8175 ID2D1DeviceContext_Release(context2);
8177 else
8179 hr = ID2D1RenderTarget_CreateCompatibleRenderTarget(rt, NULL, NULL, NULL,
8180 D2D1_COMPATIBLE_RENDER_TARGET_OPTIONS_NONE, &compatible_rt);
8181 ok_(__FILE__, line)(hr == WINCODEC_ERR_UNSUPPORTEDPIXELFORMAT, "Unexpected hr %#x.\n", hr);
8184 ID2D1DeviceContext_Release(context);
8185 if (target)
8186 ID2D1Image_Release(target);
8187 if (dc_rt)
8188 ID2D1DCRenderTarget_Release(dc_rt);
8191 static IDXGISurface *create_surface(IDXGIDevice *dxgi_device, DXGI_FORMAT format)
8193 D3D10_TEXTURE2D_DESC texture_desc;
8194 ID3D10Texture2D *texture;
8195 ID3D10Device *d3d_device;
8196 IDXGISurface *surface;
8197 HRESULT hr;
8199 texture_desc.Width = 1;
8200 texture_desc.Height = 1;
8201 texture_desc.MipLevels = 1;
8202 texture_desc.ArraySize = 1;
8203 texture_desc.Format = format;
8204 texture_desc.SampleDesc.Count = 1;
8205 texture_desc.SampleDesc.Quality = 0;
8206 texture_desc.Usage = D3D10_USAGE_DEFAULT;
8207 texture_desc.BindFlags = D3D10_BIND_SHADER_RESOURCE;
8208 texture_desc.CPUAccessFlags = 0;
8209 texture_desc.MiscFlags = 0;
8211 hr = IDXGIDevice_QueryInterface(dxgi_device, &IID_ID3D10Device, (void **)&d3d_device);
8212 ok(SUCCEEDED(hr), "Failed to get device interface, hr %#x.\n", hr);
8214 hr = ID3D10Device_CreateTexture2D(d3d_device, &texture_desc, NULL, &texture);
8215 ok(SUCCEEDED(hr), "Failed to create a texture, hr %#x.\n", hr);
8217 hr = ID3D10Texture2D_QueryInterface(texture, &IID_IDXGISurface, (void **)&surface);
8218 ok(SUCCEEDED(hr), "Failed to get surface interface, hr %#x.\n", hr);
8220 ID3D10Device_Release(d3d_device);
8221 ID3D10Texture2D_Release(texture);
8223 return surface;
8226 static void test_bitmap_surface(BOOL d3d11)
8228 static const struct bitmap_format_test
8230 D2D1_PIXEL_FORMAT original;
8231 D2D1_PIXEL_FORMAT result;
8232 HRESULT hr;
8234 bitmap_format_tests[] =
8236 { { DXGI_FORMAT_UNKNOWN, D2D1_ALPHA_MODE_PREMULTIPLIED },
8237 { DXGI_FORMAT_B8G8R8A8_UNORM, D2D1_ALPHA_MODE_PREMULTIPLIED } },
8239 { { DXGI_FORMAT_B8G8R8A8_UNORM, D2D1_ALPHA_MODE_STRAIGHT }, { 0 }, WINCODEC_ERR_UNSUPPORTEDPIXELFORMAT },
8241 { { DXGI_FORMAT_UNKNOWN, D2D1_ALPHA_MODE_IGNORE },
8242 { DXGI_FORMAT_B8G8R8A8_UNORM, D2D1_ALPHA_MODE_IGNORE } },
8244 { { DXGI_FORMAT_UNKNOWN, D2D1_ALPHA_MODE_UNKNOWN }, { 0 }, WINCODEC_ERR_UNSUPPORTEDPIXELFORMAT },
8246 { { DXGI_FORMAT_B8G8R8A8_UNORM, D2D1_ALPHA_MODE_UNKNOWN }, { 0 }, WINCODEC_ERR_UNSUPPORTEDPIXELFORMAT },
8248 { { DXGI_FORMAT_B8G8R8A8_UNORM, D2D1_ALPHA_MODE_IGNORE },
8249 { DXGI_FORMAT_B8G8R8A8_UNORM, D2D1_ALPHA_MODE_IGNORE } },
8251 { { DXGI_FORMAT_UNKNOWN, D2D1_ALPHA_MODE_STRAIGHT }, { 0 }, WINCODEC_ERR_UNSUPPORTEDPIXELFORMAT },
8253 D2D1_HWND_RENDER_TARGET_PROPERTIES hwnd_rt_desc;
8254 D2D1_RENDER_TARGET_PROPERTIES rt_desc;
8255 D2D1_BITMAP_PROPERTIES1 bitmap_desc;
8256 ID2D1DeviceContext *device_context;
8257 IDXGISurface *surface2;
8258 D2D1_PIXEL_FORMAT pixel_format;
8259 struct d2d1_test_context ctx;
8260 ID2D1Factory1 *factory;
8261 ID2D1RenderTarget *rt;
8262 ID2D1Bitmap1 *bitmap;
8263 ID2D1Device *device;
8264 ID2D1Image *target;
8265 D2D1_SIZE_U size;
8266 D2D1_TAG t1, t2;
8267 unsigned int i;
8268 HRESULT hr;
8270 IWICBitmap *wic_bitmap;
8271 IWICImagingFactory *wic_factory;
8273 if (!init_test_context(&ctx, d3d11))
8274 return;
8276 if (FAILED(D2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED, &IID_ID2D1Factory1, NULL, (void **)&factory)))
8278 win_skip("ID2D1Factory1 is not supported.\n");
8279 release_test_context(&ctx);
8280 return;
8283 /* DXGI target */
8284 hr = ID2D1RenderTarget_QueryInterface(ctx.rt, &IID_ID2D1DeviceContext, (void **)&device_context);
8285 ok(SUCCEEDED(hr), "Failed to get device context, hr %#x.\n", hr);
8287 bitmap = NULL;
8288 ID2D1DeviceContext_GetTarget(device_context, (ID2D1Image **)&bitmap);
8289 ok(!!bitmap, "Unexpected target.\n");
8290 check_bitmap_surface((ID2D1Bitmap *)bitmap, TRUE, D2D1_BITMAP_OPTIONS_TARGET | D2D1_BITMAP_OPTIONS_CANNOT_DRAW);
8291 ID2D1Bitmap1_Release(bitmap);
8293 check_rt_bitmap_surface(ctx.rt, TRUE, D2D1_BITMAP_OPTIONS_NONE);
8295 ID2D1DeviceContext_Release(device_context);
8297 /* Bitmap created from DXGI surface. */
8298 hr = ID2D1Factory1_CreateDevice(factory, ctx.device, &device);
8299 ok(SUCCEEDED(hr), "Failed to get ID2D1Device, hr %#x.\n", hr);
8301 hr = ID2D1Device_CreateDeviceContext(device, D2D1_DEVICE_CONTEXT_OPTIONS_NONE, &device_context);
8302 ok(SUCCEEDED(hr), "Failed to create device context, hr %#x.\n", hr);
8304 for (i = 0; i < ARRAY_SIZE(bitmap_format_tests); ++i)
8306 memset(&bitmap_desc, 0, sizeof(bitmap_desc));
8307 bitmap_desc.pixelFormat = bitmap_format_tests[i].original;
8308 bitmap_desc.bitmapOptions = D2D1_BITMAP_OPTIONS_TARGET | D2D1_BITMAP_OPTIONS_CANNOT_DRAW;
8310 hr = ID2D1DeviceContext_CreateBitmapFromDxgiSurface(device_context, ctx.surface, &bitmap_desc, &bitmap);
8311 todo_wine_if(bitmap_format_tests[i].hr == WINCODEC_ERR_UNSUPPORTEDPIXELFORMAT)
8312 ok(hr == bitmap_format_tests[i].hr, "%u: unexpected hr %#x.\n", i, hr);
8314 if (SUCCEEDED(bitmap_format_tests[i].hr))
8316 pixel_format = ID2D1Bitmap1_GetPixelFormat(bitmap);
8318 ok(pixel_format.format == bitmap_format_tests[i].result.format, "%u: unexpected pixel format %#x.\n",
8319 i, pixel_format.format);
8320 ok(pixel_format.alphaMode == bitmap_format_tests[i].result.alphaMode, "%u: unexpected alpha mode %d.\n",
8321 i, pixel_format.alphaMode);
8323 ID2D1Bitmap1_Release(bitmap);
8327 /* A8 surface */
8328 surface2 = create_surface(ctx.device, DXGI_FORMAT_A8_UNORM);
8330 hr = ID2D1DeviceContext_CreateBitmapFromDxgiSurface(device_context, surface2, NULL, &bitmap);
8331 ok(SUCCEEDED(hr) || broken(hr == WINCODEC_ERR_UNSUPPORTEDPIXELFORMAT) /* Win7 */,
8332 "Failed to create a bitmap, hr %#x.\n", hr);
8334 if (SUCCEEDED(hr))
8336 pixel_format = ID2D1Bitmap1_GetPixelFormat(bitmap);
8337 ok(pixel_format.alphaMode == D2D1_ALPHA_MODE_PREMULTIPLIED,
8338 "Unexpected alpha mode %#x.\n", pixel_format.alphaMode);
8340 ID2D1Bitmap1_Release(bitmap);
8343 IDXGISurface_Release(surface2);
8345 hr = ID2D1DeviceContext_CreateBitmapFromDxgiSurface(device_context, ctx.surface, NULL, &bitmap);
8346 ok(SUCCEEDED(hr), "Failed to create a bitmap, hr %#x.\n", hr);
8348 pixel_format = ID2D1Bitmap1_GetPixelFormat(bitmap);
8349 ok(pixel_format.alphaMode == D2D1_ALPHA_MODE_PREMULTIPLIED,
8350 "Unexpected alpha mode %#x.\n", pixel_format.alphaMode);
8352 check_bitmap_surface((ID2D1Bitmap *)bitmap, TRUE, D2D1_BITMAP_OPTIONS_TARGET | D2D1_BITMAP_OPTIONS_CANNOT_DRAW);
8353 check_rt_bitmap_surface((ID2D1RenderTarget *)device_context, TRUE, D2D1_BITMAP_OPTIONS_NONE);
8355 ID2D1DeviceContext_SetTarget(device_context, (ID2D1Image *)bitmap);
8356 ID2D1DeviceContext_GetTarget(device_context, &target);
8357 ok(target == (ID2D1Image *)bitmap, "Unexpected target.\n");
8359 check_rt_bitmap_surface((ID2D1RenderTarget *)device_context, TRUE, D2D1_BITMAP_OPTIONS_NONE);
8361 ID2D1Bitmap1_Release(bitmap);
8363 /* Without D2D1_BITMAP_OPTIONS_TARGET. */
8364 memset(&bitmap_desc, 0, sizeof(bitmap_desc));
8365 bitmap_desc.pixelFormat = ID2D1DeviceContext_GetPixelFormat(device_context);
8366 size.width = size.height = 4;
8367 hr = ID2D1DeviceContext_CreateBitmap(device_context, size, NULL, 0, &bitmap_desc, &bitmap);
8368 ok(SUCCEEDED(hr), "Failed to create a bitmap, hr %#x.\n", hr);
8369 check_bitmap_surface((ID2D1Bitmap *)bitmap, TRUE, D2D1_BITMAP_OPTIONS_NONE);
8370 ID2D1DeviceContext_SetTags(device_context, 1, 2);
8372 ID2D1DeviceContext_BeginDraw(device_context);
8373 ID2D1DeviceContext_SetTarget(device_context, (ID2D1Image *)bitmap);
8374 hr = ID2D1DeviceContext_EndDraw(device_context, &t1, &t2);
8375 ok(hr == D2DERR_INVALID_TARGET, "Unexpected hr %#x.\n", hr);
8376 ok(t1 == 1 && t2 == 2, "Unexpected tags %s:%s.\n", wine_dbgstr_longlong(t1), wine_dbgstr_longlong(t2));
8378 ID2D1Bitmap1_Release(bitmap);
8380 ID2D1DeviceContext_GetTarget(device_context, (ID2D1Image **)&bitmap);
8381 ok(!!bitmap, "Expected target bitmap.\n");
8382 ID2D1Bitmap1_Release(bitmap);
8384 bitmap_desc.bitmapOptions = D2D1_BITMAP_OPTIONS_TARGET;
8385 hr = ID2D1DeviceContext_CreateBitmap(device_context, size, NULL, 0, &bitmap_desc, &bitmap);
8386 ok(SUCCEEDED(hr), "Failed to create a bitmap, hr %#x.\n", hr);
8387 check_bitmap_surface((ID2D1Bitmap *)bitmap, TRUE, D2D1_BITMAP_OPTIONS_TARGET);
8388 ID2D1DeviceContext_SetTarget(device_context, NULL);
8389 ID2D1DeviceContext_SetTags(device_context, 3, 4);
8391 ID2D1DeviceContext_BeginDraw(device_context);
8392 ID2D1DeviceContext_SetTarget(device_context, (ID2D1Image *)bitmap);
8393 hr = ID2D1DeviceContext_EndDraw(device_context, &t1, &t2);
8394 ok(SUCCEEDED(hr), "Failed to end draw, hr %#x.\n", hr);
8395 ok(!t1 && !t2, "Unexpected tags %s:%s.\n", wine_dbgstr_longlong(t1), wine_dbgstr_longlong(t2));
8397 ID2D1Bitmap1_Release(bitmap);
8399 ID2D1DeviceContext_Release(device_context);
8401 ID2D1Device_Release(device);
8403 /* DC target */
8404 rt_desc.type = D2D1_RENDER_TARGET_TYPE_DEFAULT;
8405 rt_desc.pixelFormat.format = DXGI_FORMAT_B8G8R8A8_UNORM;
8406 rt_desc.pixelFormat.alphaMode = D2D1_ALPHA_MODE_PREMULTIPLIED;
8407 rt_desc.dpiX = 96.0f;
8408 rt_desc.dpiY = 96.0f;
8409 rt_desc.usage = D2D1_RENDER_TARGET_USAGE_NONE;
8410 rt_desc.minLevel = D2D1_FEATURE_LEVEL_DEFAULT;
8411 hr = ID2D1Factory1_CreateDCRenderTarget(factory, &rt_desc, (ID2D1DCRenderTarget **)&rt);
8412 ok(SUCCEEDED(hr), "Failed to create target, hr %#x.\n", hr);
8414 hr = ID2D1RenderTarget_QueryInterface(rt, &IID_ID2D1DeviceContext, (void **)&device_context);
8415 ok(SUCCEEDED(hr), "Failed to get device context, hr %#x.\n", hr);
8417 ID2D1DeviceContext_GetTarget(device_context, (ID2D1Image **)&bitmap);
8418 ok(!bitmap, "Unexpected target.\n");
8420 ID2D1DeviceContext_Release(device_context);
8421 ID2D1RenderTarget_Release(rt);
8423 /* HWND target */
8424 hwnd_rt_desc.hwnd = NULL;
8425 hwnd_rt_desc.pixelSize.width = 64;
8426 hwnd_rt_desc.pixelSize.height = 64;
8427 hwnd_rt_desc.presentOptions = D2D1_PRESENT_OPTIONS_NONE;
8428 hwnd_rt_desc.hwnd = CreateWindowA("static", "d2d_test", 0, 0, 0, 0, 0, 0, 0, 0, 0);
8429 ok(!!hwnd_rt_desc.hwnd, "Failed to create target window.\n");
8431 hr = ID2D1Factory1_CreateHwndRenderTarget(factory, &rt_desc, &hwnd_rt_desc, (ID2D1HwndRenderTarget **)&rt);
8432 ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr);
8434 check_rt_bitmap_surface(rt, FALSE, D2D1_BITMAP_OPTIONS_NONE);
8435 ID2D1RenderTarget_Release(rt);
8436 DestroyWindow(hwnd_rt_desc.hwnd);
8438 /* WIC target */
8439 CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
8441 hr = CoCreateInstance(&CLSID_WICImagingFactory, NULL, CLSCTX_INPROC_SERVER,
8442 &IID_IWICImagingFactory, (void **)&wic_factory);
8443 ok(SUCCEEDED(hr), "Failed to create WIC imaging factory, hr %#x.\n", hr);
8444 hr = IWICImagingFactory_CreateBitmap(wic_factory, 16, 16,
8445 &GUID_WICPixelFormat32bppPBGRA, WICBitmapCacheOnDemand, &wic_bitmap);
8446 ok(SUCCEEDED(hr), "Failed to create bitmap, hr %#x.\n", hr);
8447 IWICImagingFactory_Release(wic_factory);
8449 hr = ID2D1Factory1_CreateWicBitmapRenderTarget(factory, wic_bitmap, &rt_desc, &rt);
8450 ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr);
8452 check_rt_bitmap_surface(rt, FALSE, D2D1_BITMAP_OPTIONS_NONE);
8453 ID2D1RenderTarget_Release(rt);
8455 CoUninitialize();
8457 ID2D1Factory1_Release(factory);
8458 release_test_context(&ctx);
8461 static void test_device_context(BOOL d3d11)
8463 D2D1_HWND_RENDER_TARGET_PROPERTIES hwnd_rt_desc;
8464 D2D1_RENDER_TARGET_PROPERTIES rt_desc;
8465 ID2D1DeviceContext *device_context;
8466 IDXGISurface *surface, *surface2;
8467 ID2D1Device *device, *device2;
8468 struct d2d1_test_context ctx;
8469 D2D1_BITMAP_OPTIONS options;
8470 ID2D1DCRenderTarget *dc_rt;
8471 D2D1_UNIT_MODE unit_mode;
8472 ID2D1Factory1 *factory;
8473 ID2D1RenderTarget *rt;
8474 ID2D1Bitmap1 *bitmap;
8475 ID2D1Image *target;
8476 HRESULT hr;
8477 RECT rect;
8478 HDC hdc;
8480 IWICBitmap *wic_bitmap;
8481 IWICImagingFactory *wic_factory;
8483 if (!init_test_context(&ctx, d3d11))
8484 return;
8486 if (FAILED(D2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED, &IID_ID2D1Factory1, NULL, (void **)&factory)))
8488 win_skip("ID2D1Factory1 is not supported.\n");
8489 release_test_context(&ctx);
8490 return;
8493 hr = ID2D1Factory1_CreateDevice(factory, ctx.device, &device);
8494 ok(SUCCEEDED(hr), "Failed to get ID2D1Device, hr %#x.\n", hr);
8496 hr = ID2D1Device_CreateDeviceContext(device, D2D1_DEVICE_CONTEXT_OPTIONS_NONE, &device_context);
8497 ok(SUCCEEDED(hr), "Failed to create device context, hr %#x.\n", hr);
8499 ID2D1DeviceContext_GetDevice(device_context, &device2);
8500 ok(device2 == device, "Unexpected device instance.\n");
8501 ID2D1Device_Release(device2);
8503 target = (void *)0xdeadbeef;
8504 ID2D1DeviceContext_GetTarget(device_context, &target);
8505 ok(target == NULL, "Unexpected target instance %p.\n", target);
8507 unit_mode = ID2D1DeviceContext_GetUnitMode(device_context);
8508 ok(unit_mode == D2D1_UNIT_MODE_DIPS, "Unexpected unit mode %d.\n", unit_mode);
8510 ID2D1DeviceContext_Release(device_context);
8512 /* DXGI target */
8513 rt = ctx.rt;
8514 hr = ID2D1RenderTarget_QueryInterface(rt, &IID_ID2D1DeviceContext, (void **)&device_context);
8515 ok(SUCCEEDED(hr), "Failed to get device context interface, hr %#x.\n", hr);
8516 ID2D1DeviceContext_GetTarget(device_context, (ID2D1Image **)&bitmap);
8517 options = ID2D1Bitmap1_GetOptions(bitmap);
8518 ok(options == (D2D1_BITMAP_OPTIONS_TARGET | D2D1_BITMAP_OPTIONS_CANNOT_DRAW),
8519 "Unexpected bitmap options %#x.\n", options);
8520 hr = ID2D1Bitmap1_GetSurface(bitmap, &surface2);
8521 ok(SUCCEEDED(hr), "Failed to get bitmap surface, hr %#x.\n", hr);
8522 ok(surface2 == ctx.surface, "Unexpected surface instance.\n");
8523 IDXGISurface_Release(surface2);
8525 ID2D1DeviceContext_BeginDraw(device_context);
8526 hr = ID2D1Bitmap1_GetSurface(bitmap, &surface2);
8527 ok(SUCCEEDED(hr), "Failed to get bitmap surface, hr %#x.\n", hr);
8528 ok(surface2 == ctx.surface, "Unexpected surface instance.\n");
8529 IDXGISurface_Release(surface2);
8530 ID2D1DeviceContext_EndDraw(device_context, NULL, NULL);
8531 ID2D1Bitmap1_Release(bitmap);
8533 ID2D1DeviceContext_SetTarget(device_context, NULL);
8534 ID2D1DeviceContext_GetTarget(device_context, (ID2D1Image **)&bitmap);
8535 ok(bitmap == NULL, "Unexpected target instance.\n");
8537 ID2D1DeviceContext_Release(device_context);
8539 /* WIC target */
8540 CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
8542 hr = CoCreateInstance(&CLSID_WICImagingFactory, NULL, CLSCTX_INPROC_SERVER,
8543 &IID_IWICImagingFactory, (void **)&wic_factory);
8544 ok(SUCCEEDED(hr), "Failed to create WIC imaging factory, hr %#x.\n", hr);
8545 hr = IWICImagingFactory_CreateBitmap(wic_factory, 16, 16,
8546 &GUID_WICPixelFormat32bppPBGRA, WICBitmapCacheOnDemand, &wic_bitmap);
8547 ok(SUCCEEDED(hr), "Failed to create bitmap, hr %#x.\n", hr);
8548 IWICImagingFactory_Release(wic_factory);
8550 rt_desc.type = D2D1_RENDER_TARGET_TYPE_DEFAULT;
8551 rt_desc.pixelFormat.format = DXGI_FORMAT_B8G8R8A8_UNORM;
8552 rt_desc.pixelFormat.alphaMode = D2D1_ALPHA_MODE_PREMULTIPLIED;
8553 rt_desc.dpiX = 96.0f;
8554 rt_desc.dpiY = 96.0f;
8555 rt_desc.usage = D2D1_RENDER_TARGET_USAGE_NONE;
8556 rt_desc.minLevel = D2D1_FEATURE_LEVEL_DEFAULT;
8557 hr = ID2D1Factory1_CreateWicBitmapRenderTarget(factory, wic_bitmap, &rt_desc, &rt);
8558 ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr);
8560 hr = ID2D1RenderTarget_QueryInterface(rt, &IID_ID2D1DeviceContext, (void **)&device_context);
8561 ok(SUCCEEDED(hr), "Failed to get device context interface, hr %#x.\n", hr);
8562 ID2D1DeviceContext_GetTarget(device_context, (ID2D1Image **)&bitmap);
8563 options = ID2D1Bitmap1_GetOptions(bitmap);
8564 ok(options == (D2D1_BITMAP_OPTIONS_TARGET | D2D1_BITMAP_OPTIONS_CANNOT_DRAW),
8565 "Unexpected bitmap options %#x.\n", options);
8566 hr = ID2D1Bitmap1_GetSurface(bitmap, &surface);
8567 todo_wine
8568 ok(hr == E_FAIL, "Unexpected hr %#x.\n", hr);
8569 ID2D1Bitmap1_Release(bitmap);
8571 ID2D1DeviceContext_SetTarget(device_context, NULL);
8572 ID2D1DeviceContext_GetTarget(device_context, (ID2D1Image **)&bitmap);
8573 ok(bitmap == NULL, "Unexpected target instance.\n");
8575 ID2D1DeviceContext_Release(device_context);
8576 ID2D1RenderTarget_Release(rt);
8578 CoUninitialize();
8580 /* HWND target */
8581 hwnd_rt_desc.hwnd = NULL;
8582 hwnd_rt_desc.pixelSize.width = 64;
8583 hwnd_rt_desc.pixelSize.height = 64;
8584 hwnd_rt_desc.presentOptions = D2D1_PRESENT_OPTIONS_NONE;
8585 hwnd_rt_desc.hwnd = CreateWindowA("static", "d2d_test", 0, 0, 0, 0, 0, 0, 0, 0, 0);
8586 ok(!!hwnd_rt_desc.hwnd, "Failed to create target window.\n");
8588 hr = ID2D1Factory1_CreateHwndRenderTarget(factory, &rt_desc, &hwnd_rt_desc, (ID2D1HwndRenderTarget **)&rt);
8589 ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr);
8591 hr = ID2D1RenderTarget_QueryInterface(rt, &IID_ID2D1DeviceContext, (void **)&device_context);
8592 ok(SUCCEEDED(hr), "Failed to get device context interface, hr %#x.\n", hr);
8593 ID2D1DeviceContext_GetTarget(device_context, (ID2D1Image **)&bitmap);
8594 options = ID2D1Bitmap1_GetOptions(bitmap);
8595 ok(options == (D2D1_BITMAP_OPTIONS_TARGET | D2D1_BITMAP_OPTIONS_CANNOT_DRAW),
8596 "Unexpected bitmap options %#x.\n", options);
8597 hr = ID2D1Bitmap1_GetSurface(bitmap, &surface);
8598 ok(hr == D2DERR_INVALID_CALL, "Unexpected hr %#x.\n", hr);
8599 ID2D1Bitmap1_Release(bitmap);
8601 ID2D1DeviceContext_SetTarget(device_context, NULL);
8602 ID2D1DeviceContext_GetTarget(device_context, (ID2D1Image **)&bitmap);
8603 ok(bitmap == NULL, "Unexpected target instance.\n");
8605 ID2D1DeviceContext_Release(device_context);
8606 ID2D1RenderTarget_Release(rt);
8607 DestroyWindow(hwnd_rt_desc.hwnd);
8609 /* DC target */
8610 hr = ID2D1Factory1_CreateDCRenderTarget(factory, &rt_desc, &dc_rt);
8611 ok(SUCCEEDED(hr), "Failed to create target, hr %#x.\n", hr);
8613 hr = ID2D1DCRenderTarget_QueryInterface(dc_rt, &IID_ID2D1DeviceContext, (void **)&device_context);
8614 ok(SUCCEEDED(hr), "Failed to get device context interface, hr %#x.\n", hr);
8615 ID2D1DeviceContext_GetTarget(device_context, (ID2D1Image **)&bitmap);
8616 ok(bitmap == NULL, "Unexpected bitmap instance.\n");
8618 hdc = CreateCompatibleDC(NULL);
8619 ok(hdc != NULL, "Failed to create an HDC.\n");
8621 create_target_dibsection(hdc, 16, 16);
8623 SetRect(&rect, 0, 0, 16, 16);
8624 hr = ID2D1DCRenderTarget_BindDC(dc_rt, hdc, &rect);
8625 ok(SUCCEEDED(hr), "BindDC() failed, hr %#x.\n", hr);
8627 ID2D1DeviceContext_GetTarget(device_context, (ID2D1Image **)&bitmap);
8628 options = ID2D1Bitmap1_GetOptions(bitmap);
8629 ok(options == (D2D1_BITMAP_OPTIONS_TARGET | D2D1_BITMAP_OPTIONS_CANNOT_DRAW | D2D1_BITMAP_OPTIONS_GDI_COMPATIBLE),
8630 "Unexpected bitmap options %#x.\n", options);
8631 hr = ID2D1Bitmap1_GetSurface(bitmap, &surface);
8632 ok(hr == D2DERR_INVALID_CALL, "Unexpected hr %#x.\n", hr);
8633 ID2D1Bitmap1_Release(bitmap);
8635 ID2D1DeviceContext_SetTarget(device_context, NULL);
8636 ID2D1DeviceContext_GetTarget(device_context, (ID2D1Image **)&bitmap);
8637 ok(bitmap == NULL, "Unexpected target instance.\n");
8639 ID2D1DeviceContext_Release(device_context);
8640 ID2D1DCRenderTarget_Release(dc_rt);
8641 DeleteDC(hdc);
8643 ID2D1Device_Release(device);
8644 ID2D1Factory1_Release(factory);
8645 release_test_context(&ctx);
8648 static void test_invert_matrix(BOOL d3d11)
8650 static const struct
8652 D2D1_MATRIX_3X2_F matrix;
8653 D2D1_MATRIX_3X2_F inverse;
8654 BOOL invertible;
8656 invert_tests[] =
8658 { {{{ 0 }}}, {{{ 0 }}}, FALSE },
8661 1.0f, 2.0f,
8662 1.0f, 2.0f,
8663 4.0f, 8.0f
8664 }}},
8666 1.0f, 2.0f,
8667 1.0f, 2.0f,
8668 4.0f, 8.0f
8669 }}},
8670 FALSE
8674 2.0f, 0.0f,
8675 0.0f, 2.0f,
8676 4.0f, 8.0f
8677 }}},
8679 0.5f, -0.0f,
8680 -0.0f, 0.5f,
8681 -2.0f, -4.0f
8682 }}},
8683 TRUE
8687 2.0f, 1.0f,
8688 2.0f, 2.0f,
8689 4.0f, 8.0f
8690 }}},
8692 1.0f, -0.5f,
8693 -1.0f, 1.0f,
8694 4.0f, -6.0f
8695 }}},
8696 TRUE
8700 2.0f, 1.0f,
8701 3.0f, 1.0f,
8702 4.0f, 8.0f
8703 }}},
8705 -1.0f, 1.0f,
8706 3.0f, -2.0f,
8707 -20.0f, 12.0f
8708 }}},
8709 TRUE
8712 unsigned int i;
8714 for (i = 0; i < ARRAY_SIZE(invert_tests); ++i)
8716 D2D1_MATRIX_3X2_F m;
8717 BOOL ret;
8719 m = invert_tests[i].matrix;
8720 ret = D2D1InvertMatrix(&m);
8721 ok(ret == invert_tests[i].invertible, "%u: unexpected return value %d.\n", i, ret);
8722 ok(!memcmp(&m, &invert_tests[i].inverse, sizeof(m)),
8723 "%u: unexpected matrix value {%.8e, %.8e, %.8e, %.8e, %.8e, %.8e}.\n", i,
8724 m._11, m._12, m._21, m._22, m._31, m._32);
8726 ret = D2D1IsMatrixInvertible(&invert_tests[i].matrix);
8727 ok(ret == invert_tests[i].invertible, "%u: unexpected return value %d.\n", i, ret);
8731 static void test_skew_matrix(BOOL d3d11)
8733 static const struct
8735 float angle_x;
8736 float angle_y;
8737 D2D1_POINT_2F center;
8738 D2D1_MATRIX_3X2_F matrix;
8740 skew_tests[] =
8742 { 0.0f, 0.0f, { 0.0f, 0.0f }, {{{ 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f }}} },
8743 { 45.0f, 0.0f, { 0.0f, 0.0f }, {{{ 1.0f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f }}} },
8744 { 0.0f, 0.0f, { 10.0f, -3.0f }, {{{ 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f }}} },
8745 { -45.0f, 45.0f, { 0.1f, 0.5f }, {{{ 1.0f, 1.0f, -1.0f, 1.0f, 0.5f, -0.1f }}} },
8746 { -45.0f, 45.0f, { 1.0f, 2.0f }, {{{ 1.0f, 1.0f, -1.0f, 1.0f, 2.0f, -1.0f }}} },
8747 { 45.0f, -45.0f, { 1.0f, 2.0f }, {{{ 1.0f, -1.0f, 1.0f, 1.0f, -2.0f, 1.0f }}} },
8748 { 30.0f, -60.0f, { 12.0f, -5.0f }, {{{ 1.0f, -1.7320509f, 0.577350259f, 1.0f, 2.88675117f, 20.7846107f }}} },
8750 unsigned int i;
8752 for (i = 0; i < ARRAY_SIZE(skew_tests); ++i)
8754 const D2D1_MATRIX_3X2_F *expected = &skew_tests[i].matrix;
8755 D2D1_MATRIX_3X2_F m;
8756 BOOL ret;
8758 D2D1MakeSkewMatrix(skew_tests[i].angle_x, skew_tests[i].angle_y, skew_tests[i].center, &m);
8759 ret = compare_float(m._11, expected->_11, 3) && compare_float(m._12, expected->_12, 3)
8760 && compare_float(m._21, expected->_21, 3) && compare_float(m._22, expected->_22, 3)
8761 && compare_float(m._31, expected->_31, 3) && compare_float(m._32, expected->_32, 3);
8763 ok(ret, "%u: unexpected matrix value {%.8e, %.8e, %.8e, %.8e, %.8e, %.8e}, expected "
8764 "{%.8e, %.8e, %.8e, %.8e, %.8e, %.8e}.\n", i, m._11, m._12, m._21, m._22, m._31, m._32,
8765 expected->_11, expected->_12, expected->_21, expected->_22, expected->_31, expected->_32);
8769 static ID2D1DeviceContext *create_device_context(ID2D1Factory1 *factory, IDXGIDevice *dxgi_device, BOOL d3d11)
8771 ID2D1DeviceContext *device_context;
8772 ID2D1Device *device;
8773 HRESULT hr;
8775 hr = ID2D1Factory1_CreateDevice(factory, dxgi_device, &device);
8776 ok(SUCCEEDED(hr), "Failed to get ID2D1Device, hr %#x.\n", hr);
8778 hr = ID2D1Device_CreateDeviceContext(device, D2D1_DEVICE_CONTEXT_OPTIONS_NONE, &device_context);
8779 ok(SUCCEEDED(hr), "Failed to create device context, hr %#x.\n", hr);
8780 ID2D1Device_Release(device);
8782 return device_context;
8785 static void test_command_list(BOOL d3d11)
8787 static const DWORD bitmap_data[] =
8789 0xffff0000, 0xffffff00, 0xff00ff00, 0xff00ffff,
8791 static const D2D1_GRADIENT_STOP stops[] =
8793 {0.0f, {1.0f, 0.0f, 0.0f, 1.0f}},
8794 {0.5f, {0.0f, 1.0f, 0.0f, 1.0f}},
8795 {1.0f, {0.0f, 0.0f, 1.0f, 1.0f}},
8797 D2D1_RADIAL_GRADIENT_BRUSH_PROPERTIES radial_gradient_properties;
8798 D2D1_LINEAR_GRADIENT_BRUSH_PROPERTIES linear_gradient_properties;
8799 ID2D1DeviceContext *device_context, *device_context2;
8800 D2D1_STROKE_STYLE_PROPERTIES stroke_desc;
8801 ID2D1GradientStopCollection *gradient;
8802 D2D1_BITMAP_PROPERTIES bitmap_desc;
8803 ID2D1StrokeStyle *stroke_style;
8804 ID2D1CommandList *command_list;
8805 struct d2d1_test_context ctx;
8806 ID2D1Geometry *geometry;
8807 ID2D1Factory1 *factory;
8808 ID2D1RenderTarget *rt;
8809 D2D1_POINT_2F p0, p1;
8810 ID2D1Bitmap *bitmap;
8811 ID2D1Image *target;
8812 D2D1_COLOR_F color;
8813 ID2D1Brush *brush;
8814 D2D1_RECT_F rect;
8815 D2D_SIZE_U size;
8816 ULONG refcount;
8817 HRESULT hr;
8819 if (!init_test_context(&ctx, d3d11))
8820 return;
8822 if (FAILED(D2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED, &IID_ID2D1Factory1, NULL, (void **)&factory)))
8824 win_skip("ID2D1Factory1 is not supported.\n");
8825 release_test_context(&ctx);
8826 return;
8829 device_context = create_device_context(factory, ctx.device, d3d11);
8830 ok(device_context != NULL, "Failed to create device context.\n");
8832 hr = ID2D1DeviceContext_CreateCommandList(device_context, &command_list);
8833 todo_wine
8834 ok(SUCCEEDED(hr), "Failed to create command list, hr %#x.\n", hr);
8836 if (FAILED(hr))
8838 ID2D1DeviceContext_Release(device_context);
8839 ID2D1Factory1_Release(factory);
8840 return;
8843 ID2D1DeviceContext_SetTarget(device_context, (ID2D1Image *)command_list);
8844 ID2D1DeviceContext_BeginDraw(device_context);
8846 hr = ID2D1DeviceContext_QueryInterface(device_context, &IID_ID2D1RenderTarget, (void **)&rt);
8847 ok(SUCCEEDED(hr), "Failed to get rt interface, hr %#x.\n", hr);
8849 /* Test how resources are referenced by the list. */
8851 /* Bitmap. */
8852 set_size_u(&size, 4, 1);
8853 bitmap_desc.pixelFormat.format = DXGI_FORMAT_B8G8R8A8_UNORM;
8854 bitmap_desc.pixelFormat.alphaMode = D2D1_ALPHA_MODE_IGNORE;
8855 bitmap_desc.dpiX = 96.0f;
8856 bitmap_desc.dpiY = 96.0f;
8857 hr = ID2D1RenderTarget_CreateBitmap(rt, size, bitmap_data, 4 * sizeof(*bitmap_data), &bitmap_desc, &bitmap);
8858 ok(SUCCEEDED(hr), "Failed to create bitmap, hr %#x.\n", hr);
8860 ID2D1RenderTarget_DrawBitmap(rt, bitmap, NULL, 0.25f, D2D1_BITMAP_INTERPOLATION_MODE_NEAREST_NEIGHBOR, NULL);
8862 refcount = ID2D1Bitmap_Release(bitmap);
8863 ok(refcount == 1, "Got unexpected refcount %u.\n", refcount);
8865 /* Solid color brush. */
8866 set_color(&color, 0.0f, 0.0f, 0.0f, 0.0f);
8867 hr = ID2D1RenderTarget_CreateSolidColorBrush(rt, &color, NULL, (ID2D1SolidColorBrush **)&brush);
8868 ok(SUCCEEDED(hr), "Failed to create a brush, hr %#x.\n", hr);
8870 set_rect(&rect, 0.0f, 0.0f, 16.0f, 16.0f);
8871 ID2D1RenderTarget_FillRectangle(rt, &rect, brush);
8873 refcount = ID2D1Brush_Release(brush);
8874 ok(refcount == 0, "Got unexpected refcount %u.\n", refcount);
8876 /* Bitmap brush. */
8877 hr = ID2D1RenderTarget_CreateBitmap(rt, size, bitmap_data, 4 * sizeof(*bitmap_data), &bitmap_desc, &bitmap);
8878 ok(SUCCEEDED(hr), "Failed to create bitmap, hr %#x.\n", hr);
8880 hr = ID2D1RenderTarget_CreateBitmapBrush(rt, bitmap, NULL, NULL, (ID2D1BitmapBrush **)&brush);
8881 ok(SUCCEEDED(hr), "Failed to create bitmap brush, hr %#x.\n", hr);
8883 set_rect(&rect, 0.0f, 0.0f, 16.0f, 16.0f);
8884 ID2D1RenderTarget_FillRectangle(rt, &rect, brush);
8886 refcount = ID2D1Brush_Release(brush);
8887 ok(refcount == 0, "Got unexpected refcount %u.\n", refcount);
8889 refcount = ID2D1Bitmap_Release(bitmap);
8890 ok(refcount == 1, "Got unexpected refcount %u.\n", refcount);
8892 /* Linear gradient brush. */
8893 hr = ID2D1RenderTarget_CreateGradientStopCollection(rt, stops, ARRAY_SIZE(stops),
8894 D2D1_GAMMA_2_2, D2D1_EXTEND_MODE_CLAMP, &gradient);
8895 ok(SUCCEEDED(hr), "Failed to create stop collection, hr %#x.\n", hr);
8897 set_point(&linear_gradient_properties.startPoint, 320.0f, 0.0f);
8898 set_point(&linear_gradient_properties.endPoint, 0.0f, 960.0f);
8899 hr = ID2D1RenderTarget_CreateLinearGradientBrush(rt, &linear_gradient_properties, NULL, gradient,
8900 (ID2D1LinearGradientBrush **)&brush);
8901 ok(SUCCEEDED(hr), "Failed to create brush, hr %#x.\n", hr);
8903 set_rect(&rect, -1.0f, -1.0f, 1.0f, 1.0f);
8904 hr = ID2D1Factory1_CreateRectangleGeometry(factory, &rect, (ID2D1RectangleGeometry **)&geometry);
8905 ok(SUCCEEDED(hr), "Failed to create geometry, hr %#x.\n", hr);
8907 ID2D1RenderTarget_FillGeometry(rt, geometry, brush, NULL);
8909 refcount = ID2D1Brush_Release(brush);
8910 ok(refcount == 0, "Got unexpected refcount %u.\n", refcount);
8912 refcount = ID2D1Geometry_Release(geometry);
8913 ok(refcount == 1, "Got unexpected refcount %u.\n", refcount);
8915 refcount = ID2D1GradientStopCollection_Release(gradient);
8916 ok(refcount == 1, "Got unexpected refcount %u.\n", refcount);
8918 /* Radial gradient brush. */
8919 hr = ID2D1RenderTarget_CreateGradientStopCollection(rt, stops, ARRAY_SIZE(stops),
8920 D2D1_GAMMA_2_2, D2D1_EXTEND_MODE_CLAMP, &gradient);
8921 ok(SUCCEEDED(hr), "Failed to create stop collection, hr %#x.\n", hr);
8923 set_point(&radial_gradient_properties.center, 160.0f, 480.0f);
8924 set_point(&radial_gradient_properties.gradientOriginOffset, 40.0f, -120.0f);
8925 radial_gradient_properties.radiusX = 160.0f;
8926 radial_gradient_properties.radiusY = 480.0f;
8927 hr = ID2D1RenderTarget_CreateRadialGradientBrush(rt, &radial_gradient_properties, NULL, gradient,
8928 (ID2D1RadialGradientBrush **)&brush);
8929 ok(SUCCEEDED(hr), "Failed to create brush, hr %#x.\n", hr);
8931 set_rect(&rect, -1.0f, -1.0f, 1.0f, 1.0f);
8932 hr = ID2D1Factory1_CreateRectangleGeometry(factory, &rect, (ID2D1RectangleGeometry **)&geometry);
8933 ok(SUCCEEDED(hr), "Failed to create geometry, hr %#x.\n", hr);
8935 ID2D1RenderTarget_FillGeometry(rt, geometry, brush, NULL);
8937 refcount = ID2D1Brush_Release(brush);
8938 ok(refcount == 0, "Got unexpected refcount %u.\n", refcount);
8940 refcount = ID2D1Geometry_Release(geometry);
8941 ok(refcount == 1, "Got unexpected refcount %u.\n", refcount);
8943 refcount = ID2D1GradientStopCollection_Release(gradient);
8944 ok(refcount == 1, "Got unexpected refcount %u.\n", refcount);
8946 /* Geometry. */
8947 set_rect(&rect, -1.0f, -1.0f, 1.0f, 1.0f);
8948 hr = ID2D1Factory1_CreateRectangleGeometry(factory, &rect, (ID2D1RectangleGeometry **)&geometry);
8949 ok(SUCCEEDED(hr), "Failed to create geometry, hr %#x.\n", hr);
8951 set_color(&color, 0.0f, 0.0f, 0.0f, 0.0f);
8952 hr = ID2D1RenderTarget_CreateSolidColorBrush(rt, &color, NULL, (ID2D1SolidColorBrush **)&brush);
8953 ok(SUCCEEDED(hr), "Failed to create a brush, hr %#x.\n", hr);
8955 ID2D1RenderTarget_FillGeometry(rt, geometry, brush, NULL);
8957 refcount = ID2D1Brush_Release(brush);
8958 ok(refcount == 0, "Got unexpected refcount %u.\n", refcount);
8960 refcount = ID2D1Geometry_Release(geometry);
8961 ok(refcount == 1, "Got unexpected refcount %u.\n", refcount);
8963 /* Stroke style. */
8964 stroke_desc.startCap = D2D1_CAP_STYLE_SQUARE;
8965 stroke_desc.endCap = D2D1_CAP_STYLE_ROUND;
8966 stroke_desc.dashCap = D2D1_CAP_STYLE_TRIANGLE;
8967 stroke_desc.lineJoin = D2D1_LINE_JOIN_BEVEL;
8968 stroke_desc.miterLimit = 1.5f;
8969 stroke_desc.dashStyle = D2D1_DASH_STYLE_DOT;
8970 stroke_desc.dashOffset = -1.0f;
8972 hr = ID2D1Factory_CreateStrokeStyle((ID2D1Factory *)factory, &stroke_desc, NULL, 0, &stroke_style);
8973 ok(SUCCEEDED(hr), "Failed to create stroke style, %#x.\n", hr);
8975 set_color(&color, 0.0f, 0.0f, 0.0f, 0.0f);
8976 hr = ID2D1RenderTarget_CreateSolidColorBrush(rt, &color, NULL, (ID2D1SolidColorBrush **)&brush);
8977 ok(SUCCEEDED(hr), "Failed to create a brush, hr %#x.\n", hr);
8979 set_point(&p0, 100.0f, 160.0f);
8980 set_point(&p1, 140.0f, 160.0f);
8981 ID2D1RenderTarget_DrawLine(rt, p0, p1, brush, 1.0f, stroke_style);
8983 refcount = ID2D1Brush_Release(brush);
8984 ok(refcount == 0, "Got unexpected refcount %u.\n", refcount);
8986 refcount = ID2D1StrokeStyle_Release(stroke_style);
8987 ok(refcount == 1, "Got unexpected refcount %u.\n", refcount);
8989 /* Close on attached list. */
8990 ID2D1DeviceContext_GetTarget(device_context, &target);
8991 ok(target == (ID2D1Image *)command_list, "Unexpected context target.\n");
8992 ID2D1Image_Release(target);
8994 hr = ID2D1CommandList_Close(command_list);
8995 ok(SUCCEEDED(hr), "Failed to close a list, hr %#x.\n", hr);
8997 ID2D1DeviceContext_GetTarget(device_context, &target);
8998 ok(target == NULL, "Unexpected context target.\n");
9000 hr = ID2D1CommandList_Close(command_list);
9001 ok(hr == D2DERR_WRONG_STATE, "Unexpected hr %#x.\n", hr);
9003 ID2D1CommandList_Release(command_list);
9005 /* Close empty list. */
9006 hr = ID2D1DeviceContext_CreateCommandList(device_context, &command_list);
9007 ok(SUCCEEDED(hr), "Failed to create command list, hr %#x.\n", hr);
9009 hr = ID2D1CommandList_Close(command_list);
9010 ok(SUCCEEDED(hr), "Failed to close a list, hr %#x.\n", hr);
9012 ID2D1CommandList_Release(command_list);
9014 /* List created with different context. */
9015 device_context2 = create_device_context(factory, ctx.device, d3d11);
9016 ok(device_context2 != NULL, "Failed to create device context.\n");
9018 hr = ID2D1DeviceContext_CreateCommandList(device_context, &command_list);
9019 ok(SUCCEEDED(hr), "Failed to create command list, hr %#x.\n", hr);
9021 ID2D1DeviceContext_SetTarget(device_context2, (ID2D1Image *)command_list);
9022 ID2D1DeviceContext_GetTarget(device_context2, &target);
9023 ok(target == NULL, "Unexpected target.\n");
9025 ID2D1CommandList_Release(command_list);
9026 ID2D1DeviceContext_Release(device_context2);
9028 ID2D1RenderTarget_Release(rt);
9029 ID2D1DeviceContext_Release(device_context);
9030 ID2D1Factory1_Release(factory);
9031 release_test_context(&ctx);
9034 static void test_max_bitmap_size(BOOL d3d11)
9036 D2D1_RENDER_TARGET_PROPERTIES desc;
9037 D2D1_BITMAP_PROPERTIES bitmap_desc;
9038 IDXGISwapChain *swapchain;
9039 ID2D1Factory *factory;
9040 IDXGISurface *surface;
9041 ID2D1RenderTarget *rt;
9042 ID3D10Device1 *device;
9043 ID2D1Bitmap *bitmap;
9044 UINT32 bitmap_size;
9045 unsigned int i, j;
9046 HWND window;
9047 HRESULT hr;
9049 static const struct
9051 const char *name;
9052 DWORD type;
9054 device_types[] =
9056 { "HW", D3D10_DRIVER_TYPE_HARDWARE },
9057 { "WARP", D3D10_DRIVER_TYPE_WARP },
9058 { "REF", D3D10_DRIVER_TYPE_REFERENCE },
9060 static const struct
9062 const char *name;
9063 DWORD type;
9065 target_types[] =
9067 { "DEFAULT", D2D1_RENDER_TARGET_TYPE_DEFAULT },
9068 { "HW", D2D1_RENDER_TARGET_TYPE_HARDWARE },
9071 hr = D2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED, &IID_ID2D1Factory, NULL, (void **)&factory);
9072 ok(SUCCEEDED(hr), "Failed to create factory, hr %#x.\n", hr);
9074 for (i = 0; i < ARRAY_SIZE(device_types); ++i)
9076 if (FAILED(hr = D3D10CreateDevice1(NULL, device_types[i].type, NULL, D3D10_CREATE_DEVICE_BGRA_SUPPORT,
9077 D3D10_FEATURE_LEVEL_10_0, D3D10_1_SDK_VERSION, &device)))
9079 skip("Failed to create %s d3d device, hr %#x.\n", device_types[i].name, hr);
9080 continue;
9083 window = create_window();
9084 swapchain = create_d3d10_swapchain(device, window, TRUE);
9085 hr = IDXGISwapChain_GetBuffer(swapchain, 0, &IID_IDXGISurface, (void **)&surface);
9086 ok(SUCCEEDED(hr), "Failed to get buffer, hr %#x.\n", hr);
9088 for (j = 0; j < ARRAY_SIZE(target_types); ++j)
9090 D3D10_TEXTURE2D_DESC texture_desc;
9091 ID3D10Texture2D *texture;
9092 D2D1_SIZE_U size;
9094 desc.type = target_types[j].type;
9095 desc.pixelFormat.format = DXGI_FORMAT_UNKNOWN;
9096 desc.pixelFormat.alphaMode = D2D1_ALPHA_MODE_PREMULTIPLIED;
9097 desc.dpiX = 0.0f;
9098 desc.dpiY = 0.0f;
9099 desc.usage = D2D1_RENDER_TARGET_USAGE_NONE;
9100 desc.minLevel = D2D1_FEATURE_LEVEL_DEFAULT;
9102 hr = ID2D1Factory_CreateDxgiSurfaceRenderTarget(factory, surface, &desc, &rt);
9103 ok(SUCCEEDED(hr), "%s/%s: failed to create render target, hr %#x.\n", device_types[i].name,
9104 target_types[j].name, hr);
9106 bitmap_size = ID2D1RenderTarget_GetMaximumBitmapSize(rt);
9107 ok(bitmap_size >= D3D10_REQ_TEXTURE2D_U_OR_V_DIMENSION, "%s/%s: unexpected bitmap size %u.\n",
9108 device_types[i].name, target_types[j].name, bitmap_size);
9110 bitmap_desc.dpiX = 96.0f;
9111 bitmap_desc.dpiY = 96.0f;
9112 bitmap_desc.pixelFormat.format = DXGI_FORMAT_B8G8R8A8_UNORM;
9113 bitmap_desc.pixelFormat.alphaMode = D2D1_ALPHA_MODE_PREMULTIPLIED;
9115 size.width = bitmap_size;
9116 size.height = 1;
9117 hr = ID2D1RenderTarget_CreateBitmap(rt, size, NULL, 0, &bitmap_desc, &bitmap);
9118 ok(SUCCEEDED(hr), "Failed to create a bitmap, hr %#x.\n", hr);
9119 ID2D1Bitmap_Release(bitmap);
9121 ID2D1RenderTarget_Release(rt);
9123 texture_desc.Width = bitmap_size;
9124 texture_desc.Height = 1;
9125 texture_desc.MipLevels = 1;
9126 texture_desc.ArraySize = 1;
9127 texture_desc.Format = DXGI_FORMAT_B8G8R8A8_UNORM;
9128 texture_desc.SampleDesc.Count = 1;
9129 texture_desc.SampleDesc.Quality = 0;
9130 texture_desc.Usage = D3D10_USAGE_DEFAULT;
9131 texture_desc.BindFlags = 0;
9132 texture_desc.CPUAccessFlags = 0;
9133 texture_desc.MiscFlags = 0;
9135 hr = ID3D10Device1_CreateTexture2D(device, &texture_desc, NULL, &texture);
9136 ok(SUCCEEDED(hr) || broken(hr == E_INVALIDARG && device_types[i].type == D3D10_DRIVER_TYPE_WARP) /* Vista */,
9137 "%s/%s: failed to create texture, hr %#x.\n", device_types[i].name, target_types[j].name, hr);
9138 if (SUCCEEDED(hr))
9139 ID3D10Texture2D_Release(texture);
9142 IDXGISurface_Release(surface);
9143 IDXGISwapChain_Release(swapchain);
9144 DestroyWindow(window);
9146 ID3D10Device1_Release(device);
9149 ID2D1Factory_Release(factory);
9152 static void test_dpi(BOOL d3d11)
9154 D2D1_BITMAP_PROPERTIES1 bitmap_desc;
9155 ID2D1DeviceContext *device_context;
9156 IWICImagingFactory *wic_factory;
9157 struct d2d1_test_context ctx;
9158 ID2D1Factory1 *factory;
9159 ID2D1Bitmap1 *bitmap;
9160 float dpi_x, dpi_y;
9161 HRESULT hr;
9163 static const struct
9165 float dpi_x, dpi_y;
9166 HRESULT hr;
9168 create_dpi_tests[] =
9170 { 0.0f, 0.0f, S_OK},
9171 {192.0f, 0.0f, E_INVALIDARG},
9172 { 0.0f, 192.0f, E_INVALIDARG},
9173 {192.0f, -10.0f, E_INVALIDARG},
9174 {-10.0f, 192.0f, E_INVALIDARG},
9175 {-10.0f, -10.0f, E_INVALIDARG},
9176 { 48.0f, 96.0f, S_OK},
9177 { 96.0f, 48.0f, S_OK},
9179 static const float init_dpi_x = 60.0f, init_dpi_y = 288.0f;
9180 static const float dc_dpi_x = 120.0f, dc_dpi_y = 144.0f;
9181 unsigned int i;
9183 if (!init_test_context(&ctx, d3d11))
9184 return;
9186 if (FAILED(D2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED, &IID_ID2D1Factory1, NULL, (void **)&factory)))
9188 win_skip("ID2D1Factory1 is not supported.\n");
9189 release_test_context(&ctx);
9190 return;
9194 device_context = create_device_context(factory, ctx.device, d3d11);
9195 ok(!!device_context, "Failed to create device context.\n");
9197 ID2D1DeviceContext_GetDpi(device_context, &dpi_x, &dpi_y);
9198 ok(dpi_x == 96.0f, "Got unexpected dpi_x %.8e.\n", dpi_x);
9199 ok(dpi_y == 96.0f, "Got unexpected dpi_y %.8e.\n", dpi_y);
9201 /* DXGI surface */
9202 for (i = 0; i < ARRAY_SIZE(create_dpi_tests); ++i)
9204 ID2D1DeviceContext_SetDpi(device_context, init_dpi_x, init_dpi_y);
9206 bitmap_desc.pixelFormat.format = DXGI_FORMAT_UNKNOWN;
9207 bitmap_desc.pixelFormat.alphaMode = D2D1_ALPHA_MODE_PREMULTIPLIED;
9208 bitmap_desc.dpiX = create_dpi_tests[i].dpi_x;
9209 bitmap_desc.dpiY = create_dpi_tests[i].dpi_y;
9210 bitmap_desc.bitmapOptions = D2D1_BITMAP_OPTIONS_TARGET | D2D1_BITMAP_OPTIONS_CANNOT_DRAW;
9211 bitmap_desc.colorContext = NULL;
9212 hr = ID2D1DeviceContext_CreateBitmapFromDxgiSurface(device_context, ctx.surface, &bitmap_desc, &bitmap);
9213 /* Native accepts negative DPI values for DXGI surface bitmap. */
9214 ok(hr == S_OK, "Test %u: Got unexpected hr %#x.\n", i, hr);
9216 ID2D1DeviceContext_SetDpi(device_context, dc_dpi_x, dc_dpi_y);
9218 ID2D1Bitmap1_GetDpi(bitmap, &dpi_x, &dpi_y);
9219 todo_wine_if(bitmap_desc.dpiX == 0.0f)
9220 ok(dpi_x == bitmap_desc.dpiX, "Test %u: Got unexpected dpi_x %.8e, expected %.8e.\n",
9221 i, dpi_x, bitmap_desc.dpiX);
9222 todo_wine_if(bitmap_desc.dpiY == 0.0f)
9223 ok(dpi_y == bitmap_desc.dpiY, "Test %u: Got unexpected dpi_y %.8e, expected %.8e.\n",
9224 i, dpi_y, bitmap_desc.dpiY);
9226 ID2D1DeviceContext_BeginDraw(device_context);
9227 ID2D1DeviceContext_SetTarget(device_context, (ID2D1Image *)bitmap);
9228 hr = ID2D1DeviceContext_EndDraw(device_context, NULL, NULL);
9229 ok(hr == S_OK, "Test %u: Got unexpected hr %#x.\n", i, hr);
9231 /* Device context DPI values aren't updated by SetTarget. */
9232 ID2D1DeviceContext_GetDpi(device_context, &dpi_x, &dpi_y);
9233 ok(dpi_x == dc_dpi_x, "Test %u: Got unexpected dpi_x %.8e, expected %.8e.\n", i, dpi_x, dc_dpi_x);
9234 ok(dpi_y == dc_dpi_y, "Test %u: Got unexpected dpi_y %.8e, expected %.8e.\n", i, dpi_y, dc_dpi_y);
9236 ID2D1Bitmap1_Release(bitmap);
9239 /* WIC bitmap */
9240 CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
9241 hr = CoCreateInstance(&CLSID_WICImagingFactory, NULL, CLSCTX_INPROC_SERVER,
9242 &IID_IWICImagingFactory, (void **)&wic_factory);
9243 ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
9244 for (i = 0; i < ARRAY_SIZE(create_dpi_tests); ++i)
9246 IWICBitmapSource *wic_bitmap_src;
9247 IWICBitmap *wic_bitmap;
9249 ID2D1DeviceContext_SetDpi(device_context, init_dpi_x, init_dpi_y);
9251 hr = IWICImagingFactory_CreateBitmap(wic_factory, 16, 16,
9252 &GUID_WICPixelFormat32bppPBGRA, WICBitmapCacheOnDemand, &wic_bitmap);
9253 ok(hr == S_OK, "Test %u: Got unexpected hr %#x.\n", i, hr);
9254 hr = IWICBitmap_QueryInterface(wic_bitmap, &IID_IWICBitmapSource, (void **)&wic_bitmap_src);
9255 ok(hr == S_OK, "Test %u: Got unexpected hr %#x.\n", i, hr);
9256 IWICBitmap_Release(wic_bitmap);
9258 bitmap_desc.pixelFormat.format = DXGI_FORMAT_UNKNOWN;
9259 bitmap_desc.pixelFormat.alphaMode = D2D1_ALPHA_MODE_PREMULTIPLIED;
9260 bitmap_desc.dpiX = create_dpi_tests[i].dpi_x;
9261 bitmap_desc.dpiY = create_dpi_tests[i].dpi_y;
9262 bitmap_desc.bitmapOptions = D2D1_BITMAP_OPTIONS_TARGET | D2D1_BITMAP_OPTIONS_CANNOT_DRAW;
9263 bitmap_desc.colorContext = NULL;
9264 hr = ID2D1DeviceContext_CreateBitmapFromWicBitmap(device_context, wic_bitmap_src, &bitmap_desc, &bitmap);
9265 ok(hr == create_dpi_tests[i].hr, "Test %u: Got unexpected hr %#x, expected %#x.\n",
9266 i, hr, create_dpi_tests[i].hr);
9267 IWICBitmapSource_Release(wic_bitmap_src);
9269 if (FAILED(hr))
9270 continue;
9272 ID2D1DeviceContext_SetDpi(device_context, dc_dpi_x, dc_dpi_y);
9274 ID2D1Bitmap1_GetDpi(bitmap, &dpi_x, &dpi_y);
9275 if (bitmap_desc.dpiX == 0.0f && bitmap_desc.dpiY == 0.0f)
9277 /* Bitmap DPI values are inherited at creation time. */
9278 ok(dpi_x == init_dpi_x, "Test %u: Got unexpected dpi_x %.8e, expected %.8e.\n", i, dpi_x, init_dpi_x);
9279 ok(dpi_y == init_dpi_y, "Test %u: Got unexpected dpi_y %.8e, expected %.8e.\n", i, dpi_y, init_dpi_y);
9281 else
9283 ok(dpi_x == bitmap_desc.dpiX, "Test %u: Got unexpected dpi_x %.8e, expected %.8e.\n",
9284 i, dpi_x, bitmap_desc.dpiX);
9285 ok(dpi_y == bitmap_desc.dpiY, "Test %u: Got unexpected dpi_y %.8e, expected %.8e.\n",
9286 i, dpi_y, bitmap_desc.dpiY);
9289 ID2D1DeviceContext_BeginDraw(device_context);
9290 ID2D1DeviceContext_SetTarget(device_context, (ID2D1Image *)bitmap);
9291 hr = ID2D1DeviceContext_EndDraw(device_context, NULL, NULL);
9292 ok(hr == S_OK, "Test %u: Got unexpected hr %#x.\n", i, hr);
9294 /* Device context DPI values aren't updated by SetTarget. */
9295 ID2D1DeviceContext_GetDpi(device_context, &dpi_x, &dpi_y);
9296 ok(dpi_x == dc_dpi_x, "Test %u: Got unexpected dpi_x %.8e, expected %.8e.\n", i, dpi_x, dc_dpi_x);
9297 ok(dpi_y == dc_dpi_y, "Test %u: Got unexpected dpi_y %.8e, expected %.8e.\n", i, dpi_y, dc_dpi_y);
9299 ID2D1Bitmap1_Release(bitmap);
9301 IWICImagingFactory_Release(wic_factory);
9302 CoUninitialize();
9304 /* D2D bitmap */
9305 for (i = 0; i < ARRAY_SIZE(create_dpi_tests); ++i)
9307 const D2D1_SIZE_U size = {16, 16};
9309 ID2D1DeviceContext_SetDpi(device_context, init_dpi_x, init_dpi_y);
9311 bitmap_desc.pixelFormat.format = DXGI_FORMAT_B8G8R8A8_UNORM;
9312 bitmap_desc.pixelFormat.alphaMode = D2D1_ALPHA_MODE_PREMULTIPLIED;
9313 bitmap_desc.dpiX = create_dpi_tests[i].dpi_x;
9314 bitmap_desc.dpiY = create_dpi_tests[i].dpi_y;
9315 bitmap_desc.bitmapOptions = D2D1_BITMAP_OPTIONS_TARGET | D2D1_BITMAP_OPTIONS_CANNOT_DRAW;
9316 bitmap_desc.colorContext = NULL;
9317 hr = ID2D1DeviceContext_CreateBitmap(device_context, size, NULL, 0, &bitmap_desc, &bitmap);
9318 ok(hr == create_dpi_tests[i].hr, "Test %u: Got unexpected hr %#x, expected %#x.\n",
9319 i, hr, create_dpi_tests[i].hr);
9321 if (FAILED(hr))
9322 continue;
9324 ID2D1DeviceContext_SetDpi(device_context, dc_dpi_x, dc_dpi_y);
9326 ID2D1Bitmap1_GetDpi(bitmap, &dpi_x, &dpi_y);
9327 if (bitmap_desc.dpiX == 0.0f && bitmap_desc.dpiY == 0.0f)
9329 /* Bitmap DPI values are inherited at creation time. */
9330 ok(dpi_x == init_dpi_x, "Test %u: Got unexpected dpi_x %.8e, expected %.8e.\n", i, dpi_x, init_dpi_x);
9331 ok(dpi_y == init_dpi_y, "Test %u: Got unexpected dpi_y %.8e, expected %.8e.\n", i, dpi_y, init_dpi_y);
9333 else
9335 ok(dpi_x == bitmap_desc.dpiX, "Test %u: Got unexpected dpi_x %.8e, expected %.8e.\n",
9336 i, dpi_x, bitmap_desc.dpiX);
9337 ok(dpi_y == bitmap_desc.dpiY, "Test %u: Got unexpected dpi_y %.8e, expected %.8e.\n",
9338 i, dpi_y, bitmap_desc.dpiY);
9341 ID2D1DeviceContext_BeginDraw(device_context);
9342 ID2D1DeviceContext_SetTarget(device_context, (ID2D1Image *)bitmap);
9343 hr = ID2D1DeviceContext_EndDraw(device_context, NULL, NULL);
9344 ok(hr == S_OK, "Test %u: Got unexpected hr %#x.\n", i, hr);
9346 /* Device context DPI values aren't updated by SetTarget. */
9347 ID2D1DeviceContext_GetDpi(device_context, &dpi_x, &dpi_y);
9348 ok(dpi_x == dc_dpi_x, "Test %u: Got unexpected dpi_x %.8e, expected %.8e.\n", i, dpi_x, dc_dpi_x);
9349 ok(dpi_y == dc_dpi_y, "Test %u: Got unexpected dpi_y %.8e, expected %.8e.\n", i, dpi_y, dc_dpi_y);
9351 ID2D1Bitmap1_Release(bitmap);
9354 ID2D1DeviceContext_SetTarget(device_context, NULL);
9355 ID2D1DeviceContext_GetDpi(device_context, &dpi_x, &dpi_y);
9356 ok(dpi_x == dc_dpi_x, "Got unexpected dpi_x %.8e, expected %.8e.\n", dpi_x, dc_dpi_x);
9357 ok(dpi_y == dc_dpi_y, "Got unexpected dpi_y %.8e, expected %.8e.\n", dpi_y, dc_dpi_y);
9359 ID2D1DeviceContext_Release(device_context);
9360 ID2D1Factory1_Release(factory);
9361 release_test_context(&ctx);
9364 static void test_wic_bitmap_format(BOOL d3d11)
9366 IWICImagingFactory *wic_factory;
9367 struct d2d1_test_context ctx;
9368 D2D1_PIXEL_FORMAT format;
9369 IWICBitmap *wic_bitmap;
9370 ID2D1RenderTarget *rt;
9371 ID2D1Bitmap *bitmap;
9372 unsigned int i;
9373 HRESULT hr;
9375 static const struct
9377 const WICPixelFormatGUID *wic;
9378 D2D1_PIXEL_FORMAT d2d;
9380 tests[] =
9382 {&GUID_WICPixelFormat32bppPBGRA, {DXGI_FORMAT_B8G8R8A8_UNORM, D2D1_ALPHA_MODE_PREMULTIPLIED}},
9383 {&GUID_WICPixelFormat32bppPRGBA, {DXGI_FORMAT_R8G8B8A8_UNORM, D2D1_ALPHA_MODE_PREMULTIPLIED}},
9384 {&GUID_WICPixelFormat32bppBGR, {DXGI_FORMAT_B8G8R8A8_UNORM, D2D1_ALPHA_MODE_IGNORE}},
9387 if (!init_test_context(&ctx, d3d11))
9388 return;
9390 rt = ctx.rt;
9391 CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
9393 hr = CoCreateInstance(&CLSID_WICImagingFactory, NULL, CLSCTX_INPROC_SERVER,
9394 &IID_IWICImagingFactory, (void **)&wic_factory);
9395 ok(hr == S_OK, "Failed to create WIC imaging factory, hr %#x.\n", hr);
9397 for (i = 0; i < ARRAY_SIZE(tests); ++i)
9399 hr = IWICImagingFactory_CreateBitmap(wic_factory, 16, 16,
9400 tests[i].wic, WICBitmapCacheOnDemand, &wic_bitmap);
9401 ok(hr == S_OK, "%s: Failed to create WIC bitmap, hr %#x.\n", debugstr_guid(tests[i].wic), hr);
9403 hr = ID2D1RenderTarget_CreateBitmapFromWicBitmap(rt, (IWICBitmapSource *)wic_bitmap, NULL, &bitmap);
9404 ok(hr == S_OK, "%s: Failed to create bitmap from WIC source, hr %#x.\n", debugstr_guid(tests[i].wic), hr);
9406 format = ID2D1Bitmap_GetPixelFormat(bitmap);
9407 ok(format.format == tests[i].d2d.format, "%s: Got unexpected DXGI format %#x.\n",
9408 debugstr_guid(tests[i].wic), format.format);
9409 ok(format.alphaMode == tests[i].d2d.alphaMode, "%s: Got unexpected alpha mode %#x.\n",
9410 debugstr_guid(tests[i].wic), format.alphaMode);
9412 ID2D1Bitmap_Release(bitmap);
9413 IWICBitmap_Release(wic_bitmap);
9416 IWICImagingFactory_Release(wic_factory);
9417 CoUninitialize();
9418 release_test_context(&ctx);
9421 static void test_math(BOOL d3d11)
9423 float s, c, t, l;
9424 unsigned int i;
9426 static const struct
9428 float x;
9429 float s;
9430 float c;
9432 sc_data[] =
9434 {0.0f, 0.0f, 1.0f},
9435 {1.0f, 8.41470957e-001f, 5.40302277e-001f},
9436 {2.0f, 9.09297407e-001f, -4.16146845e-001f},
9437 {M_PI / 2.0f, 1.0f, -4.37113883e-008f},
9438 {M_PI, -8.74227766e-008f, -1.0f},
9441 static const struct
9443 float x;
9444 float t;
9446 t_data[] =
9448 {0.0f, 0.0f},
9449 {1.0f, 1.55740774f},
9450 {2.0f, -2.18503976f},
9451 {M_PI / 2.0f, -2.28773320e+007f},
9452 {M_PI, 8.74227766e-008f},
9455 static const struct
9457 float x;
9458 float y;
9459 float z;
9460 float l;
9462 l_data[] =
9464 {0.0f, 0.0f, 0.0f, 0.0f},
9465 {1.0f, 0.0f, 0.0f, 1.0f},
9466 {0.0f, 1.0f, 0.0f, 1.0f},
9467 {0.0f, 0.0f, 1.0f, 1.0f},
9468 {1.0f, 1.0f, 1.0f, 1.73205078f},
9469 {1.0f, 2.0f, 2.0f, 3.0f},
9470 {1.0f, 2.0f, 3.0f, 3.74165750f},
9473 if (!pD2D1SinCos || !pD2D1Tan || !pD2D1Vec3Length)
9475 win_skip("D2D1SinCos/D2D1Tan/D2D1Vec3Length not available, skipping test.\n");
9476 return;
9479 for (i = 0; i < ARRAY_SIZE(sc_data); ++i)
9481 pD2D1SinCos(sc_data[i].x, &s, &c);
9482 ok(compare_float(s, sc_data[i].s, 0),
9483 "Test %u: Got unexpected sin %.8e, expected %.8e.\n", i, s, sc_data[i].s);
9484 ok(compare_float(c, sc_data[i].c, 0),
9485 "Test %u: Got unexpected cos %.8e, expected %.8e.\n", i, c, sc_data[i].c);
9488 for (i = 0; i < ARRAY_SIZE(t_data); ++i)
9490 t = pD2D1Tan(t_data[i].x);
9491 ok(compare_float(t, t_data[i].t, 1),
9492 "Test %u: Got unexpected tan %.8e, expected %.8e.\n", i, t, t_data[i].t);
9495 for (i = 0; i < ARRAY_SIZE(l_data); ++i)
9497 l = pD2D1Vec3Length(l_data[i].x, l_data[i].y, l_data[i].z);
9498 ok(compare_float(l, l_data[i].l, 0),
9499 "Test %u: Got unexpected length %.8e, expected %.8e.\n", i, l, l_data[i].l);
9503 static void test_colour_space(BOOL d3d11)
9505 D2D1_COLOR_F src_colour, dst_colour, expected;
9506 D2D1_COLOR_SPACE src_space, dst_space;
9507 unsigned i, j, k;
9509 static const D2D1_COLOR_SPACE colour_spaces[] =
9511 D2D1_COLOR_SPACE_CUSTOM,
9512 D2D1_COLOR_SPACE_SRGB,
9513 D2D1_COLOR_SPACE_SCRGB,
9515 static struct
9517 D2D1_COLOR_F srgb;
9518 D2D1_COLOR_F scrgb;
9520 const test_data[] =
9522 {{0.0f, 0.0f, 0.0f, 0.0f}, {0.0f, 0.0f, 0.0f, 0.0f}},
9523 {{0.0f, 0.0f, 0.0f, 1.0f}, {0.0f, 0.0f, 0.0f, 1.0f}},
9524 {{1.0f, 1.0f, 1.0f, 1.0f}, {1.0f, 1.0f, 1.0f, 1.0f}},
9525 /* Samples in the non-linear region. */
9526 {{0.2f, 0.4f, 0.6f, 0.8f}, {0.0331047624f, 0.132868335f, 0.318546832f, 0.8f}},
9527 {{0.3f, 0.5f, 0.7f, 0.9f}, {0.0732389688f, 0.214041144f, 0.447988421f, 0.9f}},
9528 /* Samples in the linear region. */
9529 {{0.0002f, 0.0004f, 0.0006f, 0.0008f}, {1.54798763e-005f, 3.09597526e-005f, 4.64396289e-005f, 0.0008f}},
9530 {{0.0003f, 0.0005f, 0.0007f, 0.0009f}, {2.32198145e-005f, 3.86996908e-005f, 5.41795634e-005f, 0.0009f}},
9531 /* Out of range samples */
9532 {{-0.3f, 1.5f, -0.7f, 2.0f}, { 0.0f, 1.0f, 0.0f, 2.0f}},
9533 {{ 1.5f, -0.3f, 2.0f, -0.7f}, { 1.0f, 0.0f, 1.0f, -0.7f}},
9534 {{ 0.0f, 1.0f, 0.0f, 1.5f}, {-0.7f, 2.0f, -0.3f, 1.5f}},
9535 {{ 1.0f, 0.0f, 1.0f, -0.3f}, { 2.0f, -0.7f, 1.5f, -0.3f}},
9538 if (!pD2D1ConvertColorSpace)
9540 win_skip("D2D1ConvertColorSpace() not available, skipping test.\n");
9541 return;
9544 for (i = 0; i < ARRAY_SIZE(colour_spaces); ++i)
9546 src_space = colour_spaces[i];
9547 for (j = 0; j < ARRAY_SIZE(colour_spaces); ++j)
9549 dst_space = colour_spaces[j];
9550 for (k = 0; k < ARRAY_SIZE(test_data); ++k)
9552 if (src_space == D2D1_COLOR_SPACE_SCRGB)
9553 src_colour = test_data[k].scrgb;
9554 else
9555 src_colour = test_data[k].srgb;
9557 if (dst_space == D2D1_COLOR_SPACE_SCRGB)
9558 expected = test_data[k].scrgb;
9559 else
9560 expected = test_data[k].srgb;
9562 if (src_space == D2D1_COLOR_SPACE_CUSTOM || dst_space == D2D1_COLOR_SPACE_CUSTOM)
9564 set_color(&expected, 0.0f, 0.0f, 0.0f, 0.0f);
9566 else if (src_space != dst_space)
9568 expected.r = clamp_float(expected.r, 0.0f, 1.0f);
9569 expected.g = clamp_float(expected.g, 0.0f, 1.0f);
9570 expected.b = clamp_float(expected.b, 0.0f, 1.0f);
9573 dst_colour = pD2D1ConvertColorSpace(src_space, dst_space, &src_colour);
9574 ok(compare_colour_f(&dst_colour, expected.r, expected.g, expected.b, expected.a, 1),
9575 "Got unexpected destination colour {%.8e, %.8e, %.8e, %.8e}, "
9576 "expected destination colour {%.8e, %.8e, %.8e, %.8e} for "
9577 "source colour {%.8e, %.8e, %.8e, %.8e}, "
9578 "source colour space %#x, destination colour space %#x.\n",
9579 dst_colour.r, dst_colour.g, dst_colour.b, dst_colour.a,
9580 expected.r, expected.g, expected.b, expected.a,
9581 src_colour.r, src_colour.g, src_colour.b, src_colour.a,
9582 src_space, dst_space);
9588 static void test_geometry_group(BOOL d3d11)
9590 ID2D1Factory *factory;
9591 ID2D1GeometryGroup *group;
9592 ID2D1Geometry *geometries[2];
9593 D2D1_RECT_F rect;
9594 HRESULT hr;
9595 D2D1_MATRIX_3X2_F matrix;
9596 BOOL match;
9598 hr = D2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED, &IID_ID2D1Factory, NULL, (void **)&factory);
9599 ok(SUCCEEDED(hr), "Failed to create factory, hr %#x.\n", hr);
9601 set_rect(&rect, -1.0f, -1.0f, 1.0f, 1.0f);
9602 hr = ID2D1Factory_CreateRectangleGeometry(factory, &rect, (ID2D1RectangleGeometry **)&geometries[0]);
9603 ok(SUCCEEDED(hr), "Failed to create geometry, hr %#x.\n", hr);
9605 set_rect(&rect, -2.0f, -2.0f, 0.0f, 2.0f);
9606 hr = ID2D1Factory_CreateRectangleGeometry(factory, &rect, (ID2D1RectangleGeometry **)&geometries[1]);
9607 ok(SUCCEEDED(hr), "Failed to create geometry, hr %#x.\n", hr);
9609 hr = ID2D1Factory_CreateGeometryGroup(factory, D2D1_FILL_MODE_ALTERNATE, geometries, 2, &group);
9610 ok(SUCCEEDED(hr), "Failed to create geometry group, hr %#x.\n", hr);
9612 set_rect(&rect, 0.0f, 0.0f, 0.0f, 0.0f);
9613 hr = ID2D1GeometryGroup_GetBounds(group, NULL, &rect);
9614 ok(SUCCEEDED(hr), "Failed to get geometry group bounds, hr %#x.\n", hr);
9615 match = compare_rect(&rect, -2.0f, -2.0f, 1.0f, 2.0f, 0);
9616 ok(match, "Got unexpected rectangle {%.8e, %.8e, %.8e, %.8e}.\n",
9617 rect.left, rect.top, rect.right, rect.bottom);
9619 set_matrix_identity(&matrix);
9620 translate_matrix(&matrix, 80.0f, 640.0f);
9621 scale_matrix(&matrix, 2.0f, 0.5f);
9622 hr = ID2D1GeometryGroup_GetBounds(group, &matrix, &rect);
9623 ok(SUCCEEDED(hr), "Failed to get geometry group bounds, hr %#x.\n", hr);
9624 match = compare_rect(&rect, 76.0f, 639.0f, 82.0f, 641.0f, 0);
9625 ok(match, "Got unexpected rectangle {%.8e, %.8e, %.8e, %.8e}.\n",
9626 rect.left, rect.top, rect.right, rect.bottom);
9628 ID2D1GeometryGroup_Release(group);
9630 ID2D1Geometry_Release(geometries[0]);
9631 ID2D1Geometry_Release(geometries[1]);
9633 ID2D1Factory_Release(factory);
9636 static DWORD WINAPI mt_factory_test_thread_func(void *param)
9638 ID2D1Multithread *multithread = param;
9640 ID2D1Multithread_Enter(multithread);
9642 return 0;
9645 static void test_mt_factory(BOOL d3d11)
9647 ID2D1Multithread *multithread;
9648 ID2D1Factory *factory;
9649 HANDLE thread;
9650 HRESULT hr;
9651 DWORD ret;
9653 hr = D2D1CreateFactory(D2D1_FACTORY_TYPE_MULTI_THREADED + 1, &IID_ID2D1Factory, NULL, (void **)&factory);
9654 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
9656 hr = D2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED, &IID_ID2D1Factory, NULL, (void **)&factory);
9657 ok(SUCCEEDED(hr), "Failed to create factory, hr %#x.\n", hr);
9659 hr = ID2D1Factory_QueryInterface(factory, &IID_ID2D1Multithread, (void **)&multithread);
9660 if (hr == E_NOINTERFACE)
9662 win_skip("ID2D1Multithread is not supported.\n");
9663 ID2D1Factory_Release(factory);
9664 return;
9666 ok(SUCCEEDED(hr), "Failed to get interface, hr %#x.\n", hr);
9668 ret = ID2D1Multithread_GetMultithreadProtected(multithread);
9669 ok(!ret, "Unexpected return value.\n");
9671 ID2D1Multithread_Enter(multithread);
9672 thread = CreateThread(NULL, 0, mt_factory_test_thread_func, multithread, 0, NULL);
9673 ok(!!thread, "Failed to create a thread.\n");
9674 WaitForSingleObject(thread, INFINITE);
9675 CloseHandle(thread);
9677 ID2D1Multithread_Release(multithread);
9678 ID2D1Factory_Release(factory);
9680 hr = D2D1CreateFactory(D2D1_FACTORY_TYPE_MULTI_THREADED, &IID_ID2D1Factory, NULL, (void **)&factory);
9681 ok(SUCCEEDED(hr), "Failed to create factory, hr %#x.\n", hr);
9683 hr = ID2D1Factory_QueryInterface(factory, &IID_ID2D1Multithread, (void **)&multithread);
9684 ok(SUCCEEDED(hr), "Failed to get interface, hr %#x.\n", hr);
9686 ret = ID2D1Multithread_GetMultithreadProtected(multithread);
9687 ok(!!ret, "Unexpected return value.\n");
9689 ID2D1Multithread_Enter(multithread);
9690 thread = CreateThread(NULL, 0, mt_factory_test_thread_func, multithread, 0, NULL);
9691 ok(!!thread, "Failed to create a thread.\n");
9692 ret = WaitForSingleObject(thread, 10);
9693 ok(ret == WAIT_TIMEOUT, "Expected timeout.\n");
9694 ID2D1Multithread_Leave(multithread);
9695 WaitForSingleObject(thread, INFINITE);
9696 CloseHandle(thread);
9698 ID2D1Multithread_Release(multithread);
9700 ID2D1Factory_Release(factory);
9703 static void test_effect(BOOL d3d11)
9705 unsigned int i, j, min_inputs, max_inputs, str_size, input_count;
9706 D2D1_BITMAP_PROPERTIES bitmap_desc;
9707 D2D1_BUFFER_PRECISION precision;
9708 ID2D1Image *image_a, *image_b;
9709 struct d2d1_test_context ctx;
9710 ID2D1DeviceContext *context;
9711 ID2D1Factory1 *factory;
9712 ID2D1Bitmap *bitmap;
9713 ID2D1Effect *effect;
9714 D2D1_SIZE_U size;
9715 BYTE buffer[256];
9716 BOOL cached;
9717 CLSID clsid;
9718 HRESULT hr;
9720 const struct effect_test
9722 const CLSID *clsid;
9723 UINT32 default_input_count;
9724 UINT32 min_inputs;
9725 UINT32 max_inputs;
9727 effect_tests[] =
9729 {&CLSID_D2D12DAffineTransform, 1, 1, 1},
9730 {&CLSID_D2D13DPerspectiveTransform, 1, 1, 1},
9731 {&CLSID_D2D1Composite, 2, 1, 0xffffffff},
9732 {&CLSID_D2D1Crop, 1, 1, 1},
9735 if (!init_test_context(&ctx, d3d11))
9736 return;
9738 if (FAILED(D2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED, &IID_ID2D1Factory1, NULL, (void **)&factory)))
9740 win_skip("ID2D1Factory1 is not supported.\n");
9741 release_test_context(&ctx);
9742 return;
9745 hr = ID2D1RenderTarget_QueryInterface(ctx.rt, &IID_ID2D1DeviceContext, (void **)&context);
9746 ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
9748 for (i = 0; i < ARRAY_SIZE(effect_tests); ++i)
9750 const struct effect_test *test = effect_tests + i;
9752 winetest_push_context("Test %u", i);
9754 hr = ID2D1DeviceContext_CreateEffect(context, test->clsid, &effect);
9755 ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
9757 hr = ID2D1Effect_QueryInterface(effect, &IID_ID2D1Image, (void **)&image_a);
9758 ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
9759 ID2D1Effect_GetOutput(effect, &image_b);
9760 ok(image_b == image_a, "Got unexpected image_b %p, expected %p.\n", image_b, image_a);
9761 ID2D1Image_Release(image_b);
9762 ID2D1Image_Release(image_a);
9764 hr = ID2D1Effect_GetValue(effect, 0xdeadbeef, D2D1_PROPERTY_TYPE_CLSID, (BYTE *)&clsid, sizeof(clsid));
9765 ok(hr == D2DERR_INVALID_PROPERTY, "Got unexpected hr %#x.\n", hr);
9767 hr = ID2D1Effect_GetValue(effect, D2D1_PROPERTY_CLSID, D2D1_PROPERTY_TYPE_CLSID, buffer, sizeof(clsid) + 1);
9768 ok(hr == E_INVALIDARG, "Got unexpected hr %#x.\n", hr);
9769 hr = ID2D1Effect_GetValue(effect, D2D1_PROPERTY_CLSID, D2D1_PROPERTY_TYPE_CLSID, buffer, sizeof(clsid) - 1);
9770 ok(hr == E_INVALIDARG, "Got unexpected hr %#x.\n", hr);
9771 hr = ID2D1Effect_GetValue(effect, D2D1_PROPERTY_CLSID, D2D1_PROPERTY_TYPE_CLSID, buffer, sizeof(clsid));
9772 ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
9774 hr = ID2D1Effect_GetValue(effect, D2D1_PROPERTY_DISPLAYNAME, D2D1_PROPERTY_TYPE_STRING, buffer, sizeof(buffer));
9775 todo_wine
9776 ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
9777 str_size = (wcslen((WCHAR *)buffer) + 1) * sizeof(WCHAR);
9778 hr = ID2D1Effect_GetValue(effect, D2D1_PROPERTY_DISPLAYNAME, D2D1_PROPERTY_TYPE_STRING, buffer, str_size);
9779 todo_wine
9780 ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
9781 hr = ID2D1Effect_GetValue(effect, D2D1_PROPERTY_DISPLAYNAME, D2D1_PROPERTY_TYPE_STRING, buffer, str_size - 1);
9782 todo_wine
9783 ok(hr == D2DERR_INSUFFICIENT_BUFFER, "Got unexpected hr %#x.\n", hr);
9785 hr = ID2D1Effect_GetValue(effect, D2D1_PROPERTY_CLSID, 0xdeadbeef, (BYTE *)&clsid, sizeof(clsid));
9786 ok(hr == E_INVALIDARG, "Got unexpected hr %#x.\n", hr);
9787 hr = ID2D1Effect_GetValue(effect, D2D1_PROPERTY_CLSID, D2D1_PROPERTY_TYPE_UNKNOWN, (BYTE *)&clsid, sizeof(clsid));
9788 ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
9789 hr = ID2D1Effect_GetValue(effect, D2D1_PROPERTY_CLSID, D2D1_PROPERTY_TYPE_VECTOR4, (BYTE *)&clsid, sizeof(clsid));
9790 ok(hr == E_INVALIDARG, "Got unexpected hr %#x.\n", hr);
9791 hr = ID2D1Effect_GetValue(effect, D2D1_PROPERTY_CLSID, D2D1_PROPERTY_TYPE_VECTOR4, buffer, sizeof(buffer));
9792 ok(hr == E_INVALIDARG, "Got unexpected hr %#x.\n", hr);
9794 hr = ID2D1Effect_GetValue(effect, D2D1_PROPERTY_CLSID,
9795 D2D1_PROPERTY_TYPE_CLSID, (BYTE *)&clsid, sizeof(clsid));
9796 ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
9797 if (hr == S_OK)
9798 ok(IsEqualGUID(&clsid, test->clsid), "Got unexpected clsid %s, expected %s.\n",
9799 debugstr_guid(&clsid), debugstr_guid(test->clsid));
9801 hr = ID2D1Effect_GetValue(effect, D2D1_PROPERTY_CACHED,
9802 D2D1_PROPERTY_TYPE_BOOL, (BYTE *)&cached, sizeof(cached));
9803 todo_wine
9804 ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
9805 if (hr == S_OK)
9806 ok(cached == FALSE, "Got unexpected cached %d.\n", cached);
9808 hr = ID2D1Effect_GetValue(effect, D2D1_PROPERTY_PRECISION,
9809 D2D1_PROPERTY_TYPE_ENUM, (BYTE *)&precision, sizeof(precision));
9810 todo_wine
9811 ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
9812 if (hr == S_OK)
9813 ok(precision == D2D1_BUFFER_PRECISION_UNKNOWN, "Got unexpected precision %u.\n", precision);
9815 hr = ID2D1Effect_GetValue(effect, D2D1_PROPERTY_MIN_INPUTS,
9816 D2D1_PROPERTY_TYPE_UINT32, (BYTE *)&min_inputs, sizeof(min_inputs));
9817 ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
9818 if (hr == S_OK)
9819 ok(min_inputs == test->min_inputs, "Got unexpected min inputs %u, expected %u.\n",
9820 min_inputs, test->min_inputs);
9822 hr = ID2D1Effect_GetValue(effect, D2D1_PROPERTY_MAX_INPUTS,
9823 D2D1_PROPERTY_TYPE_UINT32, (BYTE *)&max_inputs, sizeof(max_inputs));
9824 ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
9825 if (hr == S_OK)
9826 ok(max_inputs == test->max_inputs, "Got unexpected max inputs %u, expected %u.\n",
9827 max_inputs, test->max_inputs);
9829 input_count = ID2D1Effect_GetInputCount(effect);
9830 ok (input_count == test->default_input_count, "Got unexpected input count %u, expected %u.\n",
9831 input_count, test->default_input_count);
9833 input_count = (test->max_inputs < 16 ? test->max_inputs : 16);
9834 for (j = 0; j < input_count + 4; ++j)
9836 winetest_push_context("Input %u", j);
9837 hr = ID2D1Effect_SetInputCount(effect, j);
9838 if (j < test->min_inputs || j > test->max_inputs)
9839 ok(hr == E_INVALIDARG, "Got unexpected hr %#x.\n", hr);
9840 else
9841 ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
9842 winetest_pop_context();
9845 input_count = ID2D1Effect_GetInputCount(effect);
9846 for (j = 0; j < input_count + 4; ++j)
9848 winetest_push_context("Input %u", j);
9849 ID2D1Effect_GetInput(effect, j, &image_a);
9850 ok(image_a == NULL, "Got unexpected image_a %p.\n", image_a);
9851 winetest_pop_context();
9854 set_size_u(&size, 1, 1);
9855 bitmap_desc.pixelFormat.format = DXGI_FORMAT_B8G8R8A8_UNORM;
9856 bitmap_desc.pixelFormat.alphaMode = D2D1_ALPHA_MODE_IGNORE;
9857 bitmap_desc.dpiX = 96.0f;
9858 bitmap_desc.dpiY = 96.0f;
9859 hr = ID2D1RenderTarget_CreateBitmap(ctx.rt, size, NULL, 4, &bitmap_desc, &bitmap);
9860 ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
9862 ID2D1Effect_SetInput(effect, 0, (ID2D1Image *)bitmap, FALSE);
9863 for (j = 0; j < input_count + 4; ++j)
9865 winetest_push_context("Input %u", j);
9866 image_a = (ID2D1Image *)0xdeadbeef;
9867 ID2D1Effect_GetInput(effect, j, &image_a);
9868 if (j == 0)
9870 ok(image_a == (ID2D1Image *)bitmap, "Got unexpected image_a %p.\n", image_a);
9871 ID2D1Image_Release(image_a);
9873 else
9875 ok(image_a == NULL, "Got unexpected image_a %p.\n", image_a);
9877 winetest_pop_context();
9880 for (j = input_count; j < input_count + 4; ++j)
9882 winetest_push_context("Input %u", j);
9883 image_a = (ID2D1Image *)0xdeadbeef;
9884 ID2D1Effect_SetInput(effect, j, (ID2D1Image *)bitmap, FALSE);
9885 ID2D1Effect_GetInput(effect, j, &image_a);
9886 ok(image_a == NULL, "Got unexpected image_a %p.\n", image_a);
9887 winetest_pop_context();
9889 ID2D1Bitmap_Release(bitmap);
9891 ID2D1Effect_Release(effect);
9892 winetest_pop_context();
9895 ID2D1DeviceContext_Release(context);
9896 ID2D1Factory1_Release(factory);
9897 release_test_context(&ctx);
9900 START_TEST(d2d1)
9902 HMODULE d2d1_dll = GetModuleHandleA("d2d1.dll");
9903 unsigned int argc, i;
9904 char **argv;
9906 pD2D1CreateDevice = (void *)GetProcAddress(d2d1_dll, "D2D1CreateDevice");
9907 pD2D1SinCos = (void *)GetProcAddress(d2d1_dll, "D2D1SinCos");
9908 pD2D1Tan = (void *)GetProcAddress(d2d1_dll, "D2D1Tan");
9909 pD2D1Vec3Length = (void *)GetProcAddress(d2d1_dll, "D2D1Vec3Length");
9910 pD2D1ConvertColorSpace = (void *)GetProcAddress(d2d1_dll, "D2D1ConvertColorSpace");
9912 use_mt = !getenv("WINETEST_NO_MT_D3D");
9914 argc = winetest_get_mainargs(&argv);
9915 for (i = 2; i < argc; ++i)
9917 if (!strcmp(argv[i], "--single"))
9918 use_mt = FALSE;
9921 queue_test(test_clip);
9922 queue_test(test_state_block);
9923 queue_test(test_color_brush);
9924 queue_test(test_bitmap_brush);
9925 queue_test(test_linear_brush);
9926 queue_test(test_radial_brush);
9927 queue_test(test_path_geometry);
9928 queue_d3d10_test(test_rectangle_geometry);
9929 queue_d3d10_test(test_rounded_rectangle_geometry);
9930 queue_test(test_bitmap_formats);
9931 queue_test(test_alpha_mode);
9932 queue_test(test_shared_bitmap);
9933 queue_test(test_bitmap_updates);
9934 queue_test(test_opacity_brush);
9935 queue_test(test_create_target);
9936 queue_test(test_draw_text_layout);
9937 queue_test(test_dc_target);
9938 queue_test(test_hwnd_target);
9939 queue_test(test_bitmap_target);
9940 queue_d3d10_test(test_desktop_dpi);
9941 queue_d3d10_test(test_stroke_style);
9942 queue_test(test_gradient);
9943 queue_test(test_draw_geometry);
9944 queue_test(test_fill_geometry);
9945 queue_test(test_gdi_interop);
9946 queue_test(test_layer);
9947 queue_test(test_bezier_intersect);
9948 queue_test(test_create_device);
9949 queue_test(test_bitmap_surface);
9950 queue_test(test_device_context);
9951 queue_d3d10_test(test_invert_matrix);
9952 queue_d3d10_test(test_skew_matrix);
9953 queue_test(test_command_list);
9954 queue_d3d10_test(test_max_bitmap_size);
9955 queue_test(test_dpi);
9956 queue_test(test_wic_bitmap_format);
9957 queue_d3d10_test(test_math);
9958 queue_d3d10_test(test_colour_space);
9959 queue_test(test_geometry_group);
9960 queue_test(test_mt_factory);
9961 queue_test(test_effect);
9963 run_queued_tests();