d2d1: Implement ID2D1Multithread.
[wine.git] / dlls / d2d1 / tests / d2d1.c
blob8dbad9c5ecce2c5f166a531d521b1985780f5b00
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 todo_wine_if(d3d11) ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr);
940 ID2D1Factory_Release(factory);
942 if (FAILED(hr))
943 return NULL;
945 return render_target;
948 static ID2D1RenderTarget *create_render_target(IDXGISurface *surface, BOOL d3d11)
950 D2D1_RENDER_TARGET_PROPERTIES desc;
952 desc.type = D2D1_RENDER_TARGET_TYPE_DEFAULT;
953 desc.pixelFormat.format = DXGI_FORMAT_UNKNOWN;
954 desc.pixelFormat.alphaMode = D2D1_ALPHA_MODE_PREMULTIPLIED;
955 desc.dpiX = 0.0f;
956 desc.dpiY = 0.0f;
957 desc.usage = D2D1_RENDER_TARGET_USAGE_NONE;
958 desc.minLevel = D2D1_FEATURE_LEVEL_DEFAULT;
960 return create_render_target_desc(surface, &desc, d3d11);
963 #define release_test_context(ctx) release_test_context_(__LINE__, ctx)
964 static void release_test_context_(unsigned int line, struct d2d1_test_context *ctx)
966 ID2D1Factory *factory;
967 ULONG ref;
969 ID2D1RenderTarget_GetFactory(ctx->rt, &factory);
970 ID2D1RenderTarget_Release(ctx->rt);
971 ref = ID2D1Factory_Release(factory);
972 ok_(__FILE__, line)(!ref, "Factory has %u references left.\n", ref);
974 IDXGISurface_Release(ctx->surface);
975 IDXGISwapChain_Release(ctx->swapchain);
976 DestroyWindow(ctx->window);
977 IDXGIDevice_Release(ctx->device);
980 #define init_test_context(ctx, d3d11) init_test_context_(__LINE__, ctx, d3d11)
981 static BOOL init_test_context_(unsigned int line, struct d2d1_test_context *ctx, BOOL d3d11)
983 HRESULT hr;
985 memset(ctx, 0, sizeof(*ctx));
987 ctx->d3d11 = d3d11;
988 if (!(ctx->device = create_device(d3d11)))
990 skip_(__FILE__, line)("Failed to create device, skipping tests.\n");
991 return FALSE;
994 ctx->window = create_window();
995 ok_(__FILE__, line)(!!ctx->window, "Failed to create test window.\n");
996 ctx->swapchain = create_swapchain(ctx->device, ctx->window, TRUE);
997 ok_(__FILE__, line)(!!ctx->swapchain, "Failed to create swapchain.\n");
998 hr = IDXGISwapChain_GetBuffer(ctx->swapchain, 0, &IID_IDXGISurface, (void **)&ctx->surface);
999 ok_(__FILE__, line)(SUCCEEDED(hr), "Failed to get buffer, hr %#x.\n", hr);
1001 ctx->rt = create_render_target(ctx->surface, d3d11);
1002 if (!ctx->rt && d3d11)
1004 todo_wine win_skip_(__FILE__, line)("Skipping d3d11 tests.\n");
1006 IDXGISurface_Release(ctx->surface);
1007 IDXGISwapChain_Release(ctx->swapchain);
1008 DestroyWindow(ctx->window);
1009 IDXGIDevice_Release(ctx->device);
1011 return FALSE;
1013 ok_(__FILE__, line)(!!ctx->rt, "Failed to create render target.\n");
1015 return TRUE;
1018 #define check_bitmap_surface(b, s, o) check_bitmap_surface_(__LINE__, b, s, o)
1019 static void check_bitmap_surface_(unsigned int line, ID2D1Bitmap *bitmap, BOOL has_surface, DWORD expected_options)
1021 D2D1_BITMAP_OPTIONS options;
1022 IDXGISurface *surface;
1023 ID2D1Bitmap1 *bitmap1;
1024 HRESULT hr;
1026 hr = ID2D1Bitmap_QueryInterface(bitmap, &IID_ID2D1Bitmap1, (void **)&bitmap1);
1027 if (FAILED(hr))
1028 return;
1030 options = ID2D1Bitmap1_GetOptions(bitmap1);
1031 ok_(__FILE__, line)(options == expected_options, "Unexpected bitmap options %#x, expected %#x.\n",
1032 options, expected_options);
1034 surface = (void *)0xdeadbeef;
1035 hr = ID2D1Bitmap1_GetSurface(bitmap1, &surface);
1036 if (has_surface)
1038 D3D10_TEXTURE2D_DESC desc;
1039 ID3D10Texture2D *texture;
1040 D2D1_SIZE_U pixel_size;
1041 DWORD bind_flags = 0;
1043 ok_(__FILE__, line)(SUCCEEDED(hr), "Failed to get bitmap surface, hr %#x.\n", hr);
1044 ok_(__FILE__, line)(!!surface, "Expected surface instance.\n");
1046 /* Correlate with resource configuration. */
1047 hr = IDXGISurface_QueryInterface(surface, &IID_ID3D10Texture2D, (void **)&texture);
1048 ok_(__FILE__, line)(SUCCEEDED(hr), "Failed to get texture pointer, hr %#x.\n", hr);
1050 ID3D10Texture2D_GetDesc(texture, &desc);
1051 ok_(__FILE__, line)(desc.Usage == 0, "Unexpected usage %#x.\n", desc.Usage);
1053 if (options & D2D1_BITMAP_OPTIONS_TARGET)
1054 bind_flags |= D3D10_BIND_RENDER_TARGET;
1055 if (!(options & D2D1_BITMAP_OPTIONS_CANNOT_DRAW))
1056 bind_flags |= D3D10_BIND_SHADER_RESOURCE;
1058 ok_(__FILE__, line)(desc.BindFlags == bind_flags, "Unexpected bind flags %#x for bitmap options %#x.\n",
1059 desc.BindFlags, options);
1060 ok_(__FILE__, line)(!desc.CPUAccessFlags, "Unexpected cpu access flags %#x.\n", desc.CPUAccessFlags);
1061 ok_(__FILE__, line)(!desc.MiscFlags, "Unexpected misc flags %#x.\n", desc.MiscFlags);
1063 pixel_size = ID2D1Bitmap_GetPixelSize(bitmap);
1064 if (!pixel_size.width || !pixel_size.height)
1065 pixel_size.width = pixel_size.height = 1;
1066 ok_(__FILE__, line)(desc.Width == pixel_size.width, "Got width %u, expected %u.\n",
1067 desc.Width, pixel_size.width);
1068 ok_(__FILE__, line)(desc.Height == pixel_size.height, "Got height %u, expected %u.\n",
1069 desc.Height, pixel_size.height);
1071 ID3D10Texture2D_Release(texture);
1073 IDXGISurface_Release(surface);
1075 else
1077 ok_(__FILE__, line)(hr == D2DERR_INVALID_CALL, "Unexpected hr %#x.\n", hr);
1078 ok_(__FILE__, line)(!surface, "Unexpected surface instance.\n");
1081 ID2D1Bitmap1_Release(bitmap1);
1084 static inline struct geometry_sink *impl_from_ID2D1SimplifiedGeometrySink(ID2D1SimplifiedGeometrySink *iface)
1086 return CONTAINING_RECORD(iface, struct geometry_sink, ID2D1SimplifiedGeometrySink_iface);
1089 static HRESULT STDMETHODCALLTYPE geometry_sink_QueryInterface(ID2D1SimplifiedGeometrySink *iface,
1090 REFIID iid, void **out)
1092 if (IsEqualGUID(iid, &IID_ID2D1SimplifiedGeometrySink)
1093 || IsEqualGUID(iid, &IID_IUnknown))
1095 *out = iface;
1096 return S_OK;
1099 *out = NULL;
1100 return E_NOINTERFACE;
1103 static ULONG STDMETHODCALLTYPE geometry_sink_AddRef(ID2D1SimplifiedGeometrySink *iface)
1105 return 0;
1108 static ULONG STDMETHODCALLTYPE geometry_sink_Release(ID2D1SimplifiedGeometrySink *iface)
1110 return 0;
1113 static void STDMETHODCALLTYPE geometry_sink_SetFillMode(ID2D1SimplifiedGeometrySink *iface, D2D1_FILL_MODE mode)
1115 struct geometry_sink *sink = impl_from_ID2D1SimplifiedGeometrySink(iface);
1117 sink->fill_mode = mode;
1120 static void STDMETHODCALLTYPE geometry_sink_SetSegmentFlags(ID2D1SimplifiedGeometrySink *iface,
1121 D2D1_PATH_SEGMENT flags)
1123 struct geometry_sink *sink = impl_from_ID2D1SimplifiedGeometrySink(iface);
1125 sink->segment_flags = flags;
1128 static void STDMETHODCALLTYPE geometry_sink_BeginFigure(ID2D1SimplifiedGeometrySink *iface,
1129 D2D1_POINT_2F start_point, D2D1_FIGURE_BEGIN figure_begin)
1131 struct geometry_sink *sink = impl_from_ID2D1SimplifiedGeometrySink(iface);
1132 struct geometry_figure *figure;
1134 if (sink->figure_count == sink->figures_size)
1136 sink->figures_size *= 2;
1137 sink->figures = HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sink->figures,
1138 sink->figures_size * sizeof(*sink->figures));
1140 figure = &sink->figures[sink->figure_count++];
1142 figure->begin = figure_begin;
1143 figure->start_point = start_point;
1144 figure->segments_size = 4;
1145 figure->segments = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
1146 figure->segments_size * sizeof(*figure->segments));
1149 static struct geometry_segment *geometry_figure_add_segment(struct geometry_figure *figure)
1151 if (figure->segment_count == figure->segments_size)
1153 figure->segments_size *= 2;
1154 figure->segments = HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, figure->segments,
1155 figure->segments_size * sizeof(*figure->segments));
1157 return &figure->segments[figure->segment_count++];
1160 static void STDMETHODCALLTYPE geometry_sink_AddLines(ID2D1SimplifiedGeometrySink *iface,
1161 const D2D1_POINT_2F *points, UINT32 count)
1163 struct geometry_sink *sink = impl_from_ID2D1SimplifiedGeometrySink(iface);
1164 struct geometry_figure *figure = &sink->figures[sink->figure_count - 1];
1165 struct geometry_segment *segment;
1166 unsigned int i;
1168 for (i = 0; i < count; ++i)
1170 segment = geometry_figure_add_segment(figure);
1171 segment->type = SEGMENT_LINE;
1172 segment->u.line = points[i];
1173 segment->flags = sink->segment_flags;
1177 static void STDMETHODCALLTYPE geometry_sink_AddBeziers(ID2D1SimplifiedGeometrySink *iface,
1178 const D2D1_BEZIER_SEGMENT *beziers, UINT32 count)
1180 struct geometry_sink *sink = impl_from_ID2D1SimplifiedGeometrySink(iface);
1181 struct geometry_figure *figure = &sink->figures[sink->figure_count - 1];
1182 struct geometry_segment *segment;
1183 unsigned int i;
1185 for (i = 0; i < count; ++i)
1187 segment = geometry_figure_add_segment(figure);
1188 segment->type = SEGMENT_BEZIER;
1189 segment->u.bezier = beziers[i];
1190 segment->flags = sink->segment_flags;
1194 static void STDMETHODCALLTYPE geometry_sink_EndFigure(ID2D1SimplifiedGeometrySink *iface,
1195 D2D1_FIGURE_END figure_end)
1197 struct geometry_sink *sink = impl_from_ID2D1SimplifiedGeometrySink(iface);
1198 struct geometry_figure *figure = &sink->figures[sink->figure_count - 1];
1200 figure->end = figure_end;
1203 static HRESULT STDMETHODCALLTYPE geometry_sink_Close(ID2D1SimplifiedGeometrySink *iface)
1205 struct geometry_sink *sink = impl_from_ID2D1SimplifiedGeometrySink(iface);
1207 sink->closed = TRUE;
1209 return S_OK;
1212 static const struct ID2D1SimplifiedGeometrySinkVtbl geometry_sink_vtbl =
1214 geometry_sink_QueryInterface,
1215 geometry_sink_AddRef,
1216 geometry_sink_Release,
1217 geometry_sink_SetFillMode,
1218 geometry_sink_SetSegmentFlags,
1219 geometry_sink_BeginFigure,
1220 geometry_sink_AddLines,
1221 geometry_sink_AddBeziers,
1222 geometry_sink_EndFigure,
1223 geometry_sink_Close,
1226 static void geometry_sink_init(struct geometry_sink *sink)
1228 memset(sink, 0, sizeof(*sink));
1229 sink->ID2D1SimplifiedGeometrySink_iface.lpVtbl = &geometry_sink_vtbl;
1230 sink->figures_size = 4;
1231 sink->figures = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
1232 sink->figures_size * sizeof(*sink->figures));
1235 static void geometry_sink_cleanup(struct geometry_sink *sink)
1237 unsigned int i;
1239 for (i = 0; i < sink->figure_count; ++i)
1241 HeapFree(GetProcessHeap(), 0, sink->figures[i].segments);
1243 HeapFree(GetProcessHeap(), 0, sink->figures);
1246 #define geometry_sink_check(a, b, c, d, e) geometry_sink_check_(__LINE__, a, b, c, d, e)
1247 static void geometry_sink_check_(unsigned int line, const struct geometry_sink *sink, D2D1_FILL_MODE fill_mode,
1248 unsigned int figure_count, const struct expected_geometry_figure *expected_figures, unsigned int ulps)
1250 const struct geometry_segment *segment, *expected_segment;
1251 const struct expected_geometry_figure *expected_figure;
1252 const struct geometry_figure *figure;
1253 unsigned int i, j;
1254 BOOL match;
1256 ok_(__FILE__, line)(sink->fill_mode == fill_mode,
1257 "Got unexpected fill mode %#x.\n", sink->fill_mode);
1258 ok_(__FILE__, line)(sink->figure_count == figure_count,
1259 "Got unexpected figure count %u, expected %u.\n", sink->figure_count, figure_count);
1260 ok_(__FILE__, line)(!sink->closed, "Sink is closed.\n");
1262 for (i = 0; i < figure_count; ++i)
1264 expected_figure = &expected_figures[i];
1265 figure = &sink->figures[i];
1267 ok_(__FILE__, line)(figure->begin == expected_figure->begin,
1268 "Got unexpected figure %u begin %#x, expected %#x.\n",
1269 i, figure->begin, expected_figure->begin);
1270 ok_(__FILE__, line)(figure->end == expected_figure->end,
1271 "Got unexpected figure %u end %#x, expected %#x.\n",
1272 i, figure->end, expected_figure->end);
1273 match = compare_point(&figure->start_point,
1274 expected_figure->start_point.x, expected_figure->start_point.y, ulps);
1275 ok_(__FILE__, line)(match, "Got unexpected figure %u start point {%.8e, %.8e}, expected {%.8e, %.8e}.\n",
1276 i, figure->start_point.x, figure->start_point.y,
1277 expected_figure->start_point.x, expected_figure->start_point.y);
1278 ok_(__FILE__, line)(figure->segment_count == expected_figure->segment_count,
1279 "Got unexpected figure %u segment count %u, expected %u.\n",
1280 i, figure->segment_count, expected_figure->segment_count);
1282 for (j = 0; j < figure->segment_count; ++j)
1284 expected_segment = &expected_figure->segments[j];
1285 segment = &figure->segments[j];
1286 ok_(__FILE__, line)(segment->type == expected_segment->type,
1287 "Got unexpected figure %u, segment %u type %#x, expected %#x.\n",
1288 i, j, segment->type, expected_segment->type);
1289 ok_(__FILE__, line)(segment->flags == expected_segment->flags,
1290 "Got unexpected figure %u, segment %u flags %#x, expected %#x.\n",
1291 i, j, segment->flags, expected_segment->flags);
1292 switch (segment->type)
1294 case SEGMENT_LINE:
1295 match = compare_point(&segment->u.line,
1296 expected_segment->u.line.x, expected_segment->u.line.y, ulps);
1297 ok_(__FILE__, line)(match, "Got unexpected figure %u segment %u {%.8e, %.8e}, "
1298 "expected {%.8e, %.8e}.\n",
1299 i, j, segment->u.line.x, segment->u.line.y,
1300 expected_segment->u.line.x, expected_segment->u.line.y);
1301 break;
1303 case SEGMENT_BEZIER:
1304 match = compare_bezier_segment(&segment->u.bezier,
1305 expected_segment->u.bezier.point1.x, expected_segment->u.bezier.point1.y,
1306 expected_segment->u.bezier.point2.x, expected_segment->u.bezier.point2.y,
1307 expected_segment->u.bezier.point3.x, expected_segment->u.bezier.point3.y,
1308 ulps);
1309 ok_(__FILE__, line)(match, "Got unexpected figure %u segment %u "
1310 "{%.8e, %.8e, %.8e, %.8e, %.8e, %.8e}, "
1311 "expected {%.8e, %.8e, %.8e, %.8e, %.8e, %.8e}.\n",
1312 i, j, segment->u.bezier.point1.x, segment->u.bezier.point1.y,
1313 segment->u.bezier.point2.x, segment->u.bezier.point2.y,
1314 segment->u.bezier.point3.x, segment->u.bezier.point3.y,
1315 expected_segment->u.bezier.point1.x, expected_segment->u.bezier.point1.y,
1316 expected_segment->u.bezier.point2.x, expected_segment->u.bezier.point2.y,
1317 expected_segment->u.bezier.point3.x, expected_segment->u.bezier.point3.y);
1318 break;
1324 static void test_clip(BOOL d3d11)
1326 struct d2d1_test_context ctx;
1327 D2D1_MATRIX_3X2_F matrix;
1328 D2D1_SIZE_U pixel_size;
1329 ID2D1RenderTarget *rt;
1330 D2D1_POINT_2F point;
1331 D2D1_COLOR_F color;
1332 float dpi_x, dpi_y;
1333 D2D1_RECT_F rect;
1334 D2D1_SIZE_F size;
1335 HRESULT hr;
1336 BOOL match;
1337 static const D2D1_MATRIX_3X2_F identity =
1339 1.0f, 0.0f,
1340 0.0f, 1.0f,
1341 0.0f, 0.0f,
1342 }}};
1344 if (!init_test_context(&ctx, d3d11))
1345 return;
1347 rt = ctx.rt;
1348 ID2D1RenderTarget_GetDpi(rt, &dpi_x, &dpi_y);
1349 ok(dpi_x == 96.0f, "Got unexpected dpi_x %.8e.\n", dpi_x);
1350 ok(dpi_y == 96.0f, "Got unexpected dpi_x %.8e.\n", dpi_y);
1351 size = ID2D1RenderTarget_GetSize(rt);
1352 ok(size.width == 640.0f, "Got unexpected width %.8e.\n", size.width);
1353 ok(size.height == 480.0f, "Got unexpected height %.8e.\n", size.height);
1354 pixel_size = ID2D1RenderTarget_GetPixelSize(rt);
1355 ok(pixel_size.width == 640, "Got unexpected width %u.\n", pixel_size.width);
1356 ok(pixel_size.height == 480, "Got unexpected height %u.\n", pixel_size.height);
1358 ID2D1RenderTarget_GetTransform(rt, &matrix);
1359 ok(!memcmp(&matrix, &identity, sizeof(matrix)),
1360 "Got unexpected matrix {%.8e, %.8e, %.8e, %.8e, %.8e, %.8e}.\n",
1361 matrix._11, matrix._12, matrix._21, matrix._22, matrix._31, matrix._32);
1363 ID2D1RenderTarget_BeginDraw(rt);
1365 set_color(&color, 1.0f, 1.0f, 0.0f, 1.0f);
1366 ID2D1RenderTarget_Clear(rt, &color);
1368 ID2D1RenderTarget_SetDpi(rt, 48.0f, 192.0f);
1369 ID2D1RenderTarget_GetDpi(rt, &dpi_x, &dpi_y);
1370 ok(dpi_x == 48.0f, "Got unexpected dpi_x %.8e.\n", dpi_x);
1371 ok(dpi_y == 192.0f, "Got unexpected dpi_x %.8e.\n", dpi_y);
1372 size = ID2D1RenderTarget_GetSize(rt);
1373 ok(size.width == 1280.0f, "Got unexpected width %.8e.\n", size.width);
1374 ok(size.height == 240.0f, "Got unexpected height %.8e.\n", size.height);
1375 pixel_size = ID2D1RenderTarget_GetPixelSize(rt);
1376 ok(pixel_size.width == 640, "Got unexpected width %u.\n", pixel_size.width);
1377 ok(pixel_size.height == 480, "Got unexpected height %u.\n", pixel_size.height);
1379 /* The effective clip rect is the intersection of all currently pushed
1380 * clip rects. Clip rects are in DIPs. */
1381 set_rect(&rect, 0.0f, 0.0f, 1280.0f, 80.0f);
1382 ID2D1RenderTarget_PushAxisAlignedClip(rt, &rect, D2D1_ANTIALIAS_MODE_ALIASED);
1383 set_rect(&rect, 0.0f, 0.0f, 426.0f, 240.0f);
1384 ID2D1RenderTarget_PushAxisAlignedClip(rt, &rect, D2D1_ANTIALIAS_MODE_ALIASED);
1386 set_color(&color, 0.0f, 1.0f, 0.0f, 1.0f);
1387 ID2D1RenderTarget_Clear(rt, &color);
1388 ID2D1RenderTarget_PopAxisAlignedClip(rt);
1389 ID2D1RenderTarget_PopAxisAlignedClip(rt);
1391 ID2D1RenderTarget_SetDpi(rt, 0.0f, 0.0f);
1392 ID2D1RenderTarget_GetDpi(rt, &dpi_x, &dpi_y);
1393 ok(dpi_x == 96.0f, "Got unexpected dpi_x %.8e.\n", dpi_x);
1394 ok(dpi_y == 96.0f, "Got unexpected dpi_y %.8e.\n", dpi_y);
1396 ID2D1RenderTarget_SetDpi(rt, 192.0f, 192.0f);
1397 ID2D1RenderTarget_SetDpi(rt, 0.0f, 96.0f);
1398 ID2D1RenderTarget_GetDpi(rt, &dpi_x, &dpi_y);
1399 ok(dpi_x == 192.0f, "Got unexpected dpi_x %.8e.\n", dpi_x);
1400 ok(dpi_y == 192.0f, "Got unexpected dpi_y %.8e.\n", dpi_y);
1402 ID2D1RenderTarget_SetDpi(rt, -10.0f, 96.0f);
1403 ID2D1RenderTarget_GetDpi(rt, &dpi_x, &dpi_y);
1404 ok(dpi_x == 192.0f, "Got unexpected dpi_x %.8e.\n", dpi_x);
1405 ok(dpi_y == 192.0f, "Got unexpected dpi_y %.8e.\n", dpi_y);
1407 ID2D1RenderTarget_SetDpi(rt, 96.0f, -10.0f);
1408 ID2D1RenderTarget_GetDpi(rt, &dpi_x, &dpi_y);
1409 ok(dpi_x == 192.0f, "Got unexpected dpi_x %.8e.\n", dpi_x);
1410 ok(dpi_y == 192.0f, "Got unexpected dpi_y %.8e.\n", dpi_y);
1412 ID2D1RenderTarget_SetDpi(rt, 96.0f, 0.0f);
1413 ID2D1RenderTarget_GetDpi(rt, &dpi_x, &dpi_y);
1414 ok(dpi_x == 192.0f, "Got unexpected dpi_x %.8e.\n", dpi_x);
1415 ok(dpi_y == 192.0f, "Got unexpected dpi_y %.8e.\n", dpi_y);
1417 ID2D1RenderTarget_SetDpi(rt, 96.0f, 96.0f);
1419 /* Transformations apply to clip rects, the effective clip rect is the
1420 * (axis-aligned) bounding box of the transformed clip rect. */
1421 set_point(&point, 320.0f, 240.0f);
1422 D2D1MakeRotateMatrix(30.0f, point, &matrix);
1423 ID2D1RenderTarget_SetTransform(rt, &matrix);
1424 set_rect(&rect, 215.0f, 208.0f, 425.0f, 272.0f);
1425 ID2D1RenderTarget_PushAxisAlignedClip(rt, &rect, D2D1_ANTIALIAS_MODE_ALIASED);
1426 set_color(&color, 1.0f, 1.0f, 1.0f, 1.0f);
1427 ID2D1RenderTarget_Clear(rt, &color);
1428 ID2D1RenderTarget_PopAxisAlignedClip(rt);
1430 /* Transformations are applied when pushing the clip rect, transformations
1431 * set afterwards have no effect on the current clip rect. This includes
1432 * SetDpi(). */
1433 ID2D1RenderTarget_SetTransform(rt, &identity);
1434 set_rect(&rect, 427.0f, 320.0f, 640.0f, 480.0f);
1435 ID2D1RenderTarget_PushAxisAlignedClip(rt, &rect, D2D1_ANTIALIAS_MODE_ALIASED);
1436 ID2D1RenderTarget_SetTransform(rt, &matrix);
1437 ID2D1RenderTarget_SetDpi(rt, 48.0f, 192.0f);
1438 set_color(&color, 1.0f, 0.0f, 0.0f, 1.0f);
1439 ID2D1RenderTarget_Clear(rt, &color);
1440 ID2D1RenderTarget_PopAxisAlignedClip(rt);
1442 hr = ID2D1RenderTarget_EndDraw(rt, NULL, NULL);
1443 ok(SUCCEEDED(hr), "Failed to end draw, hr %#x.\n", hr);
1444 match = compare_surface(&ctx, "035a44d4198d6e422e9de6185b5b2c2bac5e33c9");
1445 ok(match, "Surface does not match.\n");
1447 /* Fractional clip rectangle coordinates, aliased mode. */
1448 set_matrix_identity(&matrix);
1449 ID2D1RenderTarget_SetTransform(rt, &matrix);
1450 ID2D1RenderTarget_SetDpi(rt, 96.0f, 96.0f);
1452 ID2D1RenderTarget_BeginDraw(rt);
1454 set_color(&color, 0.0f, 0.0f, 0.0f, 1.0f);
1455 ID2D1RenderTarget_Clear(rt, &color);
1457 scale_matrix(&matrix, 2.0f, 2.0f);
1458 ID2D1RenderTarget_SetTransform(rt, &matrix);
1459 set_rect(&rect, 0.0f, 0.5f, 200.0f, 100.5f);
1460 set_color(&color, 1.0f, 0.0f, 1.0f, 1.0f);
1461 ID2D1RenderTarget_PushAxisAlignedClip(rt, &rect, D2D1_ANTIALIAS_MODE_ALIASED);
1462 ID2D1RenderTarget_Clear(rt, &color);
1463 ID2D1RenderTarget_PopAxisAlignedClip(rt);
1465 set_matrix_identity(&matrix);
1466 ID2D1RenderTarget_SetTransform(rt, &matrix);
1467 set_rect(&rect, 0.0f, 0.5f, 100.0f, 200.5f);
1468 set_color(&color, 1.0f, 0.0f, 0.0f, 1.0f);
1469 ID2D1RenderTarget_PushAxisAlignedClip(rt, &rect, D2D1_ANTIALIAS_MODE_ALIASED);
1470 ID2D1RenderTarget_Clear(rt, &color);
1471 ID2D1RenderTarget_PopAxisAlignedClip(rt);
1473 ID2D1RenderTarget_SetTransform(rt, &matrix);
1474 set_rect(&rect, 0.5f, 250.0f, 100.5f, 300.0f);
1475 set_color(&color, 1.0f, 1.0f, 0.0f, 1.0f);
1476 ID2D1RenderTarget_PushAxisAlignedClip(rt, &rect, D2D1_ANTIALIAS_MODE_ALIASED);
1477 ID2D1RenderTarget_Clear(rt, &color);
1478 ID2D1RenderTarget_PopAxisAlignedClip(rt);
1480 translate_matrix(&matrix, 0.1f, 0.0f);
1481 ID2D1RenderTarget_SetTransform(rt, &matrix);
1482 set_rect(&rect, 110.0f, 250.25f, 150.0f, 300.25f);
1483 set_color(&color, 0.0f, 1.0f, 0.0f, 1.0f);
1484 ID2D1RenderTarget_PushAxisAlignedClip(rt, &rect, D2D1_ANTIALIAS_MODE_ALIASED);
1485 ID2D1RenderTarget_Clear(rt, &color);
1486 ID2D1RenderTarget_PopAxisAlignedClip(rt);
1488 set_rect(&rect, 160.0f, 250.75f, 200.0f, 300.75f);
1489 set_color(&color, 0.0f, 0.0f, 1.0f, 1.0f);
1490 ID2D1RenderTarget_PushAxisAlignedClip(rt, &rect, D2D1_ANTIALIAS_MODE_ALIASED);
1491 ID2D1RenderTarget_Clear(rt, &color);
1492 ID2D1RenderTarget_PopAxisAlignedClip(rt);
1494 ID2D1RenderTarget_SetDpi(rt, 48.0f, 192.0f);
1495 set_rect(&rect, 160.25f, 0.0f, 200.25f, 100.0f);
1496 set_color(&color, 1.0f, 0.0f, 1.0f, 1.0f);
1497 ID2D1RenderTarget_PushAxisAlignedClip(rt, &rect, D2D1_ANTIALIAS_MODE_ALIASED);
1498 ID2D1RenderTarget_Clear(rt, &color);
1499 ID2D1RenderTarget_PopAxisAlignedClip(rt);
1501 ID2D1RenderTarget_SetDpi(rt, 192.0f, 48.0f);
1502 set_rect(&rect, 160.75f, 100.0f, 200.75f, 120.0f);
1503 set_color(&color, 0.0f, 1.0f, 1.0f, 1.0f);
1504 ID2D1RenderTarget_PushAxisAlignedClip(rt, &rect, D2D1_ANTIALIAS_MODE_ALIASED);
1505 ID2D1RenderTarget_Clear(rt, &color);
1506 ID2D1RenderTarget_PopAxisAlignedClip(rt);
1508 hr = ID2D1RenderTarget_EndDraw(rt, NULL, NULL);
1509 ok(SUCCEEDED(hr), "Failed to end draw, hr %#x.\n", hr);
1510 match = compare_surface(&ctx, "cb418ec4a7c8407b5e36db06fc6292a06bb8476c");
1511 ok(match, "Surface does not match.\n");
1513 release_test_context(&ctx);
1516 static void test_state_block(BOOL d3d11)
1518 IDWriteRenderingParams *text_rendering_params1, *text_rendering_params2;
1519 D2D1_DRAWING_STATE_DESCRIPTION drawing_state;
1520 ID2D1DrawingStateBlock *state_block;
1521 IDWriteFactory *dwrite_factory;
1522 struct d2d1_test_context ctx;
1523 ID2D1Factory1 *factory1;
1524 ID2D1RenderTarget *rt;
1525 ID2D1Factory *factory;
1526 ULONG refcount;
1527 HRESULT hr;
1528 static const D2D1_MATRIX_3X2_F identity =
1530 1.0f, 0.0f,
1531 0.0f, 1.0f,
1532 0.0f, 0.0f,
1533 }}};
1534 static const D2D1_MATRIX_3X2_F transform1 =
1536 1.0f, 2.0f,
1537 3.0f, 4.0f,
1538 5.0f, 6.0f,
1539 }}};
1540 static const D2D1_MATRIX_3X2_F transform2 =
1542 7.0f, 8.0f,
1543 9.0f, 10.0f,
1544 11.0f, 12.0f,
1545 }}};
1547 if (!init_test_context(&ctx, d3d11))
1548 return;
1550 rt = ctx.rt;
1551 ID2D1RenderTarget_GetFactory(rt, &factory);
1552 hr = DWriteCreateFactory(DWRITE_FACTORY_TYPE_SHARED, &IID_IDWriteFactory, (IUnknown **)&dwrite_factory);
1553 ok(SUCCEEDED(hr), "Failed to create dwrite factory, hr %#x.\n", hr);
1554 hr = IDWriteFactory_CreateRenderingParams(dwrite_factory, &text_rendering_params1);
1555 ok(SUCCEEDED(hr), "Failed to create dwrite rendering params, hr %#x.\n", hr);
1556 IDWriteFactory_Release(dwrite_factory);
1558 drawing_state.antialiasMode = ID2D1RenderTarget_GetAntialiasMode(rt);
1559 ok(drawing_state.antialiasMode == D2D1_ANTIALIAS_MODE_PER_PRIMITIVE,
1560 "Got unexpected antialias mode %#x.\n", drawing_state.antialiasMode);
1561 drawing_state.textAntialiasMode = ID2D1RenderTarget_GetTextAntialiasMode(rt);
1562 ok(drawing_state.textAntialiasMode == D2D1_TEXT_ANTIALIAS_MODE_DEFAULT,
1563 "Got unexpected text antialias mode %#x.\n", drawing_state.textAntialiasMode);
1564 ID2D1RenderTarget_GetTags(rt, &drawing_state.tag1, &drawing_state.tag2);
1565 ok(!drawing_state.tag1 && !drawing_state.tag2, "Got unexpected tags %s:%s.\n",
1566 wine_dbgstr_longlong(drawing_state.tag1), wine_dbgstr_longlong(drawing_state.tag2));
1567 ID2D1RenderTarget_GetTransform(rt, &drawing_state.transform);
1568 ok(!memcmp(&drawing_state.transform, &identity, sizeof(drawing_state.transform)),
1569 "Got unexpected matrix {%.8e, %.8e, %.8e, %.8e, %.8e, %.8e}.\n",
1570 drawing_state.transform._11, drawing_state.transform._12, drawing_state.transform._21,
1571 drawing_state.transform._22, drawing_state.transform._31, drawing_state.transform._32);
1572 ID2D1RenderTarget_GetTextRenderingParams(rt, &text_rendering_params2);
1573 ok(!text_rendering_params2, "Got unexpected text rendering params %p.\n", text_rendering_params2);
1575 hr = ID2D1Factory_CreateDrawingStateBlock(factory, NULL, NULL, &state_block);
1576 ok(SUCCEEDED(hr), "Failed to create drawing state block, hr %#x\n", hr);
1577 ID2D1DrawingStateBlock_GetDescription(state_block, &drawing_state);
1578 ok(drawing_state.antialiasMode == D2D1_ANTIALIAS_MODE_PER_PRIMITIVE,
1579 "Got unexpected antialias mode %#x.\n", drawing_state.antialiasMode);
1580 ok(drawing_state.textAntialiasMode == D2D1_TEXT_ANTIALIAS_MODE_DEFAULT,
1581 "Got unexpected text antialias mode %#x.\n", drawing_state.textAntialiasMode);
1582 ok(!drawing_state.tag1 && !drawing_state.tag2, "Got unexpected tags %s:%s.\n",
1583 wine_dbgstr_longlong(drawing_state.tag1), wine_dbgstr_longlong(drawing_state.tag2));
1584 ok(!memcmp(&drawing_state.transform, &identity, sizeof(drawing_state.transform)),
1585 "Got unexpected matrix {%.8e, %.8e, %.8e, %.8e, %.8e, %.8e}.\n",
1586 drawing_state.transform._11, drawing_state.transform._12, drawing_state.transform._21,
1587 drawing_state.transform._22, drawing_state.transform._31, drawing_state.transform._32);
1588 ID2D1DrawingStateBlock_GetTextRenderingParams(state_block, &text_rendering_params2);
1589 ok(!text_rendering_params2, "Got unexpected text rendering params %p.\n", text_rendering_params2);
1590 ID2D1DrawingStateBlock_Release(state_block);
1592 drawing_state.antialiasMode = D2D1_ANTIALIAS_MODE_ALIASED;
1593 drawing_state.textAntialiasMode = D2D1_TEXT_ANTIALIAS_MODE_ALIASED;
1594 drawing_state.tag1 = 0xdead;
1595 drawing_state.tag2 = 0xbeef;
1596 drawing_state.transform = transform1;
1597 hr = ID2D1Factory_CreateDrawingStateBlock(factory, &drawing_state, text_rendering_params1, &state_block);
1598 ok(SUCCEEDED(hr), "Failed to create drawing state block, hr %#x\n", hr);
1600 ID2D1DrawingStateBlock_GetDescription(state_block, &drawing_state);
1601 ok(drawing_state.antialiasMode == D2D1_ANTIALIAS_MODE_ALIASED,
1602 "Got unexpected antialias mode %#x.\n", drawing_state.antialiasMode);
1603 ok(drawing_state.textAntialiasMode == D2D1_TEXT_ANTIALIAS_MODE_ALIASED,
1604 "Got unexpected text antialias mode %#x.\n", drawing_state.textAntialiasMode);
1605 ok(drawing_state.tag1 == 0xdead && drawing_state.tag2 == 0xbeef, "Got unexpected tags %s:%s.\n",
1606 wine_dbgstr_longlong(drawing_state.tag1), wine_dbgstr_longlong(drawing_state.tag2));
1607 ok(!memcmp(&drawing_state.transform, &transform1, sizeof(drawing_state.transform)),
1608 "Got unexpected matrix {%.8e, %.8e, %.8e, %.8e, %.8e, %.8e}.\n",
1609 drawing_state.transform._11, drawing_state.transform._12, drawing_state.transform._21,
1610 drawing_state.transform._22, drawing_state.transform._31, drawing_state.transform._32);
1611 ID2D1DrawingStateBlock_GetTextRenderingParams(state_block, &text_rendering_params2);
1612 ok(text_rendering_params2 == text_rendering_params1, "Got unexpected text rendering params %p, expected %p.\n",
1613 text_rendering_params2, text_rendering_params1);
1614 IDWriteRenderingParams_Release(text_rendering_params2);
1616 ID2D1RenderTarget_RestoreDrawingState(rt, state_block);
1618 drawing_state.antialiasMode = ID2D1RenderTarget_GetAntialiasMode(rt);
1619 ok(drawing_state.antialiasMode == D2D1_ANTIALIAS_MODE_ALIASED,
1620 "Got unexpected antialias mode %#x.\n", drawing_state.antialiasMode);
1621 drawing_state.textAntialiasMode = ID2D1RenderTarget_GetTextAntialiasMode(rt);
1622 ok(drawing_state.textAntialiasMode == D2D1_TEXT_ANTIALIAS_MODE_ALIASED,
1623 "Got unexpected text antialias mode %#x.\n", drawing_state.textAntialiasMode);
1624 ID2D1RenderTarget_GetTags(rt, &drawing_state.tag1, &drawing_state.tag2);
1625 ok(drawing_state.tag1 == 0xdead && drawing_state.tag2 == 0xbeef, "Got unexpected tags %s:%s.\n",
1626 wine_dbgstr_longlong(drawing_state.tag1), wine_dbgstr_longlong(drawing_state.tag2));
1627 ID2D1RenderTarget_GetTransform(rt, &drawing_state.transform);
1628 ok(!memcmp(&drawing_state.transform, &transform1, sizeof(drawing_state.transform)),
1629 "Got unexpected matrix {%.8e, %.8e, %.8e, %.8e, %.8e, %.8e}.\n",
1630 drawing_state.transform._11, drawing_state.transform._12, drawing_state.transform._21,
1631 drawing_state.transform._22, drawing_state.transform._31, drawing_state.transform._32);
1632 ID2D1RenderTarget_GetTextRenderingParams(rt, &text_rendering_params2);
1633 ok(text_rendering_params2 == text_rendering_params1, "Got unexpected text rendering params %p, expected %p.\n",
1634 text_rendering_params2, text_rendering_params1);
1635 IDWriteRenderingParams_Release(text_rendering_params2);
1637 ID2D1RenderTarget_SetAntialiasMode(rt, D2D1_ANTIALIAS_MODE_PER_PRIMITIVE);
1638 ID2D1RenderTarget_SetTextAntialiasMode(rt, D2D1_TEXT_ANTIALIAS_MODE_GRAYSCALE);
1639 ID2D1RenderTarget_SetTags(rt, 1, 2);
1640 ID2D1RenderTarget_SetTransform(rt, &transform2);
1641 ID2D1RenderTarget_SetTextRenderingParams(rt, NULL);
1643 drawing_state.antialiasMode = ID2D1RenderTarget_GetAntialiasMode(rt);
1644 ok(drawing_state.antialiasMode == D2D1_ANTIALIAS_MODE_PER_PRIMITIVE,
1645 "Got unexpected antialias mode %#x.\n", drawing_state.antialiasMode);
1646 drawing_state.textAntialiasMode = ID2D1RenderTarget_GetTextAntialiasMode(rt);
1647 ok(drawing_state.textAntialiasMode == D2D1_TEXT_ANTIALIAS_MODE_GRAYSCALE,
1648 "Got unexpected text antialias mode %#x.\n", drawing_state.textAntialiasMode);
1649 ID2D1RenderTarget_GetTags(rt, &drawing_state.tag1, &drawing_state.tag2);
1650 ok(drawing_state.tag1 == 1 && drawing_state.tag2 == 2, "Got unexpected tags %s:%s.\n",
1651 wine_dbgstr_longlong(drawing_state.tag1), wine_dbgstr_longlong(drawing_state.tag2));
1652 ID2D1RenderTarget_GetTransform(rt, &drawing_state.transform);
1653 ok(!memcmp(&drawing_state.transform, &transform2, sizeof(drawing_state.transform)),
1654 "Got unexpected matrix {%.8e, %.8e, %.8e, %.8e, %.8e, %.8e}.\n",
1655 drawing_state.transform._11, drawing_state.transform._12, drawing_state.transform._21,
1656 drawing_state.transform._22, drawing_state.transform._31, drawing_state.transform._32);
1657 ID2D1RenderTarget_GetTextRenderingParams(rt, &text_rendering_params2);
1658 ok(!text_rendering_params2, "Got unexpected text rendering params %p.\n", text_rendering_params2);
1660 ID2D1RenderTarget_SaveDrawingState(rt, state_block);
1662 ID2D1DrawingStateBlock_GetDescription(state_block, &drawing_state);
1663 ok(drawing_state.antialiasMode == D2D1_ANTIALIAS_MODE_PER_PRIMITIVE,
1664 "Got unexpected antialias mode %#x.\n", drawing_state.antialiasMode);
1665 ok(drawing_state.textAntialiasMode == D2D1_TEXT_ANTIALIAS_MODE_GRAYSCALE,
1666 "Got unexpected text antialias mode %#x.\n", drawing_state.textAntialiasMode);
1667 ok(drawing_state.tag1 == 1 && drawing_state.tag2 == 2, "Got unexpected tags %s:%s.\n",
1668 wine_dbgstr_longlong(drawing_state.tag1), wine_dbgstr_longlong(drawing_state.tag2));
1669 ok(!memcmp(&drawing_state.transform, &transform2, sizeof(drawing_state.transform)),
1670 "Got unexpected matrix {%.8e, %.8e, %.8e, %.8e, %.8e, %.8e}.\n",
1671 drawing_state.transform._11, drawing_state.transform._12, drawing_state.transform._21,
1672 drawing_state.transform._22, drawing_state.transform._31, drawing_state.transform._32);
1673 ID2D1DrawingStateBlock_GetTextRenderingParams(state_block, &text_rendering_params2);
1674 ok(!text_rendering_params2, "Got unexpected text rendering params %p.\n", text_rendering_params2);
1676 drawing_state.antialiasMode = D2D1_ANTIALIAS_MODE_ALIASED;
1677 drawing_state.textAntialiasMode = D2D1_TEXT_ANTIALIAS_MODE_CLEARTYPE;
1678 drawing_state.tag1 = 3;
1679 drawing_state.tag2 = 4;
1680 drawing_state.transform = transform1;
1681 ID2D1DrawingStateBlock_SetDescription(state_block, &drawing_state);
1682 ID2D1DrawingStateBlock_SetTextRenderingParams(state_block, text_rendering_params1);
1684 ID2D1DrawingStateBlock_GetDescription(state_block, &drawing_state);
1685 ok(drawing_state.antialiasMode == D2D1_ANTIALIAS_MODE_ALIASED,
1686 "Got unexpected antialias mode %#x.\n", drawing_state.antialiasMode);
1687 ok(drawing_state.textAntialiasMode == D2D1_TEXT_ANTIALIAS_MODE_CLEARTYPE,
1688 "Got unexpected text antialias mode %#x.\n", drawing_state.textAntialiasMode);
1689 ok(drawing_state.tag1 == 3 && drawing_state.tag2 == 4, "Got unexpected tags %s:%s.\n",
1690 wine_dbgstr_longlong(drawing_state.tag1), wine_dbgstr_longlong(drawing_state.tag2));
1691 ok(!memcmp(&drawing_state.transform, &transform1, sizeof(drawing_state.transform)),
1692 "Got unexpected matrix {%.8e, %.8e, %.8e, %.8e, %.8e, %.8e}.\n",
1693 drawing_state.transform._11, drawing_state.transform._12, drawing_state.transform._21,
1694 drawing_state.transform._22, drawing_state.transform._31, drawing_state.transform._32);
1695 ID2D1DrawingStateBlock_GetTextRenderingParams(state_block, &text_rendering_params2);
1696 ok(text_rendering_params2 == text_rendering_params1, "Got unexpected text rendering params %p, expected %p.\n",
1697 text_rendering_params2, text_rendering_params1);
1698 IDWriteRenderingParams_Release(text_rendering_params2);
1700 if (SUCCEEDED(ID2D1Factory_QueryInterface(factory, &IID_ID2D1Factory1, (void **)&factory1)))
1702 D2D1_DRAWING_STATE_DESCRIPTION1 drawing_state1;
1703 ID2D1DrawingStateBlock1 *state_block1;
1705 hr = ID2D1DrawingStateBlock_QueryInterface(state_block, &IID_ID2D1DrawingStateBlock1, (void **)&state_block1);
1706 ok(SUCCEEDED(hr), "Failed to get ID2D1DrawingStateBlock1 interface, hr %#x.\n", hr);
1708 ID2D1DrawingStateBlock1_GetDescription(state_block1, &drawing_state1);
1709 ok(drawing_state1.antialiasMode == D2D1_ANTIALIAS_MODE_ALIASED,
1710 "Got unexpected antialias mode %#x.\n", drawing_state1.antialiasMode);
1711 ok(drawing_state1.textAntialiasMode == D2D1_TEXT_ANTIALIAS_MODE_CLEARTYPE,
1712 "Got unexpected text antialias mode %#x.\n", drawing_state1.textAntialiasMode);
1713 ok(drawing_state1.tag1 == 3 && drawing_state1.tag2 == 4, "Got unexpected tags %s:%s.\n",
1714 wine_dbgstr_longlong(drawing_state1.tag1), wine_dbgstr_longlong(drawing_state1.tag2));
1715 ok(!memcmp(&drawing_state1.transform, &transform1, sizeof(drawing_state1.transform)),
1716 "Got unexpected matrix {%.8e, %.8e, %.8e, %.8e, %.8e, %.8e}.\n",
1717 drawing_state1.transform._11, drawing_state1.transform._12, drawing_state1.transform._21,
1718 drawing_state1.transform._22, drawing_state1.transform._31, drawing_state1.transform._32);
1719 ok(drawing_state1.primitiveBlend == D2D1_PRIMITIVE_BLEND_SOURCE_OVER,
1720 "Got unexpected primitive blend mode %#x.\n", drawing_state1.primitiveBlend);
1721 ok(drawing_state1.unitMode == D2D1_UNIT_MODE_DIPS, "Got unexpected unit mode %#x.\n", drawing_state1.unitMode);
1722 ID2D1DrawingStateBlock1_GetTextRenderingParams(state_block1, &text_rendering_params2);
1723 ok(text_rendering_params2 == text_rendering_params1, "Got unexpected text rendering params %p, expected %p.\n",
1724 text_rendering_params2, text_rendering_params1);
1725 IDWriteRenderingParams_Release(text_rendering_params2);
1727 drawing_state1.primitiveBlend = D2D1_PRIMITIVE_BLEND_COPY;
1728 drawing_state1.unitMode = D2D1_UNIT_MODE_PIXELS;
1729 ID2D1DrawingStateBlock1_SetDescription(state_block1, &drawing_state1);
1730 ID2D1DrawingStateBlock1_GetDescription(state_block1, &drawing_state1);
1731 ok(drawing_state1.primitiveBlend == D2D1_PRIMITIVE_BLEND_COPY,
1732 "Got unexpected primitive blend mode %#x.\n", drawing_state1.primitiveBlend);
1733 ok(drawing_state1.unitMode == D2D1_UNIT_MODE_PIXELS,
1734 "Got unexpected unit mode %#x.\n", drawing_state1.unitMode);
1736 ID2D1DrawingStateBlock_SetDescription(state_block, &drawing_state);
1737 ID2D1DrawingStateBlock1_GetDescription(state_block1, &drawing_state1);
1738 ok(drawing_state1.primitiveBlend == D2D1_PRIMITIVE_BLEND_COPY,
1739 "Got unexpected primitive blend mode %#x.\n", drawing_state1.primitiveBlend);
1740 ok(drawing_state1.unitMode == D2D1_UNIT_MODE_PIXELS,
1741 "Got unexpected unit mode %#x.\n", drawing_state1.unitMode);
1743 ID2D1DrawingStateBlock1_Release(state_block1);
1745 hr = ID2D1Factory1_CreateDrawingStateBlock(factory1, NULL, NULL, &state_block1);
1746 ok(SUCCEEDED(hr), "Failed to create drawing state block, hr %#x\n", hr);
1747 ID2D1DrawingStateBlock1_GetDescription(state_block1, &drawing_state1);
1748 ok(drawing_state1.antialiasMode == D2D1_ANTIALIAS_MODE_PER_PRIMITIVE,
1749 "Got unexpected antialias mode %#x.\n", drawing_state1.antialiasMode);
1750 ok(drawing_state1.textAntialiasMode == D2D1_TEXT_ANTIALIAS_MODE_DEFAULT,
1751 "Got unexpected text antialias mode %#x.\n", drawing_state1.textAntialiasMode);
1752 ok(drawing_state1.tag1 == 0 && drawing_state1.tag2 == 0, "Got unexpected tags %s:%s.\n",
1753 wine_dbgstr_longlong(drawing_state1.tag1), wine_dbgstr_longlong(drawing_state1.tag2));
1754 ok(!memcmp(&drawing_state1.transform, &identity, sizeof(drawing_state1.transform)),
1755 "Got unexpected matrix {%.8e, %.8e, %.8e, %.8e, %.8e, %.8e}.\n",
1756 drawing_state1.transform._11, drawing_state1.transform._12, drawing_state1.transform._21,
1757 drawing_state1.transform._22, drawing_state1.transform._31, drawing_state1.transform._32);
1758 ok(drawing_state1.primitiveBlend == D2D1_PRIMITIVE_BLEND_SOURCE_OVER,
1759 "Got unexpected primitive blend mode %#x.\n", drawing_state1.primitiveBlend);
1760 ok(drawing_state1.unitMode == D2D1_UNIT_MODE_DIPS, "Got unexpected unit mode %#x.\n", drawing_state1.unitMode);
1761 ID2D1DrawingStateBlock1_GetTextRenderingParams(state_block1, &text_rendering_params2);
1762 ok(!text_rendering_params2, "Got unexpected text rendering params %p.\n", text_rendering_params2);
1763 ID2D1DrawingStateBlock1_Release(state_block1);
1765 ID2D1Factory1_Release(factory1);
1768 ID2D1DrawingStateBlock_Release(state_block);
1770 refcount = IDWriteRenderingParams_Release(text_rendering_params1);
1771 ok(!refcount, "Rendering params %u references left.\n", refcount);
1772 ID2D1Factory_Release(factory);
1773 release_test_context(&ctx);
1776 static void test_color_brush(BOOL d3d11)
1778 D2D1_MATRIX_3X2_F matrix, tmp_matrix;
1779 D2D1_BRUSH_PROPERTIES brush_desc;
1780 D2D1_COLOR_F color, tmp_color;
1781 struct d2d1_test_context ctx;
1782 ID2D1SolidColorBrush *brush;
1783 ID2D1RenderTarget *rt;
1784 D2D1_RECT_F rect;
1785 float opacity;
1786 HRESULT hr;
1787 BOOL match;
1789 if (!init_test_context(&ctx, d3d11))
1790 return;
1792 rt = ctx.rt;
1793 ID2D1RenderTarget_SetDpi(rt, 192.0f, 48.0f);
1794 ID2D1RenderTarget_SetAntialiasMode(rt, D2D1_ANTIALIAS_MODE_ALIASED);
1796 set_color(&color, 0.0f, 0.0f, 0.0f, 0.0f);
1797 hr = ID2D1RenderTarget_CreateSolidColorBrush(rt, &color, NULL, &brush);
1798 ok(SUCCEEDED(hr), "Failed to create brush, hr %#x.\n", hr);
1799 opacity = ID2D1SolidColorBrush_GetOpacity(brush);
1800 ok(opacity == 1.0f, "Got unexpected opacity %.8e.\n", opacity);
1801 set_matrix_identity(&matrix);
1802 ID2D1SolidColorBrush_GetTransform(brush, &tmp_matrix);
1803 ok(!memcmp(&tmp_matrix, &matrix, sizeof(matrix)),
1804 "Got unexpected matrix {%.8e, %.8e, %.8e, %.8e, %.8e, %.8e}.\n",
1805 tmp_matrix._11, tmp_matrix._12, tmp_matrix._21,
1806 tmp_matrix._22, tmp_matrix._31, tmp_matrix._32);
1807 tmp_color = ID2D1SolidColorBrush_GetColor(brush);
1808 ok(!memcmp(&tmp_color, &color, sizeof(color)),
1809 "Got unexpected color {%.8e, %.8e, %.8e, %.8e}.\n",
1810 tmp_color.r, tmp_color.g, tmp_color.b, tmp_color.a);
1811 ID2D1SolidColorBrush_Release(brush);
1813 set_color(&color, 0.0f, 1.0f, 0.0f, 0.8f);
1814 brush_desc.opacity = 0.3f;
1815 set_matrix_identity(&matrix);
1816 scale_matrix(&matrix, 2.0f, 2.0f);
1817 brush_desc.transform = matrix;
1818 hr = ID2D1RenderTarget_CreateSolidColorBrush(rt, &color, &brush_desc, &brush);
1819 ok(SUCCEEDED(hr), "Failed to create brush, hr %#x.\n", hr);
1820 opacity = ID2D1SolidColorBrush_GetOpacity(brush);
1821 ok(opacity == 0.3f, "Got unexpected opacity %.8e.\n", opacity);
1822 ID2D1SolidColorBrush_GetTransform(brush, &tmp_matrix);
1823 ok(!memcmp(&tmp_matrix, &matrix, sizeof(matrix)),
1824 "Got unexpected matrix {%.8e, %.8e, %.8e, %.8e, %.8e, %.8e}.\n",
1825 tmp_matrix._11, tmp_matrix._12, tmp_matrix._21,
1826 tmp_matrix._22, tmp_matrix._31, tmp_matrix._32);
1827 tmp_color = ID2D1SolidColorBrush_GetColor(brush);
1828 ok(!memcmp(&tmp_color, &color, sizeof(color)),
1829 "Got unexpected color {%.8e, %.8e, %.8e, %.8e}.\n",
1830 tmp_color.r, tmp_color.g, tmp_color.b, tmp_color.a);
1832 ID2D1RenderTarget_BeginDraw(rt);
1834 set_color(&color, 0.0f, 0.0f, 1.0f, 1.0f);
1835 ID2D1RenderTarget_Clear(rt, &color);
1837 ID2D1SolidColorBrush_SetOpacity(brush, 1.0f);
1838 set_rect(&rect, 40.0f, 120.0f, 120.0f, 360.0f);
1839 ID2D1RenderTarget_FillRectangle(rt, &rect, (ID2D1Brush *)brush);
1841 set_matrix_identity(&matrix);
1842 scale_matrix(&matrix, 0.5f, 2.0f);
1843 translate_matrix(&matrix, 320.0f, 240.0f);
1844 rotate_matrix(&matrix, M_PI / 4.0f);
1845 ID2D1RenderTarget_SetTransform(rt, &matrix);
1846 set_color(&color, 1.0f, 0.0f, 0.0f, 0.625f);
1847 ID2D1SolidColorBrush_SetColor(brush, &color);
1848 ID2D1SolidColorBrush_SetOpacity(brush, 0.75f);
1849 set_rect(&rect, -80.0f, -60.0f, 80.0f, 60.0f);
1850 ID2D1RenderTarget_FillRectangle(rt, &rect, (ID2D1Brush *)brush);
1852 hr = ID2D1RenderTarget_EndDraw(rt, NULL, NULL);
1853 ok(SUCCEEDED(hr), "Failed to end draw, hr %#x.\n", hr);
1854 match = compare_surface(&ctx, "6d1218fca5e21fb7e287b3a439d60dbc251f5ceb");
1855 ok(match, "Surface does not match.\n");
1857 ID2D1SolidColorBrush_Release(brush);
1858 release_test_context(&ctx);
1861 static void test_bitmap_brush(BOOL d3d11)
1863 D2D1_BITMAP_INTERPOLATION_MODE interpolation_mode;
1864 ID2D1TransformedGeometry *transformed_geometry;
1865 ID2D1RectangleGeometry *rectangle_geometry;
1866 D2D1_MATRIX_3X2_F matrix, tmp_matrix;
1867 D2D1_BITMAP_PROPERTIES bitmap_desc;
1868 ID2D1Bitmap *bitmap, *tmp_bitmap;
1869 D2D1_RECT_F src_rect, dst_rect;
1870 struct d2d1_test_context ctx;
1871 D2D1_EXTEND_MODE extend_mode;
1872 ID2D1BitmapBrush1 *brush1;
1873 ID2D1BitmapBrush *brush;
1874 D2D1_SIZE_F image_size;
1875 ID2D1RenderTarget *rt;
1876 ID2D1Factory *factory;
1877 D2D1_COLOR_F color;
1878 ID2D1Image *image;
1879 D2D1_SIZE_U size;
1880 unsigned int i;
1881 ULONG refcount;
1882 float opacity;
1883 HRESULT hr;
1884 BOOL match;
1886 static const struct
1888 D2D1_EXTEND_MODE extend_mode_x;
1889 D2D1_EXTEND_MODE extend_mode_y;
1890 float translate_x;
1891 float translate_y;
1892 D2D1_RECT_F rect;
1894 extend_mode_tests[] =
1896 {D2D1_EXTEND_MODE_MIRROR, D2D1_EXTEND_MODE_MIRROR, -7.0f, 1.0f, {-4.0f, 0.0f, -8.0f, 4.0f}},
1897 {D2D1_EXTEND_MODE_WRAP, D2D1_EXTEND_MODE_MIRROR, -3.0f, 1.0f, {-4.0f, 4.0f, 0.0f, 0.0f}},
1898 {D2D1_EXTEND_MODE_CLAMP, D2D1_EXTEND_MODE_MIRROR, 1.0f, 1.0f, { 4.0f, 0.0f, 0.0f, 4.0f}},
1899 {D2D1_EXTEND_MODE_MIRROR, D2D1_EXTEND_MODE_WRAP, -7.0f, 5.0f, {-8.0f, 8.0f, -4.0f, 4.0f}},
1900 {D2D1_EXTEND_MODE_WRAP, D2D1_EXTEND_MODE_WRAP, -3.0f, 5.0f, { 0.0f, 4.0f, -4.0f, 8.0f}},
1901 {D2D1_EXTEND_MODE_CLAMP, D2D1_EXTEND_MODE_WRAP, 1.0f, 5.0f, { 0.0f, 8.0f, 4.0f, 4.0f}},
1902 {D2D1_EXTEND_MODE_MIRROR, D2D1_EXTEND_MODE_CLAMP, -7.0f, 9.0f, {-4.0f, 8.0f, -8.0f, 12.0f}},
1903 {D2D1_EXTEND_MODE_WRAP, D2D1_EXTEND_MODE_CLAMP, -3.0f, 9.0f, {-4.0f, 12.0f, 0.0f, 8.0f}},
1904 {D2D1_EXTEND_MODE_CLAMP, D2D1_EXTEND_MODE_CLAMP, 1.0f, 9.0f, { 4.0f, 8.0f, 0.0f, 12.0f}},
1906 static const DWORD bitmap_data[] =
1908 0xffff0000, 0xffffff00, 0xff00ff00, 0xff00ffff,
1909 0xff0000ff, 0xffff00ff, 0xff000000, 0xff7f7f7f,
1910 0xffffffff, 0xffffffff, 0xffffffff, 0xff000000,
1911 0xffffffff, 0xff000000, 0xff000000, 0xff000000,
1914 if (!init_test_context(&ctx, d3d11))
1915 return;
1917 rt = ctx.rt;
1918 ID2D1RenderTarget_SetDpi(rt, 192.0f, 48.0f);
1919 ID2D1RenderTarget_SetAntialiasMode(rt, D2D1_ANTIALIAS_MODE_ALIASED);
1921 set_size_u(&size, 4, 4);
1922 bitmap_desc.pixelFormat.format = DXGI_FORMAT_B8G8R8A8_UNORM;
1923 bitmap_desc.pixelFormat.alphaMode = D2D1_ALPHA_MODE_IGNORE;
1924 bitmap_desc.dpiX = 96.0f;
1925 bitmap_desc.dpiY = 96.0f;
1926 hr = ID2D1RenderTarget_CreateBitmap(rt, size, bitmap_data, 4 * sizeof(*bitmap_data), &bitmap_desc, &bitmap);
1927 ok(SUCCEEDED(hr), "Failed to create bitmap, hr %#x.\n", hr);
1928 image_size = ID2D1Bitmap_GetSize(bitmap);
1930 hr = ID2D1Bitmap_QueryInterface(bitmap, &IID_ID2D1Image, (void **)&image);
1931 ok(SUCCEEDED(hr) || broken(hr == E_NOINTERFACE) /* Vista */, "Failed to get ID2D1Image, hr %#x.\n", hr);
1932 if (hr == S_OK)
1934 ID2D1DeviceContext *context;
1935 D2D1_POINT_2F offset;
1936 D2D1_RECT_F src_rect;
1938 hr = ID2D1RenderTarget_QueryInterface(rt, &IID_ID2D1DeviceContext, (void **)&context);
1939 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1941 ID2D1RenderTarget_BeginDraw(rt);
1942 set_color(&color, 0.0f, 0.0f, 1.0f, 1.0f);
1943 ID2D1RenderTarget_Clear(rt, &color);
1945 ID2D1RenderTarget_GetTransform(rt, &tmp_matrix);
1946 set_matrix_identity(&matrix);
1947 translate_matrix(&matrix, 20.0f, 12.0f);
1948 scale_matrix(&matrix, 2.0f, 6.0f);
1949 ID2D1RenderTarget_SetTransform(rt, &matrix);
1951 /* Crash on Windows 7+ */
1952 if (0)
1954 ID2D1DeviceContext_DrawImage(context, NULL, NULL, NULL, D2D1_BITMAP_INTERPOLATION_MODE_NEAREST_NEIGHBOR,
1955 D2D1_COMPOSITE_MODE_SOURCE_OVER);
1958 ID2D1DeviceContext_DrawImage(context, image, NULL, NULL, D2D1_BITMAP_INTERPOLATION_MODE_NEAREST_NEIGHBOR,
1959 D2D1_COMPOSITE_MODE_SOURCE_OVER);
1961 set_rect(&src_rect, 0.0f, 0.0f, image_size.width, image_size.height);
1963 ID2D1DeviceContext_DrawImage(context, image, NULL, &src_rect, D2D1_BITMAP_INTERPOLATION_MODE_NEAREST_NEIGHBOR,
1964 D2D1_COMPOSITE_MODE_SOURCE_OVER);
1966 offset.x = -1;
1967 offset.y = -1;
1968 ID2D1DeviceContext_DrawImage(context, image, &offset, NULL, D2D1_BITMAP_INTERPOLATION_MODE_NEAREST_NEIGHBOR,
1969 D2D1_COMPOSITE_MODE_SOURCE_OVER);
1971 offset.x = image_size.width * 2;
1972 offset.y = image_size.height;
1973 ID2D1DeviceContext_DrawImage(context, image, &offset, NULL, D2D1_BITMAP_INTERPOLATION_MODE_NEAREST_NEIGHBOR,
1974 D2D1_COMPOSITE_MODE_SOURCE_OVER);
1976 offset.x = image_size.width * 3;
1977 set_rect(&src_rect, image_size.width / 2, image_size.height / 2, image_size.width, image_size.height);
1978 ID2D1DeviceContext_DrawImage(context, image, &offset, &src_rect, D2D1_BITMAP_INTERPOLATION_MODE_NEAREST_NEIGHBOR,
1979 D2D1_COMPOSITE_MODE_SOURCE_OVER);
1981 offset.x = image_size.width * 4;
1982 set_rect(&src_rect, 0.0f, 0.0f, image_size.width * 2, image_size.height * 2);
1983 ID2D1DeviceContext_DrawImage(context, image, &offset, &src_rect, D2D1_BITMAP_INTERPOLATION_MODE_NEAREST_NEIGHBOR,
1984 D2D1_COMPOSITE_MODE_SOURCE_OVER);
1986 offset.x = image_size.width * 5;
1987 set_rect(&src_rect, image_size.width, image_size.height, 0.0f, 0.0f);
1988 ID2D1DeviceContext_DrawImage(context, image, &offset, &src_rect, D2D1_BITMAP_INTERPOLATION_MODE_NEAREST_NEIGHBOR,
1989 D2D1_COMPOSITE_MODE_SOURCE_OVER);
1991 hr = ID2D1RenderTarget_EndDraw(rt, NULL, NULL);
1992 ok(SUCCEEDED(hr), "Failed to end draw, hr %#x.\n", hr);
1993 match = compare_surface(&ctx, "95675fbc4a16404c9568d41b14e8f6be64240998");
1994 ok(match, "Surface does not match.\n");
1996 ID2D1RenderTarget_BeginDraw(rt);
1998 offset.x = image_size.width * 6;
1999 set_rect(&src_rect, 1.0f, 0.0f, 1.0f, image_size.height);
2000 ID2D1DeviceContext_DrawImage(context, image, &offset, &src_rect, D2D1_BITMAP_INTERPOLATION_MODE_NEAREST_NEIGHBOR,
2001 D2D1_COMPOSITE_MODE_SOURCE_OVER);
2003 hr = ID2D1RenderTarget_EndDraw(rt, NULL, NULL);
2004 ok(SUCCEEDED(hr), "Failed to end draw, hr %#x.\n", hr);
2005 match = compare_surface(&ctx, "95675fbc4a16404c9568d41b14e8f6be64240998");
2006 ok(match, "Surface does not match.\n");
2008 ID2D1RenderTarget_SetTransform(rt, &tmp_matrix);
2009 ID2D1DeviceContext_Release(context);
2010 ID2D1Image_Release(image);
2013 /* Creating a brush with a NULL bitmap crashes on Vista, but works fine on
2014 * Windows 7+. */
2015 hr = ID2D1RenderTarget_CreateBitmapBrush(rt, bitmap, NULL, NULL, &brush);
2016 ok(SUCCEEDED(hr), "Failed to create brush, hr %#x.\n", hr);
2017 ID2D1BitmapBrush_GetBitmap(brush, &tmp_bitmap);
2018 ok(tmp_bitmap == bitmap, "Got unexpected bitmap %p, expected %p.\n", tmp_bitmap, bitmap);
2019 ID2D1Bitmap_Release(tmp_bitmap);
2020 opacity = ID2D1BitmapBrush_GetOpacity(brush);
2021 ok(opacity == 1.0f, "Got unexpected opacity %.8e.\n", opacity);
2022 set_matrix_identity(&matrix);
2023 ID2D1BitmapBrush_GetTransform(brush, &tmp_matrix);
2024 ok(!memcmp(&tmp_matrix, &matrix, sizeof(matrix)),
2025 "Got unexpected matrix {%.8e, %.8e, %.8e, %.8e, %.8e, %.8e}.\n",
2026 tmp_matrix._11, tmp_matrix._12, tmp_matrix._21,
2027 tmp_matrix._22, tmp_matrix._31, tmp_matrix._32);
2028 extend_mode = ID2D1BitmapBrush_GetExtendModeX(brush);
2029 ok(extend_mode == D2D1_EXTEND_MODE_CLAMP, "Got unexpected extend mode %#x.\n", extend_mode);
2030 extend_mode = ID2D1BitmapBrush_GetExtendModeY(brush);
2031 ok(extend_mode == D2D1_EXTEND_MODE_CLAMP, "Got unexpected extend mode %#x.\n", extend_mode);
2032 interpolation_mode = ID2D1BitmapBrush_GetInterpolationMode(brush);
2033 ok(interpolation_mode == D2D1_BITMAP_INTERPOLATION_MODE_LINEAR,
2034 "Got unexpected interpolation mode %#x.\n", interpolation_mode);
2035 ID2D1BitmapBrush_Release(brush);
2037 hr = ID2D1RenderTarget_CreateBitmapBrush(rt, bitmap, NULL, NULL, &brush);
2038 ok(SUCCEEDED(hr), "Failed to create brush, hr %#x.\n", hr);
2039 set_matrix_identity(&matrix);
2040 translate_matrix(&matrix, 40.0f, 120.0f);
2041 scale_matrix(&matrix, 20.0f, 60.0f);
2042 ID2D1BitmapBrush_SetTransform(brush, &matrix);
2043 ID2D1BitmapBrush_SetInterpolationMode(brush, D2D1_BITMAP_INTERPOLATION_MODE_NEAREST_NEIGHBOR);
2045 ID2D1RenderTarget_BeginDraw(rt);
2047 set_color(&color, 0.0f, 0.0f, 1.0f, 1.0f);
2048 ID2D1RenderTarget_Clear(rt, &color);
2050 set_rect(&dst_rect, 40.0f, 120.0f, 120.0f, 360.0f);
2051 ID2D1RenderTarget_FillRectangle(rt, &dst_rect, (ID2D1Brush *)brush);
2053 set_matrix_identity(&matrix);
2054 scale_matrix(&matrix, 0.5f, 2.0f);
2055 translate_matrix(&matrix, 320.0f, 240.0f);
2056 rotate_matrix(&matrix, M_PI / 4.0f);
2057 ID2D1RenderTarget_SetTransform(rt, &matrix);
2058 set_matrix_identity(&matrix);
2059 translate_matrix(&matrix, -80.0f, -60.0f);
2060 scale_matrix(&matrix, 64.0f, 32.0f);
2061 ID2D1BitmapBrush_SetTransform(brush, &matrix);
2062 ID2D1BitmapBrush_SetOpacity(brush, 0.75f);
2063 set_rect(&dst_rect, -80.0f, -60.0f, 80.0f, 60.0f);
2064 ID2D1RenderTarget_FillRectangle(rt, &dst_rect, (ID2D1Brush *)brush);
2066 set_matrix_identity(&matrix);
2067 translate_matrix(&matrix, 200.0f, 120.0f);
2068 scale_matrix(&matrix, 20.0f, 60.0f);
2069 ID2D1RenderTarget_SetTransform(rt, &matrix);
2070 ID2D1RenderTarget_DrawBitmap(rt, bitmap, NULL, 0.25f,
2071 D2D1_BITMAP_INTERPOLATION_MODE_NEAREST_NEIGHBOR, NULL);
2072 set_rect(&dst_rect, -4.0f, 12.0f, -8.0f, 8.0f);
2073 ID2D1RenderTarget_DrawBitmap(rt, bitmap, &dst_rect, 0.75f,
2074 D2D1_BITMAP_INTERPOLATION_MODE_NEAREST_NEIGHBOR, NULL);
2075 set_rect(&dst_rect, 0.0f, 8.0f, 4.0f, 12.0f);
2076 set_rect(&src_rect, 2.0f, 1.0f, 4.0f, 3.0f);
2077 ID2D1RenderTarget_DrawBitmap(rt, bitmap, &dst_rect, 1.0f,
2078 D2D1_BITMAP_INTERPOLATION_MODE_NEAREST_NEIGHBOR, &src_rect);
2079 set_rect(&dst_rect, 4.0f, 12.0f, 12.0f, 20.0f);
2080 set_rect(&src_rect, 0.0f, 0.0f, image_size.width * 2, image_size.height * 2);
2081 ID2D1RenderTarget_DrawBitmap(rt, bitmap, &dst_rect, 1.0f,
2082 D2D1_BITMAP_INTERPOLATION_MODE_NEAREST_NEIGHBOR, &src_rect);
2083 set_rect(&dst_rect, 4.0f, 8.0f, 12.0f, 12.0f);
2084 set_rect(&src_rect, image_size.width / 2, image_size.height / 2, image_size.width, image_size.height);
2085 ID2D1RenderTarget_DrawBitmap(rt, bitmap, &dst_rect, 1.0f,
2086 D2D1_BITMAP_INTERPOLATION_MODE_NEAREST_NEIGHBOR, &src_rect);
2087 set_rect(&dst_rect, 0.0f, 4.0f, 4.0f, 8.0f);
2088 set_rect(&src_rect, image_size.width, 0.0f, 0.0f, image_size.height);
2089 ID2D1RenderTarget_DrawBitmap(rt, bitmap, &dst_rect, 1.0f,
2090 D2D1_BITMAP_INTERPOLATION_MODE_NEAREST_NEIGHBOR, &src_rect);
2092 hr = ID2D1RenderTarget_EndDraw(rt, NULL, NULL);
2093 ok(SUCCEEDED(hr), "Failed to end draw, hr %#x.\n", hr);
2094 match = compare_surface(&ctx, "f5d039c280fa33ba05496c9883192a34108efbbe");
2095 ok(match, "Surface does not match.\n");
2097 /* Invalid interpolation mode. */
2098 ID2D1RenderTarget_BeginDraw(rt);
2100 set_rect(&dst_rect, 4.0f, 8.0f, 8.0f, 12.0f);
2101 set_rect(&src_rect, 0.0f, 1.0f, image_size.width, 1.0f);
2102 ID2D1RenderTarget_DrawBitmap(rt, bitmap, &dst_rect, 1.0f,
2103 D2D1_BITMAP_INTERPOLATION_MODE_NEAREST_NEIGHBOR, &src_rect);
2105 set_rect(&dst_rect, 1.0f, 8.0f, 4.0f, 12.0f);
2106 set_rect(&src_rect, 2.0f, 1.0f, 4.0f, 3.0f);
2107 ID2D1RenderTarget_DrawBitmap(rt, bitmap, &dst_rect, 1.0f,
2108 D2D1_BITMAP_INTERPOLATION_MODE_LINEAR + 1, &src_rect);
2110 hr = ID2D1RenderTarget_EndDraw(rt, NULL, NULL);
2111 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
2112 match = compare_surface(&ctx, "f5d039c280fa33ba05496c9883192a34108efbbe");
2113 ok(match, "Surface does not match.\n");
2115 ID2D1RenderTarget_BeginDraw(rt);
2116 ID2D1RenderTarget_Clear(rt, &color);
2118 set_rect(&src_rect, image_size.width, 0.0f, 0.0f, image_size.height);
2119 ID2D1RenderTarget_DrawBitmap(rt, bitmap, NULL, 1.0f,
2120 D2D1_BITMAP_INTERPOLATION_MODE_NEAREST_NEIGHBOR, &src_rect);
2122 hr = ID2D1RenderTarget_EndDraw(rt, NULL, NULL);
2123 ok(SUCCEEDED(hr), "Failed to end draw, hr %#x.\n", hr);
2124 match = compare_surface(&ctx, "59043096393570ad800dbcbfdd644394b79493bd");
2125 ok(match, "Surface does not match.\n");
2127 ID2D1RenderTarget_BeginDraw(rt);
2129 ID2D1RenderTarget_Clear(rt, &color);
2131 ID2D1BitmapBrush_SetOpacity(brush, 1.0f);
2132 for (i = 0; i < ARRAY_SIZE(extend_mode_tests); ++i)
2134 ID2D1BitmapBrush_SetExtendModeX(brush, extend_mode_tests[i].extend_mode_x);
2135 extend_mode = ID2D1BitmapBrush_GetExtendModeX(brush);
2136 ok(extend_mode == extend_mode_tests[i].extend_mode_x,
2137 "Test %u: Got unexpected extend mode %#x, expected %#x.\n",
2138 i, extend_mode, extend_mode_tests[i].extend_mode_x);
2139 ID2D1BitmapBrush_SetExtendModeY(brush, extend_mode_tests[i].extend_mode_y);
2140 extend_mode = ID2D1BitmapBrush_GetExtendModeY(brush);
2141 ok(extend_mode == extend_mode_tests[i].extend_mode_y,
2142 "Test %u: Got unexpected extend mode %#x, expected %#x.\n",
2143 i, extend_mode, extend_mode_tests[i].extend_mode_y);
2144 set_matrix_identity(&matrix);
2145 translate_matrix(&matrix, extend_mode_tests[i].translate_x, extend_mode_tests[i].translate_y);
2146 scale_matrix(&matrix, 0.5f, 0.5f);
2147 ID2D1BitmapBrush_SetTransform(brush, &matrix);
2148 ID2D1RenderTarget_FillRectangle(rt, &extend_mode_tests[i].rect, (ID2D1Brush *)brush);
2151 hr = ID2D1RenderTarget_EndDraw(rt, NULL, NULL);
2152 ok(SUCCEEDED(hr), "Failed to end draw, hr %#x.\n", hr);
2153 match = compare_surface(&ctx, "b4b775afecdae2d26642001f4faff73663bb8b31");
2154 ok(match, "Surface does not match.\n");
2156 ID2D1Bitmap_Release(bitmap);
2157 bitmap_desc.dpiX = 96.0f / 20.0f;
2158 bitmap_desc.dpiY = 96.0f / 60.0f;
2159 hr = ID2D1RenderTarget_CreateBitmap(rt, size, bitmap_data, 4 * sizeof(*bitmap_data), &bitmap_desc, &bitmap);
2160 ok(SUCCEEDED(hr), "Failed to create bitmap, hr %#x.\n", hr);
2161 ID2D1BitmapBrush_SetBitmap(brush, bitmap);
2163 ID2D1RenderTarget_BeginDraw(rt);
2165 ID2D1RenderTarget_Clear(rt, &color);
2167 set_matrix_identity(&matrix);
2168 translate_matrix(&matrix, 40.0f, 120.0f);
2169 skew_matrix(&matrix, 0.125f, 2.0f);
2170 ID2D1RenderTarget_SetTransform(rt, &matrix);
2171 set_matrix_identity(&matrix);
2172 ID2D1BitmapBrush_SetTransform(brush, &matrix);
2173 set_rect(&dst_rect, 0.0f, 0.0f, 80.0f, 240.0f);
2174 ID2D1RenderTarget_FillRectangle(rt, &dst_rect, (ID2D1Brush *)brush);
2176 ID2D1RenderTarget_GetFactory(rt, &factory);
2178 set_rect(&dst_rect, -1.0f, -1.0f, 1.0f, 1.0f);
2179 hr = ID2D1Factory_CreateRectangleGeometry(factory, &dst_rect, &rectangle_geometry);
2180 ok(SUCCEEDED(hr), "Failed to create geometry, hr %#x.\n", hr);
2182 set_matrix_identity(&matrix);
2183 translate_matrix(&matrix, 240.0f, 720.0f);
2184 scale_matrix(&matrix, 40.0f, 120.0f);
2185 hr = ID2D1Factory_CreateTransformedGeometry(factory, (ID2D1Geometry *)rectangle_geometry,
2186 &matrix, &transformed_geometry);
2187 ok(SUCCEEDED(hr), "Failed to create geometry, hr %#x.\n", hr);
2188 ID2D1RectangleGeometry_Release(rectangle_geometry);
2190 set_matrix_identity(&matrix);
2191 ID2D1RenderTarget_SetTransform(rt, &matrix);
2192 set_matrix_identity(&matrix);
2193 translate_matrix(&matrix, 200.0f, 600.0f);
2194 ID2D1BitmapBrush_SetTransform(brush, &matrix);
2195 ID2D1RenderTarget_FillGeometry(rt, (ID2D1Geometry *)transformed_geometry, (ID2D1Brush *)brush, NULL);
2196 ID2D1TransformedGeometry_Release(transformed_geometry);
2198 ID2D1Factory_Release(factory);
2200 hr = ID2D1RenderTarget_EndDraw(rt, NULL, NULL);
2201 ok(SUCCEEDED(hr), "Failed to end draw, hr %#x.\n", hr);
2202 match = compare_surface(&ctx, "cf7b90ba7b139fdfbe9347e1907d635cfb4ed197");
2203 ok(match, "Surface does not match.\n");
2205 if (SUCCEEDED(ID2D1BitmapBrush_QueryInterface(brush, &IID_ID2D1BitmapBrush1, (void **)&brush1)))
2207 D2D1_INTERPOLATION_MODE interpolation_mode1;
2209 interpolation_mode = ID2D1BitmapBrush1_GetInterpolationMode(brush1);
2210 ok(interpolation_mode == D2D1_BITMAP_INTERPOLATION_MODE_NEAREST_NEIGHBOR,
2211 "Unexpected interpolation mode %#x.\n", interpolation_mode);
2213 interpolation_mode1 = ID2D1BitmapBrush1_GetInterpolationMode1(brush1);
2214 ok(interpolation_mode1 == D2D1_INTERPOLATION_MODE_NEAREST_NEIGHBOR,
2215 "Unexpected interpolation mode %#x.\n", interpolation_mode1);
2217 ID2D1BitmapBrush1_SetInterpolationMode1(brush1, D2D1_INTERPOLATION_MODE_CUBIC);
2218 interpolation_mode = ID2D1BitmapBrush1_GetInterpolationMode(brush1);
2219 ok(interpolation_mode == D2D1_BITMAP_INTERPOLATION_MODE_LINEAR,
2220 "Unexpected interpolation mode %#x.\n", interpolation_mode);
2222 interpolation_mode1 = ID2D1BitmapBrush1_GetInterpolationMode1(brush1);
2223 ok(interpolation_mode1 == D2D1_INTERPOLATION_MODE_CUBIC,
2224 "Unexpected interpolation mode %#x.\n", interpolation_mode1);
2226 ID2D1BitmapBrush1_SetInterpolationMode1(brush1, 100);
2227 interpolation_mode1 = ID2D1BitmapBrush1_GetInterpolationMode1(brush1);
2228 ok(interpolation_mode1 == D2D1_INTERPOLATION_MODE_CUBIC,
2229 "Unexpected interpolation mode %#x.\n", interpolation_mode1);
2231 ID2D1BitmapBrush1_SetInterpolationMode(brush1, 100);
2232 interpolation_mode1 = ID2D1BitmapBrush1_GetInterpolationMode1(brush1);
2233 ok(interpolation_mode1 == D2D1_INTERPOLATION_MODE_CUBIC,
2234 "Unexpected interpolation mode %#x.\n", interpolation_mode1);
2236 ID2D1BitmapBrush1_SetInterpolationMode(brush1, D2D1_BITMAP_INTERPOLATION_MODE_NEAREST_NEIGHBOR);
2237 interpolation_mode = ID2D1BitmapBrush1_GetInterpolationMode(brush1);
2238 ok(interpolation_mode == D2D1_BITMAP_INTERPOLATION_MODE_NEAREST_NEIGHBOR,
2239 "Unexpected interpolation mode %#x.\n", interpolation_mode);
2241 interpolation_mode1 = ID2D1BitmapBrush1_GetInterpolationMode1(brush1);
2242 ok(interpolation_mode1 == D2D1_INTERPOLATION_MODE_NEAREST_NEIGHBOR,
2243 "Unexpected interpolation mode %#x.\n", interpolation_mode1);
2245 ID2D1BitmapBrush1_Release(brush1);
2248 ID2D1BitmapBrush_Release(brush);
2249 refcount = ID2D1Bitmap_Release(bitmap);
2250 ok(!refcount, "Bitmap has %u references left.\n", refcount);
2251 release_test_context(&ctx);
2254 static void test_linear_brush(BOOL d3d11)
2256 D2D1_LINEAR_GRADIENT_BRUSH_PROPERTIES gradient_properties;
2257 ID2D1GradientStopCollection *gradient, *tmp_gradient;
2258 ID2D1TransformedGeometry *transformed_geometry;
2259 ID2D1RectangleGeometry *rectangle_geometry;
2260 D2D1_MATRIX_3X2_F matrix, tmp_matrix;
2261 ID2D1LinearGradientBrush *brush;
2262 struct d2d1_test_context ctx;
2263 struct resource_readback rb;
2264 ID2D1RenderTarget *rt;
2265 ID2D1Factory *factory;
2266 D2D1_COLOR_F colour;
2267 D2D1_POINT_2F p;
2268 unsigned int i;
2269 ULONG refcount;
2270 D2D1_RECT_F r;
2271 float opacity;
2272 HRESULT hr;
2274 static const D2D1_GRADIENT_STOP stops[] =
2276 {0.0f, {1.0f, 0.0f, 0.0f, 1.0f}},
2277 {0.5f, {0.0f, 1.0f, 0.0f, 1.0f}},
2278 {1.0f, {0.0f, 0.0f, 1.0f, 1.0f}},
2280 static const struct
2282 unsigned int x, y;
2283 DWORD colour;
2285 test1[] =
2287 {80, 80, 0xff857a00}, {240, 80, 0xff926d00}, {400, 80, 0xff9f6000}, {560, 80, 0xffac5300},
2288 {80, 240, 0xff00eb14}, {240, 240, 0xff00f807}, {400, 240, 0xff06f900}, {560, 240, 0xff13ec00},
2289 {80, 400, 0xff0053ac}, {240, 400, 0xff005fa0}, {400, 400, 0xff006c93}, {560, 400, 0xff007986},
2291 test2[] =
2293 { 40, 30, 0xff005ba4}, {120, 30, 0xffffffff}, { 40, 60, 0xffffffff}, { 80, 60, 0xff00b44b},
2294 {120, 60, 0xff006c93}, {200, 60, 0xffffffff}, { 40, 90, 0xffffffff}, {120, 90, 0xff0ef100},
2295 {160, 90, 0xff00c53a}, {200, 90, 0xffffffff}, { 80, 120, 0xffffffff}, {120, 120, 0xffaf5000},
2296 {160, 120, 0xff679800}, {200, 120, 0xff1fe000}, {240, 120, 0xffffffff}, {160, 150, 0xffffffff},
2297 {200, 150, 0xffc03e00}, {240, 150, 0xffffffff}, {280, 150, 0xffffffff}, {320, 150, 0xffffffff},
2298 {240, 180, 0xffffffff}, {280, 180, 0xffff4040}, {320, 180, 0xffff4040}, {380, 180, 0xffffffff},
2299 {200, 210, 0xffffffff}, {240, 210, 0xffa99640}, {280, 210, 0xffb28d40}, {320, 210, 0xffbb8440},
2300 {360, 210, 0xffc47b40}, {400, 210, 0xffffffff}, {200, 240, 0xffffffff}, {280, 240, 0xff41fe40},
2301 {320, 240, 0xff49f540}, {360, 240, 0xff52ec40}, {440, 240, 0xffffffff}, {240, 270, 0xffffffff},
2302 {280, 270, 0xff408eb0}, {320, 270, 0xff4097a7}, {360, 270, 0xff40a19e}, {440, 270, 0xffffffff},
2303 {280, 300, 0xffffffff}, {320, 300, 0xff4040ff}, {360, 300, 0xff4040ff}, {400, 300, 0xff406ad4},
2304 {440, 300, 0xff4061de}, {480, 300, 0xff4057e7}, {520, 300, 0xff404ef1}, {280, 330, 0xffffffff},
2305 {360, 330, 0xffffffff}, {400, 330, 0xff40c17e}, {440, 330, 0xff40b788}, {480, 330, 0xff40ae91},
2306 {520, 330, 0xff40a49b}, {400, 360, 0xff57e740}, {440, 360, 0xff4ef140}, {480, 360, 0xff44fb40},
2307 {520, 360, 0xff40fa45}, {400, 390, 0xffae9140}, {440, 390, 0xffa49b40}, {480, 390, 0xff9aa540},
2308 {520, 390, 0xff90ae40},
2311 if (!init_test_context(&ctx, d3d11))
2312 return;
2314 rt = ctx.rt;
2315 ID2D1RenderTarget_SetDpi(rt, 192.0f, 48.0f);
2316 ID2D1RenderTarget_SetAntialiasMode(rt, D2D1_ANTIALIAS_MODE_ALIASED);
2318 hr = ID2D1RenderTarget_CreateGradientStopCollection(rt, stops, ARRAY_SIZE(stops),
2319 D2D1_GAMMA_2_2, D2D1_EXTEND_MODE_CLAMP, &gradient);
2320 ok(SUCCEEDED(hr), "Failed to create stop collection, hr %#x.\n", hr);
2322 set_point(&gradient_properties.startPoint, 320.0f, 0.0f);
2323 set_point(&gradient_properties.endPoint, 0.0f, 960.0f);
2324 hr = ID2D1RenderTarget_CreateLinearGradientBrush(rt, &gradient_properties, NULL, gradient, &brush);
2325 ok(SUCCEEDED(hr), "Failed to create brush, hr %#x.\n", hr);
2327 opacity = ID2D1LinearGradientBrush_GetOpacity(brush);
2328 ok(opacity == 1.0f, "Got unexpected opacity %.8e.\n", opacity);
2329 set_matrix_identity(&matrix);
2330 ID2D1LinearGradientBrush_GetTransform(brush, &tmp_matrix);
2331 ok(!memcmp(&tmp_matrix, &matrix, sizeof(matrix)),
2332 "Got unexpected matrix {%.8e, %.8e, %.8e, %.8e, %.8e, %.8e}.\n",
2333 tmp_matrix._11, tmp_matrix._12, tmp_matrix._21,
2334 tmp_matrix._22, tmp_matrix._31, tmp_matrix._32);
2335 p = ID2D1LinearGradientBrush_GetStartPoint(brush);
2336 ok(compare_point(&p, 320.0f, 0.0f, 0), "Got unexpected start point {%.8e, %.8e}.\n", p.x, p.y);
2337 p = ID2D1LinearGradientBrush_GetEndPoint(brush);
2338 ok(compare_point(&p, 0.0f, 960.0f, 0), "Got unexpected end point {%.8e, %.8e}.\n", p.x, p.y);
2339 ID2D1LinearGradientBrush_GetGradientStopCollection(brush, &tmp_gradient);
2340 ok(tmp_gradient == gradient, "Got unexpected gradient %p, expected %p.\n", tmp_gradient, gradient);
2341 ID2D1GradientStopCollection_Release(tmp_gradient);
2343 ID2D1RenderTarget_BeginDraw(rt);
2345 set_color(&colour, 1.0f, 1.0f, 1.0f, 1.0f);
2346 ID2D1RenderTarget_Clear(rt, &colour);
2348 set_rect(&r, 0.0f, 0.0f, 320.0f, 960.0f);
2349 ID2D1RenderTarget_FillRectangle(rt, &r, (ID2D1Brush *)brush);
2351 hr = ID2D1RenderTarget_EndDraw(rt, NULL, NULL);
2352 ok(SUCCEEDED(hr), "Failed to end draw, hr %#x.\n", hr);
2354 get_surface_readback(&ctx, &rb);
2355 for (i = 0; i < ARRAY_SIZE(test1); ++i)
2357 DWORD colour;
2359 colour = get_readback_colour(&rb, test1[i].x, test1[i].y);
2360 ok(compare_colour(colour, test1[i].colour, 1),
2361 "Got unexpected colour 0x%08x at position {%u, %u}.\n",
2362 colour, test1[i].x, test1[i].y);
2364 release_resource_readback(&rb);
2366 ID2D1RenderTarget_BeginDraw(rt);
2368 ID2D1RenderTarget_Clear(rt, &colour);
2370 set_matrix_identity(&matrix);
2371 skew_matrix(&matrix, 0.2146f, 1.575f);
2372 ID2D1RenderTarget_SetTransform(rt, &matrix);
2374 set_matrix_identity(&matrix);
2375 translate_matrix(&matrix, 0.0f, 240.0f);
2376 scale_matrix(&matrix, 0.25f, -0.25f);
2377 ID2D1LinearGradientBrush_SetTransform(brush, &matrix);
2379 set_rect(&r, 0.0f, 0.0f, 80.0f, 240.0f);
2380 ID2D1RenderTarget_FillRectangle(rt, &r, (ID2D1Brush *)brush);
2382 set_matrix_identity(&matrix);
2383 scale_matrix(&matrix, 0.5f, 2.0f);
2384 translate_matrix(&matrix, 320.0f, 240.0f);
2385 rotate_matrix(&matrix, M_PI / 4.0f);
2386 ID2D1RenderTarget_SetTransform(rt, &matrix);
2388 set_matrix_identity(&matrix);
2389 translate_matrix(&matrix, 0.0f, -50.0f);
2390 scale_matrix(&matrix, 0.1f, 0.1f);
2391 rotate_matrix(&matrix, -M_PI / 3.0f);
2392 ID2D1LinearGradientBrush_SetTransform(brush, &matrix);
2394 ID2D1LinearGradientBrush_SetOpacity(brush, 0.75f);
2395 set_rect(&r, -80.0f, -60.0f, 80.0f, 60.0f);
2396 ID2D1RenderTarget_FillRectangle(rt, &r, (ID2D1Brush *)brush);
2398 ID2D1RenderTarget_GetFactory(rt, &factory);
2400 set_rect(&r, -1.0f, -1.0f, 1.0f, 1.0f);
2401 hr = ID2D1Factory_CreateRectangleGeometry(factory, &r, &rectangle_geometry);
2402 ok(SUCCEEDED(hr), "Failed to create geometry, hr %#x.\n", hr);
2404 set_matrix_identity(&matrix);
2405 translate_matrix(&matrix, 228.5f, 714.0f);
2406 scale_matrix(&matrix, 40.0f, 120.0f);
2407 hr = ID2D1Factory_CreateTransformedGeometry(factory, (ID2D1Geometry *)rectangle_geometry,
2408 &matrix, &transformed_geometry);
2409 ok(SUCCEEDED(hr), "Failed to create geometry, hr %#x.\n", hr);
2410 ID2D1RectangleGeometry_Release(rectangle_geometry);
2412 set_matrix_identity(&matrix);
2413 ID2D1RenderTarget_SetTransform(rt, &matrix);
2414 ID2D1LinearGradientBrush_SetTransform(brush, &matrix);
2415 set_point(&p, 188.5f, 834.0f);
2416 ID2D1LinearGradientBrush_SetStartPoint(brush, p);
2417 set_point(&p, 268.5f, 594.0f);
2418 ID2D1LinearGradientBrush_SetEndPoint(brush, p);
2419 ID2D1RenderTarget_FillGeometry(rt, (ID2D1Geometry *)transformed_geometry, (ID2D1Brush *)brush, NULL);
2420 ID2D1TransformedGeometry_Release(transformed_geometry);
2422 ID2D1Factory_Release(factory);
2424 hr = ID2D1RenderTarget_EndDraw(rt, NULL, NULL);
2425 ok(SUCCEEDED(hr), "Failed to end draw, hr %#x.\n", hr);
2427 get_surface_readback(&ctx, &rb);
2428 for (i = 0; i < ARRAY_SIZE(test2); ++i)
2430 DWORD colour;
2432 colour = get_readback_colour(&rb, test2[i].x, test2[i].y);
2433 ok(compare_colour(colour, test2[i].colour, 1),
2434 "Got unexpected colour 0x%08x at position {%u, %u}.\n",
2435 colour, test2[i].x, test2[i].y);
2437 release_resource_readback(&rb);
2439 ID2D1LinearGradientBrush_Release(brush);
2440 refcount = ID2D1GradientStopCollection_Release(gradient);
2441 ok(!refcount, "Gradient has %u references left.\n", refcount);
2442 release_test_context(&ctx);
2445 static void test_radial_brush(BOOL d3d11)
2447 D2D1_RADIAL_GRADIENT_BRUSH_PROPERTIES gradient_properties;
2448 ID2D1GradientStopCollection *gradient, *tmp_gradient;
2449 ID2D1TransformedGeometry *transformed_geometry;
2450 ID2D1RectangleGeometry *rectangle_geometry;
2451 D2D1_MATRIX_3X2_F matrix, tmp_matrix;
2452 ID2D1RadialGradientBrush *brush;
2453 struct d2d1_test_context ctx;
2454 struct resource_readback rb;
2455 ID2D1RenderTarget *rt;
2456 ID2D1Factory *factory;
2457 D2D1_COLOR_F colour;
2458 D2D1_POINT_2F p;
2459 unsigned int i;
2460 ULONG refcount;
2461 D2D1_RECT_F r;
2462 HRESULT hr;
2463 float f;
2465 static const D2D1_GRADIENT_STOP stops[] =
2467 {0.0f, {1.0f, 0.0f, 0.0f, 1.0f}},
2468 {0.5f, {0.0f, 1.0f, 0.0f, 1.0f}},
2469 {1.0f, {0.0f, 0.0f, 1.0f, 1.0f}},
2471 static const struct
2473 unsigned int x, y;
2474 DWORD colour;
2476 test1[] =
2478 {80, 80, 0xff0000ff}, {240, 80, 0xff00a857}, {400, 80, 0xff00d728}, {560, 80, 0xff0000ff},
2479 {80, 240, 0xff006699}, {240, 240, 0xff29d600}, {400, 240, 0xff966900}, {560, 240, 0xff00a55a},
2480 {80, 400, 0xff0000ff}, {240, 400, 0xff006e91}, {400, 400, 0xff007d82}, {560, 400, 0xff0000ff},
2482 test2[] =
2484 { 40, 30, 0xff000df2}, {120, 30, 0xffffffff}, { 40, 60, 0xffffffff}, { 80, 60, 0xff00b04f},
2485 {120, 60, 0xff007689}, {200, 60, 0xffffffff}, { 40, 90, 0xffffffff}, {120, 90, 0xff47b800},
2486 {160, 90, 0xff00c13e}, {200, 90, 0xffffffff}, { 80, 120, 0xffffffff}, {120, 120, 0xff0000ff},
2487 {160, 120, 0xff6f9000}, {200, 120, 0xff00718e}, {240, 120, 0xffffffff}, {160, 150, 0xffffffff},
2488 {200, 150, 0xff00609f}, {240, 150, 0xffffffff}, {280, 150, 0xffffffff}, {320, 150, 0xffffffff},
2489 {240, 180, 0xffffffff}, {280, 180, 0xff4040ff}, {320, 180, 0xff40b788}, {380, 180, 0xffffffff},
2490 {200, 210, 0xffffffff}, {240, 210, 0xff4040ff}, {280, 210, 0xff4040ff}, {320, 210, 0xff76c940},
2491 {360, 210, 0xff40cc73}, {400, 210, 0xffffffff}, {200, 240, 0xffffffff}, {280, 240, 0xff4061de},
2492 {320, 240, 0xff9fa040}, {360, 240, 0xff404af5}, {440, 240, 0xffffffff}, {240, 270, 0xffffffff},
2493 {280, 270, 0xff40aa95}, {320, 270, 0xff4ef140}, {360, 270, 0xff4040ff}, {440, 270, 0xffffffff},
2494 {280, 300, 0xffffffff}, {320, 300, 0xff4093ac}, {360, 300, 0xff4040ff}, {400, 300, 0xff4040ff},
2495 {440, 300, 0xff404af5}, {480, 300, 0xff4045fa}, {520, 300, 0xff4040ff}, {280, 330, 0xffffffff},
2496 {360, 330, 0xffffffff}, {400, 330, 0xff4069d6}, {440, 330, 0xff40c579}, {480, 330, 0xff40e956},
2497 {520, 330, 0xff4072cd}, {400, 360, 0xff408ab4}, {440, 360, 0xff49f540}, {480, 360, 0xffb98640},
2498 {520, 360, 0xff40dc62}, {400, 390, 0xff405ee1}, {440, 390, 0xff40d56a}, {480, 390, 0xff62dd40},
2499 {520, 390, 0xff4059e6},
2502 if (!init_test_context(&ctx, d3d11))
2503 return;
2505 rt = ctx.rt;
2506 ID2D1RenderTarget_SetDpi(rt, 192.0f, 48.0f);
2507 ID2D1RenderTarget_SetAntialiasMode(rt, D2D1_ANTIALIAS_MODE_ALIASED);
2509 hr = ID2D1RenderTarget_CreateGradientStopCollection(rt, stops, ARRAY_SIZE(stops),
2510 D2D1_GAMMA_2_2, D2D1_EXTEND_MODE_CLAMP, &gradient);
2511 ok(SUCCEEDED(hr), "Failed to create stop collection, hr %#x.\n", hr);
2513 set_point(&gradient_properties.center, 160.0f, 480.0f);
2514 set_point(&gradient_properties.gradientOriginOffset, 40.0f, -120.0f);
2515 gradient_properties.radiusX = 160.0f;
2516 gradient_properties.radiusY = 480.0f;
2517 hr = ID2D1RenderTarget_CreateRadialGradientBrush(rt, &gradient_properties, NULL, gradient, &brush);
2518 ok(SUCCEEDED(hr), "Failed to create brush, hr %#x.\n", hr);
2520 f = ID2D1RadialGradientBrush_GetOpacity(brush);
2521 ok(f == 1.0f, "Got unexpected opacity %.8e.\n", f);
2522 set_matrix_identity(&matrix);
2523 ID2D1RadialGradientBrush_GetTransform(brush, &tmp_matrix);
2524 ok(!memcmp(&tmp_matrix, &matrix, sizeof(matrix)),
2525 "Got unexpected matrix {%.8e, %.8e, %.8e, %.8e, %.8e, %.8e}.\n",
2526 tmp_matrix._11, tmp_matrix._12, tmp_matrix._21,
2527 tmp_matrix._22, tmp_matrix._31, tmp_matrix._32);
2528 p = ID2D1RadialGradientBrush_GetCenter(brush);
2529 ok(compare_point(&p, 160.0f, 480.0f, 0), "Got unexpected center {%.8e, %.8e}.\n", p.x, p.y);
2530 p = ID2D1RadialGradientBrush_GetGradientOriginOffset(brush);
2531 ok(compare_point(&p, 40.0f, -120.0f, 0), "Got unexpected origin offset {%.8e, %.8e}.\n", p.x, p.y);
2532 f = ID2D1RadialGradientBrush_GetRadiusX(brush);
2533 ok(compare_float(f, 160.0f, 0), "Got unexpected x-radius %.8e.\n", f);
2534 f = ID2D1RadialGradientBrush_GetRadiusY(brush);
2535 ok(compare_float(f, 480.0f, 0), "Got unexpected y-radius %.8e.\n", f);
2536 ID2D1RadialGradientBrush_GetGradientStopCollection(brush, &tmp_gradient);
2537 ok(tmp_gradient == gradient, "Got unexpected gradient %p, expected %p.\n", tmp_gradient, gradient);
2538 ID2D1GradientStopCollection_Release(tmp_gradient);
2540 ID2D1RenderTarget_BeginDraw(rt);
2542 set_color(&colour, 1.0f, 1.0f, 1.0f, 1.0f);
2543 ID2D1RenderTarget_Clear(rt, &colour);
2545 set_rect(&r, 0.0f, 0.0f, 320.0f, 960.0f);
2546 ID2D1RenderTarget_FillRectangle(rt, &r, (ID2D1Brush *)brush);
2548 hr = ID2D1RenderTarget_EndDraw(rt, NULL, NULL);
2549 ok(SUCCEEDED(hr), "Failed to end draw, hr %#x.\n", hr);
2551 get_surface_readback(&ctx, &rb);
2552 for (i = 0; i < ARRAY_SIZE(test1); ++i)
2554 DWORD colour;
2556 colour = get_readback_colour(&rb, test1[i].x, test1[i].y);
2557 ok(compare_colour(colour, test1[i].colour, 1),
2558 "Got unexpected colour 0x%08x at position {%u, %u}.\n",
2559 colour, test1[i].x, test1[i].y);
2561 release_resource_readback(&rb);
2563 ID2D1RenderTarget_BeginDraw(rt);
2565 ID2D1RenderTarget_Clear(rt, &colour);
2567 set_matrix_identity(&matrix);
2568 skew_matrix(&matrix, 0.2146f, 1.575f);
2569 ID2D1RenderTarget_SetTransform(rt, &matrix);
2571 set_matrix_identity(&matrix);
2572 translate_matrix(&matrix, 0.0f, 240.0f);
2573 scale_matrix(&matrix, 0.25f, -0.25f);
2574 ID2D1RadialGradientBrush_SetTransform(brush, &matrix);
2576 set_rect(&r, 0.0f, 0.0f, 80.0f, 240.0f);
2577 ID2D1RenderTarget_FillRectangle(rt, &r, (ID2D1Brush *)brush);
2579 set_matrix_identity(&matrix);
2580 scale_matrix(&matrix, 0.5f, 2.0f);
2581 translate_matrix(&matrix, 320.0f, 240.0f);
2582 rotate_matrix(&matrix, M_PI / 4.0f);
2583 ID2D1RenderTarget_SetTransform(rt, &matrix);
2585 set_matrix_identity(&matrix);
2586 translate_matrix(&matrix, -75.0f, -50.0f);
2587 scale_matrix(&matrix, 0.15f, 0.5f);
2588 rotate_matrix(&matrix, -M_PI / 3.0f);
2589 ID2D1RadialGradientBrush_SetTransform(brush, &matrix);
2591 ID2D1RadialGradientBrush_SetOpacity(brush, 0.75f);
2592 set_rect(&r, -80.0f, -60.0f, 80.0f, 60.0f);
2593 ID2D1RenderTarget_FillRectangle(rt, &r, (ID2D1Brush *)brush);
2595 ID2D1RenderTarget_GetFactory(rt, &factory);
2597 set_rect(&r, -1.0f, -1.0f, 1.0f, 1.0f);
2598 hr = ID2D1Factory_CreateRectangleGeometry(factory, &r, &rectangle_geometry);
2599 ok(SUCCEEDED(hr), "Failed to create geometry, hr %#x.\n", hr);
2601 set_matrix_identity(&matrix);
2602 translate_matrix(&matrix, 228.5f, 714.0f);
2603 scale_matrix(&matrix, 40.0f, 120.0f);
2604 hr = ID2D1Factory_CreateTransformedGeometry(factory, (ID2D1Geometry *)rectangle_geometry,
2605 &matrix, &transformed_geometry);
2606 ok(SUCCEEDED(hr), "Failed to create geometry, hr %#x.\n", hr);
2607 ID2D1RectangleGeometry_Release(rectangle_geometry);
2609 set_matrix_identity(&matrix);
2610 ID2D1RenderTarget_SetTransform(rt, &matrix);
2611 ID2D1RadialGradientBrush_SetTransform(brush, &matrix);
2612 set_point(&p, 228.5f, 714.0f);
2613 ID2D1RadialGradientBrush_SetCenter(brush, p);
2614 ID2D1RadialGradientBrush_SetRadiusX(brush, -40.0f);
2615 ID2D1RadialGradientBrush_SetRadiusY(brush, 120.0f);
2616 set_point(&p, 20.0f, 30.0f);
2617 ID2D1RadialGradientBrush_SetGradientOriginOffset(brush, p);
2618 ID2D1RenderTarget_FillGeometry(rt, (ID2D1Geometry *)transformed_geometry, (ID2D1Brush *)brush, NULL);
2619 ID2D1TransformedGeometry_Release(transformed_geometry);
2621 ID2D1Factory_Release(factory);
2623 hr = ID2D1RenderTarget_EndDraw(rt, NULL, NULL);
2624 ok(SUCCEEDED(hr), "Failed to end draw, hr %#x.\n", hr);
2626 get_surface_readback(&ctx, &rb);
2627 for (i = 0; i < ARRAY_SIZE(test2); ++i)
2629 DWORD colour;
2631 colour = get_readback_colour(&rb, test2[i].x, test2[i].y);
2632 ok(compare_colour(colour, test2[i].colour, 1),
2633 "Got unexpected colour 0x%08x at position {%u, %u}.\n",
2634 colour, test2[i].x, test2[i].y);
2636 release_resource_readback(&rb);
2638 ID2D1RadialGradientBrush_Release(brush);
2639 refcount = ID2D1GradientStopCollection_Release(gradient);
2640 ok(!refcount, "Gradient has %u references left.\n", refcount);
2641 release_test_context(&ctx);
2644 static void fill_geometry_sink(ID2D1GeometrySink *sink, unsigned int hollow_count)
2646 D2D1_FIGURE_BEGIN begin;
2647 unsigned int idx = 0;
2648 D2D1_POINT_2F point;
2650 set_point(&point, 15.0f, 20.0f);
2651 begin = idx++ < hollow_count ? D2D1_FIGURE_BEGIN_HOLLOW : D2D1_FIGURE_BEGIN_FILLED;
2652 ID2D1GeometrySink_BeginFigure(sink, point, begin);
2653 line_to(sink, 55.0f, 20.0f);
2654 line_to(sink, 55.0f, 220.0f);
2655 line_to(sink, 25.0f, 220.0f);
2656 line_to(sink, 25.0f, 100.0f);
2657 line_to(sink, 75.0f, 100.0f);
2658 line_to(sink, 75.0f, 300.0f);
2659 line_to(sink, 5.0f, 300.0f);
2660 line_to(sink, 5.0f, 60.0f);
2661 line_to(sink, 45.0f, 60.0f);
2662 line_to(sink, 45.0f, 180.0f);
2663 line_to(sink, 35.0f, 180.0f);
2664 line_to(sink, 35.0f, 140.0f);
2665 line_to(sink, 65.0f, 140.0f);
2666 line_to(sink, 65.0f, 260.0f);
2667 line_to(sink, 15.0f, 260.0f);
2668 ID2D1GeometrySink_EndFigure(sink, D2D1_FIGURE_END_CLOSED);
2670 set_point(&point, 155.0f, 300.0f);
2671 begin = idx++ < hollow_count ? D2D1_FIGURE_BEGIN_HOLLOW : D2D1_FIGURE_BEGIN_FILLED;
2672 ID2D1GeometrySink_BeginFigure(sink, point, begin);
2673 line_to(sink, 155.0f, 160.0f);
2674 line_to(sink, 85.0f, 160.0f);
2675 line_to(sink, 85.0f, 300.0f);
2676 line_to(sink, 120.0f, 300.0f);
2677 line_to(sink, 120.0f, 20.0f);
2678 line_to(sink, 155.0f, 20.0f);
2679 line_to(sink, 155.0f, 160.0f);
2680 line_to(sink, 85.0f, 160.0f);
2681 line_to(sink, 85.0f, 20.0f);
2682 line_to(sink, 120.0f, 20.0f);
2683 line_to(sink, 120.0f, 300.0f);
2684 ID2D1GeometrySink_EndFigure(sink, D2D1_FIGURE_END_CLOSED);
2686 set_point(&point, 165.0f, 20.0f);
2687 begin = idx++ < hollow_count ? D2D1_FIGURE_BEGIN_HOLLOW : D2D1_FIGURE_BEGIN_FILLED;
2688 ID2D1GeometrySink_BeginFigure(sink, point, begin);
2689 line_to(sink, 165.0f, 300.0f);
2690 line_to(sink, 235.0f, 300.0f);
2691 line_to(sink, 235.0f, 20.0f);
2692 ID2D1GeometrySink_EndFigure(sink, D2D1_FIGURE_END_CLOSED);
2693 set_point(&point, 225.0f, 60.0f);
2694 begin = idx++ < hollow_count ? D2D1_FIGURE_BEGIN_HOLLOW : D2D1_FIGURE_BEGIN_FILLED;
2695 ID2D1GeometrySink_BeginFigure(sink, point, begin);
2696 line_to(sink, 225.0f, 260.0f);
2697 line_to(sink, 175.0f, 260.0f);
2698 line_to(sink, 175.0f, 60.0f);
2699 ID2D1GeometrySink_EndFigure(sink, D2D1_FIGURE_END_CLOSED);
2700 set_point(&point, 215.0f, 220.0f);
2701 begin = idx++ < hollow_count ? D2D1_FIGURE_BEGIN_HOLLOW : D2D1_FIGURE_BEGIN_FILLED;
2702 ID2D1GeometrySink_BeginFigure(sink, point, begin);
2703 line_to(sink, 185.0f, 220.0f);
2704 line_to(sink, 185.0f, 100.0f);
2705 line_to(sink, 215.0f, 100.0f);
2706 ID2D1GeometrySink_EndFigure(sink, D2D1_FIGURE_END_CLOSED);
2707 set_point(&point, 195.0f, 180.0f);
2708 begin = idx++ < hollow_count ? D2D1_FIGURE_BEGIN_HOLLOW : D2D1_FIGURE_BEGIN_FILLED;
2709 ID2D1GeometrySink_BeginFigure(sink, point, begin);
2710 line_to(sink, 205.0f, 180.0f);
2711 line_to(sink, 205.0f, 140.0f);
2712 line_to(sink, 195.0f, 140.0f);
2713 ID2D1GeometrySink_EndFigure(sink, D2D1_FIGURE_END_CLOSED);
2716 static void fill_geometry_sink_bezier(ID2D1GeometrySink *sink, unsigned int hollow_count)
2718 D2D1_FIGURE_BEGIN begin;
2719 unsigned int idx = 0;
2720 D2D1_POINT_2F point;
2722 set_point(&point, 5.0f, 160.0f);
2723 begin = idx++ < hollow_count ? D2D1_FIGURE_BEGIN_HOLLOW : D2D1_FIGURE_BEGIN_FILLED;
2724 ID2D1GeometrySink_BeginFigure(sink, point, begin);
2725 quadratic_to(sink, 40.0f, 160.0f, 40.0f, 20.0f);
2726 quadratic_to(sink, 40.0f, 160.0f, 75.0f, 160.0f);
2727 quadratic_to(sink, 40.0f, 160.0f, 40.0f, 300.0f);
2728 quadratic_to(sink, 40.0f, 160.0f, 5.0f, 160.0f);
2729 ID2D1GeometrySink_EndFigure(sink, D2D1_FIGURE_END_CLOSED);
2731 set_point(&point, 20.0f, 160.0f);
2732 begin = idx++ < hollow_count ? D2D1_FIGURE_BEGIN_HOLLOW : D2D1_FIGURE_BEGIN_FILLED;
2733 ID2D1GeometrySink_BeginFigure(sink, point, begin);
2734 quadratic_to(sink, 20.0f, 80.0f, 40.0f, 80.0f);
2735 quadratic_to(sink, 60.0f, 80.0f, 60.0f, 160.0f);
2736 quadratic_to(sink, 60.0f, 240.0f, 40.0f, 240.0f);
2737 quadratic_to(sink, 20.0f, 240.0f, 20.0f, 160.0f);
2738 ID2D1GeometrySink_EndFigure(sink, D2D1_FIGURE_END_CLOSED);
2740 set_point(&point, 5.0f, 612.0f);
2741 begin = idx++ < hollow_count ? D2D1_FIGURE_BEGIN_HOLLOW : D2D1_FIGURE_BEGIN_FILLED;
2742 ID2D1GeometrySink_BeginFigure(sink, point, begin);
2743 quadratic_to(sink, 40.0f, 612.0f, 40.0f, 752.0f);
2744 quadratic_to(sink, 40.0f, 612.0f, 75.0f, 612.0f);
2745 quadratic_to(sink, 40.0f, 612.0f, 40.0f, 472.0f);
2746 quadratic_to(sink, 40.0f, 612.0f, 5.0f, 612.0f);
2747 ID2D1GeometrySink_EndFigure(sink, D2D1_FIGURE_END_CLOSED);
2749 set_point(&point, 20.0f, 612.0f);
2750 begin = idx++ < hollow_count ? D2D1_FIGURE_BEGIN_HOLLOW : D2D1_FIGURE_BEGIN_FILLED;
2751 ID2D1GeometrySink_BeginFigure(sink, point, begin);
2752 quadratic_to(sink, 20.0f, 692.0f, 40.0f, 692.0f);
2753 quadratic_to(sink, 60.0f, 692.0f, 60.0f, 612.0f);
2754 quadratic_to(sink, 60.0f, 532.0f, 40.0f, 532.0f);
2755 quadratic_to(sink, 20.0f, 532.0f, 20.0f, 612.0f);
2756 ID2D1GeometrySink_EndFigure(sink, D2D1_FIGURE_END_CLOSED);
2759 static void test_path_geometry(BOOL d3d11)
2761 ID2D1TransformedGeometry *transformed_geometry;
2762 D2D1_MATRIX_3X2_F matrix, tmp_matrix;
2763 ID2D1GeometrySink *sink, *tmp_sink;
2764 struct geometry_sink simplify_sink;
2765 D2D1_POINT_2F point = {0.0f, 0.0f};
2766 struct d2d1_test_context ctx;
2767 ID2D1SolidColorBrush *brush;
2768 ID2D1PathGeometry *geometry;
2769 ID2D1Geometry *tmp_geometry;
2770 ID2D1RenderTarget *rt;
2771 ID2D1Factory *factory;
2772 BOOL match, contains;
2773 D2D1_COLOR_F color;
2774 D2D1_RECT_F rect;
2775 UINT32 count;
2776 HRESULT hr;
2778 static const struct geometry_segment expected_segments[] =
2780 /* Figure 0. */
2781 {SEGMENT_LINE, {{{ 55.0f, 20.0f}}}},
2782 {SEGMENT_LINE, {{{ 55.0f, 220.0f}}}},
2783 {SEGMENT_LINE, {{{ 25.0f, 220.0f}}}},
2784 {SEGMENT_LINE, {{{ 25.0f, 100.0f}}}},
2785 {SEGMENT_LINE, {{{ 75.0f, 100.0f}}}},
2786 {SEGMENT_LINE, {{{ 75.0f, 300.0f}}}},
2787 {SEGMENT_LINE, {{{ 5.0f, 300.0f}}}},
2788 {SEGMENT_LINE, {{{ 5.0f, 60.0f}}}},
2789 {SEGMENT_LINE, {{{ 45.0f, 60.0f}}}},
2790 {SEGMENT_LINE, {{{ 45.0f, 180.0f}}}},
2791 {SEGMENT_LINE, {{{ 35.0f, 180.0f}}}},
2792 {SEGMENT_LINE, {{{ 35.0f, 140.0f}}}},
2793 {SEGMENT_LINE, {{{ 65.0f, 140.0f}}}},
2794 {SEGMENT_LINE, {{{ 65.0f, 260.0f}}}},
2795 {SEGMENT_LINE, {{{ 15.0f, 260.0f}}}},
2796 /* Figure 1. */
2797 {SEGMENT_LINE, {{{155.0f, 160.0f}}}},
2798 {SEGMENT_LINE, {{{ 85.0f, 160.0f}}}},
2799 {SEGMENT_LINE, {{{ 85.0f, 300.0f}}}},
2800 {SEGMENT_LINE, {{{120.0f, 300.0f}}}},
2801 {SEGMENT_LINE, {{{120.0f, 20.0f}}}},
2802 {SEGMENT_LINE, {{{155.0f, 20.0f}}}},
2803 {SEGMENT_LINE, {{{155.0f, 160.0f}}}},
2804 {SEGMENT_LINE, {{{ 85.0f, 160.0f}}}},
2805 {SEGMENT_LINE, {{{ 85.0f, 20.0f}}}},
2806 {SEGMENT_LINE, {{{120.0f, 20.0f}}}},
2807 {SEGMENT_LINE, {{{120.0f, 300.0f}}}},
2808 /* Figure 2. */
2809 {SEGMENT_LINE, {{{165.0f, 300.0f}}}},
2810 {SEGMENT_LINE, {{{235.0f, 300.0f}}}},
2811 {SEGMENT_LINE, {{{235.0f, 20.0f}}}},
2812 /* Figure 3. */
2813 {SEGMENT_LINE, {{{225.0f, 260.0f}}}},
2814 {SEGMENT_LINE, {{{175.0f, 260.0f}}}},
2815 {SEGMENT_LINE, {{{175.0f, 60.0f}}}},
2816 /* Figure 4. */
2817 {SEGMENT_LINE, {{{185.0f, 220.0f}}}},
2818 {SEGMENT_LINE, {{{185.0f, 100.0f}}}},
2819 {SEGMENT_LINE, {{{215.0f, 100.0f}}}},
2820 /* Figure 5. */
2821 {SEGMENT_LINE, {{{205.0f, 180.0f}}}},
2822 {SEGMENT_LINE, {{{205.0f, 140.0f}}}},
2823 {SEGMENT_LINE, {{{195.0f, 140.0f}}}},
2824 /* Figure 6. */
2825 {SEGMENT_LINE, {{{135.0f, 620.0f}}}},
2826 {SEGMENT_LINE, {{{135.0f, 420.0f}}}},
2827 {SEGMENT_LINE, {{{105.0f, 420.0f}}}},
2828 {SEGMENT_LINE, {{{105.0f, 540.0f}}}},
2829 {SEGMENT_LINE, {{{155.0f, 540.0f}}}},
2830 {SEGMENT_LINE, {{{155.0f, 340.0f}}}},
2831 {SEGMENT_LINE, {{{ 85.0f, 340.0f}}}},
2832 {SEGMENT_LINE, {{{ 85.0f, 580.0f}}}},
2833 {SEGMENT_LINE, {{{125.0f, 580.0f}}}},
2834 {SEGMENT_LINE, {{{125.0f, 460.0f}}}},
2835 {SEGMENT_LINE, {{{115.0f, 460.0f}}}},
2836 {SEGMENT_LINE, {{{115.0f, 500.0f}}}},
2837 {SEGMENT_LINE, {{{145.0f, 500.0f}}}},
2838 {SEGMENT_LINE, {{{145.0f, 380.0f}}}},
2839 {SEGMENT_LINE, {{{ 95.0f, 380.0f}}}},
2840 /* Figure 7. */
2841 {SEGMENT_LINE, {{{235.0f, 480.0f}}}},
2842 {SEGMENT_LINE, {{{165.0f, 480.0f}}}},
2843 {SEGMENT_LINE, {{{165.0f, 340.0f}}}},
2844 {SEGMENT_LINE, {{{200.0f, 340.0f}}}},
2845 {SEGMENT_LINE, {{{200.0f, 620.0f}}}},
2846 {SEGMENT_LINE, {{{235.0f, 620.0f}}}},
2847 {SEGMENT_LINE, {{{235.0f, 480.0f}}}},
2848 {SEGMENT_LINE, {{{165.0f, 480.0f}}}},
2849 {SEGMENT_LINE, {{{165.0f, 620.0f}}}},
2850 {SEGMENT_LINE, {{{200.0f, 620.0f}}}},
2851 {SEGMENT_LINE, {{{200.0f, 340.0f}}}},
2852 /* Figure 8. */
2853 {SEGMENT_LINE, {{{245.0f, 340.0f}}}},
2854 {SEGMENT_LINE, {{{315.0f, 340.0f}}}},
2855 {SEGMENT_LINE, {{{315.0f, 620.0f}}}},
2856 /* Figure 9. */
2857 {SEGMENT_LINE, {{{305.0f, 380.0f}}}},
2858 {SEGMENT_LINE, {{{255.0f, 380.0f}}}},
2859 {SEGMENT_LINE, {{{255.0f, 580.0f}}}},
2860 /* Figure 10. */
2861 {SEGMENT_LINE, {{{265.0f, 420.0f}}}},
2862 {SEGMENT_LINE, {{{265.0f, 540.0f}}}},
2863 {SEGMENT_LINE, {{{295.0f, 540.0f}}}},
2864 /* Figure 11. */
2865 {SEGMENT_LINE, {{{285.0f, 460.0f}}}},
2866 {SEGMENT_LINE, {{{285.0f, 500.0f}}}},
2867 {SEGMENT_LINE, {{{275.0f, 500.0f}}}},
2868 /* Figure 12. */
2869 {SEGMENT_BEZIER, {{{2.83333340e+01f, 1.60000000e+02f},
2870 {4.00000000e+01f, 1.13333336e+02f},
2871 {4.00000000e+01f, 2.00000000e+01f}}}},
2872 {SEGMENT_BEZIER, {{{4.00000000e+01f, 1.13333336e+02f},
2873 {5.16666641e+01f, 1.60000000e+02f},
2874 {7.50000000e+01f, 1.60000000e+02f}}}},
2875 {SEGMENT_BEZIER, {{{5.16666641e+01f, 1.60000000e+02f},
2876 {4.00000000e+01f, 2.06666656e+02f},
2877 {4.00000000e+01f, 3.00000000e+02f}}}},
2878 {SEGMENT_BEZIER, {{{4.00000000e+01f, 2.06666656e+02f},
2879 {2.83333340e+01f, 1.60000000e+02f},
2880 {5.00000000e+00f, 1.60000000e+02f}}}},
2881 /* Figure 13. */
2882 {SEGMENT_BEZIER, {{{2.00000000e+01f, 1.06666664e+02f},
2883 {2.66666660e+01f, 8.00000000e+01f},
2884 {4.00000000e+01f, 8.00000000e+01f}}}},
2885 {SEGMENT_BEZIER, {{{5.33333321e+01f, 8.00000000e+01f},
2886 {6.00000000e+01f, 1.06666664e+02f},
2887 {6.00000000e+01f, 1.60000000e+02f}}}},
2888 {SEGMENT_BEZIER, {{{6.00000000e+01f, 2.13333328e+02f},
2889 {5.33333321e+01f, 2.40000000e+02f},
2890 {4.00000000e+01f, 2.40000000e+02f}}}},
2891 {SEGMENT_BEZIER, {{{2.66666660e+01f, 2.40000000e+02f},
2892 {2.00000000e+01f, 2.13333328e+02f},
2893 {2.00000000e+01f, 1.60000000e+02f}}}},
2894 /* Figure 14. */
2895 {SEGMENT_BEZIER, {{{2.83333340e+01f, 6.12000000e+02f},
2896 {4.00000000e+01f, 6.58666687e+02f},
2897 {4.00000000e+01f, 7.52000000e+02f}}}},
2898 {SEGMENT_BEZIER, {{{4.00000000e+01f, 6.58666687e+02f},
2899 {5.16666641e+01f, 6.12000000e+02f},
2900 {7.50000000e+01f, 6.12000000e+02f}}}},
2901 {SEGMENT_BEZIER, {{{5.16666641e+01f, 6.12000000e+02f},
2902 {4.00000000e+01f, 5.65333313e+02f},
2903 {4.00000000e+01f, 4.72000000e+02f}}}},
2904 {SEGMENT_BEZIER, {{{4.00000000e+01f, 5.65333313e+02f},
2905 {2.83333340e+01f, 6.12000000e+02f},
2906 {5.00000000e+00f, 6.12000000e+02f}}}},
2907 /* Figure 15. */
2908 {SEGMENT_BEZIER, {{{2.00000000e+01f, 6.65333313e+02f},
2909 {2.66666660e+01f, 6.92000000e+02f},
2910 {4.00000000e+01f, 6.92000000e+02f}}}},
2911 {SEGMENT_BEZIER, {{{5.33333321e+01f, 6.92000000e+02f},
2912 {6.00000000e+01f, 6.65333313e+02f},
2913 {6.00000000e+01f, 6.12000000e+02f}}}},
2914 {SEGMENT_BEZIER, {{{6.00000000e+01f, 5.58666687e+02f},
2915 {5.33333321e+01f, 5.32000000e+02f},
2916 {4.00000000e+01f, 5.32000000e+02f}}}},
2917 {SEGMENT_BEZIER, {{{2.66666660e+01f, 5.32000000e+02f},
2918 {2.00000000e+01f, 5.58666687e+02f},
2919 {2.00000000e+01f, 6.12000000e+02f}}}},
2920 /* Figure 16. */
2921 {SEGMENT_BEZIER, {{{1.91750427e+02f, 1.27275856e+02f},
2922 {2.08249573e+02f, 1.27275856e+02f},
2923 {2.24748734e+02f, 6.12792168e+01f}}}},
2924 {SEGMENT_BEZIER, {{{2.08249573e+02f, 1.27275856e+02f},
2925 {2.08249573e+02f, 1.93272476e+02f},
2926 {2.24748734e+02f, 2.59269104e+02f}}}},
2927 {SEGMENT_BEZIER, {{{2.08249573e+02f, 1.93272476e+02f},
2928 {1.91750427e+02f, 1.93272476e+02f},
2929 {1.75251266e+02f, 2.59269104e+02f}}}},
2930 {SEGMENT_BEZIER, {{{1.91750427e+02f, 1.93272476e+02f},
2931 {1.91750427e+02f, 1.27275856e+02f},
2932 {1.75251266e+02f, 6.12792168e+01f}}}},
2933 /* Figure 17. */
2934 {SEGMENT_BEZIER, {{{1.95285950e+02f, 6.59932632e+01f},
2935 {2.04714050e+02f, 6.59932632e+01f},
2936 {2.14142136e+02f, 1.03705627e+02f}}}},
2937 {SEGMENT_BEZIER, {{{2.23570221e+02f, 1.41417984e+02f},
2938 {2.23570221e+02f, 1.79130356e+02f},
2939 {2.14142136e+02f, 2.16842712e+02f}}}},
2940 {SEGMENT_BEZIER, {{{2.04714050e+02f, 2.54555069e+02f},
2941 {1.95285950e+02f, 2.54555069e+02f},
2942 {1.85857864e+02f, 2.16842712e+02f}}}},
2943 {SEGMENT_BEZIER, {{{1.76429779e+02f, 1.79130356e+02f},
2944 {1.76429779e+02f, 1.41417984e+02f},
2945 {1.85857864e+02f, 1.03705627e+02f}}}},
2946 /* Figure 18. */
2947 {SEGMENT_BEZIER, {{{1.11847351e+02f, 4.46888092e+02f},
2948 {1.11847351e+02f, 5.12884705e+02f},
2949 {9.53481979e+01f, 5.78881348e+02f}}}},
2950 {SEGMENT_BEZIER, {{{1.11847351e+02f, 5.12884705e+02f},
2951 {1.28346512e+02f, 5.12884705e+02f},
2952 {1.44845673e+02f, 5.78881348e+02f}}}},
2953 {SEGMENT_BEZIER, {{{1.28346512e+02f, 5.12884705e+02f},
2954 {1.28346512e+02f, 4.46888092e+02f},
2955 {1.44845673e+02f, 3.80891479e+02f}}}},
2956 {SEGMENT_BEZIER, {{{1.28346512e+02f, 4.46888092e+02f},
2957 {1.11847351e+02f, 4.46888092e+02f},
2958 {9.53481979e+01f, 3.80891479e+02f}}}},
2959 /* Figure 19. */
2960 {SEGMENT_BEZIER, {{{9.65267105e+01f, 4.61030243e+02f},
2961 {9.65267105e+01f, 4.98742584e+02f},
2962 {1.05954803e+02f, 5.36454956e+02f}}}},
2963 {SEGMENT_BEZIER, {{{1.15382889e+02f, 5.74167297e+02f},
2964 {1.24810982e+02f, 5.74167297e+02f},
2965 {1.34239075e+02f, 5.36454956e+02f}}}},
2966 {SEGMENT_BEZIER, {{{1.43667160e+02f, 4.98742584e+02f},
2967 {1.43667160e+02f, 4.61030243e+02f},
2968 {1.34239075e+02f, 4.23317871e+02f}}}},
2969 {SEGMENT_BEZIER, {{{1.24810982e+02f, 3.85605499e+02f},
2970 {1.15382889e+02f, 3.85605499e+02f},
2971 {1.05954803e+02f, 4.23317871e+02f}}}},
2972 /* Figure 20. */
2973 {SEGMENT_LINE, {{{ 40.0f, 20.0f}}}},
2974 {SEGMENT_LINE, {{{ 75.0f, 160.0f}}}},
2975 {SEGMENT_LINE, {{{ 40.0f, 300.0f}}}},
2976 {SEGMENT_LINE, {{{ 5.0f, 160.0f}}}},
2977 /* Figure 21. */
2978 {SEGMENT_LINE, {{{ 40.0f, 80.0f}}}},
2979 {SEGMENT_LINE, {{{ 60.0f, 160.0f}}}},
2980 {SEGMENT_LINE, {{{ 40.0f, 240.0f}}}},
2981 {SEGMENT_LINE, {{{ 20.0f, 160.0f}}}},
2982 /* Figure 22. */
2983 {SEGMENT_LINE, {{{ 40.0f, 752.0f}}}},
2984 {SEGMENT_LINE, {{{ 75.0f, 612.0f}}}},
2985 {SEGMENT_LINE, {{{ 40.0f, 472.0f}}}},
2986 {SEGMENT_LINE, {{{ 5.0f, 612.0f}}}},
2987 /* Figure 23. */
2988 {SEGMENT_LINE, {{{ 40.0f, 692.0f}}}},
2989 {SEGMENT_LINE, {{{ 60.0f, 612.0f}}}},
2990 {SEGMENT_LINE, {{{ 40.0f, 532.0f}}}},
2991 {SEGMENT_LINE, {{{ 20.0f, 612.0f}}}},
2992 /* Figure 24. */
2993 {SEGMENT_LINE, {{{2.03125019e+01f, 1.51250000e+02f}}}},
2994 {SEGMENT_LINE, {{{3.12500019e+01f, 1.25000008e+02f}}}, D2D1_PATH_SEGMENT_FORCE_ROUND_LINE_JOIN},
2995 {SEGMENT_LINE, {{{3.78125000e+01f, 8.12500076e+01f}}}, D2D1_PATH_SEGMENT_FORCE_ROUND_LINE_JOIN},
2996 {SEGMENT_LINE, {{{4.00000000e+01f, 2.00000000e+01f}}}, D2D1_PATH_SEGMENT_FORCE_ROUND_LINE_JOIN},
2997 {SEGMENT_LINE, {{{4.21875000e+01f, 8.12500076e+01f}}}},
2998 {SEGMENT_LINE, {{{4.87500000e+01f, 1.25000008e+02f}}}, D2D1_PATH_SEGMENT_FORCE_ROUND_LINE_JOIN},
2999 {SEGMENT_LINE, {{{5.96875000e+01f, 1.51250000e+02f}}}, D2D1_PATH_SEGMENT_FORCE_ROUND_LINE_JOIN},
3000 {SEGMENT_LINE, {{{7.50000000e+01f, 1.60000000e+02f}}}, D2D1_PATH_SEGMENT_FORCE_ROUND_LINE_JOIN},
3001 {SEGMENT_LINE, {{{5.96875000e+01f, 1.68750000e+02f}}}},
3002 {SEGMENT_LINE, {{{4.87500000e+01f, 1.95000000e+02f}}}, D2D1_PATH_SEGMENT_FORCE_ROUND_LINE_JOIN},
3003 {SEGMENT_LINE, {{{4.21875000e+01f, 2.38750000e+02f}}}, D2D1_PATH_SEGMENT_FORCE_ROUND_LINE_JOIN},
3004 {SEGMENT_LINE, {{{4.00000000e+01f, 3.00000000e+02f}}}, D2D1_PATH_SEGMENT_FORCE_ROUND_LINE_JOIN},
3005 {SEGMENT_LINE, {{{3.78125000e+01f, 2.38750000e+02f}}}},
3006 {SEGMENT_LINE, {{{3.12500019e+01f, 1.95000000e+02f}}}, D2D1_PATH_SEGMENT_FORCE_ROUND_LINE_JOIN},
3007 {SEGMENT_LINE, {{{2.03125019e+01f, 1.68750000e+02f}}}, D2D1_PATH_SEGMENT_FORCE_ROUND_LINE_JOIN},
3008 {SEGMENT_LINE, {{{5.00000000e+00f, 1.60000000e+02f}}}, D2D1_PATH_SEGMENT_FORCE_ROUND_LINE_JOIN},
3009 /* Figure 25. */
3010 {SEGMENT_LINE, {{{2.50000000e+01f, 1.00000000e+02f}}}},
3011 {SEGMENT_LINE, {{{4.00000000e+01f, 8.00000000e+01f}}}, D2D1_PATH_SEGMENT_FORCE_ROUND_LINE_JOIN},
3012 {SEGMENT_LINE, {{{5.50000000e+01f, 1.00000000e+02f}}}},
3013 {SEGMENT_LINE, {{{6.00000000e+01f, 1.60000000e+02f}}}, D2D1_PATH_SEGMENT_FORCE_ROUND_LINE_JOIN},
3014 {SEGMENT_LINE, {{{5.50000000e+01f, 2.20000000e+02f}}}},
3015 {SEGMENT_LINE, {{{4.00000000e+01f, 2.40000000e+02f}}}, D2D1_PATH_SEGMENT_FORCE_ROUND_LINE_JOIN},
3016 {SEGMENT_LINE, {{{2.50000000e+01f, 2.20000000e+02f}}}},
3017 {SEGMENT_LINE, {{{2.00000000e+01f, 1.60000000e+02f}}}, D2D1_PATH_SEGMENT_FORCE_ROUND_LINE_JOIN},
3018 /* Figure 26. */
3019 {SEGMENT_LINE, {{{2.03125019e+01f, 6.20750000e+02f}}}},
3020 {SEGMENT_LINE, {{{3.12500019e+01f, 6.47000000e+02f}}}, D2D1_PATH_SEGMENT_FORCE_ROUND_LINE_JOIN},
3021 {SEGMENT_LINE, {{{3.78125000e+01f, 6.90750000e+02f}}}, D2D1_PATH_SEGMENT_FORCE_ROUND_LINE_JOIN},
3022 {SEGMENT_LINE, {{{4.00000000e+01f, 7.52000000e+02f}}}, D2D1_PATH_SEGMENT_FORCE_ROUND_LINE_JOIN},
3023 {SEGMENT_LINE, {{{4.21875000e+01f, 6.90750000e+02f}}}},
3024 {SEGMENT_LINE, {{{4.87500000e+01f, 6.47000000e+02f}}}, D2D1_PATH_SEGMENT_FORCE_ROUND_LINE_JOIN},
3025 {SEGMENT_LINE, {{{5.96875000e+01f, 6.20750000e+02f}}}, D2D1_PATH_SEGMENT_FORCE_ROUND_LINE_JOIN},
3026 {SEGMENT_LINE, {{{7.50000000e+01f, 6.12000000e+02f}}}, D2D1_PATH_SEGMENT_FORCE_ROUND_LINE_JOIN},
3027 {SEGMENT_LINE, {{{5.96875000e+01f, 6.03250000e+02f}}}},
3028 {SEGMENT_LINE, {{{4.87500000e+01f, 5.77000000e+02f}}}, D2D1_PATH_SEGMENT_FORCE_ROUND_LINE_JOIN},
3029 {SEGMENT_LINE, {{{4.21875000e+01f, 5.33250000e+02f}}}, D2D1_PATH_SEGMENT_FORCE_ROUND_LINE_JOIN},
3030 {SEGMENT_LINE, {{{4.00000000e+01f, 4.72000000e+02f}}}, D2D1_PATH_SEGMENT_FORCE_ROUND_LINE_JOIN},
3031 {SEGMENT_LINE, {{{3.78125000e+01f, 5.33250000e+02f}}}},
3032 {SEGMENT_LINE, {{{3.12500019e+01f, 5.77000000e+02f}}}, D2D1_PATH_SEGMENT_FORCE_ROUND_LINE_JOIN},
3033 {SEGMENT_LINE, {{{2.03125019e+01f, 6.03250000e+02f}}}, D2D1_PATH_SEGMENT_FORCE_ROUND_LINE_JOIN},
3034 {SEGMENT_LINE, {{{5.00000000e+00f, 6.12000000e+02f}}}, D2D1_PATH_SEGMENT_FORCE_ROUND_LINE_JOIN},
3035 /* Figure 27. */
3036 {SEGMENT_LINE, {{{2.50000000e+01f, 6.72000000e+02f}}}},
3037 {SEGMENT_LINE, {{{4.00000000e+01f, 6.92000000e+02f}}}, D2D1_PATH_SEGMENT_FORCE_ROUND_LINE_JOIN},
3038 {SEGMENT_LINE, {{{5.50000000e+01f, 6.72000000e+02f}}}},
3039 {SEGMENT_LINE, {{{6.00000000e+01f, 6.12000000e+02f}}}, D2D1_PATH_SEGMENT_FORCE_ROUND_LINE_JOIN},
3040 {SEGMENT_LINE, {{{5.50000000e+01f, 5.52000000e+02f}}}},
3041 {SEGMENT_LINE, {{{4.00000000e+01f, 5.32000000e+02f}}}, D2D1_PATH_SEGMENT_FORCE_ROUND_LINE_JOIN},
3042 {SEGMENT_LINE, {{{2.50000000e+01f, 5.52000000e+02f}}}},
3043 {SEGMENT_LINE, {{{2.00000000e+01f, 6.12000000e+02f}}}, D2D1_PATH_SEGMENT_FORCE_ROUND_LINE_JOIN},
3044 /* Figure 28. */
3045 {SEGMENT_LINE, {{{ 75.0f, 300.0f}}}},
3046 {SEGMENT_LINE, {{{ 5.0f, 300.0f}}}},
3048 static const struct expected_geometry_figure expected_figures[] =
3050 /* 0 */
3051 {D2D1_FIGURE_BEGIN_FILLED, D2D1_FIGURE_END_CLOSED, { 15.0f, 20.0f}, 15, &expected_segments[0]},
3052 {D2D1_FIGURE_BEGIN_FILLED, D2D1_FIGURE_END_CLOSED, {155.0f, 300.0f}, 11, &expected_segments[15]},
3053 {D2D1_FIGURE_BEGIN_FILLED, D2D1_FIGURE_END_CLOSED, {165.0f, 20.0f}, 3, &expected_segments[26]},
3054 {D2D1_FIGURE_BEGIN_FILLED, D2D1_FIGURE_END_CLOSED, {225.0f, 60.0f}, 3, &expected_segments[29]},
3055 {D2D1_FIGURE_BEGIN_FILLED, D2D1_FIGURE_END_CLOSED, {215.0f, 220.0f}, 3, &expected_segments[32]},
3056 {D2D1_FIGURE_BEGIN_FILLED, D2D1_FIGURE_END_CLOSED, {195.0f, 180.0f}, 3, &expected_segments[35]},
3057 /* 6 */
3058 {D2D1_FIGURE_BEGIN_FILLED, D2D1_FIGURE_END_CLOSED, { 95.0f, 620.0f}, 15, &expected_segments[38]},
3059 {D2D1_FIGURE_BEGIN_FILLED, D2D1_FIGURE_END_CLOSED, {235.0f, 340.0f}, 11, &expected_segments[53]},
3060 {D2D1_FIGURE_BEGIN_FILLED, D2D1_FIGURE_END_CLOSED, {245.0f, 620.0f}, 3, &expected_segments[64]},
3061 {D2D1_FIGURE_BEGIN_FILLED, D2D1_FIGURE_END_CLOSED, {305.0f, 580.0f}, 3, &expected_segments[67]},
3062 {D2D1_FIGURE_BEGIN_FILLED, D2D1_FIGURE_END_CLOSED, {295.0f, 420.0f}, 3, &expected_segments[70]},
3063 {D2D1_FIGURE_BEGIN_FILLED, D2D1_FIGURE_END_CLOSED, {275.0f, 460.0f}, 3, &expected_segments[73]},
3064 /* 12 */
3065 {D2D1_FIGURE_BEGIN_FILLED, D2D1_FIGURE_END_CLOSED, { 5.0f, 160.0f}, 4, &expected_segments[76]},
3066 {D2D1_FIGURE_BEGIN_FILLED, D2D1_FIGURE_END_CLOSED, { 20.0f, 160.0f}, 4, &expected_segments[80]},
3067 {D2D1_FIGURE_BEGIN_FILLED, D2D1_FIGURE_END_CLOSED, { 5.0f, 612.0f}, 4, &expected_segments[84]},
3068 {D2D1_FIGURE_BEGIN_FILLED, D2D1_FIGURE_END_CLOSED, { 20.0f, 612.0f}, 4, &expected_segments[88]},
3069 /* 16 */
3070 {D2D1_FIGURE_BEGIN_FILLED, D2D1_FIGURE_END_CLOSED,
3071 {1.75251266e+02f, 6.12792168e+01f}, 4, &expected_segments[92]},
3072 {D2D1_FIGURE_BEGIN_FILLED, D2D1_FIGURE_END_CLOSED,
3073 {1.85857864e+02f, 1.03705627e+02f}, 4, &expected_segments[96]},
3074 {D2D1_FIGURE_BEGIN_FILLED, D2D1_FIGURE_END_CLOSED,
3075 {9.53481979e+01f, 3.80891479e+02f}, 4, &expected_segments[100]},
3076 {D2D1_FIGURE_BEGIN_FILLED, D2D1_FIGURE_END_CLOSED,
3077 {1.05954803e+02f, 4.23317871e+02f}, 4, &expected_segments[104]},
3078 /* 20 */
3079 {D2D1_FIGURE_BEGIN_FILLED, D2D1_FIGURE_END_CLOSED, { 5.0f, 160.0f}, 4, &expected_segments[108]},
3080 {D2D1_FIGURE_BEGIN_FILLED, D2D1_FIGURE_END_CLOSED, { 20.0f, 160.0f}, 4, &expected_segments[112]},
3081 {D2D1_FIGURE_BEGIN_FILLED, D2D1_FIGURE_END_CLOSED, { 5.0f, 612.0f}, 4, &expected_segments[116]},
3082 {D2D1_FIGURE_BEGIN_FILLED, D2D1_FIGURE_END_CLOSED, { 20.0f, 612.0f}, 4, &expected_segments[120]},
3083 /* 24 */
3084 {D2D1_FIGURE_BEGIN_FILLED, D2D1_FIGURE_END_CLOSED, { 5.0f, 160.0f}, 16, &expected_segments[124]},
3085 {D2D1_FIGURE_BEGIN_FILLED, D2D1_FIGURE_END_CLOSED, { 20.0f, 160.0f}, 8, &expected_segments[140]},
3086 {D2D1_FIGURE_BEGIN_FILLED, D2D1_FIGURE_END_CLOSED, { 5.0f, 612.0f}, 16, &expected_segments[148]},
3087 {D2D1_FIGURE_BEGIN_FILLED, D2D1_FIGURE_END_CLOSED, { 20.0f, 612.0f}, 8, &expected_segments[164]},
3088 /* 28 */
3089 {D2D1_FIGURE_BEGIN_HOLLOW, D2D1_FIGURE_END_OPEN, { 40.0f, 20.0f}, 2, &expected_segments[172]},
3092 if (!init_test_context(&ctx, d3d11))
3093 return;
3095 rt = ctx.rt;
3096 ID2D1RenderTarget_GetFactory(rt, &factory);
3098 ID2D1RenderTarget_SetDpi(rt, 192.0f, 48.0f);
3099 ID2D1RenderTarget_SetAntialiasMode(rt, D2D1_ANTIALIAS_MODE_ALIASED);
3100 set_color(&color, 0.890f, 0.851f, 0.600f, 1.0f);
3101 hr = ID2D1RenderTarget_CreateSolidColorBrush(rt, &color, NULL, &brush);
3102 ok(SUCCEEDED(hr), "Failed to create brush, hr %#x.\n", hr);
3104 /* Close() when closed. */
3105 hr = ID2D1Factory_CreatePathGeometry(factory, &geometry);
3106 ok(SUCCEEDED(hr), "Failed to create path geometry, hr %#x.\n", hr);
3107 hr = ID2D1PathGeometry_GetFigureCount(geometry, &count);
3108 ok(hr == D2DERR_WRONG_STATE, "Got unexpected hr %#x.\n", hr);
3109 hr = ID2D1PathGeometry_GetSegmentCount(geometry, &count);
3110 ok(hr == D2DERR_WRONG_STATE, "Got unexpected hr %#x.\n", hr);
3111 hr = ID2D1PathGeometry_Open(geometry, &sink);
3112 ok(SUCCEEDED(hr), "Failed to open geometry sink, hr %#x.\n", hr);
3113 hr = ID2D1PathGeometry_GetFigureCount(geometry, &count);
3114 ok(hr == D2DERR_WRONG_STATE, "Got unexpected hr %#x.\n", hr);
3115 hr = ID2D1PathGeometry_GetSegmentCount(geometry, &count);
3116 ok(hr == D2DERR_WRONG_STATE, "Got unexpected hr %#x.\n", hr);
3117 hr = ID2D1GeometrySink_Close(sink);
3118 ok(SUCCEEDED(hr), "Failed to close geometry sink, hr %#x.\n", hr);
3119 hr = ID2D1PathGeometry_GetFigureCount(geometry, &count);
3120 ok(SUCCEEDED(hr), "Failed to get figure count, hr %#x.\n", hr);
3121 ok(!count, "Got unexpected figure count %u.\n", count);
3122 hr = ID2D1PathGeometry_GetSegmentCount(geometry, &count);
3123 ok(SUCCEEDED(hr), "Failed to get segment count, hr %#x.\n", hr);
3124 ok(!count, "Got unexpected segment count %u.\n", count);
3125 hr = ID2D1GeometrySink_Close(sink);
3126 ok(hr == D2DERR_WRONG_STATE, "Got unexpected hr %#x.\n", hr);
3127 ID2D1GeometrySink_Release(sink);
3128 hr = ID2D1PathGeometry_GetFigureCount(geometry, &count);
3129 ok(SUCCEEDED(hr), "Failed to get figure count, hr %#x.\n", hr);
3130 ok(!count, "Got unexpected figure count %u.\n", count);
3131 hr = ID2D1PathGeometry_GetSegmentCount(geometry, &count);
3132 ok(SUCCEEDED(hr), "Failed to get segment count, hr %#x.\n", hr);
3133 ok(!count, "Got unexpected segment count %u.\n", count);
3134 ID2D1PathGeometry_Release(geometry);
3136 /* Open() when closed. */
3137 hr = ID2D1Factory_CreatePathGeometry(factory, &geometry);
3138 ok(SUCCEEDED(hr), "Failed to create path geometry, hr %#x.\n", hr);
3139 hr = ID2D1PathGeometry_Open(geometry, &sink);
3140 ok(SUCCEEDED(hr), "Failed to open geometry sink, hr %#x.\n", hr);
3141 hr = ID2D1GeometrySink_Close(sink);
3142 ok(SUCCEEDED(hr), "Failed to close geometry sink, hr %#x.\n", hr);
3143 ID2D1GeometrySink_Release(sink);
3144 hr = ID2D1PathGeometry_Open(geometry, &sink);
3145 ok(hr == D2DERR_WRONG_STATE, "Got unexpected hr %#x.\n", hr);
3146 hr = ID2D1PathGeometry_GetFigureCount(geometry, &count);
3147 ok(SUCCEEDED(hr), "Failed to get figure count, hr %#x.\n", hr);
3148 ok(!count, "Got unexpected figure count %u.\n", count);
3149 hr = ID2D1PathGeometry_GetSegmentCount(geometry, &count);
3150 ok(SUCCEEDED(hr), "Failed to get segment count, hr %#x.\n", hr);
3151 ok(!count, "Got unexpected segment count %u.\n", count);
3152 ID2D1PathGeometry_Release(geometry);
3154 /* Open() when open. */
3155 hr = ID2D1Factory_CreatePathGeometry(factory, &geometry);
3156 ok(SUCCEEDED(hr), "Failed to create path geometry, hr %#x.\n", hr);
3157 hr = ID2D1PathGeometry_Open(geometry, &sink);
3158 ok(SUCCEEDED(hr), "Failed to open geometry sink, hr %#x.\n", hr);
3159 hr = ID2D1PathGeometry_Open(geometry, &tmp_sink);
3160 ok(hr == D2DERR_WRONG_STATE, "Got unexpected hr %#x.\n", hr);
3161 hr = ID2D1GeometrySink_Close(sink);
3162 ok(SUCCEEDED(hr), "Failed to close geometry sink, hr %#x.\n", hr);
3163 ID2D1GeometrySink_Release(sink);
3164 hr = ID2D1PathGeometry_GetFigureCount(geometry, &count);
3165 ok(SUCCEEDED(hr), "Failed to get figure count, hr %#x.\n", hr);
3166 ok(!count, "Got unexpected figure count %u.\n", count);
3167 hr = ID2D1PathGeometry_GetSegmentCount(geometry, &count);
3168 ok(SUCCEEDED(hr), "Failed to get segment count, hr %#x.\n", hr);
3169 ok(!count, "Got unexpected segment count %u.\n", count);
3170 ID2D1PathGeometry_Release(geometry);
3172 /* BeginFigure() without EndFigure(). */
3173 hr = ID2D1Factory_CreatePathGeometry(factory, &geometry);
3174 ok(SUCCEEDED(hr), "Failed to create path geometry, hr %#x.\n", hr);
3175 hr = ID2D1PathGeometry_Open(geometry, &sink);
3176 ok(SUCCEEDED(hr), "Failed to open geometry sink, hr %#x.\n", hr);
3177 ID2D1GeometrySink_BeginFigure(sink, point, D2D1_FIGURE_BEGIN_FILLED);
3178 hr = ID2D1GeometrySink_Close(sink);
3179 ok(hr == D2DERR_WRONG_STATE, "Got unexpected hr %#x.\n", hr);
3180 ID2D1GeometrySink_EndFigure(sink, D2D1_FIGURE_END_CLOSED);
3181 hr = ID2D1GeometrySink_Close(sink);
3182 ok(hr == D2DERR_WRONG_STATE, "Got unexpected hr %#x.\n", hr);
3183 ID2D1GeometrySink_Release(sink);
3184 hr = ID2D1PathGeometry_GetFigureCount(geometry, &count);
3185 ok(hr == D2DERR_WRONG_STATE, "Got unexpected hr %#x.\n", hr);
3186 hr = ID2D1PathGeometry_GetSegmentCount(geometry, &count);
3187 ok(hr == D2DERR_WRONG_STATE, "Got unexpected hr %#x.\n", hr);
3188 ID2D1PathGeometry_Release(geometry);
3190 /* EndFigure() without BeginFigure(). */
3191 hr = ID2D1Factory_CreatePathGeometry(factory, &geometry);
3192 ok(SUCCEEDED(hr), "Failed to create path geometry, hr %#x.\n", hr);
3193 hr = ID2D1PathGeometry_Open(geometry, &sink);
3194 ok(SUCCEEDED(hr), "Failed to open geometry sink, hr %#x.\n", hr);
3195 ID2D1GeometrySink_EndFigure(sink, D2D1_FIGURE_END_CLOSED);
3196 hr = ID2D1GeometrySink_Close(sink);
3197 ok(hr == D2DERR_WRONG_STATE, "Got unexpected hr %#x.\n", hr);
3198 ID2D1GeometrySink_Release(sink);
3199 hr = ID2D1PathGeometry_GetFigureCount(geometry, &count);
3200 ok(hr == D2DERR_WRONG_STATE, "Got unexpected hr %#x.\n", hr);
3201 hr = ID2D1PathGeometry_GetSegmentCount(geometry, &count);
3202 ok(hr == D2DERR_WRONG_STATE, "Got unexpected hr %#x.\n", hr);
3203 ID2D1PathGeometry_Release(geometry);
3205 /* BeginFigure()/EndFigure() mismatch. */
3206 hr = ID2D1Factory_CreatePathGeometry(factory, &geometry);
3207 ok(SUCCEEDED(hr), "Failed to create path geometry, hr %#x.\n", hr);
3208 hr = ID2D1PathGeometry_Open(geometry, &sink);
3209 ok(SUCCEEDED(hr), "Failed to open geometry sink, hr %#x.\n", hr);
3210 ID2D1GeometrySink_BeginFigure(sink, point, D2D1_FIGURE_BEGIN_FILLED);
3211 ID2D1GeometrySink_BeginFigure(sink, point, D2D1_FIGURE_BEGIN_FILLED);
3212 ID2D1GeometrySink_EndFigure(sink, D2D1_FIGURE_END_CLOSED);
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_EndFigure(sink, D2D1_FIGURE_END_CLOSED);
3217 hr = ID2D1GeometrySink_Close(sink);
3218 ok(hr == D2DERR_WRONG_STATE, "Got unexpected hr %#x.\n", hr);
3219 ID2D1GeometrySink_Release(sink);
3220 ID2D1PathGeometry_Release(geometry);
3222 /* AddLine() outside BeginFigure()/EndFigure(). */
3223 hr = ID2D1Factory_CreatePathGeometry(factory, &geometry);
3224 ok(SUCCEEDED(hr), "Failed to create path geometry, hr %#x.\n", hr);
3225 hr = ID2D1PathGeometry_Open(geometry, &sink);
3226 ok(SUCCEEDED(hr), "Failed to open geometry sink, hr %#x.\n", hr);
3227 ID2D1GeometrySink_AddLine(sink, point);
3228 hr = ID2D1GeometrySink_Close(sink);
3229 ok(hr == D2DERR_WRONG_STATE, "Got unexpected hr %#x.\n", hr);
3230 ID2D1GeometrySink_AddLine(sink, point);
3231 ID2D1GeometrySink_Release(sink);
3232 hr = ID2D1PathGeometry_GetFigureCount(geometry, &count);
3233 ok(hr == D2DERR_WRONG_STATE, "Got unexpected hr %#x.\n", hr);
3234 hr = ID2D1PathGeometry_GetSegmentCount(geometry, &count);
3235 ok(hr == D2DERR_WRONG_STATE, "Got unexpected hr %#x.\n", hr);
3236 ID2D1PathGeometry_Release(geometry);
3238 /* Empty figure. */
3239 hr = ID2D1Factory_CreatePathGeometry(factory, &geometry);
3240 ok(SUCCEEDED(hr), "Failed to create path geometry, hr %#x.\n", hr);
3241 hr = ID2D1PathGeometry_Open(geometry, &sink);
3242 ok(SUCCEEDED(hr), "Failed to open geometry sink, hr %#x.\n", hr);
3243 set_point(&point, 123.0f, 456.0f);
3244 ID2D1GeometrySink_BeginFigure(sink, point, D2D1_FIGURE_BEGIN_FILLED);
3245 ID2D1GeometrySink_EndFigure(sink, D2D1_FIGURE_END_CLOSED);
3246 hr = ID2D1GeometrySink_Close(sink);
3247 ok(SUCCEEDED(hr), "Failed to close geometry sink, hr %#x.\n", hr);
3248 ID2D1GeometrySink_Release(sink);
3249 hr = ID2D1PathGeometry_GetFigureCount(geometry, &count);
3250 ok(SUCCEEDED(hr), "Failed to get figure count, hr %#x.\n", hr);
3251 ok(count == 1, "Got unexpected figure count %u.\n", count);
3252 hr = ID2D1PathGeometry_GetSegmentCount(geometry, &count);
3253 ok(SUCCEEDED(hr), "Failed to get segment count, hr %#x.\n", hr);
3254 ok(count == 1, "Got unexpected segment count %u.\n", count);
3256 set_rect(&rect, 0.0f, 0.0f, 0.0f, 0.0f);
3257 hr = ID2D1PathGeometry_GetBounds(geometry, NULL, &rect);
3258 ok(SUCCEEDED(hr), "Failed to get geometry bounds, hr %#x.\n", hr);
3259 match = compare_rect(&rect, 123.0f, 456.0f, 123.0f, 456.0f, 0);
3260 ok(match, "Got unexpected rectangle {%.8e, %.8e, %.8e, %.8e}.\n",
3261 rect.left, rect.top, rect.right, rect.bottom);
3263 set_matrix_identity(&matrix);
3264 translate_matrix(&matrix, 80.0f, 640.0f);
3265 scale_matrix(&matrix, 2.0f, 0.5f);
3266 hr = ID2D1PathGeometry_GetBounds(geometry, &matrix, &rect);
3267 ok(SUCCEEDED(hr), "Failed to get geometry bounds, hr %#x.\n", hr);
3268 match = compare_rect(&rect, 326.0f, 868.0f, 326.0f, 868.0f, 0);
3269 ok(match, "Got unexpected rectangle {%.8e, %.8e, %.8e, %.8e}.\n",
3270 rect.left, rect.top, rect.right, rect.bottom);
3272 ID2D1PathGeometry_Release(geometry);
3274 /* Close right after Open(). */
3275 hr = ID2D1Factory_CreatePathGeometry(factory, &geometry);
3276 ok(SUCCEEDED(hr), "Failed to create path geometry, hr %#x.\n", hr);
3278 /* Not open yet. */
3279 set_rect(&rect, 1.0f, 2.0f, 3.0f, 4.0f);
3280 hr = ID2D1PathGeometry_GetBounds(geometry, NULL, &rect);
3281 ok(hr == D2DERR_WRONG_STATE, "Unexpected hr %#x.\n", hr);
3282 match = compare_rect(&rect, 1.0f, 2.0f, 3.0f, 4.0f, 0);
3283 ok(match, "Got unexpected rectangle {%.8e, %.8e, %.8e, %.8e}.\n",
3284 rect.left, rect.top, rect.right, rect.bottom);
3286 hr = ID2D1PathGeometry_Open(geometry, &sink);
3287 ok(SUCCEEDED(hr), "Failed to open geometry sink, hr %#x.\n", hr);
3289 /* Open, not closed. */
3290 set_rect(&rect, 1.0f, 2.0f, 3.0f, 4.0f);
3291 hr = ID2D1PathGeometry_GetBounds(geometry, NULL, &rect);
3292 ok(hr == D2DERR_WRONG_STATE, "Unexpected hr %#x.\n", hr);
3293 match = compare_rect(&rect, 1.0f, 2.0f, 3.0f, 4.0f, 0);
3294 ok(match, "Got unexpected rectangle {%.8e, %.8e, %.8e, %.8e}.\n",
3295 rect.left, rect.top, rect.right, rect.bottom);
3297 hr = ID2D1GeometrySink_Close(sink);
3298 ok(SUCCEEDED(hr), "Failed to close geometry sink, hr %#x.\n", hr);
3299 ID2D1GeometrySink_Release(sink);
3300 hr = ID2D1PathGeometry_GetFigureCount(geometry, &count);
3301 ok(SUCCEEDED(hr), "Failed to get figure count, hr %#x.\n", hr);
3302 ok(count == 0, "Got unexpected figure count %u.\n", count);
3303 hr = ID2D1PathGeometry_GetSegmentCount(geometry, &count);
3304 ok(SUCCEEDED(hr), "Failed to get segment count, hr %#x.\n", hr);
3305 ok(count == 0, "Got unexpected segment count %u.\n", count);
3307 set_rect(&rect, 0.0f, 0.0f, 0.0f, 0.0f);
3308 hr = ID2D1PathGeometry_GetBounds(geometry, NULL, &rect);
3309 ok(SUCCEEDED(hr), "Failed to get geometry bounds, hr %#x.\n", hr);
3310 ok(rect.left > rect.right && rect.top > rect.bottom,
3311 "Got unexpected rectangle {%.8e, %.8e, %.8e, %.8e}.\n", rect.left, rect.top, rect.right, rect.bottom);
3313 set_matrix_identity(&matrix);
3314 translate_matrix(&matrix, 10.0f, 20.0f);
3315 scale_matrix(&matrix, 10.0f, 20.0f);
3316 set_rect(&rect, 0.0f, 0.0f, 0.0f, 0.0f);
3317 hr = ID2D1PathGeometry_GetBounds(geometry, &matrix, &rect);
3318 ok(SUCCEEDED(hr), "Failed to get geometry bounds, hr %#x.\n", hr);
3319 ok(rect.left > rect.right && rect.top > rect.bottom,
3320 "Got unexpected rectangle {%.8e, %.8e, %.8e, %.8e}.\n", rect.left, rect.top, rect.right, rect.bottom);
3322 ID2D1PathGeometry_Release(geometry);
3324 /* GetBounds() with bezier segments. */
3325 hr = ID2D1Factory_CreatePathGeometry(factory, &geometry);
3326 ok(SUCCEEDED(hr), "Failed to create path geometry, hr %#x.\n", hr);
3327 hr = ID2D1PathGeometry_Open(geometry, &sink);
3328 ok(SUCCEEDED(hr), "Failed to open geometry sink, hr %#x.\n", hr);
3329 fill_geometry_sink_bezier(sink, 0);
3330 hr = ID2D1GeometrySink_Close(sink);
3331 ok(SUCCEEDED(hr), "Failed to close geometry sink, hr %#x.\n", hr);
3332 ID2D1GeometrySink_Release(sink);
3334 set_rect(&rect, 0.0f, 0.0f, 0.0f, 0.0f);
3335 hr = ID2D1PathGeometry_GetBounds(geometry, NULL, &rect);
3336 ok(SUCCEEDED(hr), "Failed to get geometry bounds, hr %#x.\n", hr);
3337 match = compare_rect(&rect, 5.0f, 20.0f, 75.0f, 752.0f, 0);
3338 ok(match, "Got unexpected rectangle {%.8e, %.8e, %.8e, %.8e}.\n",
3339 rect.left, rect.top, rect.right, rect.bottom);
3341 set_matrix_identity(&matrix);
3342 translate_matrix(&matrix, 80.0f, 640.0f);
3343 scale_matrix(&matrix, 2.0f, 0.5f);
3344 set_rect(&rect, 0.0f, 0.0f, 0.0f, 0.0f);
3345 hr = ID2D1PathGeometry_GetBounds(geometry, &matrix, &rect);
3346 ok(SUCCEEDED(hr), "Failed to get geometry bounds, hr %#x.\n", hr);
3347 match = compare_rect(&rect, 90.0f, 650.0f, 230.0f, 1016.0f, 0);
3348 ok(match, "Got unexpected rectangle {%.8e, %.8e, %.8e, %.8e}.\n",
3349 rect.left, rect.top, rect.right, rect.bottom);
3351 ID2D1PathGeometry_Release(geometry);
3353 /* GetBounds() with bezier segments and some hollow components. */
3354 hr = ID2D1Factory_CreatePathGeometry(factory, &geometry);
3355 ok(SUCCEEDED(hr), "Failed to create path geometry, hr %#x.\n", hr);
3356 hr = ID2D1PathGeometry_Open(geometry, &sink);
3357 ok(SUCCEEDED(hr), "Failed to open geometry sink, hr %#x.\n", hr);
3358 fill_geometry_sink_bezier(sink, 2);
3359 hr = ID2D1GeometrySink_Close(sink);
3360 ok(SUCCEEDED(hr), "Failed to close geometry sink, hr %#x.\n", hr);
3361 ID2D1GeometrySink_Release(sink);
3363 set_rect(&rect, 0.0f, 0.0f, 0.0f, 0.0f);
3364 hr = ID2D1PathGeometry_GetBounds(geometry, NULL, &rect);
3365 ok(SUCCEEDED(hr), "Failed to get geometry bounds, hr %#x.\n", hr);
3366 match = compare_rect(&rect, 5.0f, 472.0f, 75.0f, 752.0f, 0);
3367 ok(match, "Got unexpected rectangle {%.8e, %.8e, %.8e, %.8e}.\n",
3368 rect.left, rect.top, rect.right, rect.bottom);
3370 set_matrix_identity(&matrix);
3371 translate_matrix(&matrix, 80.0f, 640.0f);
3372 scale_matrix(&matrix, 2.0f, 0.5f);
3373 set_rect(&rect, 0.0f, 0.0f, 0.0f, 0.0f);
3374 hr = ID2D1PathGeometry_GetBounds(geometry, &matrix, &rect);
3375 ok(SUCCEEDED(hr), "Failed to get geometry bounds, hr %#x.\n", hr);
3376 match = compare_rect(&rect, 90.0f, 876.0f, 230.0f, 1016.0f, 0);
3377 ok(match, "Got unexpected rectangle {%.8e, %.8e, %.8e, %.8e}.\n",
3378 rect.left, rect.top, rect.right, rect.bottom);
3380 ID2D1PathGeometry_Release(geometry);
3382 /* GetBounds() with bezier segments and all hollow components. */
3383 hr = ID2D1Factory_CreatePathGeometry(factory, &geometry);
3384 ok(SUCCEEDED(hr), "Failed to create path geometry, hr %#x.\n", hr);
3385 hr = ID2D1PathGeometry_Open(geometry, &sink);
3386 ok(SUCCEEDED(hr), "Failed to open geometry sink, hr %#x.\n", hr);
3387 fill_geometry_sink_bezier(sink, 4);
3388 hr = ID2D1GeometrySink_Close(sink);
3389 ok(SUCCEEDED(hr), "Failed to close geometry sink, hr %#x.\n", hr);
3390 ID2D1GeometrySink_Release(sink);
3392 set_rect(&rect, 0.0f, 0.0f, 0.0f, 0.0f);
3393 hr = ID2D1PathGeometry_GetBounds(geometry, NULL, &rect);
3394 ok(SUCCEEDED(hr), "Failed to get geometry bounds, hr %#x.\n", hr);
3395 match = compare_rect(&rect, INFINITY, INFINITY, FLT_MAX, FLT_MAX, 0);
3396 ok(match, "Got unexpected rectangle {%.8e, %.8e, %.8e, %.8e}.\n",
3397 rect.left, rect.top, rect.right, rect.bottom);
3399 set_matrix_identity(&matrix);
3400 translate_matrix(&matrix, 80.0f, 640.0f);
3401 scale_matrix(&matrix, 2.0f, 0.5f);
3402 set_rect(&rect, 0.0f, 0.0f, 0.0f, 0.0f);
3403 hr = ID2D1PathGeometry_GetBounds(geometry, &matrix, &rect);
3404 ok(SUCCEEDED(hr), "Failed to get geometry bounds, hr %#x.\n", hr);
3405 match = compare_rect(&rect, INFINITY, INFINITY, FLT_MAX, FLT_MAX, 0);
3406 ok(match, "Got unexpected rectangle {%.8e, %.8e, %.8e, %.8e}.\n",
3407 rect.left, rect.top, rect.right, rect.bottom);
3409 ID2D1PathGeometry_Release(geometry);
3411 hr = ID2D1Factory_CreatePathGeometry(factory, &geometry);
3412 ok(SUCCEEDED(hr), "Failed to create path geometry, hr %#x.\n", hr);
3413 hr = ID2D1PathGeometry_Open(geometry, &sink);
3414 ok(SUCCEEDED(hr), "Failed to open geometry sink, hr %#x.\n", hr);
3415 /* The fillmode that's used is the last one set before the sink is closed. */
3416 ID2D1GeometrySink_SetFillMode(sink, D2D1_FILL_MODE_WINDING);
3417 fill_geometry_sink(sink, 0);
3418 ID2D1GeometrySink_SetFillMode(sink, D2D1_FILL_MODE_ALTERNATE);
3419 hr = ID2D1GeometrySink_Close(sink);
3420 ok(SUCCEEDED(hr), "Failed to close geometry sink, hr %#x.\n", hr);
3421 hr = ID2D1PathGeometry_GetFigureCount(geometry, &count);
3422 ok(SUCCEEDED(hr), "Failed to get figure count, hr %#x.\n", hr);
3423 ok(count == 6, "Got unexpected figure count %u.\n", count);
3424 hr = ID2D1PathGeometry_GetSegmentCount(geometry, &count);
3425 ok(SUCCEEDED(hr), "Failed to get segment count, hr %#x.\n", hr);
3426 /* Intersections don't create extra segments. */
3427 ok(count == 44, "Got unexpected segment count %u.\n", count);
3428 ID2D1GeometrySink_SetFillMode(sink, D2D1_FILL_MODE_WINDING);
3429 ID2D1GeometrySink_Release(sink);
3431 geometry_sink_init(&simplify_sink);
3432 hr = ID2D1PathGeometry_Simplify(geometry, D2D1_GEOMETRY_SIMPLIFICATION_OPTION_LINES,
3433 NULL, 0.0f, &simplify_sink.ID2D1SimplifiedGeometrySink_iface);
3434 ok(SUCCEEDED(hr), "Failed to simplify geometry, hr %#x.\n", hr);
3435 geometry_sink_check(&simplify_sink, D2D1_FILL_MODE_ALTERNATE, 6, &expected_figures[0], 0);
3436 geometry_sink_cleanup(&simplify_sink);
3437 geometry_sink_init(&simplify_sink);
3438 hr = ID2D1PathGeometry_Simplify(geometry, D2D1_GEOMETRY_SIMPLIFICATION_OPTION_CUBICS_AND_LINES,
3439 NULL, 0.0f, &simplify_sink.ID2D1SimplifiedGeometrySink_iface);
3440 ok(SUCCEEDED(hr), "Failed to simplify geometry, hr %#x.\n", hr);
3441 geometry_sink_check(&simplify_sink, D2D1_FILL_MODE_ALTERNATE, 6, &expected_figures[0], 0);
3442 geometry_sink_cleanup(&simplify_sink);
3444 set_matrix_identity(&matrix);
3445 translate_matrix(&matrix, 80.0f, 640.0f);
3446 scale_matrix(&matrix, 1.0f, -1.0f);
3447 hr = ID2D1Factory_CreateTransformedGeometry(factory, (ID2D1Geometry *)geometry, &matrix, &transformed_geometry);
3448 ok(SUCCEEDED(hr), "Failed to create transformed geometry, hr %#x.\n", hr);
3450 geometry_sink_init(&simplify_sink);
3451 hr = ID2D1TransformedGeometry_Simplify(transformed_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[6], 0);
3455 geometry_sink_cleanup(&simplify_sink);
3457 ID2D1TransformedGeometry_GetSourceGeometry(transformed_geometry, &tmp_geometry);
3458 ok(tmp_geometry == (ID2D1Geometry *)geometry,
3459 "Got unexpected source geometry %p, expected %p.\n", tmp_geometry, geometry);
3460 ID2D1TransformedGeometry_GetTransform(transformed_geometry, &tmp_matrix);
3461 ok(!memcmp(&tmp_matrix, &matrix, sizeof(matrix)),
3462 "Got unexpected matrix {%.8e, %.8e, %.8e, %.8e, %.8e, %.8e}.\n",
3463 tmp_matrix._11, tmp_matrix._12, tmp_matrix._21,
3464 tmp_matrix._22, tmp_matrix._31, tmp_matrix._32);
3465 geometry_sink_init(&simplify_sink);
3466 hr = ID2D1Geometry_Simplify(tmp_geometry, D2D1_GEOMETRY_SIMPLIFICATION_OPTION_LINES,
3467 &tmp_matrix, 0.0f, &simplify_sink.ID2D1SimplifiedGeometrySink_iface);
3468 ok(SUCCEEDED(hr), "Failed to simplify geometry, hr %#x.\n", hr);
3469 geometry_sink_check(&simplify_sink, D2D1_FILL_MODE_ALTERNATE, 6, &expected_figures[6], 0);
3470 geometry_sink_cleanup(&simplify_sink);
3471 ID2D1Geometry_Release(tmp_geometry);
3473 ID2D1RenderTarget_BeginDraw(rt);
3474 set_color(&color, 0.396f, 0.180f, 0.537f, 1.0f);
3475 ID2D1RenderTarget_Clear(rt, &color);
3476 ID2D1RenderTarget_FillGeometry(rt, (ID2D1Geometry *)geometry, (ID2D1Brush *)brush, NULL);
3477 ID2D1RenderTarget_FillGeometry(rt, (ID2D1Geometry *)transformed_geometry, (ID2D1Brush *)brush, NULL);
3478 hr = ID2D1RenderTarget_EndDraw(rt, NULL, NULL);
3479 ok(SUCCEEDED(hr), "Failed to end draw, hr %#x.\n", hr);
3480 match = compare_surface(&ctx, "3aace1b22aae111cb577614fed16e4eb1650dba5");
3481 ok(match, "Surface does not match.\n");
3483 /* Edge test. */
3484 set_point(&point, 94.0f, 620.0f);
3485 contains = TRUE;
3486 hr = ID2D1TransformedGeometry_FillContainsPoint(transformed_geometry, point, NULL, 0.0f, &contains);
3487 ok(hr == S_OK, "FillContainsPoint failed, hr %#x.\n", hr);
3488 ok(!contains, "Got unexpected contains %#x.\n", contains);
3490 set_point(&point, 95.0f, 620.0f);
3491 contains = FALSE;
3492 hr = ID2D1TransformedGeometry_FillContainsPoint(transformed_geometry, point, NULL, 0.0f, &contains);
3493 ok(hr == S_OK, "FillContainsPoint failed, hr %#x.\n", hr);
3494 ok(contains == TRUE, "Got unexpected contains %#x.\n", contains);
3496 /* With transformation matrix. */
3497 set_matrix_identity(&matrix);
3498 translate_matrix(&matrix, -10.0f, 0.0f);
3499 set_point(&point, 85.0f, 620.0f);
3500 contains = FALSE;
3501 hr = ID2D1TransformedGeometry_FillContainsPoint(transformed_geometry, point, &matrix, 0.0f, &contains);
3502 ok(hr == S_OK, "FillContainsPoint failed, hr %#x.\n", hr);
3503 ok(contains == TRUE, "Got unexpected contains %#x.\n", contains);
3505 ID2D1TransformedGeometry_Release(transformed_geometry);
3506 ID2D1PathGeometry_Release(geometry);
3508 hr = ID2D1Factory_CreatePathGeometry(factory, &geometry);
3509 ok(SUCCEEDED(hr), "Failed to create path geometry, hr %#x.\n", hr);
3510 hr = ID2D1PathGeometry_Open(geometry, &sink);
3511 ok(SUCCEEDED(hr), "Failed to open geometry sink, hr %#x.\n", hr);
3512 fill_geometry_sink(sink, 0);
3513 ID2D1GeometrySink_SetFillMode(sink, D2D1_FILL_MODE_WINDING);
3514 hr = ID2D1GeometrySink_Close(sink);
3515 ok(SUCCEEDED(hr), "Failed to close geometry sink, hr %#x.\n", hr);
3516 hr = ID2D1PathGeometry_GetFigureCount(geometry, &count);
3517 ok(SUCCEEDED(hr), "Failed to get figure count, hr %#x.\n", hr);
3518 ok(count == 6, "Got unexpected figure count %u.\n", count);
3519 hr = ID2D1PathGeometry_GetSegmentCount(geometry, &count);
3520 ok(SUCCEEDED(hr), "Failed to get segment count, hr %#x.\n", hr);
3521 ok(count == 44, "Got unexpected segment count %u.\n", count);
3522 ID2D1GeometrySink_Release(sink);
3524 set_rect(&rect, 0.0f, 0.0f, 0.0f, 0.0f);
3525 hr = ID2D1PathGeometry_GetBounds(geometry, NULL, &rect);
3526 ok(SUCCEEDED(hr), "Failed to get geometry bounds, hr %#x.\n", hr);
3527 match = compare_rect(&rect, 5.0f, 20.0f, 235.0f, 300.0f, 0);
3528 ok(match, "Got unexpected rectangle {%.8e, %.8e, %.8e, %.8e}.\n",
3529 rect.left, rect.top, rect.right, rect.bottom);
3531 set_matrix_identity(&matrix);
3532 translate_matrix(&matrix, 100.0f, 50.0f);
3533 scale_matrix(&matrix, 2.0f, 1.5f);
3534 rotate_matrix(&matrix, M_PI / 4.0f);
3535 set_rect(&rect, 0.0f, 0.0f, 0.0f, 0.0f);
3536 hr = ID2D1PathGeometry_GetBounds(geometry, &matrix, &rect);
3537 ok(SUCCEEDED(hr), "Failed to get geometry bounds, hr %#x.\n", hr);
3538 match = compare_rect(&rect, -3.17192993e+02f, 8.71231079e+01f, 4.04055908e+02f, 6.17453125e+02f, 1);
3539 ok(match, "Got unexpected rectangle {%.8e, %.8e, %.8e, %.8e}.\n",
3540 rect.left, rect.top, rect.right, rect.bottom);
3542 geometry_sink_init(&simplify_sink);
3543 hr = ID2D1PathGeometry_Simplify(geometry, D2D1_GEOMETRY_SIMPLIFICATION_OPTION_LINES,
3544 NULL, 0.0f, &simplify_sink.ID2D1SimplifiedGeometrySink_iface);
3545 ok(SUCCEEDED(hr), "Failed to simplify geometry, hr %#x.\n", hr);
3546 geometry_sink_check(&simplify_sink, D2D1_FILL_MODE_WINDING, 6, &expected_figures[0], 0);
3547 geometry_sink_cleanup(&simplify_sink);
3549 set_matrix_identity(&matrix);
3550 translate_matrix(&matrix, 320.0f, 320.0f);
3551 scale_matrix(&matrix, -1.0f, 1.0f);
3552 hr = ID2D1Factory_CreateTransformedGeometry(factory, (ID2D1Geometry *)geometry, &matrix, &transformed_geometry);
3553 ok(SUCCEEDED(hr), "Failed to create transformed geometry, hr %#x.\n", hr);
3555 ID2D1RenderTarget_BeginDraw(rt);
3556 ID2D1RenderTarget_Clear(rt, &color);
3557 ID2D1RenderTarget_FillGeometry(rt, (ID2D1Geometry *)geometry, (ID2D1Brush *)brush, NULL);
3558 ID2D1RenderTarget_FillGeometry(rt, (ID2D1Geometry *)transformed_geometry, (ID2D1Brush *)brush, NULL);
3559 hr = ID2D1RenderTarget_EndDraw(rt, NULL, NULL);
3560 ok(SUCCEEDED(hr), "Failed to end draw, hr %#x.\n", hr);
3561 match = compare_surface(&ctx, "bfb40a1f007694fa07dbd3b854f3f5d9c3e1d76b");
3562 ok(match, "Surface does not match.\n");
3563 ID2D1TransformedGeometry_Release(transformed_geometry);
3564 ID2D1PathGeometry_Release(geometry);
3566 hr = ID2D1Factory_CreatePathGeometry(factory, &geometry);
3567 ok(SUCCEEDED(hr), "Failed to create path geometry, hr %#x.\n", hr);
3568 hr = ID2D1PathGeometry_Open(geometry, &sink);
3569 ok(SUCCEEDED(hr), "Failed to open geometry sink, hr %#x.\n", hr);
3570 fill_geometry_sink_bezier(sink, 0);
3571 hr = ID2D1GeometrySink_Close(sink);
3572 ok(SUCCEEDED(hr), "Failed to close geometry sink, hr %#x.\n", hr);
3573 hr = ID2D1PathGeometry_GetFigureCount(geometry, &count);
3574 ok(SUCCEEDED(hr), "Failed to get figure count, hr %#x.\n", hr);
3575 ok(count == 4, "Got unexpected figure count %u.\n", count);
3576 hr = ID2D1PathGeometry_GetSegmentCount(geometry, &count);
3577 ok(SUCCEEDED(hr), "Failed to get segment count, hr %#x.\n", hr);
3578 ok(count == 20, "Got unexpected segment count %u.\n", count);
3579 ID2D1GeometrySink_Release(sink);
3581 geometry_sink_init(&simplify_sink);
3582 hr = ID2D1PathGeometry_Simplify(geometry, D2D1_GEOMETRY_SIMPLIFICATION_OPTION_CUBICS_AND_LINES,
3583 NULL, 0.0f, &simplify_sink.ID2D1SimplifiedGeometrySink_iface);
3584 ok(SUCCEEDED(hr), "Failed to simplify geometry, hr %#x.\n", hr);
3585 geometry_sink_check(&simplify_sink, D2D1_FILL_MODE_ALTERNATE, 4, &expected_figures[12], 1);
3586 geometry_sink_cleanup(&simplify_sink);
3587 geometry_sink_init(&simplify_sink);
3588 hr = ID2D1PathGeometry_Simplify(geometry, D2D1_GEOMETRY_SIMPLIFICATION_OPTION_LINES,
3589 NULL, 100.0f, &simplify_sink.ID2D1SimplifiedGeometrySink_iface);
3590 ok(SUCCEEDED(hr), "Failed to simplify geometry, hr %#x.\n", hr);
3591 geometry_sink_check(&simplify_sink, D2D1_FILL_MODE_ALTERNATE, 4, &expected_figures[20], 1);
3592 geometry_sink_cleanup(&simplify_sink);
3593 geometry_sink_init(&simplify_sink);
3594 hr = ID2D1PathGeometry_Simplify(geometry, D2D1_GEOMETRY_SIMPLIFICATION_OPTION_LINES,
3595 NULL, 10.0f, &simplify_sink.ID2D1SimplifiedGeometrySink_iface);
3596 ok(SUCCEEDED(hr), "Failed to simplify geometry, hr %#x.\n", hr);
3597 geometry_sink_check(&simplify_sink, D2D1_FILL_MODE_ALTERNATE, 4, &expected_figures[24], 1);
3598 geometry_sink_cleanup(&simplify_sink);
3600 set_matrix_identity(&matrix);
3601 scale_matrix(&matrix, 0.5f, 2.0f);
3602 translate_matrix(&matrix, 400.0f, -33.0f);
3603 rotate_matrix(&matrix, M_PI / 4.0f);
3604 scale_matrix(&matrix, 2.0f, 0.5f);
3605 hr = ID2D1Factory_CreateTransformedGeometry(factory, (ID2D1Geometry *)geometry, &matrix, &transformed_geometry);
3606 ok(SUCCEEDED(hr), "Failed to create transformed geometry, hr %#x.\n", hr);
3608 geometry_sink_init(&simplify_sink);
3609 hr = ID2D1TransformedGeometry_Simplify(transformed_geometry, D2D1_GEOMETRY_SIMPLIFICATION_OPTION_CUBICS_AND_LINES,
3610 NULL, 0.0f, &simplify_sink.ID2D1SimplifiedGeometrySink_iface);
3611 ok(SUCCEEDED(hr), "Failed to simplify geometry, hr %#x.\n", hr);
3612 geometry_sink_check(&simplify_sink, D2D1_FILL_MODE_ALTERNATE, 4, &expected_figures[16], 4);
3613 geometry_sink_cleanup(&simplify_sink);
3615 ID2D1RenderTarget_BeginDraw(rt);
3616 ID2D1RenderTarget_Clear(rt, &color);
3617 ID2D1RenderTarget_FillGeometry(rt, (ID2D1Geometry *)geometry, (ID2D1Brush *)brush, NULL);
3618 ID2D1RenderTarget_FillGeometry(rt, (ID2D1Geometry *)transformed_geometry, (ID2D1Brush *)brush, NULL);
3619 hr = ID2D1RenderTarget_EndDraw(rt, NULL, NULL);
3620 ok(SUCCEEDED(hr), "Failed to end draw, hr %#x.\n", hr);
3621 match = compare_figure(&ctx, 0, 0, 160, 160, 0xff652e89, 64,
3622 "7xoCngECngECngECngECngECngECngECnQEEnAEEnAEEnAEEnAEEmwEGmgEGmgEGmgEGmQEImAEI"
3623 "lAEECASLAQgKCIEBDQoMew8KD3YQDBByEgwSbhMOEmwUDhRpFBAUZxUQFWUVEhVjFhIWYRYUFl8X"
3624 "FBddFxYWXRYYFlsXGBdaFhoWWRYcFlgVHhVXFSAVVhQiFFUUIxRVEyYTVBIoElQRKhFUECwQUxAu"
3625 "EFIOMg5SDTQNUgs4C1IJPAlRCEAIUAZEBlAESARQAU4BTgJQAkgGUAY/C1ALMhNQEyoTUBMyC1AL"
3626 "PwZQBkgCUAJOAU4BUARIBFAGRAZQCEAIUQk8CVILOAtSDTQNUg4yDlIQLhBTECwQVBEqEVQSKBJU"
3627 "EyYTVBQjFFYUIhRWFSAVVxUeFVgWHBZZFhoWWhcYF1sWGBZcFxYWXhcUF18WFBZhFhIWYxUSFWUV"
3628 "EBVnFBAUaRQOFGsTDhJvEgwSchAMEHYPCg96DQoMggEICgiLAQQIBJQBCJgBCJkBBpoBBpoBBpoB"
3629 "BpsBBJwBBJwBBJwBBJwBBJ0BAp4BAp4BAp4BAp4BAp4BAp4BAp4BAgAA");
3630 ok(match, "Figure does not match.\n");
3631 match = compare_figure(&ctx, 0, 226, 160, 160, 0xff652e89, 64,
3632 "7xoCngECngECngECngECngECngECngECnQEEnAEEnAEEnAEEnAEEmwEGmgEGmgEGmgEGmQEImAEI"
3633 "lAEECASLAQgKCIEBDQoMew8KD3YQDBByEgwSbhMOEmwUDhRpFBAUZxUQFWUVEhVjFhIWYRYUFl8X"
3634 "FBddFxYWXRYYFlsXGBdaFhoWWRYcFlgVHhVXFSAVVhQiFFUUIxRVEyYTVBIoElQRKhFUECwQUxAu"
3635 "EFIOMg5SDTQNUgs4C1IJPAlRCEAIUAZEBlAESARQAU4BTgJQAkgGUAY/C1ALMhNQEyoTUBMyC1AL"
3636 "PwZQBkgCUAJOAU4BUARIBFAGRAZQCEAIUQk8CVILOAtSDTQNUg4yDlIQLhBTECwQVBEqEVQSKBJU"
3637 "EyYTVBQjFFYUIhRWFSAVVxUeFVgWHBZZFhoWWhcYF1sWGBZcFxYWXhcUF18WFBZhFhIWYxUSFWUV"
3638 "EBVnFBAUaRQOFGsTDhJvEgwSchAMEHYPCg96DQoMggEICgiLAQQIBJQBCJgBCJkBBpoBBpoBBpoB"
3639 "BpsBBJwBBJwBBJwBBJwBBJ0BAp4BAp4BAp4BAp4BAp4BAp4BAp4BAgAA");
3640 ok(match, "Figure does not match.\n");
3641 match = compare_figure(&ctx, 160, 0, 320, 160, 0xff652e89, 64,
3642 "gVQBwAIBWgHlAQFYAecBAVYB6QEBVAHrAQEjDCMB7AECHhQeAu0BAxoYGgPvAQMWHhYD8QEDFCAU"
3643 "A/MBBBAkEAT0AQUOJw0F9QEGCioKBvcBBggsCAb4AQgFLgUI+QEJATIBCfsBCAIwAgj8AQcFLAUH"
3644 "/QEFCCgIBf4BBAwiDAT/AQIQHBAClwISlwIBPgGAAgI8Av8BAzwD/QEEPAT7AQY6BvkBBzoH+AEI"
3645 "OAj3AQk4CfYBCTgK9AELNgvzAQw2DPIBDDYM8QEONA7wAQ40DvABDjQO7wEPNA/uAQ80D+4BEDIQ"
3646 "7QERMhHsAREyEewBETIR7AERMhHsAREyEewBETIR7AERMhHsAREyEewBETIR7AERMhHsAREyEewB"
3647 "ETIR7AERMhHsAREyEe0BEDIQ7gEQMw/uAQ80D+4BDzQP7wEONA7wAQ40DvEBDDYM8gEMNgzzAQs2"
3648 "C/QBCzcK9QEJOAn3AQg4CfcBBzoH+QEGOgb7AQU6BfwBBDwE/QEDPAP/AQE+AZkCDpkCAhIYEgKA"
3649 "AgMNIA0D/wEFCSYJBf4BBgYqBgf8AQgDLgMI+wFG+gEIAzADCPkBBwYuBgf3AQYKKgoG9gEFDCgM"
3650 "BfUBBBAlDwTzAQQSIhIE8QEDFh4WA/ABAhkaGQLvAQIcFhwC7QECIBAgAusBASgEKAHpAQFWAecB"
3651 "AVgB5QEBWgHAAgHhUgAA");
3652 ok(match, "Figure does not match.\n");
3653 match = compare_figure(&ctx, 160, 160, 320, 160, 0xff652e89, 64,
3654 "/VUB5QEBWAHnAQFWAekBAVQB6wECIQ8hAe0BAh0VHQLuAQIZGhkD7wEDFh4WA/EBBBMhEwPzAQQQ"
3655 "JQ8F9AEFDCgNBfUBBgoqCgb3AQcHLQcG+QEIBC8ECPkBPAEJ+wEIAy8CCP0BBgYrBQf9AQUJJgkF"
3656 "/wEDDSANBP8BAhEaEQKYAhAXAYACAT4BgAICPQL+AQM8BPwBBTsE+wEGOgb6AQc5B/gBCDgJ9gEJ"
3657 "OAn2AQo3CvQBCzcK8wEMNgzyAQ01DPIBDTUN8AEONA7wAQ40D+4BDzQP7gEQMw/uARAzEO0BEDIR"
3658 "7AERMhHsAREyEewBETIR7AERMhLrAREyEusBETIS6wERMhLrAREyEusBETIS6wERMhHsAREyEewB"
3659 "ETIR7QEQMhHtARAzEO0BEDMP7gEPNA/vAQ40D+8BDjQO8QENNQ3xAQ01DPMBCzYM8wELNwr1AQo3"
3660 "CvUBCTgJ9wEIOAn4AQc5B/kBBjoG+wEFOwT9AQM8BP4BAj0C/wEBPgGYAhAXAYACAhEaEQKAAgMN"
3661 "IA0E/gEFCSYJBf4BBgYrBQf8AQgDLwII+wE8AQn6AQgELwQI+AEHBy0HBvcBBgoqCgb2AQUNJw0F"
3662 "9AEEECQQBfIBBBMhEwPxAQMWHhYD8AECGRoZA+4BAh0VHQLsAQIhDiIB6wEBVAHpAQFWAecBAVgB"
3663 "wAIBwlYA");
3664 ok(match, "Figure does not match.\n");
3665 ID2D1TransformedGeometry_Release(transformed_geometry);
3666 ID2D1PathGeometry_Release(geometry);
3668 hr = ID2D1Factory_CreatePathGeometry(factory, &geometry);
3669 ok(SUCCEEDED(hr), "Failed to create path geometry, hr %#x.\n", hr);
3670 hr = ID2D1PathGeometry_Open(geometry, &sink);
3671 ok(SUCCEEDED(hr), "Failed to open geometry sink, hr %#x.\n", hr);
3672 fill_geometry_sink_bezier(sink, 0);
3673 ID2D1GeometrySink_SetFillMode(sink, D2D1_FILL_MODE_WINDING);
3674 hr = ID2D1GeometrySink_Close(sink);
3675 ok(SUCCEEDED(hr), "Failed to close geometry sink, hr %#x.\n", hr);
3676 hr = ID2D1PathGeometry_GetFigureCount(geometry, &count);
3677 ok(SUCCEEDED(hr), "Failed to get figure count, hr %#x.\n", hr);
3678 ok(count == 4, "Got unexpected figure count %u.\n", count);
3679 hr = ID2D1PathGeometry_GetSegmentCount(geometry, &count);
3680 ok(SUCCEEDED(hr), "Failed to get segment count, hr %#x.\n", hr);
3681 ok(count == 20, "Got unexpected segment count %u.\n", count);
3682 ID2D1GeometrySink_Release(sink);
3684 geometry_sink_init(&simplify_sink);
3685 hr = ID2D1PathGeometry_Simplify(geometry, D2D1_GEOMETRY_SIMPLIFICATION_OPTION_CUBICS_AND_LINES,
3686 NULL, 0.0f, &simplify_sink.ID2D1SimplifiedGeometrySink_iface);
3687 ok(SUCCEEDED(hr), "Failed to simplify geometry, hr %#x.\n", hr);
3688 geometry_sink_check(&simplify_sink, D2D1_FILL_MODE_WINDING, 4, &expected_figures[12], 1);
3689 geometry_sink_cleanup(&simplify_sink);
3690 geometry_sink_init(&simplify_sink);
3691 hr = ID2D1PathGeometry_Simplify(geometry, D2D1_GEOMETRY_SIMPLIFICATION_OPTION_LINES,
3692 NULL, 100.0f, &simplify_sink.ID2D1SimplifiedGeometrySink_iface);
3693 ok(SUCCEEDED(hr), "Failed to simplify geometry, hr %#x.\n", hr);
3694 geometry_sink_check(&simplify_sink, D2D1_FILL_MODE_WINDING, 4, &expected_figures[20], 1);
3695 geometry_sink_cleanup(&simplify_sink);
3696 geometry_sink_init(&simplify_sink);
3697 hr = ID2D1PathGeometry_Simplify(geometry, D2D1_GEOMETRY_SIMPLIFICATION_OPTION_LINES,
3698 NULL, 10.0f, &simplify_sink.ID2D1SimplifiedGeometrySink_iface);
3699 ok(SUCCEEDED(hr), "Failed to simplify geometry, hr %#x.\n", hr);
3700 geometry_sink_check(&simplify_sink, D2D1_FILL_MODE_WINDING, 4, &expected_figures[24], 1);
3701 geometry_sink_cleanup(&simplify_sink);
3703 set_matrix_identity(&matrix);
3704 scale_matrix(&matrix, 0.5f, 2.0f);
3705 translate_matrix(&matrix, 127.0f, 80.0f);
3706 rotate_matrix(&matrix, M_PI / -4.0f);
3707 scale_matrix(&matrix, 2.0f, 0.5f);
3708 hr = ID2D1Factory_CreateTransformedGeometry(factory, (ID2D1Geometry *)geometry, &matrix, &transformed_geometry);
3709 ok(SUCCEEDED(hr), "Failed to create transformed geometry, hr %#x.\n", hr);
3711 ID2D1RenderTarget_BeginDraw(rt);
3712 ID2D1RenderTarget_Clear(rt, &color);
3713 ID2D1RenderTarget_FillGeometry(rt, (ID2D1Geometry *)geometry, (ID2D1Brush *)brush, NULL);
3714 ID2D1RenderTarget_FillGeometry(rt, (ID2D1Geometry *)transformed_geometry, (ID2D1Brush *)brush, NULL);
3715 hr = ID2D1RenderTarget_EndDraw(rt, NULL, NULL);
3716 ok(SUCCEEDED(hr), "Failed to end draw, hr %#x.\n", hr);
3717 match = compare_figure(&ctx, 0, 0, 160, 160, 0xff652e89, 64,
3718 "7xoCngECngECngECngECngECngECngECnQEEnAEEnAEEnAEEnAEEmwEGmgEGmgEGmgEGmQEImAEI"
3719 "lAEQiwEagQEjeyh2LHIwbjNsNmk4ZzplPGM+YUBfQl1DXURbRlpGWUhYSFdKVkpVS1VMVExUTFRM"
3720 "U05STlJOUk5STlFQUFBQUFBQTlRIXD9mMnYqdjJmP1xIVE5QUFBQUFBQUU5STlJOUk5STlNMVExU"
3721 "TFRMVEtWSlZKV0hYSFlGWkZbRFxDXkJfQGE+YzxlOmc4aTZrM28wcix2KHojggEaiwEQlAEImAEI"
3722 "mQEGmgEGmgEGmgEGmwEEnAEEnAEEnAEEnAEEnQECngECngECngECngECngECngECngEC");
3723 ok(match, "Figure does not match.\n");
3724 match = compare_figure(&ctx, 0, 226, 160, 160, 0xff652e89, 64,
3725 "7xoCngECngECngECngECngECngECngECnQEEnAEEnAEEnAEEnAEEmwEGmgEGmgEGmgEGmQEImAEI"
3726 "lAEQiwEagQEjeyh2LHIwbjNsNmk4ZzplPGM+YUBfQl1DXURbRlpGWUhYSFdKVkpVS1VMVExUTFRM"
3727 "U05STlJOUk5STlFQUFBQUFBQTlRIXD9mMnYqdjJmP1xIVE5QUFBQUFBQUU5STlJOUk5STlNMVExU"
3728 "TFRMVEtWSlZKV0hYSFlGWkZbRFxDXkJfQGE+YzxlOmc4aTZrM28wcix2KHojggEaiwEQlAEImAEI"
3729 "mQEGmgEGmgEGmgEGmwEEnAEEnAEEnAEEnAEEnQECngECngECngECngECngECngECngEC");
3730 ok(match, "Figure does not match.\n");
3731 match = compare_figure(&ctx, 160, 0, 320, 160, 0xff652e89, 64,
3732 "4VIBwAIBWgHlAQFYAecBAVYB6QEBVAHrAQIhDiIB7QECHRUdAu4BAhkaGQPvAQMWHhYD8QEEEyET"
3733 "A/MBBBAkEAT1AQUMKA0F9QEGCioKBvcBBwctBwb5AQgELwQI+QEJATIBCfsBRP0BQ/0BQv8BQf8B"
3734 "QIECP4ACQIACQf4BQ/wBRPsBRvoBR/gBSPcBSvYBS/QBTPMBTvIBTvIBT/ABUPABUe4BUu4BUu4B"
3735 "U+0BU+wBVOwBVOwBVOwBVOwBVesBVesBVesBVesBVOwBVOwBVOwBVO0BU+0BU+0BUu4BUu8BUe8B"
3736 "UPEBT/EBTvIBTvMBTPUBS/UBSvcBSfcBSPkBRvsBRP0BQ/4BQf8BQIECP4ACQIACQf4BQv4BQ/wB"
3737 "RPsBCQEyAQn6AQgELwQI+AEHBy0GB/cBBgoqCgb2AQUMKA0F9AEEECUPBPMBBBIiEwPxAQMWHhYD"
3738 "8AECGRoZA+4BAh0VHQLsAQIhDiIB6wEBVAHpAQFWAecBAVgB5QEBWgHAAgEA");
3739 ok(match, "Figure does not match.\n");
3740 match = compare_figure(&ctx, 160, 160, 320, 160, 0xff652e89, 64,
3741 "gVQBXAHjAQFaAeUBAVgB5wEBVgHpAQEpAikB6wECIBAgAu0BAhwWHALvAQIZGhkC8AEDFh4WA/EB"
3742 "BBIiEgTzAQQPJRAE9QEFDCgMBfYBBgoqCgb3AQcGLgYH+QEIAzADCPoBRvsBRPwBRP0BQv8BQIAC"
3743 "QIECPoECQP8BQv0BRPwBRPsBRvkBSPgBSPcBSvUBTPQBTPMBTvIBTvEBUPABUO8BUu4BUu4BUu4B"
3744 "Uu0BVOwBVOwBVOwBVOwBVOwBVOwBVOwBVOwBVOwBVOwBVOwBVOwBVOwBVO0BUu4BUu4BUu8BUPAB"
3745 "UPABUPEBTvIBTvMBTPQBS/YBSvcBSPgBSPkBRvsBRP0BQv8BQIACQIECPoECQP8BQv4BQv0BRPwB"
3746 "RPsBCQEyAQn5AQgFLgUI+AEGCCwIBvcBBgoqCgb1AQUNJw4F9AEEECQQBPMBAxQgFAPxAQMWHhYD"
3747 "7wEDGhgaA+0BAh4UHgLsAQEjDCMB6wEBVAHpAQFWAecBAVgB5QEBWgGiVQAA");
3748 ok(match, "Figure does not match.\n");
3749 ID2D1TransformedGeometry_Release(transformed_geometry);
3750 ID2D1PathGeometry_Release(geometry);
3752 hr = ID2D1Factory_CreatePathGeometry(factory, &geometry);
3753 ok(SUCCEEDED(hr), "Failed to create path geometry, hr %#x.\n", hr);
3754 hr = ID2D1PathGeometry_Open(geometry, &sink);
3755 ok(SUCCEEDED(hr), "Failed to open geometry sink, hr %#x.\n", hr);
3757 set_point(&point, 40.0f, 20.0f);
3758 ID2D1GeometrySink_BeginFigure(sink, point, D2D1_FIGURE_BEGIN_FILLED);
3759 line_to(sink, 75.0f, 300.0f);
3760 line_to(sink, 5.0f, 300.0f);
3761 ID2D1GeometrySink_EndFigure(sink, D2D1_FIGURE_END_CLOSED);
3763 set_point(&point, 40.0f, 290.0f);
3764 ID2D1GeometrySink_BeginFigure(sink, point, D2D1_FIGURE_BEGIN_FILLED);
3765 line_to(sink, 55.0f, 160.0f);
3766 line_to(sink, 25.0f, 160.0f);
3767 ID2D1GeometrySink_EndFigure(sink, D2D1_FIGURE_END_CLOSED);
3769 hr = ID2D1GeometrySink_Close(sink);
3770 ok(SUCCEEDED(hr), "Failed to close geometry sink, hr %#x.\n", hr);
3771 hr = ID2D1PathGeometry_GetFigureCount(geometry, &count);
3772 ok(SUCCEEDED(hr), "Failed to get figure count, hr %#x.\n", hr);
3773 ok(count == 2, "Got unexpected figure count %u.\n", count);
3774 hr = ID2D1PathGeometry_GetSegmentCount(geometry, &count);
3775 ok(SUCCEEDED(hr), "Failed to get segment count, hr %#x.\n", hr);
3776 ok(count == 6, "Got unexpected segment count %u.\n", count);
3777 ID2D1GeometrySink_Release(sink);
3779 ID2D1RenderTarget_BeginDraw(rt);
3780 ID2D1RenderTarget_Clear(rt, &color);
3781 ID2D1RenderTarget_FillGeometry(rt, (ID2D1Geometry *)geometry, (ID2D1Brush *)brush, NULL);
3782 hr = ID2D1RenderTarget_EndDraw(rt, NULL, NULL);
3783 ok(SUCCEEDED(hr), "Failed to end draw, hr %#x.\n", hr);
3784 match = compare_surface(&ctx, "a875e68e0cb9c055927b1b50b879f90b24e38470");
3785 ok(match, "Surface does not match.\n");
3786 ID2D1PathGeometry_Release(geometry);
3788 hr = ID2D1Factory_CreatePathGeometry(factory, &geometry);
3789 ok(SUCCEEDED(hr), "Failed to create path geometry, hr %#x.\n", hr);
3790 hr = ID2D1PathGeometry_Open(geometry, &sink);
3791 ok(SUCCEEDED(hr), "Failed to open geometry sink, hr %#x.\n", hr);
3792 set_point(&point, 40.0f, 20.0f);
3793 ID2D1GeometrySink_BeginFigure(sink, point, D2D1_FIGURE_BEGIN_HOLLOW);
3794 line_to(sink, 75.0f, 300.0f);
3795 line_to(sink, 5.0f, 300.0f);
3796 ID2D1GeometrySink_EndFigure(sink, D2D1_FIGURE_END_OPEN);
3797 hr = ID2D1GeometrySink_Close(sink);
3798 ok(SUCCEEDED(hr), "Failed to close geometry sink, hr %#x.\n", hr);
3799 ID2D1GeometrySink_Release(sink);
3800 hr = ID2D1PathGeometry_GetSegmentCount(geometry, &count);
3801 ok(SUCCEEDED(hr), "Failed to get segment count, hr %#x.\n", hr);
3802 ok(count == 2, "Got unexpected segment count %u.\n", count);
3804 geometry_sink_init(&simplify_sink);
3805 hr = ID2D1PathGeometry_Simplify(geometry, D2D1_GEOMETRY_SIMPLIFICATION_OPTION_LINES,
3806 NULL, 0.0f, &simplify_sink.ID2D1SimplifiedGeometrySink_iface);
3807 ok(SUCCEEDED(hr), "Failed to simplify geometry, hr %#x.\n", hr);
3808 geometry_sink_check(&simplify_sink, D2D1_FILL_MODE_ALTERNATE, 1, &expected_figures[28], 1);
3809 geometry_sink_cleanup(&simplify_sink);
3811 ID2D1PathGeometry_Release(geometry);
3813 ID2D1SolidColorBrush_Release(brush);
3814 ID2D1Factory_Release(factory);
3815 release_test_context(&ctx);
3818 static void test_rectangle_geometry(BOOL d3d11)
3820 ID2D1TransformedGeometry *transformed_geometry;
3821 ID2D1RectangleGeometry *geometry;
3822 struct geometry_sink sink;
3823 D2D1_MATRIX_3X2_F matrix;
3824 D2D1_RECT_F rect, rect2;
3825 ID2D1Factory *factory;
3826 D2D1_POINT_2F point;
3827 BOOL contains;
3828 HRESULT hr;
3829 BOOL match;
3831 static const struct geometry_segment expected_segments[] =
3833 /* Figure 0. */
3834 {SEGMENT_LINE, {{{10.0f, 0.0f}}}},
3835 {SEGMENT_LINE, {{{10.0f, 20.0f}}}},
3836 {SEGMENT_LINE, {{{ 0.0f, 20.0f}}}},
3837 /* Figure 1. */
3838 {SEGMENT_LINE, {{{4.42705116e+01f, 1.82442951e+01f}}}},
3839 {SEGMENT_LINE, {{{7.95376282e+01f, 5.06049728e+01f}}}},
3840 {SEGMENT_LINE, {{{5.52671127e+01f, 6.23606796e+01f}}}},
3841 /* Figure 2. */
3842 {SEGMENT_LINE, {{{25.0f, 15.0f}}}},
3843 {SEGMENT_LINE, {{{25.0f, 55.0f}}}},
3844 {SEGMENT_LINE, {{{25.0f, 55.0f}}}},
3845 /* Figure 3. */
3846 {SEGMENT_LINE, {{{35.0f, 45.0f}}}},
3847 {SEGMENT_LINE, {{{35.0f, 45.0f}}}},
3848 {SEGMENT_LINE, {{{30.0f, 45.0f}}}},
3849 /* Figure 4. */
3850 {SEGMENT_LINE, {{{ 1.07179585e+01f, 2.23205078e+02f}}}},
3851 {SEGMENT_LINE, {{{-5.85640755e+01f, 2.73205078e+02f}}}},
3852 {SEGMENT_LINE, {{{-7.85640717e+01f, 2.29903809e+02f}}}},
3853 /* Figure 5. */
3854 {SEGMENT_LINE, {{{40.0f, 20.0f}}}},
3855 {SEGMENT_LINE, {{{40.0f, 40.0f}}}},
3856 {SEGMENT_LINE, {{{30.0f, 40.0f}}}},
3857 /* Figure 6. */
3858 {SEGMENT_LINE, {{{ 2.14359169e+01f, 0.0f}}}},
3859 {SEGMENT_LINE, {{{-1.17128151e+02f, 0.0f}}}},
3860 {SEGMENT_LINE, {{{-1.57128143e+02f, 0.0f}}}},
3861 /* Figure 7. */
3862 {SEGMENT_LINE, {{{0.0f, 1.11602539e+02f}}}},
3863 {SEGMENT_LINE, {{{0.0f, 1.36602539e+02f}}}},
3864 {SEGMENT_LINE, {{{0.0f, 1.14951904e+02f}}}},
3866 static const struct expected_geometry_figure expected_figures[] =
3868 {D2D1_FIGURE_BEGIN_FILLED, D2D1_FIGURE_END_CLOSED, { 0.0f, 0.0f}, 3, &expected_segments[0]},
3869 {D2D1_FIGURE_BEGIN_FILLED, D2D1_FIGURE_END_CLOSED, {20.0f, 30.0f}, 3, &expected_segments[3]},
3870 {D2D1_FIGURE_BEGIN_FILLED, D2D1_FIGURE_END_CLOSED, {25.0f, 15.0f}, 3, &expected_segments[6]},
3871 {D2D1_FIGURE_BEGIN_FILLED, D2D1_FIGURE_END_CLOSED, {30.0f, 45.0f}, 3, &expected_segments[9]},
3872 {D2D1_FIGURE_BEGIN_FILLED, D2D1_FIGURE_END_CLOSED, {-9.28203964e+00f, 1.79903809e+02f},
3873 3, &expected_segments[12]},
3874 {D2D1_FIGURE_BEGIN_FILLED, D2D1_FIGURE_END_CLOSED, {30.0f, 20.0f}, 3, &expected_segments[15]},
3875 {D2D1_FIGURE_BEGIN_FILLED, D2D1_FIGURE_END_CLOSED, {-1.85640793e+01f, 0.0f}, 3, &expected_segments[18]},
3876 {D2D1_FIGURE_BEGIN_FILLED, D2D1_FIGURE_END_CLOSED, {0.0f, 8.99519043e+01f}, 3, &expected_segments[21]},
3879 hr = D2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED, &IID_ID2D1Factory, NULL, (void **)&factory);
3880 ok(SUCCEEDED(hr), "Failed to create factory, hr %#x.\n", hr);
3882 set_rect(&rect, 0.0f, 0.0f, 0.0f, 0.0f);
3883 hr = ID2D1Factory_CreateRectangleGeometry(factory, &rect, &geometry);
3884 ok(SUCCEEDED(hr), "Failed to create geometry, hr %#x.\n", hr);
3885 ID2D1RectangleGeometry_GetRect(geometry, &rect2);
3886 match = compare_rect(&rect2, 0.0f, 0.0f, 0.0f, 0.0f, 0);
3887 ok(match, "Got unexpected rectangle {%.8e, %.8e, %.8e, %.8e}.\n",
3888 rect2.left, rect2.top, rect2.right, rect2.bottom);
3889 ID2D1RectangleGeometry_Release(geometry);
3891 set_rect(&rect, 50.0f, 0.0f, 40.0f, 100.0f);
3892 hr = ID2D1Factory_CreateRectangleGeometry(factory, &rect, &geometry);
3893 ok(SUCCEEDED(hr), "Failed to create geometry, hr %#x.\n", hr);
3894 ID2D1RectangleGeometry_GetRect(geometry, &rect2);
3895 match = compare_rect(&rect2, 50.0f, 0.0f, 40.0f, 100.0f, 0);
3896 ok(match, "Got unexpected rectangle {%.8e, %.8e, %.8e, %.8e}.\n",
3897 rect2.left, rect2.top, rect2.right, rect2.bottom);
3898 ID2D1RectangleGeometry_Release(geometry);
3900 set_rect(&rect, 0.0f, 100.0f, 40.0f, 50.0f);
3901 hr = ID2D1Factory_CreateRectangleGeometry(factory, &rect, &geometry);
3902 ok(SUCCEEDED(hr), "Failed to create geometry, hr %#x.\n", hr);
3903 ID2D1RectangleGeometry_GetRect(geometry, &rect2);
3904 match = compare_rect(&rect2, 0.0f, 100.0f, 40.0f, 50.0f, 0);
3905 ok(match, "Got unexpected rectangle {%.8e, %.8e, %.8e, %.8e}.\n",
3906 rect2.left, rect2.top, rect2.right, rect2.bottom);
3907 ID2D1RectangleGeometry_Release(geometry);
3909 set_rect(&rect, 50.0f, 100.0f, 40.0f, 50.0f);
3910 hr = ID2D1Factory_CreateRectangleGeometry(factory, &rect, &geometry);
3911 ok(SUCCEEDED(hr), "Failed to create geometry, hr %#x.\n", hr);
3912 ID2D1RectangleGeometry_GetRect(geometry, &rect2);
3913 match = compare_rect(&rect2, 50.0f, 100.0f, 40.0f, 50.0f, 0);
3914 ok(match, "Got unexpected rectangle {%.8e, %.8e, %.8e, %.8e}.\n",
3915 rect2.left, rect2.top, rect2.right, rect2.bottom);
3916 ID2D1RectangleGeometry_Release(geometry);
3918 set_rect(&rect, 0.0f, 0.0f, 10.0f, 20.0f);
3919 hr = ID2D1Factory_CreateRectangleGeometry(factory, &rect, &geometry);
3920 ok(SUCCEEDED(hr), "Failed to create geometry, hr %#x.\n", hr);
3922 /* Edge. */
3923 contains = FALSE;
3924 set_point(&point, 0.0f, 0.0f);
3925 hr = ID2D1RectangleGeometry_FillContainsPoint(geometry, point, NULL, 0.0f, &contains);
3926 ok(SUCCEEDED(hr), "FillContainsPoint() failed, hr %#x.\n", hr);
3927 ok(!!contains, "Got wrong hit test result %d.\n", contains);
3929 /* Within tolerance limit around corner. */
3930 contains = TRUE;
3931 set_point(&point, -D2D1_DEFAULT_FLATTENING_TOLERANCE, 0.0f);
3932 hr = ID2D1RectangleGeometry_FillContainsPoint(geometry, point, NULL, 0.0f, &contains);
3933 ok(SUCCEEDED(hr), "FillContainsPoint() failed, hr %#x.\n", hr);
3934 ok(!contains, "Got wrong hit test result %d.\n", contains);
3936 contains = FALSE;
3937 set_point(&point, -D2D1_DEFAULT_FLATTENING_TOLERANCE + 0.01f, 0.0f);
3938 hr = ID2D1RectangleGeometry_FillContainsPoint(geometry, point, NULL, 0.0f, &contains);
3939 ok(SUCCEEDED(hr), "FillContainsPoint() failed, hr %#x.\n", hr);
3940 ok(!!contains, "Got wrong hit test result %d.\n", contains);
3942 contains = TRUE;
3943 set_point(&point, -D2D1_DEFAULT_FLATTENING_TOLERANCE - 0.01f, 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 contains = TRUE;
3949 set_point(&point, -D2D1_DEFAULT_FLATTENING_TOLERANCE, -D2D1_DEFAULT_FLATTENING_TOLERANCE);
3950 hr = ID2D1RectangleGeometry_FillContainsPoint(geometry, point, NULL, 0.0f, &contains);
3951 ok(SUCCEEDED(hr), "FillContainsPoint() failed, hr %#x.\n", hr);
3952 ok(!contains, "Got wrong hit test result %d.\n", contains);
3954 /* Inside. */
3955 contains = FALSE;
3956 set_point(&point, 5.0f, 5.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 /* Test GetBounds() and Simplify(). */
3962 hr = ID2D1RectangleGeometry_GetBounds(geometry, NULL, &rect);
3963 ok(SUCCEEDED(hr), "Failed to get bounds.\n");
3964 match = compare_rect(&rect, 0.0f, 0.0f, 10.0f, 20.0f, 0);
3965 ok(match, "Got unexpected bounds {%.8e, %.8e, %.8e, %.8e}.\n",
3966 rect.left, rect.top, rect.right, rect.bottom);
3967 geometry_sink_init(&sink);
3968 hr = ID2D1RectangleGeometry_Simplify(geometry, D2D1_GEOMETRY_SIMPLIFICATION_OPTION_CUBICS_AND_LINES,
3969 NULL, 0.0f, &sink.ID2D1SimplifiedGeometrySink_iface);
3970 ok(SUCCEEDED(hr), "Failed to simplify geometry, hr %#x.\n", hr);
3971 geometry_sink_check(&sink, D2D1_FILL_MODE_ALTERNATE, 1, &expected_figures[0], 0);
3972 geometry_sink_cleanup(&sink);
3973 geometry_sink_init(&sink);
3974 hr = ID2D1RectangleGeometry_Simplify(geometry, D2D1_GEOMETRY_SIMPLIFICATION_OPTION_LINES,
3975 NULL, 0.0f, &sink.ID2D1SimplifiedGeometrySink_iface);
3976 ok(SUCCEEDED(hr), "Failed to simplify geometry, hr %#x.\n", hr);
3977 geometry_sink_check(&sink, D2D1_FILL_MODE_ALTERNATE, 1, &expected_figures[0], 0);
3978 geometry_sink_cleanup(&sink);
3980 set_matrix_identity(&matrix);
3981 translate_matrix(&matrix, 20.0f, 30.0f);
3982 scale_matrix(&matrix, 3.0f, 2.0f);
3983 rotate_matrix(&matrix, M_PI / -5.0f);
3984 hr = ID2D1RectangleGeometry_GetBounds(geometry, &matrix, &rect);
3985 ok(SUCCEEDED(hr), "Failed to get bounds.\n");
3986 match = compare_rect(&rect, 2.00000000e+01f, 1.82442951e+01f, 7.95376282e+01f, 6.23606796e+01f, 0);
3987 ok(match, "Got unexpected bounds {%.8e, %.8e, %.8e, %.8e}.\n",
3988 rect.left, rect.top, rect.right, rect.bottom);
3989 geometry_sink_init(&sink);
3990 hr = ID2D1RectangleGeometry_Simplify(geometry, D2D1_GEOMETRY_SIMPLIFICATION_OPTION_CUBICS_AND_LINES,
3991 &matrix, 0.0f, &sink.ID2D1SimplifiedGeometrySink_iface);
3992 ok(SUCCEEDED(hr), "Failed to simplify geometry, hr %#x.\n", hr);
3993 geometry_sink_check(&sink, D2D1_FILL_MODE_ALTERNATE, 1, &expected_figures[1], 1);
3994 geometry_sink_cleanup(&sink);
3996 set_matrix_identity(&matrix);
3997 translate_matrix(&matrix, 25.0f, 15.0f);
3998 scale_matrix(&matrix, 0.0f, 2.0f);
3999 hr = ID2D1RectangleGeometry_GetBounds(geometry, &matrix, &rect);
4000 ok(SUCCEEDED(hr), "Failed to get bounds.\n");
4001 match = compare_rect(&rect, 25.0f, 15.0f, 25.0f, 55.0f, 0);
4002 ok(match, "Got unexpected bounds {%.8e, %.8e, %.8e, %.8e}.\n",
4003 rect.left, rect.top, rect.right, rect.bottom);
4004 geometry_sink_init(&sink);
4005 hr = ID2D1RectangleGeometry_Simplify(geometry, D2D1_GEOMETRY_SIMPLIFICATION_OPTION_LINES,
4006 &matrix, 0.0f, &sink.ID2D1SimplifiedGeometrySink_iface);
4007 ok(SUCCEEDED(hr), "Failed to simplify geometry, hr %#x.\n", hr);
4008 geometry_sink_check(&sink, D2D1_FILL_MODE_ALTERNATE, 1, &expected_figures[2], 0);
4009 geometry_sink_cleanup(&sink);
4011 set_matrix_identity(&matrix);
4012 translate_matrix(&matrix, 30.0f, 45.0f);
4013 scale_matrix(&matrix, 0.5f, 0.0f);
4014 hr = ID2D1RectangleGeometry_GetBounds(geometry, &matrix, &rect);
4015 ok(SUCCEEDED(hr), "Failed to get bounds.\n");
4016 match = compare_rect(&rect, 30.0f, 45.0f, 35.0f, 45.0f, 0);
4017 ok(match, "Got unexpected bounds {%.8e, %.8e, %.8e, %.8e}.\n",
4018 rect.left, rect.top, rect.right, rect.bottom);
4019 geometry_sink_init(&sink);
4020 hr = ID2D1RectangleGeometry_Simplify(geometry, D2D1_GEOMETRY_SIMPLIFICATION_OPTION_LINES,
4021 &matrix, 0.0f, &sink.ID2D1SimplifiedGeometrySink_iface);
4022 ok(SUCCEEDED(hr), "Failed to simplify geometry, hr %#x.\n", hr);
4023 geometry_sink_check(&sink, D2D1_FILL_MODE_ALTERNATE, 1, &expected_figures[3], 0);
4024 geometry_sink_cleanup(&sink);
4026 set_matrix_identity(&matrix);
4027 scale_matrix(&matrix, 4.0f, 5.0f);
4028 rotate_matrix(&matrix, M_PI / 3.0f);
4029 translate_matrix(&matrix, 30.0f, 20.0f);
4030 hr = ID2D1Factory_CreateTransformedGeometry(factory, (ID2D1Geometry *)geometry, &matrix, &transformed_geometry);
4031 ok(SUCCEEDED(hr), "Failed to create transformed geometry, hr %#x.\n", hr);
4033 ID2D1TransformedGeometry_GetBounds(transformed_geometry, NULL, &rect);
4034 ok(SUCCEEDED(hr), "Failed to get bounds.\n");
4035 match = compare_rect(&rect, -7.85640717e+01f, 1.79903809e+02f, 1.07179594e+01f, 2.73205078e+02f, 1);
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 = ID2D1TransformedGeometry_Simplify(transformed_geometry, D2D1_GEOMETRY_SIMPLIFICATION_OPTION_CUBICS_AND_LINES,
4040 NULL, 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[4], 1);
4043 geometry_sink_cleanup(&sink);
4044 geometry_sink_init(&sink);
4045 hr = ID2D1TransformedGeometry_Simplify(transformed_geometry, D2D1_GEOMETRY_SIMPLIFICATION_OPTION_LINES,
4046 NULL, 0.0f, &sink.ID2D1SimplifiedGeometrySink_iface);
4047 ok(SUCCEEDED(hr), "Failed to simplify geometry, hr %#x.\n", hr);
4048 geometry_sink_check(&sink, D2D1_FILL_MODE_ALTERNATE, 1, &expected_figures[4], 1);
4049 geometry_sink_cleanup(&sink);
4051 set_matrix_identity(&matrix);
4052 rotate_matrix(&matrix, M_PI / -3.0f);
4053 scale_matrix(&matrix, 0.25f, 0.2f);
4054 ID2D1TransformedGeometry_GetBounds(transformed_geometry, &matrix, &rect);
4055 ok(SUCCEEDED(hr), "Failed to get bounds.\n");
4056 match = compare_rect(&rect, 30.0f, 20.0f, 40.0f, 40.0f, 2);
4057 ok(match, "Got unexpected bounds {%.8e, %.8e, %.8e, %.8e}.\n",
4058 rect.left, rect.top, rect.right, rect.bottom);
4059 geometry_sink_init(&sink);
4060 hr = ID2D1TransformedGeometry_Simplify(transformed_geometry, D2D1_GEOMETRY_SIMPLIFICATION_OPTION_LINES,
4061 &matrix, 0.0f, &sink.ID2D1SimplifiedGeometrySink_iface);
4062 ok(SUCCEEDED(hr), "Failed to simplify geometry, hr %#x.\n", hr);
4063 geometry_sink_check(&sink, D2D1_FILL_MODE_ALTERNATE, 1, &expected_figures[5], 4);
4064 geometry_sink_cleanup(&sink);
4066 set_matrix_identity(&matrix);
4067 scale_matrix(&matrix, 2.0f, 0.0f);
4068 ID2D1TransformedGeometry_GetBounds(transformed_geometry, &matrix, &rect);
4069 ok(SUCCEEDED(hr), "Failed to get bounds.\n");
4070 match = compare_rect(&rect, -1.57128143e+02f, 0.00000000e+00f, 2.14359188e+01f, 0.00000000e+00f, 1);
4071 ok(match, "Got unexpected bounds {%.8e, %.8e, %.8e, %.8e}.\n",
4072 rect.left, rect.top, rect.right, rect.bottom);
4073 geometry_sink_init(&sink);
4074 hr = ID2D1TransformedGeometry_Simplify(transformed_geometry, D2D1_GEOMETRY_SIMPLIFICATION_OPTION_CUBICS_AND_LINES,
4075 &matrix, 0.0f, &sink.ID2D1SimplifiedGeometrySink_iface);
4076 ok(SUCCEEDED(hr), "Failed to simplify geometry, hr %#x.\n", hr);
4077 geometry_sink_check(&sink, D2D1_FILL_MODE_ALTERNATE, 1, &expected_figures[6], 1);
4078 geometry_sink_cleanup(&sink);
4080 set_matrix_identity(&matrix);
4081 scale_matrix(&matrix, 0.0f, 0.5f);
4082 ID2D1TransformedGeometry_GetBounds(transformed_geometry, &matrix, &rect);
4083 ok(SUCCEEDED(hr), "Failed to get bounds.\n");
4084 match = compare_rect(&rect, 0.00000000e+00f, 8.99519043e+01f, 0.00000000e+00, 1.36602539e+02f, 1);
4085 ok(match, "Got unexpected bounds {%.8e, %.8e, %.8e, %.8e}.\n",
4086 rect.left, rect.top, rect.right, rect.bottom);
4087 geometry_sink_init(&sink);
4088 hr = ID2D1TransformedGeometry_Simplify(transformed_geometry, D2D1_GEOMETRY_SIMPLIFICATION_OPTION_CUBICS_AND_LINES,
4089 &matrix, 0.0f, &sink.ID2D1SimplifiedGeometrySink_iface);
4090 ok(SUCCEEDED(hr), "Failed to simplify geometry, hr %#x.\n", hr);
4091 geometry_sink_check(&sink, D2D1_FILL_MODE_ALTERNATE, 1, &expected_figures[7], 1);
4092 geometry_sink_cleanup(&sink);
4094 ID2D1TransformedGeometry_Release(transformed_geometry);
4095 ID2D1RectangleGeometry_Release(geometry);
4096 ID2D1Factory_Release(factory);
4099 static void test_rounded_rectangle_geometry(BOOL d3d11)
4101 ID2D1RoundedRectangleGeometry *geometry;
4102 D2D1_ROUNDED_RECT rect, rect2;
4103 ID2D1Factory *factory;
4104 HRESULT hr;
4106 hr = D2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED, &IID_ID2D1Factory, NULL, (void **)&factory);
4107 ok(SUCCEEDED(hr), "Failed to create factory, hr %#x.\n", hr);
4109 set_rounded_rect(&rect, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f);
4110 hr = ID2D1Factory_CreateRoundedRectangleGeometry(factory, &rect, &geometry);
4111 ok(SUCCEEDED(hr), "Failed to create geometry, hr %#x.\n", hr);
4113 ID2D1RoundedRectangleGeometry_GetRoundedRect(geometry, &rect2);
4114 ok(!memcmp(&rect, &rect2, sizeof(rect)), "Got unexpected rectangle {%.8e, %.8e, %.8e, %.8e, %.8e, %.8e}.\n",
4115 rect2.rect.left, rect2.rect.top, rect2.rect.right, rect2.rect.bottom, rect2.radiusX, rect2.radiusY);
4116 ID2D1RoundedRectangleGeometry_Release(geometry);
4118 /* X radius larger than half width. */
4119 set_rounded_rect(&rect, 0.0f, 0.0f, 50.0f, 40.0f, 30.0f, 5.0f);
4120 hr = ID2D1Factory_CreateRoundedRectangleGeometry(factory, &rect, &geometry);
4121 ID2D1RoundedRectangleGeometry_GetRoundedRect(geometry, &rect2);
4122 ok(!memcmp(&rect, &rect2, sizeof(rect)), "Got unexpected rectangle {%.8e, %.8e, %.8e, %.8e, %.8e, %.8e}.\n",
4123 rect2.rect.left, rect2.rect.top, rect2.rect.right, rect2.rect.bottom, rect2.radiusX, rect2.radiusY);
4124 ID2D1RoundedRectangleGeometry_Release(geometry);
4126 /* Y radius larger than half height. */
4127 set_rounded_rect(&rect, 0.0f, 0.0f, 50.0f, 40.0f, 5.0f, 30.0f);
4128 hr = ID2D1Factory_CreateRoundedRectangleGeometry(factory, &rect, &geometry);
4129 ID2D1RoundedRectangleGeometry_GetRoundedRect(geometry, &rect2);
4130 ok(!memcmp(&rect, &rect2, sizeof(rect)), "Got unexpected rectangle {%.8e, %.8e, %.8e, %.8e, %.8e, %.8e}.\n",
4131 rect2.rect.left, rect2.rect.top, rect2.rect.right, rect2.rect.bottom, rect2.radiusX, rect2.radiusY);
4132 ID2D1RoundedRectangleGeometry_Release(geometry);
4134 /* Both exceed rectangle size. */
4135 set_rounded_rect(&rect, 0.0f, 0.0f, 50.0f, 40.0f, 30.0f, 25.0f);
4136 hr = ID2D1Factory_CreateRoundedRectangleGeometry(factory, &rect, &geometry);
4137 ID2D1RoundedRectangleGeometry_GetRoundedRect(geometry, &rect2);
4138 ok(!memcmp(&rect, &rect2, sizeof(rect)), "Got unexpected rectangle {%.8e, %.8e, %.8e, %.8e, %.8e, %.8e}.\n",
4139 rect2.rect.left, rect2.rect.top, rect2.rect.right, rect2.rect.bottom, rect2.radiusX, rect2.radiusY);
4140 ID2D1RoundedRectangleGeometry_Release(geometry);
4142 ID2D1Factory_Release(factory);
4145 static void test_bitmap_formats(BOOL d3d11)
4147 D2D1_BITMAP_PROPERTIES bitmap_desc;
4148 struct d2d1_test_context ctx;
4149 D2D1_SIZE_U size = {4, 4};
4150 ID2D1RenderTarget *rt;
4151 ID2D1Bitmap *bitmap;
4152 unsigned int i, j;
4153 HRESULT hr;
4155 static const struct
4157 DXGI_FORMAT format;
4158 DWORD mask;
4160 bitmap_formats[] =
4162 {DXGI_FORMAT_R32G32B32A32_FLOAT, 0x8a},
4163 {DXGI_FORMAT_R16G16B16A16_FLOAT, 0x8a},
4164 {DXGI_FORMAT_R16G16B16A16_UNORM, 0x8a},
4165 {DXGI_FORMAT_R8G8B8A8_TYPELESS, 0x00},
4166 {DXGI_FORMAT_R8G8B8A8_UNORM, 0x0a},
4167 {DXGI_FORMAT_R8G8B8A8_UNORM_SRGB, 0x8a},
4168 {DXGI_FORMAT_R8G8B8A8_UINT, 0x00},
4169 {DXGI_FORMAT_R8G8B8A8_SNORM, 0x00},
4170 {DXGI_FORMAT_R8G8B8A8_SINT, 0x00},
4171 {DXGI_FORMAT_A8_UNORM, 0x06},
4172 {DXGI_FORMAT_B8G8R8A8_UNORM, 0x0a},
4173 {DXGI_FORMAT_B8G8R8X8_UNORM, 0x88},
4174 {DXGI_FORMAT_B8G8R8A8_TYPELESS, 0x00},
4175 {DXGI_FORMAT_B8G8R8A8_UNORM_SRGB, 0x8a},
4178 if (!init_test_context(&ctx, d3d11))
4179 return;
4181 rt = ctx.rt;
4182 bitmap_desc.dpiX = 96.0f;
4183 bitmap_desc.dpiY = 96.0f;
4184 for (i = 0; i < ARRAY_SIZE(bitmap_formats); ++i)
4186 for (j = 0; j < 4; ++j)
4188 if ((bitmap_formats[i].mask & (0x80 | (1u << j))) == (0x80 | (1u << j)))
4189 continue;
4191 bitmap_desc.pixelFormat.format = bitmap_formats[i].format;
4192 bitmap_desc.pixelFormat.alphaMode = j;
4193 hr = ID2D1RenderTarget_CreateBitmap(rt, size, NULL, 0, &bitmap_desc, &bitmap);
4194 if (bitmap_formats[i].mask & (1u << j))
4195 ok(hr == S_OK, "Got unexpected hr %#x, for format %#x/%#x.\n",
4196 hr, bitmap_formats[i].format, j);
4197 else
4198 ok(hr == D2DERR_UNSUPPORTED_PIXEL_FORMAT, "Got unexpected hr %#x, for format %#x/%#x.\n",
4199 hr, bitmap_formats[i].format, j);
4200 if (SUCCEEDED(hr))
4201 ID2D1Bitmap_Release(bitmap);
4205 release_test_context(&ctx);
4208 static void test_alpha_mode(BOOL d3d11)
4210 D2D1_RENDER_TARGET_PROPERTIES rt_desc;
4211 D2D1_BITMAP_PROPERTIES bitmap_desc;
4212 ID2D1SolidColorBrush *color_brush;
4213 ID2D1BitmapBrush *bitmap_brush;
4214 struct d2d1_test_context ctx;
4215 ID2D1RenderTarget *rt;
4216 ID2D1Bitmap *bitmap;
4217 D2D1_COLOR_F color;
4218 D2D1_RECT_F rect;
4219 D2D1_SIZE_U size;
4220 ULONG refcount;
4221 HRESULT hr;
4222 BOOL match;
4224 static const DWORD bitmap_data[] =
4226 0x7f7f0000, 0x7f7f7f00, 0x7f007f00, 0x7f007f7f,
4227 0x7f00007f, 0x7f7f007f, 0x7f000000, 0x7f404040,
4228 0x7f7f7f7f, 0x7f7f7f7f, 0x7f7f7f7f, 0x7f000000,
4229 0x7f7f7f7f, 0x7f000000, 0x7f000000, 0x7f000000,
4232 if (!init_test_context(&ctx, d3d11))
4233 return;
4235 rt = ctx.rt;
4236 ID2D1RenderTarget_SetAntialiasMode(rt, D2D1_ANTIALIAS_MODE_ALIASED);
4238 set_size_u(&size, 4, 4);
4239 bitmap_desc.pixelFormat.format = DXGI_FORMAT_B8G8R8A8_UNORM;
4240 bitmap_desc.pixelFormat.alphaMode = D2D1_ALPHA_MODE_IGNORE;
4241 bitmap_desc.dpiX = 96.0f / 40.0f;
4242 bitmap_desc.dpiY = 96.0f / 30.0f;
4243 hr = ID2D1RenderTarget_CreateBitmap(rt, size, bitmap_data, 4 * sizeof(*bitmap_data), &bitmap_desc, &bitmap);
4244 ok(SUCCEEDED(hr), "Failed to create bitmap, hr %#x.\n", hr);
4246 hr = ID2D1RenderTarget_CreateBitmapBrush(rt, bitmap, NULL, NULL, &bitmap_brush);
4247 ok(SUCCEEDED(hr), "Failed to create brush, hr %#x.\n", hr);
4248 ID2D1BitmapBrush_SetInterpolationMode(bitmap_brush, D2D1_BITMAP_INTERPOLATION_MODE_NEAREST_NEIGHBOR);
4249 ID2D1BitmapBrush_SetExtendModeX(bitmap_brush, D2D1_EXTEND_MODE_WRAP);
4250 ID2D1BitmapBrush_SetExtendModeY(bitmap_brush, D2D1_EXTEND_MODE_WRAP);
4252 set_color(&color, 0.0f, 1.0f, 0.0f, 0.75f);
4253 hr = ID2D1RenderTarget_CreateSolidColorBrush(rt, &color, NULL, &color_brush);
4254 ok(SUCCEEDED(hr), "Failed to create brush, hr %#x.\n", hr);
4256 ID2D1RenderTarget_BeginDraw(rt);
4257 ID2D1RenderTarget_Clear(rt, NULL);
4258 hr = ID2D1RenderTarget_EndDraw(rt, NULL, NULL);
4259 ok(SUCCEEDED(hr), "Failed to end draw, hr %#x.\n", hr);
4260 match = compare_surface(&ctx, "48c41aff3a130a17ee210866b2ab7d36763934d5");
4261 ok(match, "Surface does not match.\n");
4263 ID2D1RenderTarget_BeginDraw(rt);
4264 set_color(&color, 1.0f, 0.0f, 0.0f, 0.25f);
4265 ID2D1RenderTarget_Clear(rt, &color);
4266 hr = ID2D1RenderTarget_EndDraw(rt, NULL, NULL);
4267 ok(SUCCEEDED(hr), "Failed to end draw, hr %#x.\n", hr);
4268 match = compare_surface(&ctx, "6487e683730fb5a77c1911388d00b04664c5c4e4");
4269 ok(match, "Surface does not match.\n");
4271 ID2D1RenderTarget_BeginDraw(rt);
4272 set_color(&color, 0.0f, 0.0f, 1.0f, 0.75f);
4273 ID2D1RenderTarget_Clear(rt, &color);
4274 hr = ID2D1RenderTarget_EndDraw(rt, NULL, NULL);
4275 ok(SUCCEEDED(hr), "Failed to end draw, hr %#x.\n", hr);
4276 match = compare_surface(&ctx, "7a35ba09e43cbaf591388ff1ef8de56157630c98");
4277 ok(match, "Surface does not match.\n");
4279 ID2D1RenderTarget_BeginDraw(rt);
4281 set_rect(&rect, 0.0f, 0.0f, 160.0f, 120.0f);
4282 ID2D1RenderTarget_FillRectangle(rt, &rect, (ID2D1Brush *)bitmap_brush);
4283 set_rect(&rect, 160.0f, 0.0f, 320.0f, 120.0f);
4284 ID2D1BitmapBrush_SetOpacity(bitmap_brush, 0.75f);
4285 ID2D1RenderTarget_FillRectangle(rt, &rect, (ID2D1Brush *)bitmap_brush);
4286 set_rect(&rect, 320.0f, 0.0f, 480.0f, 120.0f);
4287 ID2D1BitmapBrush_SetOpacity(bitmap_brush, 0.25f);
4288 ID2D1RenderTarget_FillRectangle(rt, &rect, (ID2D1Brush *)bitmap_brush);
4290 ID2D1Bitmap_Release(bitmap);
4291 bitmap_desc.pixelFormat.alphaMode = D2D1_ALPHA_MODE_PREMULTIPLIED;
4292 hr = ID2D1RenderTarget_CreateBitmap(rt, size, bitmap_data, 4 * sizeof(*bitmap_data), &bitmap_desc, &bitmap);
4293 ok(SUCCEEDED(hr), "Failed to create bitmap, hr %#x.\n", hr);
4294 ID2D1BitmapBrush_SetBitmap(bitmap_brush, bitmap);
4296 set_rect(&rect, 0.0f, 120.0f, 160.0f, 240.0f);
4297 ID2D1BitmapBrush_SetOpacity(bitmap_brush, 1.0f);
4298 ID2D1RenderTarget_FillRectangle(rt, &rect, (ID2D1Brush *)bitmap_brush);
4299 set_rect(&rect, 160.0f, 120.0f, 320.0f, 240.0f);
4300 ID2D1BitmapBrush_SetOpacity(bitmap_brush, 0.75f);
4301 ID2D1RenderTarget_FillRectangle(rt, &rect, (ID2D1Brush *)bitmap_brush);
4302 set_rect(&rect, 320.0f, 120.0f, 480.0f, 240.0f);
4303 ID2D1BitmapBrush_SetOpacity(bitmap_brush, 0.25f);
4304 ID2D1RenderTarget_FillRectangle(rt, &rect, (ID2D1Brush *)bitmap_brush);
4306 set_rect(&rect, 0.0f, 240.0f, 160.0f, 360.0f);
4307 ID2D1RenderTarget_FillRectangle(rt, &rect, (ID2D1Brush *)color_brush);
4308 set_rect(&rect, 160.0f, 240.0f, 320.0f, 360.0f);
4309 ID2D1SolidColorBrush_SetOpacity(color_brush, 0.75f);
4310 ID2D1RenderTarget_FillRectangle(rt, &rect, (ID2D1Brush *)color_brush);
4311 set_rect(&rect, 320.0f, 240.0f, 480.0f, 360.0f);
4312 ID2D1SolidColorBrush_SetOpacity(color_brush, 0.25f);
4313 ID2D1RenderTarget_FillRectangle(rt, &rect, (ID2D1Brush *)color_brush);
4315 hr = ID2D1RenderTarget_EndDraw(rt, NULL, NULL);
4316 ok(SUCCEEDED(hr), "Failed to end draw, hr %#x.\n", hr);
4317 match = compare_surface(&ctx, "14f8ac64b70966c7c3c6281c59aaecdb17c3b16a");
4318 ok(match, "Surface does not match.\n");
4320 rt_desc.type = D2D1_RENDER_TARGET_TYPE_DEFAULT;
4321 rt_desc.pixelFormat.format = DXGI_FORMAT_UNKNOWN;
4322 rt_desc.pixelFormat.alphaMode = D2D1_ALPHA_MODE_IGNORE;
4323 rt_desc.dpiX = 0.0f;
4324 rt_desc.dpiY = 0.0f;
4325 rt_desc.usage = D2D1_RENDER_TARGET_USAGE_NONE;
4326 rt_desc.minLevel = D2D1_FEATURE_LEVEL_DEFAULT;
4327 rt = create_render_target_desc(ctx.surface, &rt_desc, d3d11);
4328 ok(!!rt, "Failed to create render target.\n");
4330 ID2D1RenderTarget_SetAntialiasMode(rt, D2D1_ANTIALIAS_MODE_ALIASED);
4332 ID2D1Bitmap_Release(bitmap);
4333 bitmap_desc.pixelFormat.alphaMode = D2D1_ALPHA_MODE_IGNORE;
4334 hr = ID2D1RenderTarget_CreateBitmap(rt, size, bitmap_data, 4 * sizeof(*bitmap_data), &bitmap_desc, &bitmap);
4335 ok(SUCCEEDED(hr), "Failed to create bitmap, hr %#x.\n", hr);
4336 ID2D1BitmapBrush_SetBitmap(bitmap_brush, bitmap);
4338 ID2D1BitmapBrush_Release(bitmap_brush);
4339 hr = ID2D1RenderTarget_CreateBitmapBrush(rt, bitmap, NULL, NULL, &bitmap_brush);
4340 ok(SUCCEEDED(hr), "Failed to create brush, hr %#x.\n", hr);
4341 ID2D1BitmapBrush_SetInterpolationMode(bitmap_brush, D2D1_BITMAP_INTERPOLATION_MODE_NEAREST_NEIGHBOR);
4342 ID2D1BitmapBrush_SetExtendModeX(bitmap_brush, D2D1_EXTEND_MODE_WRAP);
4343 ID2D1BitmapBrush_SetExtendModeY(bitmap_brush, D2D1_EXTEND_MODE_WRAP);
4345 ID2D1SolidColorBrush_Release(color_brush);
4346 set_color(&color, 0.0f, 1.0f, 0.0f, 0.75f);
4347 hr = ID2D1RenderTarget_CreateSolidColorBrush(rt, &color, NULL, &color_brush);
4348 ok(SUCCEEDED(hr), "Failed to create brush, hr %#x.\n", hr);
4350 ID2D1RenderTarget_BeginDraw(rt);
4351 ID2D1RenderTarget_Clear(rt, NULL);
4352 hr = ID2D1RenderTarget_EndDraw(rt, NULL, NULL);
4353 ok(SUCCEEDED(hr), "Failed to end draw, hr %#x.\n", hr);
4354 match = compare_surface(&ctx, "b44510bf2d2e61a8d7c0ad862de49a471f1fd13f");
4355 ok(match, "Surface does not match.\n");
4357 ID2D1RenderTarget_BeginDraw(rt);
4358 set_color(&color, 1.0f, 0.0f, 0.0f, 0.25f);
4359 ID2D1RenderTarget_Clear(rt, &color);
4360 hr = ID2D1RenderTarget_EndDraw(rt, NULL, NULL);
4361 ok(SUCCEEDED(hr), "Failed to end draw, hr %#x.\n", hr);
4362 match = compare_surface(&ctx, "2184f4a9198fc1de09ac85301b7a03eebadd9b81");
4363 ok(match, "Surface does not match.\n");
4365 ID2D1RenderTarget_BeginDraw(rt);
4366 set_color(&color, 0.0f, 0.0f, 1.0f, 0.75f);
4367 ID2D1RenderTarget_Clear(rt, &color);
4368 hr = ID2D1RenderTarget_EndDraw(rt, NULL, NULL);
4369 ok(SUCCEEDED(hr), "Failed to end draw, hr %#x.\n", hr);
4370 match = compare_surface(&ctx, "6527ec83b4039c895b50f9b3e144fe0cf90d1889");
4371 ok(match, "Surface does not match.\n");
4373 ID2D1RenderTarget_BeginDraw(rt);
4375 set_rect(&rect, 0.0f, 0.0f, 160.0f, 120.0f);
4376 ID2D1RenderTarget_FillRectangle(rt, &rect, (ID2D1Brush *)bitmap_brush);
4377 set_rect(&rect, 160.0f, 0.0f, 320.0f, 120.0f);
4378 ID2D1BitmapBrush_SetOpacity(bitmap_brush, 0.75f);
4379 ID2D1RenderTarget_FillRectangle(rt, &rect, (ID2D1Brush *)bitmap_brush);
4380 set_rect(&rect, 320.0f, 0.0f, 480.0f, 120.0f);
4381 ID2D1BitmapBrush_SetOpacity(bitmap_brush, 0.25f);
4382 ID2D1RenderTarget_FillRectangle(rt, &rect, (ID2D1Brush *)bitmap_brush);
4384 ID2D1Bitmap_Release(bitmap);
4385 bitmap_desc.pixelFormat.alphaMode = D2D1_ALPHA_MODE_PREMULTIPLIED;
4386 hr = ID2D1RenderTarget_CreateBitmap(rt, size, bitmap_data, 4 * sizeof(*bitmap_data), &bitmap_desc, &bitmap);
4387 ok(SUCCEEDED(hr), "Failed to create bitmap, hr %#x.\n", hr);
4388 ID2D1BitmapBrush_SetBitmap(bitmap_brush, bitmap);
4390 set_rect(&rect, 0.0f, 120.0f, 160.0f, 240.0f);
4391 ID2D1BitmapBrush_SetOpacity(bitmap_brush, 1.0f);
4392 ID2D1RenderTarget_FillRectangle(rt, &rect, (ID2D1Brush *)bitmap_brush);
4393 set_rect(&rect, 160.0f, 120.0f, 320.0f, 240.0f);
4394 ID2D1BitmapBrush_SetOpacity(bitmap_brush, 0.75f);
4395 ID2D1RenderTarget_FillRectangle(rt, &rect, (ID2D1Brush *)bitmap_brush);
4396 set_rect(&rect, 320.0f, 120.0f, 480.0f, 240.0f);
4397 ID2D1BitmapBrush_SetOpacity(bitmap_brush, 0.25f);
4398 ID2D1RenderTarget_FillRectangle(rt, &rect, (ID2D1Brush *)bitmap_brush);
4400 set_rect(&rect, 0.0f, 240.0f, 160.0f, 360.0f);
4401 ID2D1RenderTarget_FillRectangle(rt, &rect, (ID2D1Brush *)color_brush);
4402 set_rect(&rect, 160.0f, 240.0f, 320.0f, 360.0f);
4403 ID2D1SolidColorBrush_SetOpacity(color_brush, 0.75f);
4404 ID2D1RenderTarget_FillRectangle(rt, &rect, (ID2D1Brush *)color_brush);
4405 set_rect(&rect, 320.0f, 240.0f, 480.0f, 360.0f);
4406 ID2D1SolidColorBrush_SetOpacity(color_brush, 0.25f);
4407 ID2D1RenderTarget_FillRectangle(rt, &rect, (ID2D1Brush *)color_brush);
4409 hr = ID2D1RenderTarget_EndDraw(rt, NULL, NULL);
4410 ok(SUCCEEDED(hr), "Failed to end draw, hr %#x.\n", hr);
4411 match = compare_surface(&ctx, "465f5a3190d7bde408b3206b4be939fb22f8a3d6");
4412 ok(match, "Surface does not match.\n");
4414 refcount = ID2D1Bitmap_Release(bitmap);
4415 ok(refcount == 1, "Bitmap has %u references left.\n", refcount);
4416 ID2D1SolidColorBrush_Release(color_brush);
4417 ID2D1BitmapBrush_Release(bitmap_brush);
4418 ID2D1RenderTarget_Release(rt);
4419 release_test_context(&ctx);
4422 static void test_shared_bitmap(BOOL d3d11)
4424 IWICBitmap *wic_bitmap1, *wic_bitmap2;
4425 ID2D1GdiInteropRenderTarget *interop;
4426 D2D1_RENDER_TARGET_PROPERTIES desc;
4427 D2D1_BITMAP_PROPERTIES bitmap_desc;
4428 ID2D1RenderTarget *rt1, *rt2, *rt3;
4429 IDXGISurface *surface2;
4430 ID2D1Factory *factory1, *factory2;
4431 IWICImagingFactory *wic_factory;
4432 ID2D1Bitmap *bitmap1, *bitmap2;
4433 DXGI_SURFACE_DESC surface_desc;
4434 D2D1_PIXEL_FORMAT pixel_format;
4435 struct d2d1_test_context ctx;
4436 IDXGISwapChain *swapchain2;
4437 D2D1_SIZE_U size = {4, 4};
4438 IDXGISurface1 *surface3;
4439 IDXGIDevice *device2;
4440 HWND window2;
4441 HRESULT hr;
4443 if (!init_test_context(&ctx, d3d11))
4444 return;
4446 window2 = create_window();
4447 swapchain2 = create_swapchain(ctx.device, window2, TRUE);
4448 hr = IDXGISwapChain_GetBuffer(swapchain2, 0, &IID_IDXGISurface, (void **)&surface2);
4449 ok(SUCCEEDED(hr), "Failed to get buffer, hr %#x.\n", hr);
4451 CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
4452 hr = CoCreateInstance(&CLSID_WICImagingFactory, NULL, CLSCTX_INPROC_SERVER,
4453 &IID_IWICImagingFactory, (void **)&wic_factory);
4454 ok(SUCCEEDED(hr), "Failed to create WIC imaging factory, hr %#x.\n", hr);
4455 hr = IWICImagingFactory_CreateBitmap(wic_factory, 640, 480,
4456 &GUID_WICPixelFormat32bppPBGRA, WICBitmapCacheOnDemand, &wic_bitmap1);
4457 ok(SUCCEEDED(hr), "Failed to create bitmap, hr %#x.\n", hr);
4458 hr = IWICImagingFactory_CreateBitmap(wic_factory, 640, 480,
4459 &GUID_WICPixelFormat32bppPBGRA, WICBitmapCacheOnDemand, &wic_bitmap2);
4460 ok(SUCCEEDED(hr), "Failed to create bitmap, hr %#x.\n", hr);
4461 IWICImagingFactory_Release(wic_factory);
4463 desc.type = D2D1_RENDER_TARGET_TYPE_DEFAULT;
4464 desc.pixelFormat.format = DXGI_FORMAT_UNKNOWN;
4465 desc.pixelFormat.alphaMode = D2D1_ALPHA_MODE_PREMULTIPLIED;
4466 desc.dpiX = 0.0f;
4467 desc.dpiY = 0.0f;
4468 desc.usage = D2D1_RENDER_TARGET_USAGE_NONE;
4469 desc.minLevel = D2D1_FEATURE_LEVEL_DEFAULT;
4471 bitmap_desc.pixelFormat.format = DXGI_FORMAT_B8G8R8A8_UNORM;
4472 bitmap_desc.pixelFormat.alphaMode = D2D1_ALPHA_MODE_PREMULTIPLIED;
4473 bitmap_desc.dpiX = 96.0f;
4474 bitmap_desc.dpiY = 96.0f;
4476 hr = D2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED, &IID_ID2D1Factory, NULL, (void **)&factory1);
4477 ok(SUCCEEDED(hr), "Failed to create factory, hr %#x.\n", hr);
4478 hr = D2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED, &IID_ID2D1Factory, NULL, (void **)&factory2);
4479 ok(SUCCEEDED(hr), "Failed to create factory, hr %#x.\n", hr);
4481 /* DXGI surface render targets with the same device and factory. */
4482 hr = ID2D1Factory_CreateDxgiSurfaceRenderTarget(factory1, ctx.surface, &desc, &rt1);
4483 ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr);
4484 hr = ID2D1RenderTarget_CreateBitmap(rt1, size, NULL, 0, &bitmap_desc, &bitmap1);
4485 check_bitmap_surface(bitmap1, TRUE, 0);
4486 ok(SUCCEEDED(hr), "Failed to create bitmap, hr %#x.\n", hr);
4488 hr = ID2D1Factory_CreateDxgiSurfaceRenderTarget(factory1, surface2, &desc, &rt2);
4489 ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr);
4490 hr = ID2D1RenderTarget_CreateSharedBitmap(rt2, &IID_ID2D1Bitmap, bitmap1, NULL, &bitmap2);
4491 ok(SUCCEEDED(hr), "Failed to create bitmap, hr %#x.\n", hr);
4492 check_bitmap_surface(bitmap2, TRUE, 0);
4493 ID2D1Bitmap_Release(bitmap2);
4494 hr = ID2D1RenderTarget_CreateSharedBitmap(rt2, &IID_IUnknown, bitmap1, NULL, &bitmap2);
4495 ok(hr == E_INVALIDARG, "Got unexpected hr %#x.\n", hr);
4496 ID2D1RenderTarget_Release(rt2);
4498 /* DXGI surface render targets with the same device but different factories. */
4499 hr = ID2D1Factory_CreateDxgiSurfaceRenderTarget(factory2, surface2, &desc, &rt2);
4500 ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr);
4501 hr = ID2D1RenderTarget_CreateSharedBitmap(rt2, &IID_ID2D1Bitmap, bitmap1, NULL, &bitmap2);
4502 ok(hr == D2DERR_WRONG_FACTORY, "Got unexpected hr %#x.\n", hr);
4503 ID2D1RenderTarget_Release(rt2);
4505 /* DXGI surface render targets with different devices but the same factory. */
4506 IDXGISurface_Release(surface2);
4507 IDXGISwapChain_Release(swapchain2);
4508 device2 = create_device(d3d11);
4509 ok(!!device2, "Failed to create device.\n");
4510 swapchain2 = create_swapchain(device2, window2, TRUE);
4511 hr = IDXGISwapChain_GetBuffer(swapchain2, 0, &IID_IDXGISurface, (void **)&surface2);
4512 ok(SUCCEEDED(hr), "Failed to get buffer, hr %#x.\n", hr);
4514 hr = ID2D1Factory_CreateDxgiSurfaceRenderTarget(factory1, surface2, &desc, &rt2);
4515 ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr);
4516 hr = ID2D1RenderTarget_CreateSharedBitmap(rt2, &IID_ID2D1Bitmap, bitmap1, NULL, &bitmap2);
4517 ok(hr == D2DERR_UNSUPPORTED_OPERATION, "Got unexpected hr %#x.\n", hr);
4518 ID2D1RenderTarget_Release(rt2);
4520 /* DXGI surface render targets with different devices and different factories. */
4521 hr = ID2D1Factory_CreateDxgiSurfaceRenderTarget(factory2, surface2, &desc, &rt2);
4522 ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr);
4523 hr = ID2D1RenderTarget_CreateSharedBitmap(rt2, &IID_ID2D1Bitmap, bitmap1, NULL, &bitmap2);
4524 ok(hr == D2DERR_WRONG_FACTORY, "Got unexpected hr %#x.\n", hr);
4525 ID2D1RenderTarget_Release(rt2);
4527 /* DXGI surface render target and WIC bitmap render target, same factory. */
4528 hr = ID2D1Factory_CreateWicBitmapRenderTarget(factory1, wic_bitmap2, &desc, &rt2);
4529 ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr);
4530 hr = ID2D1RenderTarget_CreateSharedBitmap(rt2, &IID_ID2D1Bitmap, bitmap1, NULL, &bitmap2);
4531 ok(hr == D2DERR_UNSUPPORTED_OPERATION, "Got unexpected hr %#x.\n", hr);
4532 ID2D1RenderTarget_Release(rt2);
4534 /* WIC bitmap render targets on different D2D factories. */
4535 ID2D1Bitmap_Release(bitmap1);
4536 ID2D1RenderTarget_Release(rt1);
4537 hr = ID2D1Factory_CreateWicBitmapRenderTarget(factory1, wic_bitmap1, &desc, &rt1);
4538 ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr);
4539 hr = ID2D1RenderTarget_CreateBitmap(rt1, size, NULL, 0, &bitmap_desc, &bitmap1);
4540 ok(SUCCEEDED(hr), "Failed to create bitmap, hr %#x.\n", hr);
4542 hr = ID2D1RenderTarget_QueryInterface(rt1, &IID_ID2D1GdiInteropRenderTarget, (void **)&interop);
4543 ok(SUCCEEDED(hr), "Failed to get interop target, hr %#x.\n", hr);
4544 hr = ID2D1GdiInteropRenderTarget_QueryInterface(interop, &IID_ID2D1RenderTarget, (void **)&rt3);
4545 ok(SUCCEEDED(hr), "Failed to get render target back, %#x.\n", hr);
4546 ok(rt3 == rt1, "Unexpected render target\n");
4547 ID2D1RenderTarget_Release(rt3);
4548 ID2D1GdiInteropRenderTarget_Release(interop);
4550 hr = ID2D1Factory_CreateWicBitmapRenderTarget(factory2, wic_bitmap2, &desc, &rt2);
4551 ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr);
4552 hr = ID2D1RenderTarget_CreateSharedBitmap(rt2, &IID_ID2D1Bitmap, bitmap1, NULL, &bitmap2);
4553 ok(hr == D2DERR_WRONG_FACTORY, "Got unexpected hr %#x.\n", hr);
4554 ID2D1RenderTarget_Release(rt2);
4556 /* WIC bitmap render targets on the same D2D factory. */
4557 hr = ID2D1Factory_CreateWicBitmapRenderTarget(factory1, wic_bitmap2, &desc, &rt2);
4558 ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr);
4559 hr = ID2D1RenderTarget_CreateSharedBitmap(rt2, &IID_ID2D1Bitmap, bitmap1, NULL, &bitmap2);
4560 ok(SUCCEEDED(hr), "Failed to create bitmap, hr %#x.\n", hr);
4561 check_bitmap_surface(bitmap2, FALSE, 0);
4562 ID2D1Bitmap_Release(bitmap2);
4563 ID2D1RenderTarget_Release(rt2);
4565 /* Shared DXGI surface. */
4566 desc.type = D2D1_RENDER_TARGET_TYPE_DEFAULT;
4567 desc.pixelFormat.format = DXGI_FORMAT_B8G8R8A8_UNORM;
4568 desc.pixelFormat.alphaMode = D2D1_ALPHA_MODE_PREMULTIPLIED;
4569 desc.dpiX = 0.0f;
4570 desc.dpiY = 0.0f;
4571 desc.usage = D2D1_RENDER_TARGET_USAGE_NONE;
4572 desc.minLevel = D2D1_FEATURE_LEVEL_DEFAULT;
4574 hr = ID2D1Factory_CreateDxgiSurfaceRenderTarget(factory1, surface2, &desc, &rt2);
4575 ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr);
4577 bitmap_desc.pixelFormat.format = DXGI_FORMAT_B8G8R8A8_UNORM;
4578 bitmap_desc.pixelFormat.alphaMode = D2D1_ALPHA_MODE_PREMULTIPLIED;
4579 bitmap_desc.dpiX = 0.0f;
4580 bitmap_desc.dpiY = 0.0f;
4582 hr = ID2D1RenderTarget_CreateSharedBitmap(rt2, &IID_IDXGISurface, surface2, &bitmap_desc, &bitmap2);
4583 ok(SUCCEEDED(hr) || broken(hr == E_INVALIDARG) /* vista */, "Failed to create bitmap, hr %#x.\n", hr);
4585 if (SUCCEEDED(hr))
4587 static const struct bitmap_format_test
4589 D2D1_PIXEL_FORMAT original;
4590 D2D1_PIXEL_FORMAT result;
4591 HRESULT hr;
4593 bitmap_format_tests[] =
4595 { { DXGI_FORMAT_UNKNOWN, D2D1_ALPHA_MODE_PREMULTIPLIED },
4596 { DXGI_FORMAT_B8G8R8A8_UNORM, D2D1_ALPHA_MODE_PREMULTIPLIED } },
4598 { { DXGI_FORMAT_UNKNOWN, D2D1_ALPHA_MODE_IGNORE },
4599 { DXGI_FORMAT_B8G8R8A8_UNORM, D2D1_ALPHA_MODE_IGNORE } },
4601 { { DXGI_FORMAT_UNKNOWN, D2D1_ALPHA_MODE_UNKNOWN }, { 0 }, WINCODEC_ERR_UNSUPPORTEDPIXELFORMAT },
4603 { { DXGI_FORMAT_B8G8R8A8_UNORM, D2D1_ALPHA_MODE_UNKNOWN }, { 0 }, WINCODEC_ERR_UNSUPPORTEDPIXELFORMAT },
4605 { { DXGI_FORMAT_B8G8R8A8_UNORM, D2D1_ALPHA_MODE_IGNORE },
4606 { DXGI_FORMAT_B8G8R8A8_UNORM, D2D1_ALPHA_MODE_IGNORE } },
4608 { { DXGI_FORMAT_UNKNOWN, D2D1_ALPHA_MODE_STRAIGHT }, { 0 }, WINCODEC_ERR_UNSUPPORTEDPIXELFORMAT },
4609 { { DXGI_FORMAT_B8G8R8A8_UNORM, D2D1_ALPHA_MODE_STRAIGHT }, { 0 }, WINCODEC_ERR_UNSUPPORTEDPIXELFORMAT },
4611 unsigned int i;
4613 size = ID2D1Bitmap_GetPixelSize(bitmap2);
4614 hr = IDXGISurface_GetDesc(surface2, &surface_desc);
4615 ok(SUCCEEDED(hr), "Failed to get surface description, hr %#x.\n", hr);
4616 ok(size.width == surface_desc.Width && size.height == surface_desc.Height, "Got wrong bitmap size.\n");
4618 check_bitmap_surface(bitmap2, TRUE, D2D1_BITMAP_OPTIONS_TARGET | D2D1_BITMAP_OPTIONS_CANNOT_DRAW);
4620 ID2D1Bitmap_Release(bitmap2);
4622 /* IDXGISurface1 is supported too. */
4623 if (IDXGISurface_QueryInterface(surface2, &IID_IDXGISurface1, (void **)&surface3) == S_OK)
4625 hr = ID2D1RenderTarget_CreateSharedBitmap(rt2, &IID_IDXGISurface1, surface3, &bitmap_desc, &bitmap2);
4626 ok(SUCCEEDED(hr), "Failed to create bitmap, hr %#x.\n", hr);
4628 ID2D1Bitmap_Release(bitmap2);
4629 IDXGISurface1_Release(surface3);
4632 for (i = 0; i < ARRAY_SIZE(bitmap_format_tests); ++i)
4634 bitmap_desc.pixelFormat = bitmap_format_tests[i].original;
4636 hr = ID2D1RenderTarget_CreateSharedBitmap(rt2, &IID_IDXGISurface, surface2, &bitmap_desc, &bitmap2);
4637 todo_wine_if(i == 2 || i == 3 || i == 5 || i == 6)
4638 ok(hr == bitmap_format_tests[i].hr, "%u: unexpected hr %#x.\n", i, hr);
4640 if (SUCCEEDED(bitmap_format_tests[i].hr))
4642 pixel_format = ID2D1Bitmap_GetPixelFormat(bitmap2);
4643 ok(pixel_format.format == bitmap_format_tests[i].result.format, "%u: unexpected pixel format %#x.\n",
4644 i, pixel_format.format);
4645 ok(pixel_format.alphaMode == bitmap_format_tests[i].result.alphaMode, "%u: unexpected alpha mode %d.\n",
4646 i, pixel_format.alphaMode);
4648 ID2D1Bitmap_Release(bitmap2);
4653 ID2D1RenderTarget_Release(rt2);
4655 ID2D1Bitmap_Release(bitmap1);
4656 ID2D1RenderTarget_Release(rt1);
4657 ID2D1Factory_Release(factory2);
4658 ID2D1Factory_Release(factory1);
4659 IWICBitmap_Release(wic_bitmap2);
4660 IWICBitmap_Release(wic_bitmap1);
4661 IDXGISurface_Release(surface2);
4662 IDXGISwapChain_Release(swapchain2);
4663 IDXGIDevice_Release(device2);
4664 release_test_context(&ctx);
4665 DestroyWindow(window2);
4666 CoUninitialize();
4669 static void test_bitmap_updates(BOOL d3d11)
4671 D2D1_BITMAP_PROPERTIES bitmap_desc;
4672 struct d2d1_test_context ctx;
4673 ID2D1RenderTarget *rt;
4674 D2D1_RECT_U dst_rect;
4675 ID2D1Bitmap *bitmap;
4676 D2D1_COLOR_F color;
4677 D2D1_RECT_F rect;
4678 D2D1_SIZE_U size;
4679 HRESULT hr;
4680 BOOL match;
4682 static const DWORD bitmap_data[] =
4684 0xffff0000, 0xffffff00, 0xff00ff00, 0xff00ffff,
4685 0xff0000ff, 0xffff00ff, 0xff000000, 0xff7f7f7f,
4686 0xffffffff, 0xffffffff, 0xffffffff, 0xff000000,
4687 0xffffffff, 0xff000000, 0xff000000, 0xff000000,
4690 if (!init_test_context(&ctx, d3d11))
4691 return;
4693 rt = ctx.rt;
4694 ID2D1RenderTarget_SetAntialiasMode(rt, D2D1_ANTIALIAS_MODE_ALIASED);
4696 ID2D1RenderTarget_BeginDraw(rt);
4697 set_color(&color, 0.0f, 0.0f, 1.0f, 1.0f);
4698 ID2D1RenderTarget_Clear(rt, &color);
4700 set_size_u(&size, 4, 4);
4701 bitmap_desc.pixelFormat.format = DXGI_FORMAT_B8G8R8A8_UNORM;
4702 bitmap_desc.pixelFormat.alphaMode = D2D1_ALPHA_MODE_PREMULTIPLIED;
4703 bitmap_desc.dpiX = 96.0f;
4704 bitmap_desc.dpiY = 96.0f;
4705 hr = ID2D1RenderTarget_CreateBitmap(rt, size, NULL, 0, &bitmap_desc, &bitmap);
4706 ok(SUCCEEDED(hr), "Failed to create bitmap, hr %#x.\n", hr);
4708 set_rect(&rect, 0.0f, 0.0f, 320.0f, 240.0f);
4709 ID2D1RenderTarget_DrawBitmap(rt, bitmap, &rect, 1.0f,
4710 D2D1_BITMAP_INTERPOLATION_MODE_NEAREST_NEIGHBOR, NULL);
4712 ID2D1Bitmap_Release(bitmap);
4714 bitmap_desc.pixelFormat.alphaMode = D2D1_ALPHA_MODE_IGNORE;
4715 hr = ID2D1RenderTarget_CreateBitmap(rt, size, NULL, 0, &bitmap_desc, &bitmap);
4716 ok(SUCCEEDED(hr), "Failed to create bitmap, hr %#x.\n", hr);
4718 set_rect(&rect, 0.0f, 240.0f, 320.0f, 480.0f);
4719 ID2D1RenderTarget_DrawBitmap(rt, bitmap, &rect, 1.0f,
4720 D2D1_BITMAP_INTERPOLATION_MODE_NEAREST_NEIGHBOR, NULL);
4722 set_rect_u(&dst_rect, 1, 1, 3, 3);
4723 hr = ID2D1Bitmap_CopyFromMemory(bitmap, &dst_rect, bitmap_data, 4 * sizeof(*bitmap_data));
4724 ok(SUCCEEDED(hr), "Failed to update bitmap, hr %#x.\n", hr);
4725 set_rect_u(&dst_rect, 0, 3, 3, 4);
4726 hr = ID2D1Bitmap_CopyFromMemory(bitmap, &dst_rect, &bitmap_data[6], 4 * sizeof(*bitmap_data));
4727 ok(SUCCEEDED(hr), "Failed to update bitmap, hr %#x.\n", hr);
4728 set_rect_u(&dst_rect, 0, 0, 4, 1);
4729 hr = ID2D1Bitmap_CopyFromMemory(bitmap, &dst_rect, &bitmap_data[10], 4 * sizeof(*bitmap_data));
4730 ok(SUCCEEDED(hr), "Failed to update bitmap, hr %#x.\n", hr);
4731 set_rect_u(&dst_rect, 0, 1, 1, 3);
4732 hr = ID2D1Bitmap_CopyFromMemory(bitmap, &dst_rect, &bitmap_data[2], sizeof(*bitmap_data));
4733 ok(SUCCEEDED(hr), "Failed to update bitmap, hr %#x.\n", hr);
4734 set_rect_u(&dst_rect, 4, 4, 3, 1);
4735 hr = ID2D1Bitmap_CopyFromMemory(bitmap, &dst_rect, bitmap_data, sizeof(*bitmap_data));
4736 ok(SUCCEEDED(hr), "Failed to update bitmap, hr %#x.\n", hr);
4737 set_rect(&rect, 320.0f, 240.0f, 640.0f, 480.0f);
4738 ID2D1RenderTarget_DrawBitmap(rt, bitmap, &rect, 1.0f,
4739 D2D1_BITMAP_INTERPOLATION_MODE_NEAREST_NEIGHBOR, NULL);
4741 hr = ID2D1Bitmap_CopyFromMemory(bitmap, NULL, bitmap_data, 4 * sizeof(*bitmap_data));
4742 ok(SUCCEEDED(hr), "Failed to update bitmap, hr %#x.\n", hr);
4743 set_rect(&rect, 320.0f, 0.0f, 640.0f, 240.0f);
4744 ID2D1RenderTarget_DrawBitmap(rt, bitmap, &rect, 1.0f,
4745 D2D1_BITMAP_INTERPOLATION_MODE_NEAREST_NEIGHBOR, NULL);
4747 hr = ID2D1RenderTarget_EndDraw(rt, NULL, NULL);
4748 ok(SUCCEEDED(hr), "Failed to end draw, hr %#x.\n", hr);
4750 match = compare_surface(&ctx, "cb8136c91fbbdc76bb83b8c09edc1907b0a5d0a6");
4751 ok(match, "Surface does not match.\n");
4753 ID2D1Bitmap_Release(bitmap);
4754 release_test_context(&ctx);
4757 static void test_opacity_brush(BOOL d3d11)
4759 ID2D1BitmapBrush *bitmap_brush, *opacity_brush;
4760 D2D1_BITMAP_PROPERTIES bitmap_desc;
4761 ID2D1RectangleGeometry *geometry;
4762 ID2D1SolidColorBrush *color_brush;
4763 struct d2d1_test_context ctx;
4764 D2D1_MATRIX_3X2_F matrix;
4765 ID2D1RenderTarget *rt;
4766 ID2D1Factory *factory;
4767 ID2D1Bitmap *bitmap;
4768 D2D1_COLOR_F color;
4769 D2D1_RECT_F rect;
4770 D2D1_SIZE_U size;
4771 ULONG refcount;
4772 HRESULT hr;
4773 BOOL match;
4775 static const DWORD bitmap_data[] =
4777 0xffff0000, 0x40ffff00, 0x4000ff00, 0xff00ffff,
4778 0x7f0000ff, 0x00ff00ff, 0x00000000, 0x7f7f7f7f,
4779 0x7fffffff, 0x00ffffff, 0x00ffffff, 0x7f000000,
4780 0xffffffff, 0x40000000, 0x40000000, 0xff000000,
4783 if (!init_test_context(&ctx, d3d11))
4784 return;
4786 rt = ctx.rt;
4787 ID2D1RenderTarget_GetFactory(rt, &factory);
4789 ID2D1RenderTarget_SetDpi(rt, 192.0f, 48.0f);
4790 ID2D1RenderTarget_SetAntialiasMode(rt, D2D1_ANTIALIAS_MODE_ALIASED);
4792 set_color(&color, 0.0f, 1.0f, 0.0f, 0.8f);
4793 hr = ID2D1RenderTarget_CreateSolidColorBrush(rt, &color, NULL, &color_brush);
4794 ok(SUCCEEDED(hr), "Failed to create color brush, hr %#x.\n", hr);
4796 set_size_u(&size, 4, 4);
4797 bitmap_desc.pixelFormat.format = DXGI_FORMAT_B8G8R8A8_UNORM;
4798 bitmap_desc.pixelFormat.alphaMode = D2D1_ALPHA_MODE_PREMULTIPLIED;
4799 bitmap_desc.dpiX = 96.0f;
4800 bitmap_desc.dpiY = 96.0f;
4801 hr = ID2D1RenderTarget_CreateBitmap(rt, size, bitmap_data, 4 * sizeof(*bitmap_data), &bitmap_desc, &bitmap);
4802 ok(SUCCEEDED(hr), "Failed to create bitmap, hr %#x.\n", hr);
4803 hr = ID2D1RenderTarget_CreateBitmapBrush(rt, bitmap, NULL, NULL, &opacity_brush);
4804 ok(SUCCEEDED(hr), "Failed to create bitmap brush, hr %#x.\n", hr);
4805 ID2D1BitmapBrush_SetInterpolationMode(opacity_brush, D2D1_BITMAP_INTERPOLATION_MODE_NEAREST_NEIGHBOR);
4806 refcount = ID2D1Bitmap_Release(bitmap);
4807 ok(refcount == 1, "Got unexpected refcount %u.\n", refcount);
4809 set_size_u(&size, 1, 1);
4810 bitmap_desc.pixelFormat.format = DXGI_FORMAT_B8G8R8A8_UNORM;
4811 bitmap_desc.pixelFormat.alphaMode = D2D1_ALPHA_MODE_IGNORE;
4812 bitmap_desc.dpiX = 96.0f;
4813 bitmap_desc.dpiY = 96.0f;
4814 hr = ID2D1RenderTarget_CreateBitmap(rt, size, &bitmap_data[2], sizeof(*bitmap_data), &bitmap_desc, &bitmap);
4815 ok(SUCCEEDED(hr), "Failed to create bitmap, hr %#x.\n", hr);
4816 hr = ID2D1RenderTarget_CreateBitmapBrush(rt, bitmap, NULL, NULL, &bitmap_brush);
4817 ok(SUCCEEDED(hr), "Failed to create bitmap brush, hr %#x.\n", hr);
4818 ID2D1BitmapBrush_SetInterpolationMode(bitmap_brush, D2D1_BITMAP_INTERPOLATION_MODE_NEAREST_NEIGHBOR);
4819 refcount = ID2D1Bitmap_Release(bitmap);
4820 ok(refcount == 1, "Got unexpected refcount %u.\n", refcount);
4822 ID2D1RenderTarget_BeginDraw(rt);
4824 set_color(&color, 0.0f, 0.0f, 1.0f, 1.0f);
4825 ID2D1RenderTarget_Clear(rt, &color);
4827 set_rect(&rect, 40.0f, 120.0f, 120.0f, 360.0f);
4828 ID2D1RenderTarget_FillRectangle(rt, &rect, (ID2D1Brush *)color_brush);
4830 set_matrix_identity(&matrix);
4831 translate_matrix(&matrix, 120.0f, 120.0f);
4832 scale_matrix(&matrix, 20.0f, 60.0f);
4833 ID2D1BitmapBrush_SetTransform(opacity_brush, &matrix);
4834 set_rect(&rect, 120.0f, 120.0f, 200.0f, 360.0f);
4835 ID2D1RenderTarget_FillRectangle(rt, &rect, (ID2D1Brush *)opacity_brush);
4837 set_rect(&rect, 200.0f, 120.0f, 280.0f, 360.0f);
4838 ID2D1RenderTarget_FillRectangle(rt, &rect, (ID2D1Brush *)bitmap_brush);
4840 set_matrix_identity(&matrix);
4841 translate_matrix(&matrix, 40.0f, 360.0f);
4842 scale_matrix(&matrix, 20.0f, 60.0f);
4843 ID2D1BitmapBrush_SetTransform(opacity_brush, &matrix);
4844 set_rect(&rect, 40.0f, 360.0f, 120.0f, 600.0f);
4845 ID2D1Factory_CreateRectangleGeometry(factory, &rect, &geometry);
4846 ID2D1RenderTarget_FillGeometry(rt, (ID2D1Geometry *)geometry,
4847 (ID2D1Brush *)opacity_brush, (ID2D1Brush *)color_brush);
4848 ID2D1RectangleGeometry_Release(geometry);
4850 set_matrix_identity(&matrix);
4851 translate_matrix(&matrix, 120.0f, 360.0f);
4852 scale_matrix(&matrix, 20.0f, 60.0f);
4853 ID2D1BitmapBrush_SetTransform(opacity_brush, &matrix);
4854 set_rect(&rect, 120.0f, 360.0f, 200.0f, 600.0f);
4855 ID2D1Factory_CreateRectangleGeometry(factory, &rect, &geometry);
4856 ID2D1RenderTarget_FillGeometry(rt, (ID2D1Geometry *)geometry,
4857 (ID2D1Brush *)color_brush, (ID2D1Brush *)opacity_brush);
4858 ID2D1RectangleGeometry_Release(geometry);
4860 set_matrix_identity(&matrix);
4861 translate_matrix(&matrix, 200.0f, 360.0f);
4862 scale_matrix(&matrix, 20.0f, 60.0f);
4863 ID2D1BitmapBrush_SetTransform(opacity_brush, &matrix);
4864 set_rect(&rect, 200.0f, 360.0f, 280.0f, 600.0f);
4865 ID2D1Factory_CreateRectangleGeometry(factory, &rect, &geometry);
4866 ID2D1RenderTarget_FillGeometry(rt, (ID2D1Geometry *)geometry,
4867 (ID2D1Brush *)bitmap_brush, (ID2D1Brush *)opacity_brush);
4869 hr = ID2D1RenderTarget_EndDraw(rt, NULL, NULL);
4870 ok(hr == D2DERR_INCOMPATIBLE_BRUSH_TYPES, "Got unexpected hr %#x.\n", hr);
4871 match = compare_surface(&ctx, "7141c6c7b3decb91196428efb1856bcbf9872935");
4872 ok(match, "Surface does not match.\n");
4873 ID2D1RenderTarget_BeginDraw(rt);
4875 ID2D1RenderTarget_FillGeometry(rt, (ID2D1Geometry *)geometry,
4876 (ID2D1Brush *)bitmap_brush, (ID2D1Brush *)opacity_brush);
4877 ID2D1RectangleGeometry_Release(geometry);
4879 ID2D1SolidColorBrush_SetOpacity(color_brush, 0.5f);
4880 set_matrix_identity(&matrix);
4881 translate_matrix(&matrix, 40.0f, 600.0f);
4882 scale_matrix(&matrix, 20.0f, 60.0f);
4883 ID2D1BitmapBrush_SetTransform(opacity_brush, &matrix);
4884 set_rect(&rect, 40.0f, 600.0f, 120.0f, 840.0f);
4885 ID2D1Factory_CreateRectangleGeometry(factory, &rect, &geometry);
4886 ID2D1RenderTarget_FillGeometry(rt, (ID2D1Geometry *)geometry,
4887 (ID2D1Brush *)opacity_brush, (ID2D1Brush *)color_brush);
4888 ID2D1RectangleGeometry_Release(geometry);
4890 ID2D1BitmapBrush_SetOpacity(opacity_brush, 0.8f);
4891 set_matrix_identity(&matrix);
4892 translate_matrix(&matrix, 120.0f, 600.0f);
4893 scale_matrix(&matrix, 20.0f, 60.0f);
4894 ID2D1BitmapBrush_SetTransform(opacity_brush, &matrix);
4895 set_rect(&rect, 120.0f, 600.0f, 200.0f, 840.0f);
4896 ID2D1Factory_CreateRectangleGeometry(factory, &rect, &geometry);
4897 ID2D1RenderTarget_FillGeometry(rt, (ID2D1Geometry *)geometry,
4898 (ID2D1Brush *)opacity_brush, (ID2D1Brush *)bitmap_brush);
4899 ID2D1RectangleGeometry_Release(geometry);
4901 set_matrix_identity(&matrix);
4902 translate_matrix(&matrix, 200.0f, 600.0f);
4903 scale_matrix(&matrix, 20.0f, 60.0f);
4904 ID2D1BitmapBrush_SetTransform(opacity_brush, &matrix);
4905 set_rect(&rect, 200.0f, 600.0f, 280.0f, 840.0f);
4906 ID2D1Factory_CreateRectangleGeometry(factory, &rect, &geometry);
4907 ID2D1RenderTarget_FillGeometry(rt, (ID2D1Geometry *)geometry,
4908 (ID2D1Brush *)bitmap_brush, (ID2D1Brush *)opacity_brush);
4909 ID2D1RectangleGeometry_Release(geometry);
4911 hr = ID2D1RenderTarget_EndDraw(rt, NULL, NULL);
4912 ok(SUCCEEDED(hr), "Failed to end draw, hr %#x.\n", hr);
4913 match = compare_surface(&ctx, "c3a5802d1750efa3e9122c1a92f6064df3872732");
4914 ok(match, "Surface does not match.\n");
4916 ID2D1BitmapBrush_Release(bitmap_brush);
4917 ID2D1BitmapBrush_Release(opacity_brush);
4918 ID2D1SolidColorBrush_Release(color_brush);
4919 ID2D1Factory_Release(factory);
4920 release_test_context(&ctx);
4923 static void test_create_target(BOOL d3d11)
4925 struct d2d1_test_context ctx;
4926 ID2D1Factory *factory;
4927 ID2D1RenderTarget *rt;
4928 HRESULT hr;
4929 static const struct
4931 float dpi_x, dpi_y;
4932 float rt_dpi_x, rt_dpi_y;
4933 HRESULT hr;
4935 create_dpi_tests[] =
4937 { 0.0f, 0.0f, 96.0f, 96.0f, S_OK },
4938 { 192.0f, 0.0f, 96.0f, 96.0f, E_INVALIDARG },
4939 { 0.0f, 192.0f, 96.0f, 96.0f, E_INVALIDARG },
4940 { 192.0f, -10.0f, 96.0f, 96.0f, E_INVALIDARG },
4941 { -10.0f, 192.0f, 96.0f, 96.0f, E_INVALIDARG },
4942 { 48.0f, 96.0f, 48.0f, 96.0f, S_OK },
4944 unsigned int i;
4946 if (!init_test_context(&ctx, d3d11))
4947 return;
4949 hr = D2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED, &IID_ID2D1Factory, NULL, (void **)&factory);
4950 ok(SUCCEEDED(hr), "Failed to create factory, hr %#x.\n", hr);
4952 for (i = 0; i < ARRAY_SIZE(create_dpi_tests); ++i)
4954 ID2D1GdiInteropRenderTarget *interop;
4955 D2D1_RENDER_TARGET_PROPERTIES desc;
4956 ID2D1RenderTarget *rt2;
4957 float dpi_x, dpi_y;
4958 IUnknown *unk;
4960 desc.type = D2D1_RENDER_TARGET_TYPE_DEFAULT;
4961 desc.pixelFormat.format = DXGI_FORMAT_UNKNOWN;
4962 desc.pixelFormat.alphaMode = D2D1_ALPHA_MODE_PREMULTIPLIED;
4963 desc.dpiX = create_dpi_tests[i].dpi_x;
4964 desc.dpiY = create_dpi_tests[i].dpi_y;
4965 desc.usage = D2D1_RENDER_TARGET_USAGE_NONE;
4966 desc.minLevel = D2D1_FEATURE_LEVEL_DEFAULT;
4968 hr = ID2D1Factory_CreateDxgiSurfaceRenderTarget(factory, ctx.surface, &desc, &rt);
4969 ok(hr == create_dpi_tests[i].hr, "Wrong return code, hr %#x, expected %#x, test %u.\n", hr,
4970 create_dpi_tests[i].hr, i);
4972 if (FAILED(hr))
4973 continue;
4975 hr = ID2D1RenderTarget_QueryInterface(rt, &IID_IUnknown, (void **)&unk);
4976 ok(SUCCEEDED(hr), "Failed to get IUnknown, hr %#x.\n", hr);
4977 ok(unk == (IUnknown *)rt, "Expected same interface pointer.\n");
4978 IUnknown_Release(unk);
4980 hr = ID2D1RenderTarget_QueryInterface(rt, &IID_ID2D1GdiInteropRenderTarget, (void **)&interop);
4981 ok(SUCCEEDED(hr), "Failed to get interop target, hr %#x.\n", hr);
4982 hr = ID2D1GdiInteropRenderTarget_QueryInterface(interop, &IID_ID2D1RenderTarget, (void **)&rt2);
4983 ok(SUCCEEDED(hr), "Failed to get render target back, %#x.\n", hr);
4984 ok(rt2 == rt, "Unexpected render target\n");
4985 ID2D1RenderTarget_Release(rt2);
4986 ID2D1GdiInteropRenderTarget_Release(interop);
4988 ID2D1RenderTarget_GetDpi(rt, &dpi_x, &dpi_y);
4989 ok(dpi_x == create_dpi_tests[i].rt_dpi_x, "Wrong dpi_x %.8e, expected %.8e, test %u\n",
4990 dpi_x, create_dpi_tests[i].rt_dpi_x, i);
4991 ok(dpi_y == create_dpi_tests[i].rt_dpi_y, "Wrong dpi_y %.8e, expected %.8e, test %u\n",
4992 dpi_y, create_dpi_tests[i].rt_dpi_y, i);
4994 ID2D1RenderTarget_Release(rt);
4997 ID2D1Factory_Release(factory);
4998 release_test_context(&ctx);
5001 static void test_draw_text_layout(BOOL d3d11)
5003 static const struct
5005 D2D1_TEXT_ANTIALIAS_MODE aa_mode;
5006 DWRITE_RENDERING_MODE rendering_mode;
5007 HRESULT hr;
5009 antialias_mode_tests[] =
5011 { D2D1_TEXT_ANTIALIAS_MODE_DEFAULT, DWRITE_RENDERING_MODE_ALIASED },
5012 { D2D1_TEXT_ANTIALIAS_MODE_ALIASED, DWRITE_RENDERING_MODE_ALIASED },
5013 { D2D1_TEXT_ANTIALIAS_MODE_ALIASED, DWRITE_RENDERING_MODE_DEFAULT },
5014 { D2D1_TEXT_ANTIALIAS_MODE_ALIASED, DWRITE_RENDERING_MODE_OUTLINE },
5015 { D2D1_TEXT_ANTIALIAS_MODE_GRAYSCALE, DWRITE_RENDERING_MODE_DEFAULT },
5016 { D2D1_TEXT_ANTIALIAS_MODE_GRAYSCALE, DWRITE_RENDERING_MODE_OUTLINE },
5017 { D2D1_TEXT_ANTIALIAS_MODE_GRAYSCALE, DWRITE_RENDERING_MODE_CLEARTYPE_NATURAL },
5018 { D2D1_TEXT_ANTIALIAS_MODE_GRAYSCALE, DWRITE_RENDERING_MODE_CLEARTYPE_NATURAL_SYMMETRIC },
5019 { D2D1_TEXT_ANTIALIAS_MODE_GRAYSCALE, DWRITE_RENDERING_MODE_CLEARTYPE_GDI_NATURAL },
5020 { D2D1_TEXT_ANTIALIAS_MODE_GRAYSCALE, DWRITE_RENDERING_MODE_CLEARTYPE_GDI_CLASSIC },
5021 { D2D1_TEXT_ANTIALIAS_MODE_CLEARTYPE, DWRITE_RENDERING_MODE_DEFAULT },
5022 { D2D1_TEXT_ANTIALIAS_MODE_CLEARTYPE, DWRITE_RENDERING_MODE_CLEARTYPE_NATURAL },
5023 { D2D1_TEXT_ANTIALIAS_MODE_CLEARTYPE, DWRITE_RENDERING_MODE_CLEARTYPE_NATURAL_SYMMETRIC },
5024 { D2D1_TEXT_ANTIALIAS_MODE_CLEARTYPE, DWRITE_RENDERING_MODE_CLEARTYPE_GDI_NATURAL },
5025 { D2D1_TEXT_ANTIALIAS_MODE_CLEARTYPE, DWRITE_RENDERING_MODE_CLEARTYPE_GDI_CLASSIC },
5026 { D2D1_TEXT_ANTIALIAS_MODE_CLEARTYPE, DWRITE_RENDERING_MODE_OUTLINE, E_INVALIDARG },
5027 { D2D1_TEXT_ANTIALIAS_MODE_GRAYSCALE, DWRITE_RENDERING_MODE_ALIASED, E_INVALIDARG },
5028 { D2D1_TEXT_ANTIALIAS_MODE_CLEARTYPE, DWRITE_RENDERING_MODE_ALIASED, E_INVALIDARG },
5029 { D2D1_TEXT_ANTIALIAS_MODE_ALIASED, DWRITE_RENDERING_MODE_CLEARTYPE_NATURAL, E_INVALIDARG },
5030 { D2D1_TEXT_ANTIALIAS_MODE_ALIASED, DWRITE_RENDERING_MODE_CLEARTYPE_NATURAL_SYMMETRIC, E_INVALIDARG },
5031 { D2D1_TEXT_ANTIALIAS_MODE_ALIASED, DWRITE_RENDERING_MODE_CLEARTYPE_GDI_NATURAL, E_INVALIDARG },
5032 { D2D1_TEXT_ANTIALIAS_MODE_ALIASED, DWRITE_RENDERING_MODE_CLEARTYPE_GDI_CLASSIC, E_INVALIDARG },
5034 D2D1_RENDER_TARGET_PROPERTIES desc;
5035 ID2D1Factory *factory, *factory2;
5036 ID2D1RenderTarget *rt, *rt2;
5037 HRESULT hr;
5038 IDWriteFactory *dwrite_factory;
5039 IDWriteTextFormat *text_format;
5040 IDWriteTextLayout *text_layout;
5041 struct d2d1_test_context ctx;
5042 D2D1_POINT_2F origin;
5043 DWRITE_TEXT_RANGE range;
5044 D2D1_COLOR_F color;
5045 ID2D1SolidColorBrush *brush, *brush2;
5046 ID2D1RectangleGeometry *geometry;
5047 D2D1_RECT_F rect;
5048 unsigned int i;
5050 if (!init_test_context(&ctx, d3d11))
5051 return;
5054 hr = D2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED, &IID_ID2D1Factory, NULL, (void **)&factory);
5055 ok(SUCCEEDED(hr), "Failed to create factory, hr %#x.\n", hr);
5057 hr = D2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED, &IID_ID2D1Factory, NULL, (void **)&factory2);
5058 ok(SUCCEEDED(hr), "Failed to create factory, hr %#x.\n", hr);
5059 ok(factory != factory2, "got same factory\n");
5061 desc.type = D2D1_RENDER_TARGET_TYPE_DEFAULT;
5062 desc.pixelFormat.format = DXGI_FORMAT_UNKNOWN;
5063 desc.pixelFormat.alphaMode = D2D1_ALPHA_MODE_PREMULTIPLIED;
5064 desc.dpiX = 0.0f;
5065 desc.dpiY = 0.0f;
5066 desc.usage = D2D1_RENDER_TARGET_USAGE_NONE;
5067 desc.minLevel = D2D1_FEATURE_LEVEL_DEFAULT;
5069 hr = ID2D1Factory_CreateDxgiSurfaceRenderTarget(factory, ctx.surface, &desc, &rt);
5070 ok(SUCCEEDED(hr), "Failed to create a target, hr %#x.\n", hr);
5072 hr = ID2D1Factory_CreateDxgiSurfaceRenderTarget(factory2, ctx.surface, &desc, &rt2);
5073 ok(SUCCEEDED(hr), "Failed to create a target, hr %#x.\n", hr);
5075 hr = DWriteCreateFactory(DWRITE_FACTORY_TYPE_SHARED, &IID_IDWriteFactory, (IUnknown **)&dwrite_factory);
5076 ok(SUCCEEDED(hr), "Failed to create factory, hr %#x.\n", hr);
5078 hr = IDWriteFactory_CreateTextFormat(dwrite_factory, L"Tahoma", NULL, DWRITE_FONT_WEIGHT_NORMAL,
5079 DWRITE_FONT_STYLE_NORMAL, DWRITE_FONT_STRETCH_NORMAL, 10.0f, L"", &text_format);
5080 ok(SUCCEEDED(hr), "Failed to create text format, hr %#x.\n", hr);
5082 hr = IDWriteFactory_CreateTextLayout(dwrite_factory, L"text", 4, text_format, 100.0f, 100.0f, &text_layout);
5083 ok(SUCCEEDED(hr), "Failed to create text layout, hr %#x.\n", hr);
5085 set_color(&color, 0.0f, 0.0f, 0.0f, 0.0f);
5086 hr = ID2D1RenderTarget_CreateSolidColorBrush(rt, &color, NULL, &brush);
5087 ok(SUCCEEDED(hr), "Failed to create brush, hr %#x.\n", hr);
5089 hr = ID2D1RenderTarget_CreateSolidColorBrush(rt2, &color, NULL, &brush2);
5090 ok(SUCCEEDED(hr), "Failed to create brush, hr %#x.\n", hr);
5092 /* effect brush is created from different factory */
5093 range.startPosition = 0;
5094 range.length = 4;
5095 hr = IDWriteTextLayout_SetDrawingEffect(text_layout, (IUnknown*)brush2, range);
5096 ok(SUCCEEDED(hr), "Failed to set drawing effect, hr %#x.\n", hr);
5098 ID2D1RenderTarget_BeginDraw(rt);
5100 origin.x = origin.y = 0.0f;
5101 ID2D1RenderTarget_DrawTextLayout(rt, origin, text_layout, (ID2D1Brush*)brush, D2D1_DRAW_TEXT_OPTIONS_NONE);
5103 hr = ID2D1RenderTarget_EndDraw(rt, NULL, NULL);
5104 todo_wine
5105 ok(hr == D2DERR_WRONG_FACTORY, "Unexpected hr %#x.\n", hr);
5107 /* Effect is d2d resource, but not a brush. */
5108 set_rect(&rect, 0.0f, 0.0f, 10.0f, 10.0f);
5109 hr = ID2D1Factory_CreateRectangleGeometry(factory, &rect, &geometry);
5110 ok(SUCCEEDED(hr), "Failed to geometry, hr %#x.\n", hr);
5112 range.startPosition = 0;
5113 range.length = 4;
5114 hr = IDWriteTextLayout_SetDrawingEffect(text_layout, (IUnknown*)geometry, range);
5115 ok(SUCCEEDED(hr), "Failed to set drawing effect, hr %#x.\n", hr);
5116 ID2D1RectangleGeometry_Release(geometry);
5118 ID2D1RenderTarget_BeginDraw(rt);
5120 origin.x = origin.y = 0.0f;
5121 ID2D1RenderTarget_DrawTextLayout(rt, origin, text_layout, (ID2D1Brush*)brush, D2D1_DRAW_TEXT_OPTIONS_NONE);
5123 hr = ID2D1RenderTarget_EndDraw(rt, NULL, NULL);
5124 ok(SUCCEEDED(hr), "EndDraw() failed, hr %#x.\n", hr);
5126 for (i = 0; i < ARRAY_SIZE(antialias_mode_tests); ++i)
5128 IDWriteRenderingParams *rendering_params;
5130 ID2D1RenderTarget_SetTextAntialiasMode(rt, antialias_mode_tests[i].aa_mode);
5132 hr = IDWriteFactory_CreateCustomRenderingParams(dwrite_factory, 2.0f, 1.0f, 0.0f, DWRITE_PIXEL_GEOMETRY_FLAT,
5133 antialias_mode_tests[i].rendering_mode, &rendering_params);
5134 ok(SUCCEEDED(hr), "Failed to create custom rendering params, hr %#x.\n", hr);
5136 ID2D1RenderTarget_SetTextRenderingParams(rt, rendering_params);
5138 ID2D1RenderTarget_BeginDraw(rt);
5140 ID2D1RenderTarget_DrawTextLayout(rt, origin, text_layout, (ID2D1Brush *)brush, D2D1_DRAW_TEXT_OPTIONS_NONE);
5142 hr = ID2D1RenderTarget_EndDraw(rt, NULL, NULL);
5143 ok(hr == antialias_mode_tests[i].hr, "%u: unexpected hr %#x.\n", i, hr);
5145 IDWriteRenderingParams_Release(rendering_params);
5148 IDWriteTextFormat_Release(text_format);
5149 IDWriteTextLayout_Release(text_layout);
5150 IDWriteFactory_Release(dwrite_factory);
5151 ID2D1RenderTarget_Release(rt);
5152 ID2D1RenderTarget_Release(rt2);
5154 ID2D1Factory_Release(factory);
5155 ID2D1Factory_Release(factory2);
5156 release_test_context(&ctx);
5159 static void create_target_dibsection(HDC hdc, UINT32 width, UINT32 height)
5161 char bmibuf[FIELD_OFFSET(BITMAPINFO, bmiColors[256])];
5162 BITMAPINFO *bmi = (BITMAPINFO*)bmibuf;
5163 HBITMAP hbm;
5165 memset(bmi, 0, sizeof(bmibuf));
5166 bmi->bmiHeader.biSize = sizeof(bmi->bmiHeader);
5167 bmi->bmiHeader.biHeight = -height;
5168 bmi->bmiHeader.biWidth = width;
5169 bmi->bmiHeader.biBitCount = 32;
5170 bmi->bmiHeader.biPlanes = 1;
5171 bmi->bmiHeader.biCompression = BI_RGB;
5173 hbm = CreateDIBSection(hdc, bmi, DIB_RGB_COLORS, NULL, NULL, 0);
5174 ok(hbm != NULL, "Failed to create a dib section.\n");
5176 DeleteObject(SelectObject(hdc, hbm));
5179 static void test_dc_target(BOOL d3d11)
5181 static const D2D1_PIXEL_FORMAT invalid_formats[] =
5183 { DXGI_FORMAT_UNKNOWN, D2D1_ALPHA_MODE_PREMULTIPLIED },
5184 { DXGI_FORMAT_B8G8R8A8_UNORM, D2D1_ALPHA_MODE_UNKNOWN },
5185 { DXGI_FORMAT_R8G8B8A8_UNORM, D2D1_ALPHA_MODE_PREMULTIPLIED },
5187 D2D1_TEXT_ANTIALIAS_MODE text_aa_mode;
5188 ID2D1GdiInteropRenderTarget *interop;
5189 D2D1_RENDER_TARGET_PROPERTIES desc;
5190 D2D1_MATRIX_3X2_F matrix, matrix2;
5191 ID2D1DCRenderTarget *rt, *rt2;
5192 struct d2d1_test_context ctx;
5193 D2D1_ANTIALIAS_MODE aa_mode;
5194 ID2D1SolidColorBrush *brush;
5195 ID2D1RenderTarget *rt3;
5196 ID2D1Factory *factory;
5197 FLOAT dpi_x, dpi_y;
5198 D2D1_COLOR_F color;
5199 D2D1_SIZE_U sizeu;
5200 D2D1_SIZE_F size;
5201 D2D1_TAG t1, t2;
5202 unsigned int i;
5203 HDC hdc, hdc2;
5204 D2D_RECT_F r;
5205 COLORREF clr;
5206 HRESULT hr;
5207 RECT rect;
5209 if (!init_test_context(&ctx, d3d11))
5210 return;
5211 release_test_context(&ctx);
5213 hr = D2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED, &IID_ID2D1Factory, NULL, (void **)&factory);
5214 ok(SUCCEEDED(hr), "Failed to create factory, hr %#x.\n", hr);
5216 for (i = 0; i < ARRAY_SIZE(invalid_formats); ++i)
5218 desc.type = D2D1_RENDER_TARGET_TYPE_DEFAULT;
5219 desc.pixelFormat = invalid_formats[i];
5220 desc.dpiX = 96.0f;
5221 desc.dpiY = 96.0f;
5222 desc.usage = D2D1_RENDER_TARGET_USAGE_NONE;
5223 desc.minLevel = D2D1_FEATURE_LEVEL_DEFAULT;
5225 hr = ID2D1Factory_CreateDCRenderTarget(factory, &desc, &rt);
5226 ok(hr == D2DERR_UNSUPPORTED_PIXEL_FORMAT, "Got unexpected hr %#x.\n", hr);
5229 desc.type = D2D1_RENDER_TARGET_TYPE_DEFAULT;
5230 desc.pixelFormat.format = DXGI_FORMAT_B8G8R8A8_UNORM;
5231 desc.pixelFormat.alphaMode = D2D1_ALPHA_MODE_PREMULTIPLIED;
5232 desc.dpiX = 96.0f;
5233 desc.dpiY = 96.0f;
5234 desc.usage = D2D1_RENDER_TARGET_USAGE_NONE;
5235 desc.minLevel = D2D1_FEATURE_LEVEL_DEFAULT;
5236 hr = ID2D1Factory_CreateDCRenderTarget(factory, &desc, &rt);
5237 ok(SUCCEEDED(hr), "Failed to create target, hr %#x.\n", hr);
5239 hr = ID2D1DCRenderTarget_QueryInterface(rt, &IID_ID2D1GdiInteropRenderTarget, (void **)&interop);
5240 ok(SUCCEEDED(hr), "Failed to get interop target, hr %#x.\n", hr);
5241 hr = ID2D1GdiInteropRenderTarget_QueryInterface(interop, &IID_ID2D1RenderTarget, (void **)&rt3);
5242 ok(SUCCEEDED(hr), "Failed to get render target back, %#x.\n", hr);
5243 ok(rt3 == (ID2D1RenderTarget *)rt, "Unexpected render target\n");
5244 ID2D1RenderTarget_Release(rt3);
5245 hr = ID2D1GdiInteropRenderTarget_QueryInterface(interop, &IID_ID2D1DCRenderTarget, (void **)&rt2);
5246 ok(SUCCEEDED(hr), "Failed to get render target back, %#x.\n", hr);
5247 ok(rt2 == rt, "Unexpected render target\n");
5248 ID2D1DCRenderTarget_Release(rt2);
5249 ID2D1GdiInteropRenderTarget_Release(interop);
5251 size = ID2D1DCRenderTarget_GetSize(rt);
5252 ok(size.width == 0.0f, "got width %.08e.\n", size.width);
5253 ok(size.height == 0.0f, "got height %.08e.\n", size.height);
5255 sizeu = ID2D1DCRenderTarget_GetPixelSize(rt);
5256 ok(sizeu.width == 0, "got width %u.\n", sizeu.width);
5257 ok(sizeu.height == 0, "got height %u.\n", sizeu.height);
5259 /* object creation methods work without BindDC() */
5260 set_color(&color, 0.0f, 0.0f, 0.0f, 0.0f);
5261 hr = ID2D1DCRenderTarget_CreateSolidColorBrush(rt, &color, NULL, &brush);
5262 ok(SUCCEEDED(hr), "Failed to create a brush, hr %#x.\n", hr);
5263 ID2D1SolidColorBrush_Release(brush);
5265 ID2D1DCRenderTarget_BeginDraw(rt);
5266 hr = ID2D1DCRenderTarget_EndDraw(rt, NULL, NULL);
5267 ok(hr == D2DERR_WRONG_STATE, "Got unexpected hr %#x.\n", hr);
5269 ID2D1DCRenderTarget_Release(rt);
5271 /* BindDC() */
5272 hr = ID2D1Factory_CreateDCRenderTarget(factory, &desc, &rt);
5273 ok(SUCCEEDED(hr), "Failed to create target, hr %#x.\n", hr);
5275 aa_mode = ID2D1DCRenderTarget_GetAntialiasMode(rt);
5276 ok(aa_mode == D2D1_ANTIALIAS_MODE_PER_PRIMITIVE, "Got wrong default aa mode %d.\n", aa_mode);
5277 text_aa_mode = ID2D1DCRenderTarget_GetTextAntialiasMode(rt);
5278 ok(text_aa_mode == D2D1_TEXT_ANTIALIAS_MODE_DEFAULT, "Got wrong default text aa mode %d.\n", text_aa_mode);
5280 ID2D1DCRenderTarget_GetDpi(rt, &dpi_x, &dpi_y);
5281 ok(dpi_x == 96.0f && dpi_y == 96.0f, "Got dpi_x %f, dpi_y %f.\n", dpi_x, dpi_y);
5283 hdc = CreateCompatibleDC(NULL);
5284 ok(hdc != NULL, "Failed to create an HDC.\n");
5286 create_target_dibsection(hdc, 16, 16);
5288 SetRect(&rect, 0, 0, 32, 32);
5289 hr = ID2D1DCRenderTarget_BindDC(rt, NULL, &rect);
5290 ok(hr == E_INVALIDARG, "BindDC() returned %#x.\n", hr);
5292 /* Target properties are retained during BindDC() */
5293 ID2D1DCRenderTarget_SetTags(rt, 1, 2);
5294 ID2D1DCRenderTarget_SetAntialiasMode(rt, D2D1_ANTIALIAS_MODE_ALIASED);
5295 ID2D1DCRenderTarget_SetTextAntialiasMode(rt, D2D1_TEXT_ANTIALIAS_MODE_CLEARTYPE);
5297 set_matrix_identity(&matrix);
5298 translate_matrix(&matrix, 200.0f, 600.0f);
5299 ID2D1DCRenderTarget_SetTransform(rt, &matrix);
5301 hr = ID2D1DCRenderTarget_BindDC(rt, hdc, &rect);
5302 ok(hr == S_OK, "BindDC() returned %#x.\n", hr);
5304 ID2D1DCRenderTarget_GetTags(rt, &t1, &t2);
5305 ok(t1 == 1 && t2 == 2, "Got wrong tags.\n");
5307 aa_mode = ID2D1DCRenderTarget_GetAntialiasMode(rt);
5308 ok(aa_mode == D2D1_ANTIALIAS_MODE_ALIASED, "Got wrong aa mode %d.\n", aa_mode);
5310 text_aa_mode = ID2D1DCRenderTarget_GetTextAntialiasMode(rt);
5311 ok(text_aa_mode == D2D1_TEXT_ANTIALIAS_MODE_CLEARTYPE, "Got wrong text aa mode %d.\n", text_aa_mode);
5313 ID2D1DCRenderTarget_GetTransform(rt, &matrix2);
5314 ok(!memcmp(&matrix, &matrix2, sizeof(matrix)), "Got wrong target transform.\n");
5316 set_matrix_identity(&matrix);
5317 ID2D1DCRenderTarget_SetTransform(rt, &matrix);
5319 /* target size comes from specified dimensions, not from selected bitmap size */
5320 size = ID2D1DCRenderTarget_GetSize(rt);
5321 ok(size.width == 32.0f, "got width %.08e.\n", size.width);
5322 ok(size.height == 32.0f, "got height %.08e.\n", size.height);
5324 /* clear one HDC to red, switch to another one, partially fill it and test contents */
5325 ID2D1DCRenderTarget_BeginDraw(rt);
5327 set_color(&color, 1.0f, 0.0f, 0.0f, 1.0f);
5328 ID2D1DCRenderTarget_Clear(rt, &color);
5330 hr = ID2D1DCRenderTarget_EndDraw(rt, NULL, NULL);
5331 ok(SUCCEEDED(hr), "EndDraw() failed, hr %#x.\n", hr);
5333 clr = GetPixel(hdc, 0, 0);
5334 ok(clr == RGB(255, 0, 0), "Unexpected color 0x%08x.\n", clr);
5336 hdc2 = CreateCompatibleDC(NULL);
5337 ok(hdc2 != NULL, "Failed to create an HDC.\n");
5339 create_target_dibsection(hdc2, 16, 16);
5341 hr = ID2D1DCRenderTarget_BindDC(rt, hdc2, &rect);
5342 ok(hr == S_OK, "BindDC() returned %#x.\n", hr);
5344 clr = GetPixel(hdc2, 0, 0);
5345 ok(clr == 0, "Unexpected color 0x%08x.\n", clr);
5347 set_color(&color, 0.0f, 1.0f, 0.0f, 1.0f);
5348 hr = ID2D1DCRenderTarget_CreateSolidColorBrush(rt, &color, NULL, &brush);
5349 ok(SUCCEEDED(hr), "Failed to create brush, hr %#x.\n", hr);
5351 ID2D1DCRenderTarget_BeginDraw(rt);
5353 r.left = r.top = 0.0f;
5354 r.bottom = 16.0f;
5355 r.right = 8.0f;
5356 ID2D1DCRenderTarget_FillRectangle(rt, &r, (ID2D1Brush*)brush);
5358 hr = ID2D1DCRenderTarget_EndDraw(rt, NULL, NULL);
5359 ok(SUCCEEDED(hr), "EndDraw() failed, hr %#x.\n", hr);
5361 ID2D1SolidColorBrush_Release(brush);
5363 clr = GetPixel(hdc2, 0, 0);
5364 ok(clr == RGB(0, 255, 0), "Unexpected color 0x%08x.\n", clr);
5366 clr = GetPixel(hdc2, 10, 0);
5367 ok(clr == 0, "Unexpected color 0x%08x.\n", clr);
5369 /* Invalid DC. */
5370 hr = ID2D1DCRenderTarget_BindDC(rt, (HDC)0xdeadbeef, &rect);
5371 todo_wine
5372 ok(hr == E_INVALIDARG, "BindDC() returned %#x.\n", hr);
5374 ID2D1DCRenderTarget_BeginDraw(rt);
5376 set_color(&color, 1.0f, 0.0f, 0.0f, 1.0f);
5377 ID2D1DCRenderTarget_Clear(rt, &color);
5379 hr = ID2D1DCRenderTarget_EndDraw(rt, NULL, NULL);
5380 ok(SUCCEEDED(hr), "EndDraw() failed, hr %#x.\n", hr);
5382 clr = GetPixel(hdc2, 0, 0);
5383 todo_wine
5384 ok(clr == RGB(255, 0, 0), "Unexpected color 0x%08x.\n", clr);
5386 hr = ID2D1DCRenderTarget_BindDC(rt, NULL, &rect);
5387 ok(hr == E_INVALIDARG, "BindDC() returned %#x.\n", hr);
5389 ID2D1DCRenderTarget_BeginDraw(rt);
5391 set_color(&color, 0.0f, 0.0f, 1.0f, 1.0f);
5392 ID2D1DCRenderTarget_Clear(rt, &color);
5394 hr = ID2D1DCRenderTarget_EndDraw(rt, NULL, NULL);
5395 ok(SUCCEEDED(hr), "EndDraw() failed, hr %#x.\n", hr);
5397 clr = GetPixel(hdc2, 0, 0);
5398 todo_wine
5399 ok(clr == RGB(0, 0, 255), "Unexpected color 0x%08x.\n", clr);
5401 DeleteDC(hdc);
5402 DeleteDC(hdc2);
5403 ID2D1DCRenderTarget_Release(rt);
5404 ID2D1Factory_Release(factory);
5407 static void test_hwnd_target(BOOL d3d11)
5409 D2D1_HWND_RENDER_TARGET_PROPERTIES hwnd_rt_desc;
5410 ID2D1GdiInteropRenderTarget *interop;
5411 D2D1_RENDER_TARGET_PROPERTIES desc;
5412 ID2D1HwndRenderTarget *rt, *rt2;
5413 struct d2d1_test_context ctx;
5414 ID2D1RenderTarget *rt3;
5415 ID2D1Factory *factory;
5416 D2D1_SIZE_U size;
5417 HRESULT hr;
5419 if (!init_test_context(&ctx, d3d11))
5420 return;
5421 release_test_context(&ctx);
5423 hr = D2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED, &IID_ID2D1Factory, NULL, (void **)&factory);
5424 ok(SUCCEEDED(hr), "Failed to create factory, hr %#x.\n", hr);
5426 desc.type = D2D1_RENDER_TARGET_TYPE_DEFAULT;
5427 desc.pixelFormat.format = DXGI_FORMAT_B8G8R8A8_UNORM;
5428 desc.pixelFormat.alphaMode = D2D1_ALPHA_MODE_PREMULTIPLIED;
5429 desc.dpiX = 0.0f;
5430 desc.dpiY = 0.0f;
5431 desc.usage = D2D1_RENDER_TARGET_USAGE_NONE;
5432 desc.minLevel = D2D1_FEATURE_LEVEL_DEFAULT;
5434 hwnd_rt_desc.hwnd = NULL;
5435 hwnd_rt_desc.pixelSize.width = 64;
5436 hwnd_rt_desc.pixelSize.height = 64;
5437 hwnd_rt_desc.presentOptions = D2D1_PRESENT_OPTIONS_NONE;
5439 hr = ID2D1Factory_CreateHwndRenderTarget(factory, &desc, &hwnd_rt_desc, &rt);
5440 ok(FAILED(hr), "Target creation should fail, hr %#x.\n", hr);
5442 hwnd_rt_desc.hwnd = (HWND)0xdeadbeef;
5443 hr = ID2D1Factory_CreateHwndRenderTarget(factory, &desc, &hwnd_rt_desc, &rt);
5444 ok(FAILED(hr), "Target creation should fail, hr %#x.\n", hr);
5446 hwnd_rt_desc.hwnd = CreateWindowA("static", "d2d_test", 0, 0, 0, 0, 0, 0, 0, 0, 0);
5447 ok(!!hwnd_rt_desc.hwnd, "Failed to create target window.\n");
5448 hr = ID2D1Factory_CreateHwndRenderTarget(factory, &desc, &hwnd_rt_desc, &rt);
5449 ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr);
5451 hr = ID2D1HwndRenderTarget_QueryInterface(rt, &IID_ID2D1GdiInteropRenderTarget, (void **)&interop);
5452 ok(SUCCEEDED(hr), "Failed to get interop target, hr %#x.\n", hr);
5453 hr = ID2D1GdiInteropRenderTarget_QueryInterface(interop, &IID_ID2D1RenderTarget, (void **)&rt3);
5454 ok(SUCCEEDED(hr), "Failed to get render target back, %#x.\n", hr);
5455 ok(rt3 == (ID2D1RenderTarget *)rt, "Unexpected render target\n");
5456 ID2D1RenderTarget_Release(rt3);
5457 hr = ID2D1GdiInteropRenderTarget_QueryInterface(interop, &IID_ID2D1HwndRenderTarget, (void **)&rt2);
5458 ok(SUCCEEDED(hr), "Failed to get render target back, %#x.\n", hr);
5459 ok(rt2 == rt, "Unexpected render target\n");
5460 ID2D1HwndRenderTarget_Release(rt2);
5461 ID2D1GdiInteropRenderTarget_Release(interop);
5463 size.width = 128;
5464 size.height = 64;
5465 hr = ID2D1HwndRenderTarget_Resize(rt, &size);
5466 ok(SUCCEEDED(hr), "Failed to resize render target, hr %#x.\n", hr);
5468 ID2D1HwndRenderTarget_Release(rt);
5470 DestroyWindow(hwnd_rt_desc.hwnd);
5471 ID2D1Factory_Release(factory);
5474 #define test_compatible_target_size(r) test_compatible_target_size_(__LINE__, r)
5475 static void test_compatible_target_size_(unsigned int line, ID2D1RenderTarget *rt)
5477 static const D2D1_SIZE_F size_1_0 = { 1.0f, 0.0f };
5478 static const D2D1_SIZE_F size_1_1 = { 1.0f, 1.0f };
5479 static const D2D1_SIZE_U px_size_1_1 = { 1, 1 };
5480 static const D2D1_SIZE_U zero_px_size;
5481 static const D2D1_SIZE_F zero_size;
5482 static const struct size_test
5484 const D2D1_SIZE_U *pixel_size;
5485 const D2D1_SIZE_F *size;
5487 size_tests[] =
5489 { &zero_px_size, NULL },
5490 { &zero_px_size, &zero_size },
5491 { NULL, &zero_size },
5492 { NULL, &size_1_0 },
5493 { &px_size_1_1, &size_1_1 },
5495 float dpi_x, dpi_y, rt_dpi_x, rt_dpi_y;
5496 D2D1_SIZE_U pixel_size, expected_size;
5497 ID2D1BitmapRenderTarget *bitmap_rt;
5498 ID2D1DeviceContext *context;
5499 unsigned int i;
5500 HRESULT hr;
5502 ID2D1RenderTarget_GetDpi(rt, &rt_dpi_x, &rt_dpi_y);
5504 for (i = 0; i < ARRAY_SIZE(size_tests); ++i)
5506 hr = ID2D1RenderTarget_CreateCompatibleRenderTarget(rt, size_tests[i].size, size_tests[i].pixel_size,
5507 NULL, D2D1_COMPATIBLE_RENDER_TARGET_OPTIONS_NONE, &bitmap_rt);
5508 ok_(__FILE__, line)(SUCCEEDED(hr), "%u: Failed to create render target, hr %#x.\n", i, hr);
5510 if (size_tests[i].pixel_size)
5512 expected_size = *size_tests[i].pixel_size;
5514 else if (size_tests[i].size)
5516 expected_size.width = ceilf((size_tests[i].size->width * rt_dpi_x) / 96.0f);
5517 expected_size.height = ceilf((size_tests[i].size->height * rt_dpi_y) / 96.0f);
5519 else
5521 expected_size = ID2D1RenderTarget_GetPixelSize(rt);
5524 pixel_size = ID2D1BitmapRenderTarget_GetPixelSize(bitmap_rt);
5525 ok_(__FILE__, line)(!memcmp(&pixel_size, &expected_size, sizeof(pixel_size)),
5526 "%u: unexpected target size %ux%u.\n", i, pixel_size.width, pixel_size.height);
5528 ID2D1BitmapRenderTarget_GetDpi(bitmap_rt, &dpi_x, &dpi_y);
5529 if (size_tests[i].pixel_size && size_tests[i].size && size_tests[i].size->width != 0.0f
5530 && size_tests[i].size->height != 0.0f)
5532 ok_(__FILE__, line)(dpi_x == pixel_size.width * 96.0f / size_tests[i].size->width
5533 && dpi_y == pixel_size.height * 96.0f / size_tests[i].size->height,
5534 "%u: unexpected target dpi %.8ex%.8e.\n", i, dpi_x, dpi_y);
5536 else
5537 ok_(__FILE__, line)(dpi_x == rt_dpi_x && dpi_y == rt_dpi_y,
5538 "%u: unexpected target dpi %.8ex%.8e.\n", i, dpi_x, dpi_y);
5539 ID2D1BitmapRenderTarget_Release(bitmap_rt);
5542 pixel_size.height = pixel_size.width = 0;
5543 hr = ID2D1RenderTarget_CreateCompatibleRenderTarget(rt, NULL, &pixel_size, NULL,
5544 D2D1_COMPATIBLE_RENDER_TARGET_OPTIONS_NONE, &bitmap_rt);
5545 ok_(__FILE__, line)(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr);
5547 if (SUCCEEDED(ID2D1BitmapRenderTarget_QueryInterface(bitmap_rt, &IID_ID2D1DeviceContext, (void **)&context)))
5549 ID2D1Bitmap *bitmap;
5551 pixel_size = ID2D1DeviceContext_GetPixelSize(context);
5552 ok_(__FILE__, line)(!pixel_size.width && !pixel_size.height, "Unexpected target size %ux%u.\n",
5553 pixel_size.width, pixel_size.height);
5555 ID2D1DeviceContext_GetTarget(context, (ID2D1Image **)&bitmap);
5556 pixel_size = ID2D1Bitmap_GetPixelSize(bitmap);
5557 ok_(__FILE__, line)(!pixel_size.width && !pixel_size.height, "Unexpected target size %ux%u.\n",
5558 pixel_size.width, pixel_size.height);
5559 ID2D1Bitmap_Release(bitmap);
5561 ID2D1DeviceContext_Release(context);
5564 ID2D1BitmapRenderTarget_Release(bitmap_rt);
5567 static void test_bitmap_target(BOOL d3d11)
5569 D2D1_HWND_RENDER_TARGET_PROPERTIES hwnd_rt_desc;
5570 ID2D1GdiInteropRenderTarget *interop;
5571 D2D1_SIZE_U pixel_size, pixel_size2;
5572 D2D1_RENDER_TARGET_PROPERTIES desc;
5573 ID2D1BitmapRenderTarget *rt, *rt2;
5574 ID2D1HwndRenderTarget *hwnd_rt;
5575 ID2D1Bitmap *bitmap, *bitmap2;
5576 struct d2d1_test_context ctx;
5577 ID2D1DCRenderTarget *dc_rt;
5578 D2D1_SIZE_F size, size2;
5579 ID2D1RenderTarget *rt3;
5580 ID2D1Factory *factory;
5581 float dpi[2], dpi2[2];
5582 D2D1_COLOR_F color;
5583 ULONG refcount;
5584 HRESULT hr;
5586 if (!init_test_context(&ctx, d3d11))
5587 return;
5588 release_test_context(&ctx);
5590 hr = D2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED, &IID_ID2D1Factory, NULL, (void **)&factory);
5591 ok(SUCCEEDED(hr), "Failed to create factory, hr %#x.\n", hr);
5593 desc.type = D2D1_RENDER_TARGET_TYPE_DEFAULT;
5594 desc.pixelFormat.format = DXGI_FORMAT_B8G8R8A8_UNORM;
5595 desc.pixelFormat.alphaMode = D2D1_ALPHA_MODE_PREMULTIPLIED;
5596 desc.dpiX = 96.0f;
5597 desc.dpiY = 192.0f;
5598 desc.usage = D2D1_RENDER_TARGET_USAGE_NONE;
5599 desc.minLevel = D2D1_FEATURE_LEVEL_DEFAULT;
5601 hwnd_rt_desc.hwnd = CreateWindowA("static", "d2d_test", 0, 0, 0, 0, 0, 0, 0, 0, 0);
5602 ok(!!hwnd_rt_desc.hwnd, "Failed to create target window.\n");
5603 hwnd_rt_desc.pixelSize.width = 64;
5604 hwnd_rt_desc.pixelSize.height = 64;
5605 hwnd_rt_desc.presentOptions = D2D1_PRESENT_OPTIONS_NONE;
5607 hr = ID2D1Factory_CreateHwndRenderTarget(factory, &desc, &hwnd_rt_desc, &hwnd_rt);
5608 ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr);
5610 test_compatible_target_size((ID2D1RenderTarget *)hwnd_rt);
5612 hr = ID2D1HwndRenderTarget_CreateCompatibleRenderTarget(hwnd_rt, NULL, NULL, NULL,
5613 D2D1_COMPATIBLE_RENDER_TARGET_OPTIONS_NONE, &rt);
5614 ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr);
5616 hr = ID2D1BitmapRenderTarget_QueryInterface(rt, &IID_ID2D1GdiInteropRenderTarget, (void **)&interop);
5617 ok(SUCCEEDED(hr), "Failed to get interop target, hr %#x.\n", hr);
5618 hr = ID2D1GdiInteropRenderTarget_QueryInterface(interop, &IID_ID2D1RenderTarget, (void **)&rt3);
5619 ok(SUCCEEDED(hr), "Failed to get render target back, %#x.\n", hr);
5620 ok(rt3 == (ID2D1RenderTarget *)rt, "Unexpected render target\n");
5621 ID2D1RenderTarget_Release(rt3);
5622 hr = ID2D1GdiInteropRenderTarget_QueryInterface(interop, &IID_ID2D1BitmapRenderTarget, (void **)&rt2);
5623 ok(SUCCEEDED(hr), "Failed to get render target back, %#x.\n", hr);
5624 ok(rt2 == rt, "Unexpected render target\n");
5625 ID2D1BitmapRenderTarget_Release(rt2);
5626 ID2D1GdiInteropRenderTarget_Release(interop);
5628 /* See if parent target is referenced. */
5629 ID2D1HwndRenderTarget_AddRef(hwnd_rt);
5630 refcount = ID2D1HwndRenderTarget_Release(hwnd_rt);
5631 ok(refcount == 1, "Target should not have been referenced, got %u.\n", refcount);
5633 /* Size was not specified, should match parent. */
5634 pixel_size = ID2D1HwndRenderTarget_GetPixelSize(hwnd_rt);
5635 pixel_size2 = ID2D1BitmapRenderTarget_GetPixelSize(rt);
5636 ok(!memcmp(&pixel_size, &pixel_size2, sizeof(pixel_size)), "Got target pixel size mismatch.\n");
5638 size = ID2D1HwndRenderTarget_GetSize(hwnd_rt);
5639 size2 = ID2D1BitmapRenderTarget_GetSize(rt);
5640 ok(!memcmp(&size, &size2, sizeof(size)), "Got target DIP size mismatch.\n");
5642 ID2D1HwndRenderTarget_GetDpi(hwnd_rt, dpi, dpi + 1);
5643 ID2D1BitmapRenderTarget_GetDpi(rt, dpi2, dpi2 + 1);
5644 ok(!memcmp(dpi, dpi2, sizeof(dpi)), "Got dpi mismatch.\n");
5646 ID2D1BitmapRenderTarget_Release(rt);
5648 /* Pixel size specified. */
5649 set_size_u(&pixel_size, 32, 32);
5650 hr = ID2D1HwndRenderTarget_CreateCompatibleRenderTarget(hwnd_rt, NULL, &pixel_size, NULL,
5651 D2D1_COMPATIBLE_RENDER_TARGET_OPTIONS_NONE, &rt);
5652 ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr);
5654 pixel_size2 = ID2D1BitmapRenderTarget_GetPixelSize(rt);
5655 ok(!memcmp(&pixel_size, &pixel_size2, sizeof(pixel_size)), "Got target pixel size mismatch.\n");
5657 ID2D1BitmapRenderTarget_GetDpi(rt, dpi2, dpi2 + 1);
5658 ok(!memcmp(dpi, dpi2, sizeof(dpi)), "Got dpi mismatch.\n");
5660 ID2D1BitmapRenderTarget_Release(rt);
5662 /* Both pixel size and DIP size are specified. */
5663 set_size_u(&pixel_size, 128, 128);
5664 hr = ID2D1HwndRenderTarget_CreateCompatibleRenderTarget(hwnd_rt, &size, &pixel_size, NULL,
5665 D2D1_COMPATIBLE_RENDER_TARGET_OPTIONS_NONE, &rt);
5666 ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr);
5668 /* Doubled pixel size dimensions with the same DIP size give doubled dpi. */
5669 ID2D1BitmapRenderTarget_GetDpi(rt, dpi2, dpi2 + 1);
5670 ok(dpi[0] == dpi2[0] / 2.0f && dpi[1] == dpi2[1] / 2.0f, "Got dpi mismatch.\n");
5672 ID2D1BitmapRenderTarget_Release(rt);
5674 /* DIP size is specified, fractional. */
5675 set_size_f(&size, 70.1f, 70.4f);
5676 hr = ID2D1HwndRenderTarget_CreateCompatibleRenderTarget(hwnd_rt, &size, NULL, NULL,
5677 D2D1_COMPATIBLE_RENDER_TARGET_OPTIONS_NONE, &rt);
5678 ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr);
5680 ID2D1BitmapRenderTarget_GetDpi(rt, dpi2, dpi2 + 1);
5682 pixel_size = ID2D1BitmapRenderTarget_GetPixelSize(rt);
5683 ok(pixel_size.width == ceilf(size.width * dpi[0] / 96.0f)
5684 && pixel_size.height == ceilf(size.height * dpi[1] / 96.0f), "Wrong pixel size %ux%u\n",
5685 pixel_size.width, pixel_size.height);
5687 dpi[0] *= (pixel_size.width / size.width) * (96.0f / dpi[0]);
5688 dpi[1] *= (pixel_size.height / size.height) * (96.0f / dpi[1]);
5690 ok(compare_float(dpi[0], dpi2[0], 1) && compare_float(dpi[1], dpi2[1], 1), "Got dpi mismatch.\n");
5692 ID2D1HwndRenderTarget_Release(hwnd_rt);
5694 /* Check if GetBitmap() returns same instance. */
5695 hr = ID2D1BitmapRenderTarget_GetBitmap(rt, &bitmap);
5696 ok(SUCCEEDED(hr), "GetBitmap() failed, hr %#x.\n", hr);
5697 hr = ID2D1BitmapRenderTarget_GetBitmap(rt, &bitmap2);
5698 ok(SUCCEEDED(hr), "GetBitmap() failed, hr %#x.\n", hr);
5699 ok(bitmap == bitmap2, "Got different bitmap instances.\n");
5701 /* Draw something, see if bitmap instance is retained. */
5702 ID2D1BitmapRenderTarget_BeginDraw(rt);
5703 set_color(&color, 1.0f, 1.0f, 0.0f, 1.0f);
5704 ID2D1BitmapRenderTarget_Clear(rt, &color);
5705 hr = ID2D1BitmapRenderTarget_EndDraw(rt, NULL, NULL);
5706 ok(SUCCEEDED(hr), "EndDraw() failed, hr %#x.\n", hr);
5708 ID2D1Bitmap_Release(bitmap2);
5709 hr = ID2D1BitmapRenderTarget_GetBitmap(rt, &bitmap2);
5710 ok(SUCCEEDED(hr), "GetBitmap() failed, hr %#x.\n", hr);
5711 ok(bitmap == bitmap2, "Got different bitmap instances.\n");
5713 ID2D1Bitmap_Release(bitmap);
5714 ID2D1Bitmap_Release(bitmap2);
5716 refcount = ID2D1BitmapRenderTarget_Release(rt);
5717 ok(!refcount, "Target should be released, got %u.\n", refcount);
5719 DestroyWindow(hwnd_rt_desc.hwnd);
5721 /* Compatible target created from a DC target without associated HDC */
5722 desc.type = D2D1_RENDER_TARGET_TYPE_DEFAULT;
5723 desc.pixelFormat.format = DXGI_FORMAT_B8G8R8A8_UNORM;
5724 desc.pixelFormat.alphaMode = D2D1_ALPHA_MODE_PREMULTIPLIED;
5725 desc.dpiX = 192.0f;
5726 desc.dpiY = 96.0f;
5727 desc.usage = D2D1_RENDER_TARGET_USAGE_NONE;
5728 desc.minLevel = D2D1_FEATURE_LEVEL_DEFAULT;
5729 hr = ID2D1Factory_CreateDCRenderTarget(factory, &desc, &dc_rt);
5730 ok(SUCCEEDED(hr), "Failed to create target, hr %#x.\n", hr);
5732 test_compatible_target_size((ID2D1RenderTarget *)dc_rt);
5734 hr = ID2D1DCRenderTarget_CreateCompatibleRenderTarget(dc_rt, NULL, NULL, NULL,
5735 D2D1_COMPATIBLE_RENDER_TARGET_OPTIONS_NONE, &rt);
5736 ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr);
5738 pixel_size = ID2D1BitmapRenderTarget_GetPixelSize(rt);
5739 ok(pixel_size.width == 0 && pixel_size.height == 0, "Got wrong size\n");
5741 hr = ID2D1BitmapRenderTarget_GetBitmap(rt, &bitmap);
5742 ok(SUCCEEDED(hr), "GetBitmap() failed, hr %#x.\n", hr);
5743 pixel_size = ID2D1Bitmap_GetPixelSize(bitmap);
5744 ok(pixel_size.width == 0 && pixel_size.height == 0, "Got wrong size\n");
5745 ID2D1Bitmap_Release(bitmap);
5747 ID2D1BitmapRenderTarget_Release(rt);
5748 ID2D1DCRenderTarget_Release(dc_rt);
5750 ID2D1Factory_Release(factory);
5753 static void test_desktop_dpi(BOOL d3d11)
5755 ID2D1Factory *factory;
5756 float dpi_x, dpi_y;
5757 HRESULT hr;
5759 hr = D2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED, &IID_ID2D1Factory, NULL, (void **)&factory);
5760 ok(SUCCEEDED(hr), "Failed to create factory, hr %#x.\n", hr);
5762 dpi_x = dpi_y = 0.0f;
5763 ID2D1Factory_GetDesktopDpi(factory, &dpi_x, &dpi_y);
5764 ok(dpi_x > 0.0f && dpi_y > 0.0f, "Got wrong dpi %f x %f.\n", dpi_x, dpi_y);
5766 ID2D1Factory_Release(factory);
5769 static void test_stroke_style(BOOL d3d11)
5771 static const struct
5773 D2D1_DASH_STYLE dash_style;
5774 UINT32 dash_count;
5775 float dashes[6];
5777 dash_style_tests[] =
5779 {D2D1_DASH_STYLE_SOLID, 0},
5780 {D2D1_DASH_STYLE_DASH, 2, {2.0f, 2.0f}},
5781 {D2D1_DASH_STYLE_DOT, 2, {0.0f, 2.0f}},
5782 {D2D1_DASH_STYLE_DASH_DOT, 4, {2.0f, 2.0f, 0.0f, 2.0f}},
5783 {D2D1_DASH_STYLE_DASH_DOT_DOT, 6, {2.0f, 2.0f, 0.0f, 2.0f, 0.0f, 2.0f}},
5785 D2D1_STROKE_STYLE_PROPERTIES desc;
5786 ID2D1StrokeStyle *style;
5787 ID2D1Factory *factory;
5788 UINT32 count;
5789 HRESULT hr;
5790 D2D1_CAP_STYLE cap_style;
5791 D2D1_LINE_JOIN line_join;
5792 float miter_limit, dash_offset;
5793 D2D1_DASH_STYLE dash_style;
5794 unsigned int i;
5795 float dashes[2];
5797 hr = D2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED, &IID_ID2D1Factory, NULL, (void **)&factory);
5798 ok(SUCCEEDED(hr), "Failed to create factory, hr %#x.\n", hr);
5800 desc.startCap = D2D1_CAP_STYLE_SQUARE;
5801 desc.endCap = D2D1_CAP_STYLE_ROUND;
5802 desc.dashCap = D2D1_CAP_STYLE_TRIANGLE;
5803 desc.lineJoin = D2D1_LINE_JOIN_BEVEL;
5804 desc.miterLimit = 1.5f;
5805 desc.dashStyle = D2D1_DASH_STYLE_DOT;
5806 desc.dashOffset = -1.0f;
5808 hr = ID2D1Factory_CreateStrokeStyle(factory, &desc, NULL, 0, &style);
5809 ok(SUCCEEDED(hr), "Failed to create stroke style, %#x.\n", hr);
5811 cap_style = ID2D1StrokeStyle_GetStartCap(style);
5812 ok(cap_style == D2D1_CAP_STYLE_SQUARE, "Unexpected cap style %d.\n", cap_style);
5813 cap_style = ID2D1StrokeStyle_GetEndCap(style);
5814 ok(cap_style == D2D1_CAP_STYLE_ROUND, "Unexpected cap style %d.\n", cap_style);
5815 cap_style = ID2D1StrokeStyle_GetDashCap(style);
5816 ok(cap_style == D2D1_CAP_STYLE_TRIANGLE, "Unexpected cap style %d.\n", cap_style);
5817 line_join = ID2D1StrokeStyle_GetLineJoin(style);
5818 ok(line_join == D2D1_LINE_JOIN_BEVEL, "Unexpected line joind %d.\n", line_join);
5819 miter_limit = ID2D1StrokeStyle_GetMiterLimit(style);
5820 ok(miter_limit == 1.5f, "Unexpected miter limit %f.\n", miter_limit);
5821 dash_style = ID2D1StrokeStyle_GetDashStyle(style);
5822 ok(dash_style == D2D1_DASH_STYLE_DOT, "Unexpected dash style %d.\n", dash_style);
5823 dash_offset = ID2D1StrokeStyle_GetDashOffset(style);
5824 ok(dash_offset == -1.0f, "Unexpected dash offset %f.\n", dash_offset);
5826 /* Custom dash pattern, no dashes data specified. */
5827 desc.startCap = D2D1_CAP_STYLE_SQUARE;
5828 desc.endCap = D2D1_CAP_STYLE_ROUND;
5829 desc.dashCap = D2D1_CAP_STYLE_TRIANGLE;
5830 desc.lineJoin = D2D1_LINE_JOIN_BEVEL;
5831 desc.miterLimit = 1.5f;
5832 desc.dashStyle = D2D1_DASH_STYLE_CUSTOM;
5833 desc.dashOffset = 0.0f;
5835 ID2D1StrokeStyle_Release(style);
5837 hr = ID2D1Factory_CreateStrokeStyle(factory, &desc, NULL, 0, &style);
5838 ok(hr == E_INVALIDARG, "Unexpected return value, %#x.\n", hr);
5840 hr = ID2D1Factory_CreateStrokeStyle(factory, &desc, dashes, 0, &style);
5841 ok(hr == E_INVALIDARG, "Unexpected return value, %#x.\n", hr);
5843 hr = ID2D1Factory_CreateStrokeStyle(factory, &desc, dashes, 1, &style);
5844 ok(hr == S_OK, "Unexpected return value, %#x.\n", hr);
5845 ID2D1StrokeStyle_Release(style);
5847 /* Builtin style, dashes are specified. */
5848 desc.dashStyle = D2D1_DASH_STYLE_DOT;
5849 hr = ID2D1Factory_CreateStrokeStyle(factory, &desc, dashes, 1, &style);
5850 ok(hr == E_INVALIDARG, "Unexpected return value, %#x.\n", hr);
5852 /* Invalid style. */
5853 desc.dashStyle = 100;
5854 hr = ID2D1Factory_CreateStrokeStyle(factory, &desc, NULL, 0, &style);
5855 ok(hr == E_INVALIDARG, "Unexpected return value, %#x.\n", hr);
5857 /* Test returned dash pattern for builtin styles. */
5858 desc.startCap = D2D1_CAP_STYLE_SQUARE;
5859 desc.endCap = D2D1_CAP_STYLE_ROUND;
5860 desc.dashCap = D2D1_CAP_STYLE_TRIANGLE;
5861 desc.lineJoin = D2D1_LINE_JOIN_BEVEL;
5862 desc.miterLimit = 1.5f;
5863 desc.dashOffset = 0.0f;
5865 for (i = 0; i < ARRAY_SIZE(dash_style_tests); ++i)
5867 float dashes[10];
5868 UINT dash_count;
5870 desc.dashStyle = dash_style_tests[i].dash_style;
5872 hr = ID2D1Factory_CreateStrokeStyle(factory, &desc, NULL, 0, &style);
5873 ok(SUCCEEDED(hr), "Failed to create stroke style, %#x.\n", hr);
5875 dash_count = ID2D1StrokeStyle_GetDashesCount(style);
5876 ok(dash_count == dash_style_tests[i].dash_count, "%u: unexpected dash count %u, expected %u.\n",
5877 i, dash_count, dash_style_tests[i].dash_count);
5878 ok(dash_count < ARRAY_SIZE(dashes), "%u: unexpectedly large dash count %u.\n", i, dash_count);
5879 if (dash_count == dash_style_tests[i].dash_count)
5881 unsigned int j;
5883 ID2D1StrokeStyle_GetDashes(style, dashes, dash_count);
5884 ok(!memcmp(dashes, dash_style_tests[i].dashes, sizeof(*dashes) * dash_count),
5885 "%u: unexpected dash array.\n", i);
5887 /* Ask for more dashes than style actually has. */
5888 memset(dashes, 0xcc, sizeof(dashes));
5889 ID2D1StrokeStyle_GetDashes(style, dashes, ARRAY_SIZE(dashes));
5890 ok(!memcmp(dashes, dash_style_tests[i].dashes, sizeof(*dashes) * dash_count),
5891 "%u: unexpected dash array.\n", i);
5893 for (j = dash_count; j < ARRAY_SIZE(dashes); ++j)
5894 ok(dashes[j] == 0.0f, "%u: unexpected dash value at %u.\n", i, j);
5897 ID2D1StrokeStyle_Release(style);
5900 /* NULL dashes array, non-zero length. */
5901 memset(&desc, 0, sizeof(desc));
5902 hr = ID2D1Factory_CreateStrokeStyle(factory, &desc, NULL, 1, &style);
5903 ok(SUCCEEDED(hr), "Failed to create stroke style, %#x.\n", hr);
5905 count = ID2D1StrokeStyle_GetDashesCount(style);
5906 ok(count == 0, "Unexpected dashes count %u.\n", count);
5908 ID2D1StrokeStyle_Release(style);
5910 ID2D1Factory_Release(factory);
5913 static void test_gradient(BOOL d3d11)
5915 ID2D1GradientStopCollection *gradient;
5916 D2D1_GRADIENT_STOP stops[3], stops2[3];
5917 struct d2d1_test_context ctx;
5918 ID2D1RenderTarget *rt;
5919 D2D1_COLOR_F color;
5920 unsigned int i;
5921 UINT32 count;
5922 HRESULT hr;
5924 if (!init_test_context(&ctx, d3d11))
5925 return;
5927 rt = ctx.rt;
5928 stops2[0].position = 0.5f;
5929 set_color(&stops2[0].color, 1.0f, 1.0f, 0.0f, 1.0f);
5930 stops2[1] = stops2[0];
5931 hr = ID2D1RenderTarget_CreateGradientStopCollection(rt, stops2, 2, D2D1_GAMMA_2_2,
5932 D2D1_EXTEND_MODE_CLAMP, &gradient);
5933 ok(SUCCEEDED(hr), "Failed to create stop collection, hr %#x.\n", hr);
5935 count = ID2D1GradientStopCollection_GetGradientStopCount(gradient);
5936 ok(count == 2, "Unexpected stop count %u.\n", count);
5938 /* Request more stops than collection has. */
5939 stops[0].position = 123.4f;
5940 set_color(&stops[0].color, 1.0f, 0.5f, 0.4f, 1.0f);
5941 color = stops[0].color;
5942 stops[2] = stops[1] = stops[0];
5943 ID2D1GradientStopCollection_GetGradientStops(gradient, stops, ARRAY_SIZE(stops));
5944 ok(!memcmp(stops, stops2, sizeof(*stops) * count), "Unexpected gradient stops array.\n");
5945 for (i = count; i < ARRAY_SIZE(stops); ++i)
5947 ok(stops[i].position == 123.4f, "%u: unexpected stop position %f.\n", i, stops[i].position);
5948 ok(!memcmp(&stops[i].color, &color, sizeof(color)), "%u: unexpected stop color.\n", i);
5951 ID2D1GradientStopCollection_Release(gradient);
5953 release_test_context(&ctx);
5956 static void test_draw_geometry(BOOL d3d11)
5958 ID2D1TransformedGeometry *transformed_geometry[4];
5959 ID2D1RectangleGeometry *rect_geometry[2];
5960 D2D1_POINT_2F point = {0.0f, 0.0f};
5961 D2D1_ROUNDED_RECT rounded_rect;
5962 struct d2d1_test_context ctx;
5963 ID2D1SolidColorBrush *brush;
5964 ID2D1PathGeometry *geometry;
5965 D2D1_MATRIX_3X2_F matrix;
5966 ID2D1GeometrySink *sink;
5967 ID2D1RenderTarget *rt;
5968 ID2D1Factory *factory;
5969 D2D1_POINT_2F p0, p1;
5970 D2D1_ELLIPSE ellipse;
5971 D2D1_COLOR_F color;
5972 D2D1_RECT_F rect;
5973 HRESULT hr;
5974 BOOL match;
5976 if (!init_test_context(&ctx, d3d11))
5977 return;
5979 rt = ctx.rt;
5980 ID2D1RenderTarget_GetFactory(rt, &factory);
5982 ID2D1RenderTarget_SetDpi(rt, 192.0f, 48.0f);
5983 ID2D1RenderTarget_SetAntialiasMode(rt, D2D1_ANTIALIAS_MODE_ALIASED);
5984 set_color(&color, 0.890f, 0.851f, 0.600f, 1.0f);
5985 hr = ID2D1RenderTarget_CreateSolidColorBrush(rt, &color, NULL, &brush);
5986 ok(SUCCEEDED(hr), "Failed to create brush, hr %#x.\n", hr);
5988 ID2D1RenderTarget_BeginDraw(rt);
5989 set_color(&color, 0.396f, 0.180f, 0.537f, 1.0f);
5990 ID2D1RenderTarget_Clear(rt, &color);
5992 set_point(&p0, 40.0f, 160.0f);
5993 ID2D1RenderTarget_DrawLine(rt, p0, p0, (ID2D1Brush *)brush, 10.0f, NULL);
5994 set_point(&p0, 100.0f, 160.0f);
5995 set_point(&p1, 140.0f, 160.0f);
5996 ID2D1RenderTarget_DrawLine(rt, p0, p1, (ID2D1Brush *)brush, 10.0f, NULL);
5997 set_point(&p0, 200.0f, 80.0f);
5998 set_point(&p1, 200.0f, 240.0f);
5999 ID2D1RenderTarget_DrawLine(rt, p0, p1, (ID2D1Brush *)brush, 10.0f, NULL);
6000 set_point(&p0, 260.0f, 240.0f);
6001 set_point(&p1, 300.0f, 80.0f);
6002 ID2D1RenderTarget_DrawLine(rt, p0, p1, (ID2D1Brush *)brush, 10.0f, NULL);
6004 set_rect(&rect, 40.0f, 480.0f, 40.0f, 480.0f);
6005 ID2D1RenderTarget_DrawRectangle(rt, &rect, (ID2D1Brush *)brush, 10.0f, NULL);
6006 set_rect(&rect, 100.0f, 480.0f, 140.0f, 480.0f);
6007 ID2D1RenderTarget_DrawRectangle(rt, &rect, (ID2D1Brush *)brush, 10.0f, NULL);
6008 set_rect(&rect, 200.0f, 400.0f, 200.0f, 560.0f);
6009 ID2D1RenderTarget_DrawRectangle(rt, &rect, (ID2D1Brush *)brush, 10.0f, NULL);
6010 set_rect(&rect, 260.0f, 560.0f, 300.0f, 400.0f);
6011 ID2D1RenderTarget_DrawRectangle(rt, &rect, (ID2D1Brush *)brush, 10.0f, NULL);
6013 set_ellipse(&ellipse, 40.0f, 800.0f, 0.0f, 0.0f);
6014 ID2D1RenderTarget_DrawEllipse(rt, &ellipse, (ID2D1Brush *)brush, 10.0f, NULL);
6015 set_ellipse(&ellipse, 120.0f, 800.0f, 20.0f, 0.0f);
6016 ID2D1RenderTarget_DrawEllipse(rt, &ellipse, (ID2D1Brush *)brush, 10.0f, NULL);
6017 set_ellipse(&ellipse, 200.0f, 800.0f, 0.0f, 80.0f);
6018 ID2D1RenderTarget_DrawEllipse(rt, &ellipse, (ID2D1Brush *)brush, 10.0f, NULL);
6019 set_ellipse(&ellipse, 280.0f, 800.0f, 20.0f, 80.0f);
6020 ID2D1RenderTarget_DrawEllipse(rt, &ellipse, (ID2D1Brush *)brush, 10.0f, NULL);
6022 hr = ID2D1RenderTarget_EndDraw(rt, NULL, NULL);
6023 ok(SUCCEEDED(hr), "Failed to end draw, hr %#x.\n", hr);
6025 match = compare_figure(&ctx, 0, 0, 160, 160, 0xff652e89, 0, "");
6026 ok(match, "Figure does not match.\n");
6027 match = compare_figure(&ctx, 160, 0, 160, 160, 0xff652e89, 0, "yGBQUFBQUFBQUFDoYQAA");
6028 ok(match, "Figure does not match.\n");
6029 match = compare_figure(&ctx, 320, 0, 160, 160, 0xff652e89, 0,
6030 "xjIUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEU"
6031 "jAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEU"
6032 "jAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEU"
6033 "jAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEU"
6034 "jAEUjAEUjAEUjAEUxjIA");
6035 ok(match, "Figure does not match.\n");
6036 match = compare_figure(&ctx, 480, 0, 160, 160, 0xff652e89, 2,
6037 "zjECnQETjAEVigEVigEVigEVigEVigEVigEVigEVigEVigEVigEVigEVigEVigEVigEVigEVigEV"
6038 "igEVigEVigEVigEVigEVigEVigEVigEVigEVigEVigEVigEVigEVigEVigEVigEVigEVigEVigEV"
6039 "igEVigEVigEVigEVigEVigEVigEVigEVigEVigEVigEVigEVigEVigEVigEVigEVigEVigEVigEV"
6040 "igEVigEVigEVigEVigEVigEVigEVigEVigEVigEVigEVigEVigEVigEVigEVigEVigEVigEVigEV"
6041 "igEVigEVigEVigEVjAETnQECzjEA");
6042 ok(match, "Figure does not match.\n");
6044 match = compare_figure(&ctx, 0, 160, 160, 160, 0xff652e89, 0, "5mAUjAEUjAEUjAEUjAEUhmIA");
6045 ok(match, "Figure does not match.\n");
6046 match = compare_figure(&ctx, 160, 160, 160, 160, 0xff652e89, 0, "vmBkPGQ8ZDxkPGTeYQAA");
6047 ok(match, "Figure does not match.\n");
6048 match = compare_figure(&ctx, 320, 160, 160, 160, 0xff652e89, 0,
6049 "5i4UjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEU"
6050 "jAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEU"
6051 "jAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEU"
6052 "jAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEU"
6053 "jAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUhjAA");
6054 ok(match, "Figure does not match.\n");
6055 match = compare_figure(&ctx, 480, 160, 160, 160, 0xff652e89, 0,
6056 "vi5kPGQ8ZDxkPGQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwU"
6057 "PBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8"
6058 "FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwU"
6059 "PBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8"
6060 "FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwU"
6061 "PBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8ZDxkPGQ8ZDxk3i8A");
6062 ok(match, "Figure does not match.\n");
6064 match = compare_figure(&ctx, 0, 320, 160, 160, 0xff652e89, 0, "iGIQjgEUjAEUjgEQiGIA");
6065 todo_wine ok(match, "Figure does not match.\n");
6066 match = compare_figure(&ctx, 160, 320, 160, 160, 0xff652e89, 0, "yGBQSGA+ZDxkPmDgYQAA");
6067 todo_wine ok(match, "Figure does not match.\n");
6068 match = compare_figure(&ctx, 320, 320, 160, 160, 0xff652e89, 0,
6069 "iDAQjgEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEU"
6070 "jAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEU"
6071 "jAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEU"
6072 "jAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEU"
6073 "jAEUjAEUjAEUjAEUjAEUjAEUjAEUjgEQiDAA");
6074 todo_wine ok(match, "Figure does not match.\n");
6075 match = compare_figure(&ctx, 480, 320, 160, 160, 0xff652e89, 10,
6076 "hDAYgwEieyh1LnAybBcIF2gWDhZkFhIWYRUWFV4VGhVbFRwVWRUeFVcVIBVVFCQUUxQmFFEUKBRP"
6077 "FSgVTRUqFUwULBRLFC4USRQwFEgUMBRHFDIURhQyFEUUNBREFDQUQxQ2FEIUNhRBFDgUQBQ4FEAU"
6078 "OBQ/FDoUPhQ6FD4UOhQ+FDoUPhQ6FD0UPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8"
6079 "FDwUPBQ8FDwUPBQ8FD0UOhQ+FDoUPhQ6FD4UOhQ+FDoUPxQ4FEAUOBRAFDgUQRQ2FEIUNhRDFDQU"
6080 "RBQ0FEUUMhRGFDIURxQwFEgUMBRJFC4USxQsFEwVKhVNFSgVTxQoFFEUJhRTFCQUVRUgFVcVHhVZ"
6081 "FRwVWxUaFV4VFhVhFhIWZBYOFmgXCBdsMnAudSh7IoMBGIQw");
6082 todo_wine ok(match, "Figure does not match.\n");
6084 ID2D1RenderTarget_BeginDraw(rt);
6085 set_color(&color, 0.396f, 0.180f, 0.537f, 1.0f);
6086 ID2D1RenderTarget_Clear(rt, &color);
6088 set_rounded_rect(&rounded_rect, 40.0f, 160.0f, 40.0f, 160.0f, 10.0f, 10.0f);
6089 ID2D1RenderTarget_DrawRoundedRectangle(rt, &rounded_rect, (ID2D1Brush *)brush, 10.0f, NULL);
6090 set_rounded_rect(&rounded_rect, 100.0f, 160.0f, 140.0f, 160.0f, 10.0f, 10.0f);
6091 ID2D1RenderTarget_DrawRoundedRectangle(rt, &rounded_rect, (ID2D1Brush *)brush, 10.0f, NULL);
6092 set_rounded_rect(&rounded_rect, 200.0f, 80.0f, 200.0f, 240.0f, 10.0f, 10.0f);
6093 ID2D1RenderTarget_DrawRoundedRectangle(rt, &rounded_rect, (ID2D1Brush *)brush, 10.0f, NULL);
6094 set_rounded_rect(&rounded_rect, 260.0f, 240.0f, 300.0f, 80.0f, 10.0f, 10.0f);
6095 ID2D1RenderTarget_DrawRoundedRectangle(rt, &rounded_rect, (ID2D1Brush *)brush, 10.0f, NULL);
6097 set_rounded_rect(&rounded_rect, 40.0f, 480.0f, 40.0f, 480.0f, 10.0f, 20.0f);
6098 ID2D1RenderTarget_DrawRoundedRectangle(rt, &rounded_rect, (ID2D1Brush *)brush, 10.0f, NULL);
6099 set_rounded_rect(&rounded_rect, 100.0f, 480.0f, 140.0f, 480.0f, 10.0f, 20.0f);
6100 ID2D1RenderTarget_DrawRoundedRectangle(rt, &rounded_rect, (ID2D1Brush *)brush, 10.0f, NULL);
6101 set_rounded_rect(&rounded_rect, 200.0f, 400.0f, 200.0f, 560.0f, 10.0f, 20.0f);
6102 ID2D1RenderTarget_DrawRoundedRectangle(rt, &rounded_rect, (ID2D1Brush *)brush, 10.0f, NULL);
6103 set_rounded_rect(&rounded_rect, 260.0f, 560.0f, 300.0f, 400.0f, 10.0f, 20.0f);
6104 ID2D1RenderTarget_DrawRoundedRectangle(rt, &rounded_rect, (ID2D1Brush *)brush, 10.0f, NULL);
6106 set_rounded_rect(&rounded_rect, 40.0f, 800.0f, 40.0f, 800.0f, 10.0f, 5.0f);
6107 ID2D1RenderTarget_DrawRoundedRectangle(rt, &rounded_rect, (ID2D1Brush *)brush, 10.0f, NULL);
6108 set_rounded_rect(&rounded_rect, 100.0f, 800.0f, 140.0f, 800.0f, 10.0f, 5.0f);
6109 ID2D1RenderTarget_DrawRoundedRectangle(rt, &rounded_rect, (ID2D1Brush *)brush, 10.0f, NULL);
6110 set_rounded_rect(&rounded_rect, 200.0f, 720.0f, 200.0f, 880.0f, 10.0f, 5.0f);
6111 ID2D1RenderTarget_DrawRoundedRectangle(rt, &rounded_rect, (ID2D1Brush *)brush, 10.0f, NULL);
6112 set_rounded_rect(&rounded_rect, 260.0f, 880.0f, 300.0f, 720.0f, 10.0f, 5.0f);
6113 ID2D1RenderTarget_DrawRoundedRectangle(rt, &rounded_rect, (ID2D1Brush *)brush, 10.0f, NULL);
6115 hr = ID2D1RenderTarget_EndDraw(rt, NULL, NULL);
6116 ok(SUCCEEDED(hr), "Failed to end draw, hr %#x.\n", hr);
6118 match = compare_figure(&ctx, 0, 0, 160, 160, 0xff652e89, 0, "iGIQjgEUjAEUjgEQiGIA");
6119 todo_wine ok(match, "Figure does not match.\n");
6120 match = compare_figure(&ctx, 160, 0, 160, 160, 0xff652e89, 0, "yGBQSGA+ZDxkPmDgYQAA");
6121 todo_wine ok(match, "Figure does not match.\n");
6122 match = compare_figure(&ctx, 320, 0, 160, 160, 0xff652e89, 0,
6123 "iDAQjgEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEU"
6124 "jAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEU"
6125 "jAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEU"
6126 "jAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEU"
6127 "jAEUjAEUjAEUjAEUjAEUjAEUjAEUjgEQiDAA");
6128 todo_wine ok(match, "Figure does not match.\n");
6129 match = compare_figure(&ctx, 480, 0, 160, 160, 0xff652e89, 0,
6130 "3C4oaUZVUExYRlxCHCgcPxU4FT0UPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwU"
6131 "PBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8"
6132 "FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwU"
6133 "PBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8"
6134 "FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwU"
6135 "PBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FD0VOBU/YEJcRlhMUFVG7S8A");
6136 todo_wine ok(match, "Figure does not match.\n");
6138 match = compare_figure(&ctx, 0, 160, 160, 160, 0xff652e89, 0, "iGIQjgEUjAEUjgEQiGIA");
6139 todo_wine ok(match, "Figure does not match.\n");
6140 match = compare_figure(&ctx, 160, 160, 160, 160, 0xff652e89, 0, "yGBQSGA+ZDxkPmDgYQAA");
6141 todo_wine ok(match, "Figure does not match.\n");
6142 match = compare_figure(&ctx, 320, 160, 160, 160, 0xff652e89, 0,
6143 "iDAQjgEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEU"
6144 "jAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEU"
6145 "jAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEU"
6146 "jAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEU"
6147 "jAEUjAEUjAEUjAEUjAEUjAEUjAEUjgEQiDAA");
6148 todo_wine ok(match, "Figure does not match.\n");
6149 match = compare_figure(&ctx, 480, 160, 160, 160, 0xff652e89, 8,
6150 "3C4obT5dSFRQTlRKGCgYRhYwFkMVNBVBFTYVPxU5FD4UOhQ9FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwU"
6151 "PBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8"
6152 "FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwU"
6153 "PBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8"
6154 "FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwU"
6155 "PBQ8FDwUPRQ6FD4UOhQ/FTYVQRU0FUMWMBZGWEpVTVBTSltA8C8A");
6156 todo_wine ok(match, "Figure does not match.\n");
6158 match = compare_figure(&ctx, 0, 320, 160, 160, 0xff652e89, 0, "iGIQjgEUjAEUjgEQiGIA");
6159 todo_wine ok(match, "Figure does not match.\n");
6160 match = compare_figure(&ctx, 160, 320, 160, 160, 0xff652e89, 0, "yGBQSGA+ZDxkPmDgYQAA");
6161 todo_wine ok(match, "Figure does not match.\n");
6162 match = compare_figure(&ctx, 320, 320, 160, 160, 0xff652e89, 0,
6163 "iDAQjgEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEU"
6164 "jAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEU"
6165 "jAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEU"
6166 "jAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEU"
6167 "jAEUjAEUjAEUjAEUjAEUjAEUjAEUjgEQiDAA");
6168 todo_wine ok(match, "Figure does not match.\n");
6169 match = compare_figure(&ctx, 480, 320, 160, 160, 0xff652e89, 0,
6170 "3C4oZU5NWERgP2I9HigePBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwU"
6171 "PBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8"
6172 "FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwU"
6173 "PBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8"
6174 "FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwU"
6175 "PBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8ZD1iP2BEWE1O6S8A");
6176 todo_wine ok(match, "Figure does not match.\n");
6178 ID2D1RenderTarget_BeginDraw(rt);
6179 set_color(&color, 0.396f, 0.180f, 0.537f, 1.0f);
6180 ID2D1RenderTarget_Clear(rt, &color);
6182 set_rounded_rect(&rounded_rect, 40.0f, 160.0f, 40.0f, 160.0f, 1000.0f, 1000.0f);
6183 ID2D1RenderTarget_DrawRoundedRectangle(rt, &rounded_rect, (ID2D1Brush *)brush, 10.0f, NULL);
6184 set_rounded_rect(&rounded_rect, 100.0f, 160.0f, 140.0f, 160.0f, 1000.0f, 1000.0f);
6185 ID2D1RenderTarget_DrawRoundedRectangle(rt, &rounded_rect, (ID2D1Brush *)brush, 10.0f, NULL);
6186 set_rounded_rect(&rounded_rect, 200.0f, 80.0f, 200.0f, 240.0f, 1000.0f, 1000.0f);
6187 ID2D1RenderTarget_DrawRoundedRectangle(rt, &rounded_rect, (ID2D1Brush *)brush, 10.0f, NULL);
6188 set_rounded_rect(&rounded_rect, 260.0f, 240.0f, 300.0f, 80.0f, 1000.0f, 1000.0f);
6189 ID2D1RenderTarget_DrawRoundedRectangle(rt, &rounded_rect, (ID2D1Brush *)brush, 10.0f, NULL);
6191 set_rounded_rect(&rounded_rect, 40.0f, 480.0f, 40.0f, 480.0f, 10.0f, 1000.0f);
6192 ID2D1RenderTarget_DrawRoundedRectangle(rt, &rounded_rect, (ID2D1Brush *)brush, 10.0f, NULL);
6193 set_rounded_rect(&rounded_rect, 100.0f, 480.0f, 140.0f, 480.0f, 10.0f, 1000.0f);
6194 ID2D1RenderTarget_DrawRoundedRectangle(rt, &rounded_rect, (ID2D1Brush *)brush, 10.0f, NULL);
6195 set_rounded_rect(&rounded_rect, 200.0f, 400.0f, 200.0f, 560.0f, 10.0f, 1000.0f);
6196 ID2D1RenderTarget_DrawRoundedRectangle(rt, &rounded_rect, (ID2D1Brush *)brush, 10.0f, NULL);
6197 set_rounded_rect(&rounded_rect, 260.0f, 560.0f, 300.0f, 400.0f, 10.0f, 1000.0f);
6198 ID2D1RenderTarget_DrawRoundedRectangle(rt, &rounded_rect, (ID2D1Brush *)brush, 10.0f, NULL);
6200 set_rounded_rect(&rounded_rect, 40.0f, 800.0f, 40.0f, 800.0f, 1000.0f, 10.0f);
6201 ID2D1RenderTarget_DrawRoundedRectangle(rt, &rounded_rect, (ID2D1Brush *)brush, 10.0f, NULL);
6202 set_rounded_rect(&rounded_rect, 100.0f, 800.0f, 140.0f, 800.0f, 1000.0f, 10.0f);
6203 ID2D1RenderTarget_DrawRoundedRectangle(rt, &rounded_rect, (ID2D1Brush *)brush, 10.0f, NULL);
6204 set_rounded_rect(&rounded_rect, 200.0f, 720.0f, 200.0f, 880.0f, 1000.0f, 10.0f);
6205 ID2D1RenderTarget_DrawRoundedRectangle(rt, &rounded_rect, (ID2D1Brush *)brush, 10.0f, NULL);
6206 set_rounded_rect(&rounded_rect, 260.0f, 880.0f, 300.0f, 720.0f, 1000.0f, 10.0f);
6207 ID2D1RenderTarget_DrawRoundedRectangle(rt, &rounded_rect, (ID2D1Brush *)brush, 10.0f, NULL);
6209 hr = ID2D1RenderTarget_EndDraw(rt, NULL, NULL);
6210 ok(SUCCEEDED(hr), "Failed to end draw, hr %#x.\n", hr);
6212 match = compare_figure(&ctx, 0, 0, 160, 160, 0xff652e89, 0, "iGIQjgEUjAEUjgEQiGIA");
6213 todo_wine ok(match, "Figure does not match.\n");
6214 match = compare_figure(&ctx, 160, 0, 160, 160, 0xff652e89, 0, "yGBQSGA+ZDxkPmDgYQAA");
6215 todo_wine ok(match, "Figure does not match.\n");
6216 match = compare_figure(&ctx, 320, 0, 160, 160, 0xff652e89, 0,
6217 "iDAQjgEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEU"
6218 "jAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEU"
6219 "jAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEU"
6220 "jAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEU"
6221 "jAEUjAEUjAEUjAEUjAEUjAEUjAEUjgEQiDAA");
6222 todo_wine ok(match, "Figure does not match.\n");
6223 match = compare_figure(&ctx, 480, 0, 160, 160, 0xff652e89, 16,
6224 "hDAYgwEieyh1LnAybBcIF2gWDhZkFhIWYRUWFV4WGRVbFRwVWRUeFVcVIBVVFSMUUxQmFFEVJxRP"
6225 "FSgVTRUqFUwULBRLFC4USRUvFEgUMBRHFDIURhQyFEUUNBREFDQUQxQ2FEIUNhRBFDgUQBQ4FEAU"
6226 "OBQ/FTkUPhQ6FD4UOhQ+FDoUPhQ6FD0UPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8"
6227 "FDwUPBQ8FDwUPBQ8FD0UOhQ+FDoUPhQ6FD4UOhQ+FDoUPxQ4FEAUOBRAFDgUQRQ2FEIUNhRDFDQU"
6228 "RBQ0FEUUMhRGFDIURxQwFEgUMBRJFC4USxQsFEwVKhVNFSgVTxQoFFEUJhRTFCQUVRUgFVcVHhVZ"
6229 "FRwVWxUaFV4VFhVhFhIWZBYOFmgWChZsMnAudCp6IoMBGIQw");
6230 todo_wine ok(match, "Figure does not match.\n");
6232 match = compare_figure(&ctx, 0, 160, 160, 160, 0xff652e89, 0, "iGIQjgEUjAEUjgEQiGIA");
6233 todo_wine ok(match, "Figure does not match.\n");
6234 match = compare_figure(&ctx, 160, 160, 160, 160, 0xff652e89, 0, "yGBQSGA+ZDxkPmDgYQAA");
6235 todo_wine ok(match, "Figure does not match.\n");
6236 match = compare_figure(&ctx, 320, 160, 160, 160, 0xff652e89, 0,
6237 "iDAQjgEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEU"
6238 "jAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEU"
6239 "jAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEU"
6240 "jAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEU"
6241 "jAEUjAEUjAEUjAEUjAEUjAEUjAEUjgEQiDAA");
6242 todo_wine ok(match, "Figure does not match.\n");
6243 match = compare_figure(&ctx, 480, 160, 160, 160, 0xff652e89, 16,
6244 "3C4obzpjQF5EWkhXFSAVVRQkFFMUJhRRFCgUTxQqFE0VKhVMFCwUSxQuFEoULhVIFDAUSBQwFUYU"
6245 "MhRGFDIURRQ0FEQUNBRDFTQVQhQ2FEIUNhRCFDYUQRQ4FEAUOBRAFDgUQBQ4FD8UOhQ+FDoUPhQ6"
6246 "FD4UOhQ+FDoUPhQ6FD0VOxQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwU"
6247 "PBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBU7FD0UOhQ+FDoUPhQ6FD4UOhQ+FDoUPhQ6FD8UOBRA"
6248 "FDgUQBQ4FEAUOBRBFDYUQhQ2FEIUNhRCFTQVQxQ0FEQUNBRFFDIURhQyFEYVMBVHFDAUSBUuFUkU"
6249 "LhRLFCwUTBUrFE0UKhRPFCgUURQmFFMUJBRVSldIWUZdQWI78i8A");
6250 todo_wine ok(match, "Figure does not match.\n");
6252 match = compare_figure(&ctx, 0, 320, 160, 160, 0xff652e89, 0, "iGIQjgEUjAEUjgEQiGIA");
6253 todo_wine ok(match, "Figure does not match.\n");
6254 match = compare_figure(&ctx, 160, 320, 160, 160, 0xff652e89, 0, "yGBQSGA+ZDxkPmDgYQAA");
6255 todo_wine ok(match, "Figure does not match.\n");
6256 match = compare_figure(&ctx, 320, 320, 160, 160, 0xff652e89, 0,
6257 "iDAQjgEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEU"
6258 "jAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEU"
6259 "jAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEU"
6260 "jAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEU"
6261 "jAEUjAEUjAEUjAEUjAEUjAEUjAEUjgEQiDAA");
6262 todo_wine ok(match, "Figure does not match.\n");
6263 match = compare_figure(&ctx, 480, 320, 160, 160, 0xff652e89, 8,
6264 "9i80ZERWUExYRV5AHCocPRY4FjwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwU"
6265 "PBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8"
6266 "FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwU"
6267 "PBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8"
6268 "FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwU"
6269 "PBQ8FDwUPBQ8FDwUPBQ8FToVPRssG0BeRFpLUFVGYzT2LwAA");
6270 todo_wine ok(match, "Figure does not match.\n");
6272 hr = ID2D1Factory_CreatePathGeometry(factory, &geometry);
6273 ok(SUCCEEDED(hr), "Failed to create path geometry, hr %#x.\n", hr);
6274 hr = ID2D1PathGeometry_Open(geometry, &sink);
6275 ok(SUCCEEDED(hr), "Failed to open geometry sink, hr %#x.\n", hr);
6277 set_point(&point, 40.0f, 160.0f);
6278 ID2D1GeometrySink_BeginFigure(sink, point, D2D1_FIGURE_BEGIN_FILLED);
6279 ID2D1GeometrySink_EndFigure(sink, D2D1_FIGURE_END_OPEN);
6281 set_point(&point, 120.0f, 160.0f);
6282 ID2D1GeometrySink_BeginFigure(sink, point, D2D1_FIGURE_BEGIN_FILLED);
6283 line_to(sink, 120.0f, 160.0f);
6284 ID2D1GeometrySink_EndFigure(sink, D2D1_FIGURE_END_OPEN);
6286 set_point(&point, 200.0f, 160.0f);
6287 ID2D1GeometrySink_BeginFigure(sink, point, D2D1_FIGURE_BEGIN_FILLED);
6288 ID2D1GeometrySink_EndFigure(sink, D2D1_FIGURE_END_CLOSED);
6290 set_point(&point, 280.0f, 160.0f);
6291 ID2D1GeometrySink_BeginFigure(sink, point, D2D1_FIGURE_BEGIN_FILLED);
6292 line_to(sink, 280.0f, 160.0f);
6293 ID2D1GeometrySink_EndFigure(sink, D2D1_FIGURE_END_CLOSED);
6295 set_point(&point, 20.0f, 480.0f);
6296 ID2D1GeometrySink_BeginFigure(sink, point, D2D1_FIGURE_BEGIN_FILLED);
6297 line_to(sink, 60.0f, 480.0f);
6298 ID2D1GeometrySink_EndFigure(sink, D2D1_FIGURE_END_OPEN);
6300 set_point(&point, 120.0f, 400.0f);
6301 ID2D1GeometrySink_BeginFigure(sink, point, D2D1_FIGURE_BEGIN_FILLED);
6302 line_to(sink, 120.0f, 560.0f);
6303 line_to(sink, 120.0f, 400.0f);
6304 line_to(sink, 120.0f, 560.0f);
6305 ID2D1GeometrySink_EndFigure(sink, D2D1_FIGURE_END_OPEN);
6307 set_point(&point, 180.0f, 480.0f);
6308 ID2D1GeometrySink_BeginFigure(sink, point, D2D1_FIGURE_BEGIN_FILLED);
6309 line_to(sink, 220.0f, 480.0f);
6310 ID2D1GeometrySink_EndFigure(sink, D2D1_FIGURE_END_CLOSED);
6312 set_point(&point, 280.0f, 400.0f);
6313 ID2D1GeometrySink_BeginFigure(sink, point, D2D1_FIGURE_BEGIN_FILLED);
6314 line_to(sink, 280.0f, 560.0f);
6315 line_to(sink, 280.0f, 400.0f);
6316 line_to(sink, 280.0f, 560.0f);
6317 ID2D1GeometrySink_EndFigure(sink, D2D1_FIGURE_END_CLOSED);
6319 set_point(&point, 20.0f, 880.0f);
6320 ID2D1GeometrySink_BeginFigure(sink, point, D2D1_FIGURE_BEGIN_FILLED);
6321 line_to(sink, 40.0f, 720.0f);
6322 line_to(sink, 60.0f, 880.0f);
6323 ID2D1GeometrySink_EndFigure(sink, D2D1_FIGURE_END_OPEN);
6325 set_point(&point, 100.0f, 720.0f);
6326 ID2D1GeometrySink_BeginFigure(sink, point, D2D1_FIGURE_BEGIN_FILLED);
6327 line_to(sink, 120.0f, 880.0f);
6328 line_to(sink, 140.0f, 720.0f);
6329 ID2D1GeometrySink_EndFigure(sink, D2D1_FIGURE_END_OPEN);
6331 set_point(&point, 180.0f, 880.0f);
6332 ID2D1GeometrySink_BeginFigure(sink, point, D2D1_FIGURE_BEGIN_FILLED);
6333 line_to(sink, 200.0f, 720.0f);
6334 line_to(sink, 220.0f, 880.0f);
6335 ID2D1GeometrySink_EndFigure(sink, D2D1_FIGURE_END_CLOSED);
6337 set_point(&point, 260.0f, 720.0f);
6338 ID2D1GeometrySink_BeginFigure(sink, point, D2D1_FIGURE_BEGIN_FILLED);
6339 line_to(sink, 280.0f, 880.0f);
6340 line_to(sink, 300.0f, 720.0f);
6341 ID2D1GeometrySink_EndFigure(sink, D2D1_FIGURE_END_CLOSED);
6343 ID2D1GeometrySink_SetFillMode(sink, D2D1_FILL_MODE_ALTERNATE);
6344 hr = ID2D1GeometrySink_Close(sink);
6345 ok(SUCCEEDED(hr), "Failed to close geometry sink, hr %#x.\n", hr);
6346 ID2D1GeometrySink_Release(sink);
6348 ID2D1RenderTarget_BeginDraw(rt);
6349 ID2D1RenderTarget_Clear(rt, &color);
6350 ID2D1RenderTarget_DrawGeometry(rt, (ID2D1Geometry *)geometry, (ID2D1Brush *)brush, 5.0f, NULL);
6351 hr = ID2D1RenderTarget_EndDraw(rt, NULL, NULL);
6352 ok(SUCCEEDED(hr), "Failed to end draw, hr %#x.\n", hr);
6353 ID2D1PathGeometry_Release(geometry);
6355 match = compare_figure(&ctx, 0, 0, 160, 160, 0xff652e89, 0, "");
6356 ok(match, "Figure does not match.\n");
6357 match = compare_figure(&ctx, 160, 0, 160, 160, 0xff652e89, 0, "");
6358 ok(match, "Figure does not match.\n");
6359 match = compare_figure(&ctx, 320, 0, 160, 160, 0xff652e89, 0, "");
6360 ok(match, "Figure does not match.\n");
6361 match = compare_figure(&ctx, 480, 0, 160, 160, 0xff652e89, 0, "q2MKlgEKq2MA");
6362 todo_wine ok(match, "Figure does not match.\n");
6364 match = compare_figure(&ctx, 0, 160, 160, 160, 0xff652e89, 0, "iGNQUFCIYwAA");
6365 ok(match, "Figure does not match.\n");
6366 match = compare_figure(&ctx, 160, 160, 160, 160, 0xff652e89, 0,
6367 "qyIKlgEKlgEKlgEKlgEKlgEKlgEKlgEKlgEKlgEKlgEKlgEKlgEKlgEKlgEKlgEKlgEKlgEKlgEK"
6368 "lgEKlgEKlgEKlgEKlgEKlgEKlgEKlgEKlgEKlgEKlgEKlgEKlgEKlgEKlgEKlgEKlgEKlgEKlgEK"
6369 "lgEKlgEKlgEKlgEKlgEKlgEKlgEKlgEKlgEKlgEKlgEKlgEKlgEKlgEKlgEKQQpLCkEKSwqWAQqW"
6370 "AQqWAQqWAQqWAQqWAQqWAQqWAQqWAQqWAQqWAQqWAQqWAQqWAQqWAQqWAQqWAQqWAQqWAQqWAQqW"
6371 "AQqWAQqWAQqWAQqWAQqWAQqWAQqWAQqWAQqWAQqWAQqWAQqWAQqWAQqWAQqWAQqWAQqWAQqWAQqW"
6372 "AQqWAQqWAQqWAQqWAQqWAQqWAQqWAQqWAQqWAQqWAQrLIwAA");
6373 ok(match, "Figure does not match.\n");
6374 match = compare_figure(&ctx, 320, 160, 160, 160, 0xff652e89, 0, "4GLAAuBi");
6375 ok(match, "Figure does not match.\n");
6376 match = compare_figure(&ctx, 480, 160, 160, 160, 0xff652e89, 0,
6377 "qyIKlgEKlgEKlgEKlgEKlgEKlgEKlgEKlgEKlgEKlgEKlgEKlgEKlgEKlgEKlgEKlgEKlgEKlgEK"
6378 "lgEKlgEKlgEKlgEKlgEKlgEKlgEKlgEKlgEKlgEKlgEKlgEKlgEKlgEKlgEKlgEKlgEKlgEKlgEK"
6379 "lgEKlgEKlgEKlgEKlgEKlgEKlgEKlgEKlgEKlgEKlgEKlgEKlgEKlgEKSwpBCksKQQqWAQqWAQqW"
6380 "AQqWAQqWAQqWAQqWAQqWAQqWAQqWAQqWAQqWAQqWAQqWAQqWAQqWAQqWAQqWAQqWAQqWAQqWAQqW"
6381 "AQqWAQqWAQqWAQqWAQqWAQqWAQqWAQqWAQqWAQqWAQqWAQqWAQqWAQqWAQqWAQqWAQqWAQqWAQqW"
6382 "AQqWAQqWAQqWAQqWAQqWAQqWAQqWAQqWAQqWAQqWAQrLIwAA");
6383 ok(match, "Figure does not match.\n");
6385 match = compare_figure(&ctx, 0, 320, 160, 160, 0xff652e89, 0,
6386 "rycCngECnQEEnAEEmwEGmgEGmQEImAEIlwEKlgEKlQEMlAEMkwEOkgEOkQEQkAEQjwESjgESjQEU"
6387 "jAEUiwEKAgqKAQoCCokBCgQKiAEKBAqHAQoGCoYBCgYKhQEKCAqEAQoICoMBCgoKggEKCgqBAQoM"
6388 "CoABCgwKfwoOCn4KDgp9ChAKfAoQCnsKEgp6ChIKeQoUCngKFAp3ChYKdgoWCnUKGAp0ChgKcwoa"
6389 "CnIKGgpxChwKcAocCm8KHgpuCh4KbQogCmwKIAprCiIKagoiCmkKJApoCiQKZwomCmYKJgplCigK"
6390 "ZAooCmMKKgpiCioKYQosCmAKLApfCi4KXgouCl0KMApcCjAKWwoyCloKMgpZCjQKWAo0ClcKNgpW"
6391 "CjYKVQo4ClQKOApTCjoKUgo6ClEKPApQCjwKTwo+Ck4KPgpNCkAKTApACksKQgpKCkIKSQpECkgK"
6392 "RApHCkYKozIA");
6393 ok(match, "Figure does not match.\n");
6394 match = compare_figure(&ctx, 160, 320, 160, 160, 0xff652e89, 0,
6395 "ozIKRgpHCkQKSApECkkKQgpKCkIKSwpACkwKQApNCj4KTgo+Ck8KPApQCjwKUQo6ClIKOgpTCjgK"
6396 "VAo4ClUKNgpWCjYKVwo0ClgKNApZCjIKWgoyClsKMApcCjAKXQouCl4KLgpfCiwKYAosCmEKKgpi"
6397 "CioKYwooCmQKKAplCiYKZgomCmcKJApoCiQKaQoiCmoKIgprCiAKbAogCm0KHgpuCh4KbwocCnAK"
6398 "HApxChoKcgoaCnMKGAp0ChgKdQoWCnYKFgp3ChQKeAoUCnkKEgp6ChIKewoQCnwKEAp9Cg4KfgoO"
6399 "Cn8KDAqAAQoMCoEBCgoKggEKCgqDAQoICoQBCggKhQEKBgqGAQoGCocBCgQKiAEKBAqJAQoCCooB"
6400 "CgIKiwEUjAEUjQESjgESjwEQkAEQkQEOkgEOkwEMlAEMlQEKlgEKlwEImAEImQEGmgEGmwEEnAEE"
6401 "nQECngECrycA");
6402 ok(match, "Figure does not match.\n");
6403 match = compare_figure(&ctx, 320, 320, 160, 160, 0xff652e89, 0,
6404 "rycCngECnQEEnAEEmwEGmgEGmQEImAEIlwEKlgEKlQEMlAEMkwEOkgEOkQEQkAEQjwESjgESjQEU"
6405 "jAEUiwEKAgqKAQoCCokBCgQKiAEKBAqHAQoGCoYBCgYKhQEKCAqEAQoICoMBCgoKggEKCgqBAQoM"
6406 "CoABCgwKfwoOCn4KDgp9ChAKfAoQCnsKEgp6ChIKeQoUCngKFAp3ChYKdgoWCnUKGAp0ChgKcwoa"
6407 "CnIKGgpxChwKcAocCm8KHgpuCh4KbQogCmwKIAprCiIKagoiCmkKJApoCiQKZwomCmYKJgplCigK"
6408 "ZAooCmMKKgpiCioKYQosCmAKLApfCi4KXgouCl0KMApcCjAKWwoyCloKMgpZCjQKWAo0ClcKNgpW"
6409 "CjYKVQo4ClQKOApTCjoKUgo6ClEKPApQCjwKTwo+Ck4KPgpNCkAKTApACksKQgpKCkIKSQpECkgK"
6410 "RApHWkZagzEA");
6411 ok(match, "Figure does not match.\n");
6412 match = compare_figure(&ctx, 480, 320, 160, 160, 0xff652e89, 0,
6413 "gzFaRlpHCkQKSApECkkKQgpKCkIKSwpACkwKQApNCj4KTgo+Ck8KPApQCjwKUQo6ClIKOgpTCjgK"
6414 "VAo4ClUKNgpWCjYKVwo0ClgKNApZCjIKWgoyClsKMApcCjAKXQouCl4KLgpfCiwKYAosCmEKKgpi"
6415 "CioKYwooCmQKKAplCiYKZgomCmcKJApoCiQKaQoiCmoKIgprCiAKbAogCm0KHgpuCh4KbwocCnAK"
6416 "HApxChoKcgoaCnMKGAp0ChgKdQoWCnYKFgp3ChQKeAoUCnkKEgp6ChIKewoQCnwKEAp9Cg4KfgoO"
6417 "Cn8KDAqAAQoMCoEBCgoKggEKCgqDAQoICoQBCggKhQEKBgqGAQoGCocBCgQKiAEKBAqJAQoCCooB"
6418 "CgIKiwEUjAEUjQESjgESjwEQkAEQkQEOkgEOkwEMlAEMlQEKlgEKlwEImAEImQEGmgEGmwEEnAEE"
6419 "nQECngECrycA");
6420 ok(match, "Figure does not match.\n");
6422 set_rect(&rect, 20.0f, 80.0f, 60.0f, 240.0f);
6423 hr = ID2D1Factory_CreateRectangleGeometry(factory, &rect, &rect_geometry[0]);
6424 ok(SUCCEEDED(hr), "Failed to create geometry, hr %#x.\n", hr);
6426 set_rect(&rect, -1.0f, -1.0f, 1.0f, 1.0f);
6427 hr = ID2D1Factory_CreateRectangleGeometry(factory, &rect, &rect_geometry[1]);
6428 ok(SUCCEEDED(hr), "Failed to create geometry, hr %#x.\n", hr);
6430 set_matrix_identity(&matrix);
6431 translate_matrix(&matrix, 160.0f, 640.0f);
6432 scale_matrix(&matrix, 40.0f, 160.0f);
6433 rotate_matrix(&matrix, M_PI / -5.0f);
6434 hr = ID2D1Factory_CreateTransformedGeometry(factory,
6435 (ID2D1Geometry *)rect_geometry[1], &matrix, &transformed_geometry[0]);
6436 ok(SUCCEEDED(hr), "Failed to create geometry, hr %#x.\n", hr);
6438 set_matrix_identity(&matrix);
6439 scale_matrix(&matrix, 0.5f, 1.0f);
6440 translate_matrix(&matrix, -80.0f, 0.0f);
6441 hr = ID2D1Factory_CreateTransformedGeometry(factory,
6442 (ID2D1Geometry *)transformed_geometry[0], &matrix, &transformed_geometry[1]);
6443 ok(SUCCEEDED(hr), "Failed to create geometry, hr %#x.\n", hr);
6445 set_matrix_identity(&matrix);
6446 rotate_matrix(&matrix, M_PI / 2.0f);
6447 translate_matrix(&matrix, 80.0f, -320.0f);
6448 scale_matrix(&matrix, 2.0f, 0.25f);
6449 hr = ID2D1Factory_CreateTransformedGeometry(factory,
6450 (ID2D1Geometry *)transformed_geometry[1], &matrix, &transformed_geometry[2]);
6451 ok(SUCCEEDED(hr), "Failed to create geometry, hr %#x.\n", hr);
6453 ID2D1RenderTarget_BeginDraw(rt);
6454 ID2D1RenderTarget_Clear(rt, &color);
6455 ID2D1RenderTarget_DrawGeometry(rt, (ID2D1Geometry *)rect_geometry[0], (ID2D1Brush *)brush, 10.0f, NULL);
6456 ID2D1RenderTarget_DrawGeometry(rt, (ID2D1Geometry *)transformed_geometry[0], (ID2D1Brush *)brush, 10.0f, NULL);
6457 ID2D1RenderTarget_DrawGeometry(rt, (ID2D1Geometry *)transformed_geometry[1], (ID2D1Brush *)brush, 5.0f, NULL);
6458 ID2D1RenderTarget_DrawGeometry(rt, (ID2D1Geometry *)transformed_geometry[2], (ID2D1Brush *)brush, 15.0f, NULL);
6459 hr = ID2D1RenderTarget_EndDraw(rt, NULL, NULL);
6460 ok(SUCCEEDED(hr), "Failed to end draw, hr %#x.\n", hr);
6461 ID2D1TransformedGeometry_Release(transformed_geometry[2]);
6462 ID2D1TransformedGeometry_Release(transformed_geometry[1]);
6463 ID2D1TransformedGeometry_Release(transformed_geometry[0]);
6464 ID2D1RectangleGeometry_Release(rect_geometry[1]);
6465 ID2D1RectangleGeometry_Release(rect_geometry[0]);
6467 match = compare_figure(&ctx, 0, 0, 160, 160, 0xff652e89, 0,
6468 "vi5kPGQ8ZDxkPGQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwU"
6469 "PBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8"
6470 "FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwU"
6471 "PBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8"
6472 "FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwU"
6473 "PBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8ZDxkPGQ8ZDxk3i8A");
6474 ok(match, "Figure does not match.\n");
6475 match = compare_figure(&ctx, 160, 0, 320, 160, 0xff652e89, 32,
6476 "8XYGtQIOrAIXpAIfmwIokwIwigI4gwJA+gFJ8gFR6QEzAiXhATMKJdgBMxMl0AEzGyXHATMkJb8B"
6477 "MysmtgEzNCWvATM8JaYBM0UlngEzTSWVATNWJY0BM14lhAEzZyV8M28lczN4JWszgAElYjOIASZa"
6478 "M5ABJVgtmQElWCWhASVYJaEBJVgloQElWCWhASVYJaEBJVgloQElWCWhASVYJaEBJVglmQEtWCWQ"
6479 "ATNaJogBM2IlgAEzayV4M3MlbzN8JWczhAElXjONASVWM5UBJU0zngElRTOmASU8M68BJTQztgEm"
6480 "KzO/ASUkM8cBJRsz0AElEzPYASUKM+EBJQIz6QFR8gFJ+gFAgwI4igIwkwIomwIfpAIXrAIOtQIG"
6481 "8XYA");
6482 ok(match, "Figure does not match.\n");
6483 match = compare_figure(&ctx, 0, 160, 160, 320, 0xff652e89, 32,
6484 "ujEBngECnQEDnQEEmwEFmgEHmQEHmAEIlwEKlgEKlQELlAENkwENkgEOkQEQjwERjwESjQETjAEU"
6485 "jAEKAQqKAQoCCokBCgMKiQEKBAqHAQoFCoYBCgYKhgEKBwqEAQoICoMBCgkKgwEKCgqBAQoLCoAB"
6486 "Cg0KfgsNCn4KDgp9ChAKewsQCnsKEQp6ChMKeAoUCngKFAp3ChYKdQoXCnUKGApzChkKcgoaCnIK"
6487 "GwpwChwKbwodCm4LHgptCh8KbAogCmsLIQpqCiIKaQokCmcKJQpnCiUKZgonCmQKKApkCigKYwoq"
6488 "CmEKKwphCisKYAotCl4KLgpdCy8KXAowClsKMQpaCzIKWQozClgKNApXCjYKVgo2ClUKNwpUCjkK"
6489 "Uwo5ClIKOwpQCjwKTws8Ck8KPgpNCj8KTAs/CkwKQQpKCkIKSQtCCkkKRApHCkUKRgpHCkUKRwpE"
6490 "CkgKQwpKCkIKSgpBCksKQApNCj4LTQo+Ck4KPQpQCjsLUAo7ClIKOQpTCjgLUwo4ClUKNgpWCjUK"
6491 "Vwo1ClgKMwpZCjQKWAo0ClkKMwpZCjQKWQozClkKMwpZCjQKWQozClkKMwpZCjQKWQozClkKNApY"
6492 "CjQKWQozClkKNApZCjMKWQozClkKNApZCjMKWQozClkKNApZCjMKWQo0ClgKNApZCjMKWQo0ClkK"
6493 "MwpZCjMKWQo0ClkKMwpZCjMKWQo0ClkKMwpZCjQKWAo0ClkKMwpYCjUKVwo1ClYKNgpVCjgKUws4"
6494 "ClMKOQpSCjsKUAs7ClAKPQpOCj4KTQs+Ck0KQApLCkEKSgpCCkoKQwpICkQKRwpFCkcKRgpFCkcK"
6495 "RApJCkILSQpCCkoKQQpMCj8LTAo/Ck0KPgpPCjwLTwo8ClAKOwpSCjkKUwo5ClQKNwpVCjYKVgo2"
6496 "ClcKNApYCjMKWQoyC1oKMQpbCjAKXAovC10KLgpeCi0KYAorCmEKKwphCioKYwooCmQKKApkCicK"
6497 "ZgolCmcKJQpnCiQKaQoiCmoKIQtrCiAKbAofCm0KHgtuCh0KbwocCnAKGwpyChoKcgoZCnMKGAp1"
6498 "ChcKdQoWCncKFAp4ChQKeAoTCnoKEQp7ChALewoQCn0KDgp+Cg0LfgoNCoABCgsKgQEKCgqDAQoJ"
6499 "CoMBCggKhAEKBwqGAQoGCoYBCgUKhwEKBAqJAQoDCokBCgIKigEKAQqMARSMARONARKPARGPARCR"
6500 "AQ6SAQ2TAQ2UAQuVAQqWAQqXAQiYAQeZAQeaAQWbAQSdAQOdAQKeAQG6MQAA");
6501 ok(match, "Figure does not match.\n");
6502 match = compare_figure(&ctx, 160, 160, 320, 320, 0xff652e89, 64,
6503 "82ICvQIEugIHuAIJtgIKtAINsgIPsAIRrQITrAIVqQIYpwIZpgIbowIeoQIgnwIhnQIkmwImmAIp"
6504 "lgIVARSVAhUDFJICFQUVkAIVBxSPAhUJFIwCFQwUigIVDRWHAhYPFIYCFRIUhAIVFBSBAhUWFf8B"
6505 "FRgU/gEVGhT7ARUcFfkBFR4U9wEWIBT1ARUjFPMBFSQV8AEVJxTvARUpFOwBFisU6gEVLRXoARUv"
6506 "FOYBFjEU5AEVMxXiARU1FOABFTgU3gEVOhTbARY7FdkBFT4U2AEVQBTVARZCFNMBFUQV0QEVRhTP"
6507 "ARVJFM0BFUoVygEWTBTJARVPFMcBFVEUxAEVUxXCARVVFMEBFVcUvgEVWRW8ARVbFbkBFl0UuAEV"
6508 "YBS2ARVhFbMBFWQUsgEVZhSwARVoFK0BFWoVqwEVbBSpARZuFKcBFXAVpQEVchWiARV1FKEBFXcU"
6509 "nwEVeBWcARV7FJsBFX0UmAEWfxSWARWBARWUARWDARSSARWGARSQARWHARWOARWJARWLARWMARSK"
6510 "ARWOARSHARaPARWFARWSARSEARWUARSBARWXARR/FZgBFX0VmgEUexWdARR5FZ4BFXYWoAEVdBWj"
6511 "ARRzFaUBFHAVpwEVbhWpARRtFasBFGoVrgEUaBWvARVmFbEBFGcUsgEUZxSxARVmFbEBFWYUsgEU"
6512 "ZxSyARRnFLEBFWYVsQEUZxSyARRnFLIBFGcUsQEVZhWxARRnFLIBFGcUsQEVZhWxARVmFLIBFGcU"
6513 "sgEUZxSxARVmFbEBFGcUsgEUZxSyARRmFbEBFWYVsQEUZxSyARRnFLEBFWYVsQEUZxSyARRnFLIB"
6514 "FGcUsQEVZhWxARRnFLIBFGcUsgEUZhWxARVmFbEBFGcUsgEUZxSxARVmFa8BFWgUrgEVahSrARVt"
6515 "FKkBFW4VpwEVcBSlARVzFKMBFXQVoAEWdhWeARV5FJ0BFXsUmgEVfRWYARV/FJcBFYEBFJQBFYQB"
6516 "FJIBFYUBFY8BFocBFI4BFYoBFIwBFYsBFYkBFY4BFYcBFZABFIYBFZIBFIMBFZQBFYEBFZYBFH8W"
6517 "mAEUfRWbARR7FZwBFXgVnwEUdxWhARR1FaIBFXIVpQEVcBWnARRuFqkBFGwVqwEVahWtARRoFbAB"
6518 "FGYVsgEUZBWzARVhFbYBFGAVuAEUXRa5ARVbFbwBFVkVvgEUVxXBARRVFcIBFVMVxAEUURXHARRP"
6519 "FckBFEwWygEVShXNARRJFc8BFEYV0QEVRBXTARRCFtUBFEAV2AEUPhXZARU7FtsBFDoV3gEUOBXg"
6520 "ARQ1FeIBFTMV5AEUMRbmARQvFegBFS0V6gEUKxbsARQpFe8BFCcV8AEVJBXzARQjFfUBFCAW9wEU"
6521 "HhX5ARUcFfsBFBoV/gEUGBX/ARUWFYECFBQVhAIUEhWGAhQPFocCFQ0VigIUDBWMAhQJFY8CFAcV"
6522 "kAIVBRWSAhQDFZUCFAEVlgIpmAImmwIknQIhnwIgoQIeowIbpgIZpwIYqQIVrAITrQIRsAIPsgIN"
6523 "tAIKtgIJuAIHugIEvQIC82IA");
6524 ok(match, "Figure does not match.\n");
6526 hr = ID2D1Factory_CreatePathGeometry(factory, &geometry);
6527 ok(SUCCEEDED(hr), "Failed to create path geometry, hr %#x.\n", hr);
6528 hr = ID2D1PathGeometry_Open(geometry, &sink);
6529 ok(SUCCEEDED(hr), "Failed to open geometry sink, hr %#x.\n", hr);
6531 set_point(&point, 20.0f, 80.0f);
6532 ID2D1GeometrySink_BeginFigure(sink, point, D2D1_FIGURE_BEGIN_HOLLOW);
6533 quadratic_to(sink, 40.0f, 80.0f, 60.0f, 80.0f);
6534 quadratic_to(sink, 60.0f, 160.0f, 60.0f, 240.0f);
6535 quadratic_to(sink, 40.0f, 240.0f, 20.0f, 240.0f);
6536 quadratic_to(sink, 20.0f, 160.0f, 20.0f, 80.0f);
6537 ID2D1GeometrySink_EndFigure(sink, D2D1_FIGURE_END_CLOSED);
6539 set_point(&point, 100.0f, 80.0f);
6540 ID2D1GeometrySink_BeginFigure(sink, point, D2D1_FIGURE_BEGIN_HOLLOW);
6541 quadratic_to(sink, 105.0f, 80.0f, 140.0f, 80.0f);
6542 quadratic_to(sink, 140.0f, 100.0f, 140.0f, 240.0f);
6543 quadratic_to(sink, 135.0f, 240.0f, 100.0f, 240.0f);
6544 quadratic_to(sink, 100.0f, 220.0f, 100.0f, 80.0f);
6545 ID2D1GeometrySink_EndFigure(sink, D2D1_FIGURE_END_CLOSED);
6547 set_point(&point, 180.0f, 80.0f);
6548 ID2D1GeometrySink_BeginFigure(sink, point, D2D1_FIGURE_BEGIN_HOLLOW);
6549 quadratic_to(sink, 215.0f, 80.0f, 220.0f, 80.0f);
6550 quadratic_to(sink, 220.0f, 220.0f, 220.0f, 240.0f);
6551 quadratic_to(sink, 185.0f, 240.0f, 180.0f, 240.0f);
6552 quadratic_to(sink, 180.0f, 100.0f, 180.0f, 80.0f);
6553 ID2D1GeometrySink_EndFigure(sink, D2D1_FIGURE_END_CLOSED);
6555 set_point(&point, 260.0f, 80.0f);
6556 ID2D1GeometrySink_BeginFigure(sink, point, D2D1_FIGURE_BEGIN_HOLLOW);
6557 quadratic_to(sink, 280.0f, 80.0f, 300.0f, 80.0f);
6558 quadratic_to(sink, 300.0f, 160.0f, 300.0f, 240.0f);
6559 quadratic_to(sink, 280.0f, 240.0f, 260.0f, 240.0f);
6560 quadratic_to(sink, 260.0f, 160.0f, 260.0f, 80.0f);
6561 ID2D1GeometrySink_EndFigure(sink, D2D1_FIGURE_END_OPEN);
6563 set_point(&point, 20.0f, 400.0f);
6564 ID2D1GeometrySink_BeginFigure(sink, point, D2D1_FIGURE_BEGIN_HOLLOW);
6565 quadratic_to(sink, 40.0f, 420.0f, 60.0f, 400.0f);
6566 quadratic_to(sink, 55.0f, 480.0f, 60.0f, 560.0f);
6567 quadratic_to(sink, 40.0f, 540.0f, 20.0f, 560.0f);
6568 quadratic_to(sink, 25.0f, 480.0f, 20.0f, 400.0f);
6569 ID2D1GeometrySink_EndFigure(sink, D2D1_FIGURE_END_CLOSED);
6571 set_point(&point, 100.0f, 400.0f);
6572 ID2D1GeometrySink_BeginFigure(sink, point, D2D1_FIGURE_BEGIN_HOLLOW);
6573 quadratic_to(sink, 105.0f, 420.0f, 140.0f, 400.0f);
6574 quadratic_to(sink, 135.0f, 420.0f, 140.0f, 560.0f);
6575 quadratic_to(sink, 135.0f, 540.0f, 100.0f, 560.0f);
6576 quadratic_to(sink, 105.0f, 540.0f, 100.0f, 400.0f);
6577 ID2D1GeometrySink_EndFigure(sink, D2D1_FIGURE_END_CLOSED);
6579 set_point(&point, 180.0f, 400.0f);
6580 ID2D1GeometrySink_BeginFigure(sink, point, D2D1_FIGURE_BEGIN_HOLLOW);
6581 quadratic_to(sink, 215.0f, 420.0f, 220.0f, 400.0f);
6582 quadratic_to(sink, 215.0f, 540.0f, 220.0f, 560.0f);
6583 quadratic_to(sink, 185.0f, 540.0f, 180.0f, 560.0f);
6584 quadratic_to(sink, 185.0f, 420.0f, 180.0f, 400.0f);
6585 ID2D1GeometrySink_EndFigure(sink, D2D1_FIGURE_END_CLOSED);
6587 set_point(&point, 260.0f, 400.0f);
6588 ID2D1GeometrySink_BeginFigure(sink, point, D2D1_FIGURE_BEGIN_HOLLOW);
6589 quadratic_to(sink, 280.0f, 420.0f, 300.0f, 400.0f);
6590 quadratic_to(sink, 295.0f, 480.0f, 300.0f, 560.0f);
6591 quadratic_to(sink, 280.0f, 540.0f, 260.0f, 560.0f);
6592 quadratic_to(sink, 265.0f, 480.0f, 260.0f, 400.0f);
6593 ID2D1GeometrySink_EndFigure(sink, D2D1_FIGURE_END_OPEN);
6595 set_point(&point, 20.0f, 720.0f);
6596 ID2D1GeometrySink_BeginFigure(sink, point, D2D1_FIGURE_BEGIN_HOLLOW);
6597 quadratic_to(sink, 40.0f, 700.0f, 60.0f, 720.0f);
6598 quadratic_to(sink, 65.0f, 800.0f, 60.0f, 880.0f);
6599 quadratic_to(sink, 40.0f, 900.0f, 20.0f, 880.0f);
6600 quadratic_to(sink, 15.0f, 800.0f, 20.0f, 720.0f);
6601 ID2D1GeometrySink_EndFigure(sink, D2D1_FIGURE_END_CLOSED);
6603 set_point(&point, 100.0f, 720.0f);
6604 ID2D1GeometrySink_BeginFigure(sink, point, D2D1_FIGURE_BEGIN_HOLLOW);
6605 quadratic_to(sink, 105.0f, 700.0f, 140.0f, 720.0f);
6606 quadratic_to(sink, 145.0f, 740.0f, 140.0f, 880.0f);
6607 quadratic_to(sink, 135.0f, 900.0f, 100.0f, 880.0f);
6608 quadratic_to(sink, 95.0f, 860.0f, 100.0f, 720.0f);
6609 ID2D1GeometrySink_EndFigure(sink, D2D1_FIGURE_END_CLOSED);
6611 set_point(&point, 180.0f, 720.0f);
6612 ID2D1GeometrySink_BeginFigure(sink, point, D2D1_FIGURE_BEGIN_HOLLOW);
6613 quadratic_to(sink, 215.0f, 700.0f, 220.0f, 720.0f);
6614 quadratic_to(sink, 225.0f, 860.0f, 220.0f, 880.0f);
6615 quadratic_to(sink, 185.0f, 900.0f, 180.0f, 880.0f);
6616 quadratic_to(sink, 175.0f, 740.0f, 180.0f, 720.0f);
6617 ID2D1GeometrySink_EndFigure(sink, D2D1_FIGURE_END_CLOSED);
6619 set_point(&point, 260.0f, 720.0f);
6620 ID2D1GeometrySink_BeginFigure(sink, point, D2D1_FIGURE_BEGIN_HOLLOW);
6621 quadratic_to(sink, 280.0f, 700.0f, 300.0f, 720.0f);
6622 quadratic_to(sink, 305.0f, 800.0f, 300.0f, 880.0f);
6623 quadratic_to(sink, 280.0f, 900.0f, 260.0f, 880.0f);
6624 quadratic_to(sink, 255.0f, 800.0f, 260.0f, 720.0f);
6625 ID2D1GeometrySink_EndFigure(sink, D2D1_FIGURE_END_OPEN);
6627 hr = ID2D1GeometrySink_Close(sink);
6628 ok(SUCCEEDED(hr), "Failed to close geometry sink, hr %#x.\n", hr);
6629 ID2D1GeometrySink_Release(sink);
6631 ID2D1RenderTarget_BeginDraw(rt);
6632 ID2D1RenderTarget_Clear(rt, &color);
6633 ID2D1RenderTarget_DrawGeometry(rt, (ID2D1Geometry *)geometry, (ID2D1Brush *)brush, 10.0f, NULL);
6634 hr = ID2D1RenderTarget_EndDraw(rt, NULL, NULL);
6635 ok(SUCCEEDED(hr), "Failed to end draw, hr %#x.\n", hr);
6636 ID2D1PathGeometry_Release(geometry);
6638 match = compare_figure(&ctx, 0, 0, 160, 160, 0xff652e89, 0,
6639 "vi5kPGQ8ZDxkPGQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwU"
6640 "PBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8"
6641 "FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwU"
6642 "PBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8"
6643 "FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwU"
6644 "PBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8ZDxkPGQ8ZDxk3i8A");
6645 ok(match, "Figure does not match.\n");
6646 match = compare_figure(&ctx, 160, 0, 160, 160, 0xff652e89, 0,
6647 "vi5kPGQ8ZDxkPGQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwU"
6648 "PBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8"
6649 "FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwU"
6650 "PBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8"
6651 "FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwU"
6652 "PBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8ZDxkPGQ8ZDxk3i8A");
6653 ok(match, "Figure does not match.\n");
6654 match = compare_figure(&ctx, 320, 0, 160, 160, 0xff652e89, 0,
6655 "vi5kPGQ8ZDxkPGQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwU"
6656 "PBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8"
6657 "FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwU"
6658 "PBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8"
6659 "FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwU"
6660 "PBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8ZDxkPGQ8ZDxk3i8A");
6661 ok(match, "Figure does not match.\n");
6662 match = compare_figure(&ctx, 480, 0, 160, 160, 0xff652e89, 0,
6663 "yC5aRlpGWjxkPGQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwU"
6664 "PBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8"
6665 "FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwU"
6666 "PBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8"
6667 "FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwU"
6668 "PBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8ZDxkPGQ8ZDxk3i8A");
6669 ok(match, "Figure does not match.\n");
6671 match = compare_figure(&ctx, 0, 160, 160, 160, 0xff652e89, 64,
6672 "3SoDYAM6B1gHOgtQCzoPSA87EkASPBc2FzwcLBw8IiAiPWI+Yj5iPhQBOAEUPhQKJgoUPxQ4FEAU"
6673 "OBRAFDgUQBQ4FEAUOBRBFDYUQhQ2FEIUNhRCFDYUQhQ2FEIUNhRDFDQURBQ0FEQUNBREFDQURBQ0"
6674 "FEQUNBREFDQURBQ0FEQUNBREFDQURRQyFEYUMhRGFDIURhQyFEYUMhRGFDIURhQyFEYUMhRGFDIU"
6675 "RhQyFEYUMhRGFDIURhQyFEYUMhRGFDIURhQyFEYUMhRGFDIURhQyFEYUMhRGFDIURhQyFEYUMhRG"
6676 "FDIURRQ0FEQUNBREFDQURBQ0FEQUNBREFDQURBQ0FEQUNBREFDQURBQ0FEMUNhRCFDYUQhQ2FEIU"
6677 "NhRCFDYUQhQ2FEEUOBRAFDgUQBQ4FEAUOBRAFDgUPxQKJgoUPhQBOAEUPmI+Yj5iPSIgIjwcLBw8"
6678 "FzYXPBJAEjsPSA86C1ALOgdYBzoDYAPdKgAA");
6679 ok(match, "Figure does not match.\n");
6680 match = compare_figure(&ctx, 160, 160, 160, 160, 0xff652e89, 1024,
6681 "uxUBnwECngEDnQEEnAEFmwEGmwEGmgEHmQEImAEJlwEKlgELlQEMlQEMlAENkwEOkgEPkQEQkAER"
6682 "VQQ2Ek0KOBJFEDkTPRY6FDUcOxUrJDwYHi09Yj5iP2BAQwkUQDgUFEAUOBRAFDcUQRQ3FEEUNxRC"
6683 "FDYUQhQ2FEIUNhRCFDUUQxQ1FEMUNRRDFDUUQxQ1FEQUNBREFDQURBQ0FEQUNBREFDQURBQ0FEQU"
6684 "NBREFDQURBQ0FEQUNBRFFDMURRQzFEUUMxRFFDMURRQzFEUUMxRFFDMURRQzFEUUMxRFFDMURRQ0"
6685 "FEQUNBRFFDMURRQzFEUUMxRFFDMURRQzFEUUMxRFFDMURRQzFEUUMxRFFDMURRQ0FEQUNBREFDQU"
6686 "RBQ0FEQUNBREFDQURBQ0FEQUNBREFDQURBQ0FEQUNRRDFDUUQxQ1FEMUNRRDFDUUQhQ2FEIUNhRC"
6687 "FDYUQhQ3FEEUNxRBFDcUQBQ4FEAUFDhAFAlDQGA/Yj5iPS0eGDwkKxU7HDUUOhY9EzkQRRI4Ck0S"
6688 "NgRVEZABEJEBD5IBDpMBDZQBDJUBDJUBC5YBCpcBCZgBCJkBB5oBBpsBBpsBBZwBBJ0BA54BAp8B"
6689 "AbsV");
6690 ok(match, "Figure does not match.\n");
6691 match = compare_figure(&ctx, 320, 160, 160, 160, 0xff652e89, 1024,
6692 "pBYBngECnQEDnAEEmwEFmgEGmQEGmQEHmAEIlwEJlgEKlQELlAEMkwEMkwENkgEOkQEPkAEQNgRV"
6693 "ETcKTRI4EEUSOhY9EzscNRQ8JCsVPS0eGD5iPmI/YEAUCUNAFBQ4QBQ4FEEUNxRBFDcUQRQ3FEEU"
6694 "NhRCFDYUQhQ2FEMUNRRDFDUUQxQ1FEMUNRRDFDUUQxQ0FEQUNBREFDQURBQ0FEQUNBREFDQURBQ0"
6695 "FEQUNBREFDQURBQ0FEQUMxRFFDMURRQzFEUUMxRFFDMURRQzFEUUMxRFFDMURRQzFEUUMxREFDQU"
6696 "RBQ0FEQUMxRFFDMURRQzFEUUMxRFFDMURRQzFEUUMxRFFDMURRQzFEUUMxREFDQURBQ0FEQUNBRE"
6697 "FDQURBQ0FEQUNBREFDQURBQ0FEQUNBREFDQUQxQ1FEMUNRRDFDUUQxQ1FEMUNRRDFDYUQhQ2FEIU"
6698 "NhRBFDcUQRQ3FEEUNxRBFDgUQDgUFEBDCRRAYD9iPmI+GB4tPRUrJDwUNRw7Ez0WOhJFEDgSTQo3"
6699 "EVUENhCQAQ+RAQ6SAQ2TAQyTAQyUAQuVAQqWAQmXAQiYAQeZAQaZAQaaAQWbAQScAQOdAQKeAQGk"
6700 "FgAA");
6701 ok(match, "Figure does not match.\n");
6702 match = compare_figure(&ctx, 480, 160, 160, 160, 0xff652e89, 64,
6703 "wCsDmQEHlQELkQEPSwJAEkgLNhc8HCwcPCIgIj1iPmI+Yj4UATgBFD4UCiYKFD8UOBRAFDgUQBQ4"
6704 "FEAUOBRAFDgUQRQ2FEIUNhRCFDYUQhQ2FEIUNhRCFDYUQxQ0FEQUNBREFDQURBQ0FEQUNBREFDQU"
6705 "RBQ0FEQUNBREFDQURBQ0FEUUMhRGFDIURhQyFEYUMhRGFDIURhQyFEYUMhRGFDIURhQyFEYUMhRG"
6706 "FDIURhQyFEYUMhRGFDIURhQyFEYUMhRGFDIURhQyFEYUMhRGFDIURhQyFEYUMhRGFDIURhQyFEUU"
6707 "NBREFDQURBQ0FEQUNBREFDQURBQ0FEQUNBREFDQURBQ0FEQUNBRDFDYUQhQ2FEIUNhRCFDYUQhQ2"
6708 "FEIUNhRBFDgUQBQ4FEAUOBRAFDgUQBQ4FD8UCiYKFD4UATgBFD5iPmI+Yj0iICI8HCwcPBc2FzwS"
6709 "QBI7D0gPOgtQCzoHWAc6A2AD3SoA");
6710 ok(match, "Figure does not match.\n");
6712 match = compare_figure(&ctx, 0, 320, 160, 160, 0xff652e89, 64,
6713 "3SkmcThiRFdOTVhEICAgPhwsHDwXNhc8FDwUOxQ+FDoUPhQ6FD4UOhQ+FDoUPhQ5FEAUOBRAFDgU"
6714 "QBQ4FEAUOBRAFDcUQhQ2FEIUNhRCFDYUQhQ2FEIUNhRCFDUURBQ0FEQUNBREFDQURBQ0FEQUNBRE"
6715 "FDQURBQ0FEQUNBREFDQURBQzFEYUMhRGFDIURhQyFEYUMhRGFDIURhQyFEYUMhRGFDIURhQyFEYU"
6716 "MhRGFDIURhQyFEYUMhRGFDIURhQyFEYUMhRGFDIURhQyFEYUMhRGFDIURhQyFEYUMhRGFDIURhQz"
6717 "FEQUNBREFDQURBQ0FEQUNBREFDQURBQ0FEQUNBREFDQURBQ0FEQUNRRCFDYUQhQ2FEIUNhRCFDYU"
6718 "QhQ2FEIUNxRAFDgUQBQ4FEAUOBRAFDgUQBQ5FD4UOhQ+FDoUPhQ6FD4UOhQ+FDsUPBQ8FzYXPBws"
6719 "HD4gICBEWE1OV0RiOHEm3SkA");
6720 ok(match, "Figure does not match.\n");
6721 match = compare_figure(&ctx, 160, 320, 160, 160, 0xff652e89, 1024,
6722 "zykoczhkRVhQTlpEFx4tPRUrJDwUNRw7FDwVOxQ+FDoUPhQ5FEAUOBRAFDgUQBQ4FEAUOBRBFDcU"
6723 "QRQ3FEEUNhRCFDYUQhQ2FEIUNhRDFDUUQxQ1FEMUNRRDFDUUQxQ0FEQUNBREFDQURBQ0FEQUNBRE"
6724 "FDQURBQ0FEQUNBREFDQURBQ0FEQUMxRFFDMURRQzFEUUMxRFFDMURRQzFEUUMxRFFDMURRQzFEUU"
6725 "MxRFFDMURBQ0FEQUMxRFFDMURRQzFEUUMxRFFDMURRQzFEUUMxRFFDMURRQzFEUUMxRFFDMURBQ0"
6726 "FEQUNBREFDQURBQ0FEQUNBREFDQURBQ0FEQUNBREFDQURBQ0FEMUNRRDFDUUQxQ1FEMUNRRDFDYU"
6727 "QhQ2FEIUNhRCFDYUQRQ3FEEUNxRBFDgUQBQ4FEAUOBRAFDgUQBQ5FD4UOhQ+FDsVPBQ7HDUUPCQr"
6728 "FT0tHhdEWk5QWEVkOHMozykA");
6729 ok(match, "Figure does not match.\n");
6730 match = compare_figure(&ctx, 320, 320, 160, 160, 0xff652e89, 1024,
6731 "6SkobThfRVNQSFpALR4XPSQrFTscNRQ7FTwUOhQ+FDoUPhQ5FEAUOBRAFDgUQBQ4FEAUNxRBFDcU"
6732 "QRQ3FEEUNxRCFDYUQhQ2FEIUNRRDFDUUQxQ1FEMUNRRDFDUUQxQ1FEQUNBREFDQURBQ0FEQUNBRE"
6733 "FDQURBQ0FEQUNBREFDQURBQ0FEQUNBRFFDMURRQzFEUUMxRFFDMURRQzFEUUMxRFFDMURRQzFEUU"
6734 "MxRFFDQURBQ0FEQUNBRFFDMURRQzFEUUMxRFFDMURRQzFEUUMxRFFDMURRQzFEUUMxRFFDQURBQ0"
6735 "FEQUNBREFDQURBQ0FEQUNBREFDQURBQ0FEQUNBREFDQURBQ1FEMUNRRDFDUUQxQ1FEMUNRRDFDUU"
6736 "QhQ2FEIUNhRCFDcUQRQ3FEEUNxRBFDcUQBQ4FEAUOBRAFDgUQBQ5FD4UOhQ+FDoUPBU7FDUcOxUr"
6737 "JD0XHi1AWkhQU0VfOG0o6SkA");
6738 ok(match, "Figure does not match.\n");
6739 match = compare_figure(&ctx, 480, 320, 160, 160, 0xff652e89, 64,
6740 "3SkmcThiRFdOTVhGHiAgRhQsHDwXNhc8FDwUOxQ+FDoUPhQ6FD4UOhQ+FDoUPhQ5FEAUOBRAFDgU"
6741 "QBQ4FEAUOBRAFDcUQhQ2FEIUNhRCFDYUQhQ2FEIUNhRCFDUURBQ0FEQUNBREFDQURBQ0FEQUNBRE"
6742 "FDQURBQ0FEQUNBREFDQURBQzFEYUMhRGFDIURhQyFEYUMhRGFDIURhQyFEYUMhRGFDIURhQyFEYU"
6743 "MhRGFDIURhQyFEYUMhRGFDIURhQyFEYUMhRGFDIURhQyFEYUMhRGFDIURhQyFEYUMhRGFDIURhQz"
6744 "FEQUNBREFDQURBQ0FEQUNBREFDQURBQ0FEQUNBREFDQURBQ0FEQUNRRCFDYUQhQ2FEIUNhRCFDYU"
6745 "QhQ2FEIUNxRAFDgUQBQ4FEAUOBRAFDgUQBQ5FD4UOhQ+FDoUPhQ6FD4UOhQ+FDsUPBQ8FzYXPBws"
6746 "HD4gICBEWE1OV0RiOHEm3SkA");
6747 ok(match, "Figure does not match.\n");
6749 hr = ID2D1Factory_CreatePathGeometry(factory, &geometry);
6750 ok(SUCCEEDED(hr), "Failed to create path geometry, hr %#x.\n", hr);
6751 hr = ID2D1PathGeometry_Open(geometry, &sink);
6752 ok(SUCCEEDED(hr), "Failed to open geometry sink, hr %#x.\n", hr);
6754 set_point(&point, -0.402914f, 0.915514f);
6755 ID2D1GeometrySink_BeginFigure(sink, point, D2D1_FIGURE_BEGIN_HOLLOW);
6756 quadratic_to(sink, -0.310379f, 0.882571f, -0.116057f, 0.824000f);
6757 quadratic_to(sink, 0.008350f, 0.693614f, -0.052343f, 0.448886f);
6758 quadratic_to(sink, -0.154236f, 0.246072f, -0.279229f, 0.025343f);
6759 quadratic_to(sink, -0.370064f, -0.588586f, -0.383029f, -0.924114f);
6760 quadratic_to(sink, -0.295479f, -0.958764f, -0.017086f, -0.988400f);
6761 quadratic_to(sink, 0.208836f, -0.954157f, 0.272200f, -0.924114f);
6762 quadratic_to(sink, 0.295614f, -0.569071f, 0.230143f, 0.022886f);
6763 quadratic_to(sink, 0.101664f, 0.220643f, 0.012057f, 0.451571f);
6764 quadratic_to(sink, -0.028764f, 0.709014f, 0.104029f, 0.833943f);
6765 quadratic_to(sink, 0.319414f, 0.913057f, 0.403229f, 0.942628f);
6766 quadratic_to(sink, 0.317721f, 1.023450f, -0.017086f, 1.021771f);
6767 quadratic_to(sink, -0.310843f, 1.007472f, -0.402914f, 0.915514f);
6768 ID2D1GeometrySink_EndFigure(sink, D2D1_FIGURE_END_CLOSED);
6770 hr = ID2D1GeometrySink_Close(sink);
6771 ok(SUCCEEDED(hr), "Failed to close geometry sink, hr %#x.\n", hr);
6772 ID2D1GeometrySink_Release(sink);
6774 set_matrix_identity(&matrix);
6775 translate_matrix(&matrix, 40.0f, 160.0f);
6776 scale_matrix(&matrix, 20.0f, 80.0f);
6777 hr = ID2D1Factory_CreateTransformedGeometry(factory,
6778 (ID2D1Geometry *)geometry, &matrix, &transformed_geometry[0]);
6779 ok(SUCCEEDED(hr), "Failed to create geometry, hr %#x.\n", hr);
6781 set_matrix_identity(&matrix);
6782 translate_matrix(&matrix, 160.0f, 640.0f);
6783 scale_matrix(&matrix, 40.0f, 160.0f);
6784 rotate_matrix(&matrix, M_PI / -5.0f);
6785 hr = ID2D1Factory_CreateTransformedGeometry(factory,
6786 (ID2D1Geometry *)geometry, &matrix, &transformed_geometry[1]);
6787 ok(SUCCEEDED(hr), "Failed to create geometry, hr %#x.\n", hr);
6788 ID2D1PathGeometry_Release(geometry);
6790 set_matrix_identity(&matrix);
6791 scale_matrix(&matrix, 0.5f, 1.0f);
6792 translate_matrix(&matrix, -80.0f, 0.0f);
6793 hr = ID2D1Factory_CreateTransformedGeometry(factory,
6794 (ID2D1Geometry *)transformed_geometry[1], &matrix, &transformed_geometry[2]);
6795 ok(SUCCEEDED(hr), "Failed to create geometry, hr %#x.\n", hr);
6797 set_matrix_identity(&matrix);
6798 rotate_matrix(&matrix, M_PI / 2.0f);
6799 translate_matrix(&matrix, 80.0f, -320.0f);
6800 scale_matrix(&matrix, 2.0f, 0.25f);
6801 hr = ID2D1Factory_CreateTransformedGeometry(factory,
6802 (ID2D1Geometry *)transformed_geometry[2], &matrix, &transformed_geometry[3]);
6803 ok(SUCCEEDED(hr), "Failed to create geometry, hr %#x.\n", hr);
6805 ID2D1RenderTarget_BeginDraw(rt);
6806 ID2D1RenderTarget_Clear(rt, &color);
6807 ID2D1RenderTarget_DrawGeometry(rt, (ID2D1Geometry *)transformed_geometry[0], (ID2D1Brush *)brush, 2.0f, NULL);
6808 ID2D1RenderTarget_DrawGeometry(rt, (ID2D1Geometry *)transformed_geometry[1], (ID2D1Brush *)brush, 10.0f, NULL);
6809 ID2D1RenderTarget_DrawGeometry(rt, (ID2D1Geometry *)transformed_geometry[2], (ID2D1Brush *)brush, 5.0f, NULL);
6810 ID2D1RenderTarget_DrawGeometry(rt, (ID2D1Geometry *)transformed_geometry[3], (ID2D1Brush *)brush, 15.0f, NULL);
6811 hr = ID2D1RenderTarget_EndDraw(rt, NULL, NULL);
6812 ok(SUCCEEDED(hr), "Failed to end draw, hr %#x.\n", hr);
6813 ID2D1TransformedGeometry_Release(transformed_geometry[3]);
6814 ID2D1TransformedGeometry_Release(transformed_geometry[2]);
6815 ID2D1TransformedGeometry_Release(transformed_geometry[1]);
6816 ID2D1TransformedGeometry_Release(transformed_geometry[0]);
6818 match = compare_figure(&ctx, 0, 0, 160, 160, 0xff652e89, 128,
6819 "yjIJkQEHBwaIAQUSBYMBBBYEggEEFgSCAQQWBIIBBBYEggEEFgSCAQQWBIIBBBYEggEEFgSCAQQW"
6820 "BIIBBBYEggEEFgSDAQQVBIMBBBUEgwEEFQSDAQQVBIMBBBUEgwEEFQSDAQQVBIMBBBUEgwEEFQSD"
6821 "AQQVBIQBBBQEhAEEFASEAQQTBIUBBBMEhQEEEwSFAQQTBIUBBBMEhQEEEwSGAQQSBIYBBBIEhgEE"
6822 "EgSGAQQSBIYBBBIEhgEEEgSGAQQRBIgBBBAEiAEEEASIAQQQBIkBBA4EigEEDgSLAQQMBIwBBAwE"
6823 "jQEECgSOAQQJBJABBAgEkAEFBgSSAQQGBJMBBAQElAEEBASVAQQDBJUBBAIElwEEAQSXAQiZAQeZ"
6824 "AQaaAQaaAQaaAQabAQWbAQWbAQWbAQWaAQeZAQeZAQeZAQiXAQQBBJYBBAMElQEEAwWRAQUGBY0B"
6825 "BQwFhwEFEgSCAQUXBYABBBoFfgUYBIIBBhEFiAEUpTEA");
6826 ok(match, "Figure does not match.\n");
6827 match = compare_figure(&ctx, 160, 0, 320, 160, 0xff652e89, 512,
6828 "yJIBArkCDa4CGKMCIZoCK5ECM4gCO4ECQ/gBS/EBUesBLAYl5QEsDiPeASwWIdkBLBwh0wEsISHO"
6829 "ASsgKMsBKR4vyAEnHDPIASUaNMsBIxg1mQEFMCIUN54BCygiDzijAREhIgY9qAEYGWGuAR4RXbMB"
6830 "JAhbuQGAAcABesYBc84Ba9YBTvQBP4MCOIoCNI4CM5ACMZICL5QCLZYCK5kCKJsCJ54CI6MCHq8C"
6831 "EraSAQAA");
6832 ok(match, "Figure does not match.\n");
6833 match = compare_figure(&ctx, 0, 160, 160, 320, 0xff652e89, 512,
6834 "xWkCmwEFmAEJlQELlAENkgEOkQEPjwESjQETjAEVigELAQqJAQsCCogBCwQKhwEKBQqGAQoGCoYB"
6835 "CgcKhAEKCAqEAQoIC4IBCgoKggEKCgqBAQoMCoABCgwKfwoNCn8KDgp9Cg8KfQoPCnwKEQp7ChEK"
6836 "egoSCnoKEwp4ChQKeAoUCncLFQp2ChYKdgoWCnYKFwp2ChYKdgoWCncKFgp2ChYKdgoWCncKFQt2"
6837 "ChYKdwoVCncKFQp4ChUKdwoVCncKFQp4ChUKdwoVCngKFAp4ChUKeAoUCngKFAp4CxMKeQoUCngK"
6838 "FAp5ChMKeQoUCnkKEwp5ChMKegoSC3kKEwp6ChIKegoSCnoLEgp6ChIKegoSCnsKEQp7ChEKfAoQ"
6839 "CnwKEAp9Cg8KfQoPCn4KDgp+Cg4KfwoOCn4KDgp/Cg0KfwoNCoABCgwKgAEKDAqBAQoLCoEBCgsK"
6840 "gQELCgqCAQoKCoIBCwkKgwEKCQqDAQoJCoQBCggKhAEKCQqEAQsHCoUBCwYKhgELBQqHAQsECogB"
6841 "CwMKiQELAgqLAQoBCowBFI0BE44BE44BEo8BEZABEJEBD5IBDpMBDpMBDZMBDZQBDJQBDZQBDJQB"
6842 "DBUCfgwSBH4MEQV/DA4GgAEMDAiAAQ0KCYEBDAgLgQENBQ2BAQ0EDoIBDQEPgwEdgwEdgwEdgwEc"
6843 "hAEKAgQCCoUBCgYKhgEKBgqGAQoFC4YBCgUKhwEKBAqIAQoECogBCgMKiQEKAwqIAQoDCokBCgMK"
6844 "iQEKAgqJAQoCCooBCgIKiQEKAgqKAQoBCosBCgEKigEKAQqLARSMARSLARSMAROMARONARKOARGO"
6845 "ARGPARCQAQ6RAQ2YAQTEZAAA");
6846 ok(match, "Figure does not match.\n");
6847 match = compare_figure(&ctx, 160, 160, 320, 320, 0xff652e89, 1024,
6848 "ytABA7gCCbICD60CFKkCF6cCGqMCHqACIZ0CJJoCJpgCKZUCFgIUkgIWBBWPAhYHFI4CFQoUjAIV"
6849 "DBSKAhUNFYgCFQ8UhwIVERSFAhUTFIMCFRQVgQIUFxSAAhQZFP4BFBoV/AEUHBT7ARQeFPkBFB8V"
6850 "9wEUIRT2ARQjFPQBFSMV8gEVJRTxARUnFPABFCgV7gEUKhTtARQsFOwBFCwV7AEULBTsARUsFOwB"
6851 "FSsV7AEULBTtARQsFO0BFCsU7QEVKxTtARUqFe0BFSoU7gEUKxTuARQqFe4BFCoU7wEUKhTuARUp"
6852 "FO8BFSkU7wEVKBXvARUoFPABFCkU8AEUKBTxARQoFPEBFCcV8QEUJxTxARUnFPEBFSYU8gEVJhTy"
6853 "ARUlFfIBFSUU8wEUJRXzARQlFPQBFCUU9AEUJBT1ARQkFPUBFCMU9gEUIhT2ARUhFPcBFSAU+AEV"
6854 "HxT5ARUeFPoBFR4U+gEVHRT7ARUcFPwBFRsU/QEVGhT+ARUZFP8BFBkUgAIUGBSBAhQXFIICFBcU"
6855 "ggIUFhSDAhQVFIQCFBQUhQIUExSGAhQSFIcCFBIUhwIUERSIAhUPFIkCFg0UigIXCxSNAhYJFI8C"
6856 "FggUkAIXBRSSAhcDFJQCFwEUlgIrlwIpmgImnAIkngIjnwIhoQIfowIepAIcpgIbpgIaqAIZqAIZ"
6857 "qAIYKwP7ARgnBf0BGCMI/QEZHgz+ARgbD/8BGBcSgAIYEhaAAhoNGIICGggcgwIaBB+DAjyEAjyF"
6858 "AjqGAjmIAjiIAiECFIkCFAIIBBSKAhQNFIsCFAwUjAIUCxSNAhQKFI4CFAkUjwIUBxWQAhQGFZEC"
6859 "FAUVkQIUBRWRAhQFFZECFQMVkwIUAxWTAhQDFZMCFAIVlAIVARWVAiqVAimWAimWAiiYAiaZAiaZ"
6860 "AiWaAiScAiKdAiGeAh+hAhyjAhmuAg3GxgEA");
6861 ok(match, "Figure does not match.\n");
6863 ID2D1SolidColorBrush_Release(brush);
6864 ID2D1Factory_Release(factory);
6865 release_test_context(&ctx);
6868 static void test_fill_geometry(BOOL d3d11)
6870 ID2D1TransformedGeometry *transformed_geometry[4];
6871 ID2D1RectangleGeometry *rect_geometry[2];
6872 D2D1_POINT_2F point = {0.0f, 0.0f};
6873 D2D1_ROUNDED_RECT rounded_rect;
6874 struct d2d1_test_context ctx;
6875 ID2D1SolidColorBrush *brush;
6876 ID2D1PathGeometry *geometry;
6877 D2D1_MATRIX_3X2_F matrix;
6878 ID2D1GeometrySink *sink;
6879 ID2D1RenderTarget *rt;
6880 ID2D1Factory *factory;
6881 D2D1_ELLIPSE ellipse;
6882 D2D1_COLOR_F color;
6883 D2D1_RECT_F rect;
6884 HRESULT hr;
6885 BOOL match;
6887 if (!init_test_context(&ctx, d3d11))
6888 return;
6890 rt = ctx.rt;
6891 ID2D1RenderTarget_GetFactory(rt, &factory);
6893 ID2D1RenderTarget_SetDpi(rt, 192.0f, 48.0f);
6894 ID2D1RenderTarget_SetAntialiasMode(rt, D2D1_ANTIALIAS_MODE_ALIASED);
6895 set_color(&color, 0.890f, 0.851f, 0.600f, 1.0f);
6896 hr = ID2D1RenderTarget_CreateSolidColorBrush(rt, &color, NULL, &brush);
6897 ok(SUCCEEDED(hr), "Failed to create brush, hr %#x.\n", hr);
6899 ID2D1RenderTarget_BeginDraw(rt);
6900 set_color(&color, 0.396f, 0.180f, 0.537f, 1.0f);
6901 ID2D1RenderTarget_Clear(rt, &color);
6903 set_rect(&rect, 40.0f, 480.0f, 40.0f, 480.0f);
6904 ID2D1RenderTarget_FillRectangle(rt, &rect, (ID2D1Brush *)brush);
6905 set_rect(&rect, 100.0f, 480.0f, 140.0f, 480.0f);
6906 ID2D1RenderTarget_FillRectangle(rt, &rect, (ID2D1Brush *)brush);
6907 set_rect(&rect, 200.0f, 400.0f, 200.0f, 560.0f);
6908 ID2D1RenderTarget_FillRectangle(rt, &rect, (ID2D1Brush *)brush);
6909 set_rect(&rect, 260.0f, 560.0f, 300.0f, 400.0f);
6910 ID2D1RenderTarget_FillRectangle(rt, &rect, (ID2D1Brush *)brush);
6912 set_ellipse(&ellipse, 40.0f, 800.0f, 0.0f, 0.0f);
6913 ID2D1RenderTarget_FillEllipse(rt, &ellipse, (ID2D1Brush *)brush);
6914 set_ellipse(&ellipse, 120.0f, 800.0f, 20.0f, 0.0f);
6915 ID2D1RenderTarget_FillEllipse(rt, &ellipse, (ID2D1Brush *)brush);
6916 set_ellipse(&ellipse, 200.0f, 800.0f, 0.0f, 80.0f);
6917 ID2D1RenderTarget_FillEllipse(rt, &ellipse, (ID2D1Brush *)brush);
6918 set_ellipse(&ellipse, 280.0f, 800.0f, 20.0f, 80.0f);
6919 ID2D1RenderTarget_FillEllipse(rt, &ellipse, (ID2D1Brush *)brush);
6921 hr = ID2D1RenderTarget_EndDraw(rt, NULL, NULL);
6922 ok(SUCCEEDED(hr), "Failed to end draw, hr %#x.\n", hr);
6924 match = compare_figure(&ctx, 0, 160, 160, 160, 0xff652e89, 0, "gMgB");
6925 ok(match, "Figure does not match.\n");
6926 match = compare_figure(&ctx, 160, 160, 160, 160, 0xff652e89, 0, "gMgB");
6927 ok(match, "Figure does not match.\n");
6928 match = compare_figure(&ctx, 320, 160, 160, 160, 0xff652e89, 0, "gMgB");
6929 ok(match, "Figure does not match.\n");
6930 match = compare_figure(&ctx, 480, 160, 160, 160, 0xff652e89, 0,
6931 "qDJQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQ"
6932 "UFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQ"
6933 "UFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFCoMgAA");
6934 ok(match, "Figure does not match.\n");
6936 match = compare_figure(&ctx, 0, 320, 160, 160, 0xff652e89, 0, "gMgB");
6937 ok(match, "Figure does not match.\n");
6938 match = compare_figure(&ctx, 160, 320, 160, 160, 0xff652e89, 0, "gMgB");
6939 ok(match, "Figure does not match.\n");
6940 match = compare_figure(&ctx, 320, 320, 160, 160, 0xff652e89, 0, "gMgB");
6941 ok(match, "Figure does not match.\n");
6942 match = compare_figure(&ctx, 480, 320, 160, 160, 0xff652e89, 8,
6943 "yjIMjwEWhwEcggEgfiR6KHYscy5xMG40azZpOGc6ZTxjPmI+YUBfQl1EXERbRlpGWUhYSFdKVkpV"
6944 "TFRMVExTTlJOUk5STlJOUVBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUU5STlJOUk5STlNMVExUTFVK"
6945 "VkpXSFhIWUZaRltEXERdQl9AYT5iPmM8ZTpnOGk2azRuMHEucyx2KHokfiCCARyHARaPAQzKMgAA");
6946 ok(match, "Figure does not match.\n");
6948 ID2D1RenderTarget_BeginDraw(rt);
6949 set_color(&color, 0.396f, 0.180f, 0.537f, 1.0f);
6950 ID2D1RenderTarget_Clear(rt, &color);
6952 set_rounded_rect(&rounded_rect, 40.0f, 160.0f, 40.0f, 160.0f, 10.0f, 10.0f);
6953 ID2D1RenderTarget_FillRoundedRectangle(rt, &rounded_rect, (ID2D1Brush *)brush);
6954 set_rounded_rect(&rounded_rect, 100.0f, 160.0f, 140.0f, 160.0f, 10.0f, 10.0f);
6955 ID2D1RenderTarget_FillRoundedRectangle(rt, &rounded_rect, (ID2D1Brush *)brush);
6956 set_rounded_rect(&rounded_rect, 200.0f, 80.0f, 200.0f, 240.0f, 10.0f, 10.0f);
6957 ID2D1RenderTarget_FillRoundedRectangle(rt, &rounded_rect, (ID2D1Brush *)brush);
6958 set_rounded_rect(&rounded_rect, 260.0f, 240.0f, 300.0f, 80.0f, 10.0f, 10.0f);
6959 ID2D1RenderTarget_FillRoundedRectangle(rt, &rounded_rect, (ID2D1Brush *)brush);
6961 set_rounded_rect(&rounded_rect, 40.0f, 480.0f, 40.0f, 480.0f, 10.0f, 20.0f);
6962 ID2D1RenderTarget_FillRoundedRectangle(rt, &rounded_rect, (ID2D1Brush *)brush);
6963 set_rounded_rect(&rounded_rect, 100.0f, 480.0f, 140.0f, 480.0f, 10.0f, 20.0f);
6964 ID2D1RenderTarget_FillRoundedRectangle(rt, &rounded_rect, (ID2D1Brush *)brush);
6965 set_rounded_rect(&rounded_rect, 200.0f, 400.0f, 200.0f, 560.0f, 10.0f, 20.0f);
6966 ID2D1RenderTarget_FillRoundedRectangle(rt, &rounded_rect, (ID2D1Brush *)brush);
6967 set_rounded_rect(&rounded_rect, 260.0f, 560.0f, 300.0f, 400.0f, 10.0f, 20.0f);
6968 ID2D1RenderTarget_FillRoundedRectangle(rt, &rounded_rect, (ID2D1Brush *)brush);
6970 set_rounded_rect(&rounded_rect, 40.0f, 800.0f, 40.0f, 800.0f, 10.0f, 5.0f);
6971 ID2D1RenderTarget_FillRoundedRectangle(rt, &rounded_rect, (ID2D1Brush *)brush);
6972 set_rounded_rect(&rounded_rect, 100.0f, 800.0f, 140.0f, 800.0f, 10.0f, 5.0f);
6973 ID2D1RenderTarget_FillRoundedRectangle(rt, &rounded_rect, (ID2D1Brush *)brush);
6974 set_rounded_rect(&rounded_rect, 200.0f, 720.0f, 200.0f, 880.0f, 10.0f, 5.0f);
6975 ID2D1RenderTarget_FillRoundedRectangle(rt, &rounded_rect, (ID2D1Brush *)brush);
6976 set_rounded_rect(&rounded_rect, 260.0f, 880.0f, 300.0f, 720.0f, 10.0f, 5.0f);
6977 ID2D1RenderTarget_FillRoundedRectangle(rt, &rounded_rect, (ID2D1Brush *)brush);
6979 hr = ID2D1RenderTarget_EndDraw(rt, NULL, NULL);
6980 ok(SUCCEEDED(hr), "Failed to end draw, hr %#x.\n", hr);
6982 match = compare_figure(&ctx, 0, 0, 160, 160, 0xff652e89, 0, "gMgB");
6983 ok(match, "Figure does not match.\n");
6984 match = compare_figure(&ctx, 160, 0, 160, 160, 0xff652e89, 0, "gMgB");
6985 ok(match, "Figure does not match.\n");
6986 match = compare_figure(&ctx, 320, 0, 160, 160, 0xff652e89, 0, "gMgB");
6987 ok(match, "Figure does not match.\n");
6988 match = compare_figure(&ctx, 480, 0, 160, 160, 0xff652e89, 0,
6989 "szI6YURZSlROUVBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQ"
6990 "UFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQ"
6991 "UFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUU5USllEYTqzMgAA");
6992 ok(match, "Figure does not match.\n");
6994 match = compare_figure(&ctx, 0, 160, 160, 160, 0xff652e89, 0, "gMgB");
6995 ok(match, "Figure does not match.\n");
6996 match = compare_figure(&ctx, 160, 160, 160, 160, 0xff652e89, 0, "gMgB");
6997 ok(match, "Figure does not match.\n");
6998 match = compare_figure(&ctx, 320, 160, 160, 160, 0xff652e89, 0, "gMgB");
6999 ok(match, "Figure does not match.\n");
7000 match = compare_figure(&ctx, 480, 160, 160, 160, 0xff652e89, 2,
7001 "tjI0aDxhQlxGWEpVTFNOUk5RUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQ"
7002 "UFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQ"
7003 "UFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFFOUk5TTFVKWEZcQmA+ZzS2MgAA");
7004 ok(match, "Figure does not match.\n");
7006 match = compare_figure(&ctx, 0, 320, 160, 160, 0xff652e89, 0, "gMgB");
7007 ok(match, "Figure does not match.\n");
7008 match = compare_figure(&ctx, 160, 320, 160, 160, 0xff652e89, 0, "gMgB");
7009 ok(match, "Figure does not match.\n");
7010 match = compare_figure(&ctx, 320, 320, 160, 160, 0xff652e89, 0, "gMgB");
7011 ok(match, "Figure does not match.\n");
7012 match = compare_figure(&ctx, 480, 320, 160, 160, 0xff652e89, 0,
7013 "sDJAWkxSUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQ"
7014 "UFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQ"
7015 "UFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFJMWkCwMgAA");
7016 ok(match, "Figure does not match.\n");
7018 ID2D1RenderTarget_BeginDraw(rt);
7019 set_color(&color, 0.396f, 0.180f, 0.537f, 1.0f);
7020 ID2D1RenderTarget_Clear(rt, &color);
7022 set_rounded_rect(&rounded_rect, 40.0f, 160.0f, 40.0f, 160.0f, 1000.0f, 1000.0f);
7023 ID2D1RenderTarget_FillRoundedRectangle(rt, &rounded_rect, (ID2D1Brush *)brush);
7024 set_rounded_rect(&rounded_rect, 100.0f, 160.0f, 140.0f, 160.0f, 1000.0f, 1000.0f);
7025 ID2D1RenderTarget_FillRoundedRectangle(rt, &rounded_rect, (ID2D1Brush *)brush);
7026 set_rounded_rect(&rounded_rect, 200.0f, 80.0f, 200.0f, 240.0f, 1000.0f, 1000.0f);
7027 ID2D1RenderTarget_FillRoundedRectangle(rt, &rounded_rect, (ID2D1Brush *)brush);
7028 set_rounded_rect(&rounded_rect, 260.0f, 240.0f, 300.0f, 80.0f, 1000.0f, 1000.0f);
7029 ID2D1RenderTarget_FillRoundedRectangle(rt, &rounded_rect, (ID2D1Brush *)brush);
7031 set_rounded_rect(&rounded_rect, 40.0f, 480.0f, 40.0f, 480.0f, 10.0f, 1000.0f);
7032 ID2D1RenderTarget_FillRoundedRectangle(rt, &rounded_rect, (ID2D1Brush *)brush);
7033 set_rounded_rect(&rounded_rect, 100.0f, 480.0f, 140.0f, 480.0f, 10.0f, 1000.0f);
7034 ID2D1RenderTarget_FillRoundedRectangle(rt, &rounded_rect, (ID2D1Brush *)brush);
7035 set_rounded_rect(&rounded_rect, 200.0f, 400.0f, 200.0f, 560.0f, 10.0f, 1000.0f);
7036 ID2D1RenderTarget_FillRoundedRectangle(rt, &rounded_rect, (ID2D1Brush *)brush);
7037 set_rounded_rect(&rounded_rect, 260.0f, 560.0f, 300.0f, 400.0f, 10.0f, 1000.0f);
7038 ID2D1RenderTarget_FillRoundedRectangle(rt, &rounded_rect, (ID2D1Brush *)brush);
7040 set_rounded_rect(&rounded_rect, 40.0f, 800.0f, 40.0f, 800.0f, 1000.0f, 10.0f);
7041 ID2D1RenderTarget_FillRoundedRectangle(rt, &rounded_rect, (ID2D1Brush *)brush);
7042 set_rounded_rect(&rounded_rect, 100.0f, 800.0f, 140.0f, 800.0f, 1000.0f, 10.0f);
7043 ID2D1RenderTarget_FillRoundedRectangle(rt, &rounded_rect, (ID2D1Brush *)brush);
7044 set_rounded_rect(&rounded_rect, 200.0f, 720.0f, 200.0f, 880.0f, 1000.0f, 10.0f);
7045 ID2D1RenderTarget_FillRoundedRectangle(rt, &rounded_rect, (ID2D1Brush *)brush);
7046 set_rounded_rect(&rounded_rect, 260.0f, 880.0f, 300.0f, 720.0f, 1000.0f, 10.0f);
7047 ID2D1RenderTarget_FillRoundedRectangle(rt, &rounded_rect, (ID2D1Brush *)brush);
7049 hr = ID2D1RenderTarget_EndDraw(rt, NULL, NULL);
7050 ok(SUCCEEDED(hr), "Failed to end draw, hr %#x.\n", hr);
7052 match = compare_figure(&ctx, 0, 0, 160, 160, 0xff652e89, 0, "gMgB");
7053 ok(match, "Figure does not match.\n");
7054 match = compare_figure(&ctx, 160, 0, 160, 160, 0xff652e89, 0, "gMgB");
7055 ok(match, "Figure does not match.\n");
7056 match = compare_figure(&ctx, 320, 0, 160, 160, 0xff652e89, 0, "gMgB");
7057 ok(match, "Figure does not match.\n");
7058 match = compare_figure(&ctx, 480, 0, 160, 160, 0xff652e89, 10,
7059 "yjIMjwEWhwEcggEgfiR6KHYscy5xMG40azZpOGc6ZTxjPmI+YUBfQl1EXERbRlpGWUhYSFdKVkpV"
7060 "TFRMVExTTlJOUk5STlJOUVBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUU5STlJOUk5STlNMVExUTFVK"
7061 "VkpXSFhIWUZaRltEXERdQl9AYT5iPmM8ZTpnOGk2azRuMHEucyx2KHokfiCCARyHARaPAQzKMgAA");
7062 ok(match, "Figure does not match.\n");
7064 match = compare_figure(&ctx, 0, 160, 160, 160, 0xff652e89, 0, "gMgB");
7065 ok(match, "Figure does not match.\n");
7066 match = compare_figure(&ctx, 160, 160, 160, 160, 0xff652e89, 0, "gMgB");
7067 ok(match, "Figure does not match.\n");
7068 match = compare_figure(&ctx, 320, 160, 160, 160, 0xff652e89, 0, "gMgB");
7069 ok(match, "Figure does not match.\n");
7070 match = compare_figure(&ctx, 480, 160, 160, 160, 0xff652e89, 10,
7071 "uTIucDJsNmk4ZzplPGM+YUBgQF9CXkJdRFxEW0ZaRllIWEhXSlZKVkpWSlVMVExUTFRMU05STlJO"
7072 "Uk5STlJOUk9QUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFFPUU5STlJOUk5STlJOU0xU"
7073 "TFRMVExVSlZKVkpWSldIWEhZRlpGW0RcRF1CXkJfQGBAYT5jPGU6ZzhpNmwycC65MgAA");
7074 ok(match, "Figure does not match.\n");
7076 match = compare_figure(&ctx, 0, 320, 160, 160, 0xff652e89, 0, "gMgB");
7077 ok(match, "Figure does not match.\n");
7078 match = compare_figure(&ctx, 160, 320, 160, 160, 0xff652e89, 0, "gMgB");
7079 ok(match, "Figure does not match.\n");
7080 match = compare_figure(&ctx, 320, 320, 160, 160, 0xff652e89, 0, "gMgB");
7081 ok(match, "Figure does not match.\n");
7082 match = compare_figure(&ctx, 480, 320, 160, 160, 0xff652e89, 10,
7083 "vzIiczhhRldMUlBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQ"
7084 "UFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQ"
7085 "UFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUkxXRmA6cSS+MgAA");
7086 ok(match, "Figure does not match.\n");
7088 hr = ID2D1Factory_CreatePathGeometry(factory, &geometry);
7089 ok(SUCCEEDED(hr), "Failed to create path geometry, hr %#x.\n", hr);
7090 hr = ID2D1PathGeometry_Open(geometry, &sink);
7091 ok(SUCCEEDED(hr), "Failed to open geometry sink, hr %#x.\n", hr);
7093 set_point(&point, 40.0f, 160.0f);
7094 ID2D1GeometrySink_BeginFigure(sink, point, D2D1_FIGURE_BEGIN_FILLED);
7095 ID2D1GeometrySink_EndFigure(sink, D2D1_FIGURE_END_OPEN);
7097 set_point(&point, 120.0f, 160.0f);
7098 ID2D1GeometrySink_BeginFigure(sink, point, D2D1_FIGURE_BEGIN_FILLED);
7099 line_to(sink, 120.0f, 160.0f);
7100 ID2D1GeometrySink_EndFigure(sink, D2D1_FIGURE_END_OPEN);
7102 set_point(&point, 200.0f, 160.0f);
7103 ID2D1GeometrySink_BeginFigure(sink, point, D2D1_FIGURE_BEGIN_FILLED);
7104 ID2D1GeometrySink_EndFigure(sink, D2D1_FIGURE_END_CLOSED);
7106 set_point(&point, 280.0f, 160.0f);
7107 ID2D1GeometrySink_BeginFigure(sink, point, D2D1_FIGURE_BEGIN_FILLED);
7108 line_to(sink, 280.0f, 160.0f);
7109 ID2D1GeometrySink_EndFigure(sink, D2D1_FIGURE_END_CLOSED);
7111 set_point(&point, 20.0f, 480.0f);
7112 ID2D1GeometrySink_BeginFigure(sink, point, D2D1_FIGURE_BEGIN_FILLED);
7113 line_to(sink, 60.0f, 480.0f);
7114 ID2D1GeometrySink_EndFigure(sink, D2D1_FIGURE_END_OPEN);
7116 set_point(&point, 120.0f, 400.0f);
7117 ID2D1GeometrySink_BeginFigure(sink, point, D2D1_FIGURE_BEGIN_FILLED);
7118 line_to(sink, 120.0f, 560.0f);
7119 line_to(sink, 120.0f, 400.0f);
7120 line_to(sink, 120.0f, 560.0f);
7121 ID2D1GeometrySink_EndFigure(sink, D2D1_FIGURE_END_OPEN);
7123 set_point(&point, 180.0f, 480.0f);
7124 ID2D1GeometrySink_BeginFigure(sink, point, D2D1_FIGURE_BEGIN_FILLED);
7125 line_to(sink, 220.0f, 480.0f);
7126 ID2D1GeometrySink_EndFigure(sink, D2D1_FIGURE_END_CLOSED);
7128 set_point(&point, 280.0f, 400.0f);
7129 ID2D1GeometrySink_BeginFigure(sink, point, D2D1_FIGURE_BEGIN_FILLED);
7130 line_to(sink, 280.0f, 560.0f);
7131 line_to(sink, 280.0f, 400.0f);
7132 line_to(sink, 280.0f, 560.0f);
7133 ID2D1GeometrySink_EndFigure(sink, D2D1_FIGURE_END_CLOSED);
7135 set_point(&point, 20.0f, 880.0f);
7136 ID2D1GeometrySink_BeginFigure(sink, point, D2D1_FIGURE_BEGIN_FILLED);
7137 line_to(sink, 40.0f, 720.0f);
7138 line_to(sink, 60.0f, 880.0f);
7139 ID2D1GeometrySink_EndFigure(sink, D2D1_FIGURE_END_OPEN);
7141 set_point(&point, 100.0f, 720.0f);
7142 ID2D1GeometrySink_BeginFigure(sink, point, D2D1_FIGURE_BEGIN_FILLED);
7143 line_to(sink, 120.0f, 880.0f);
7144 line_to(sink, 140.0f, 720.0f);
7145 ID2D1GeometrySink_EndFigure(sink, D2D1_FIGURE_END_OPEN);
7147 set_point(&point, 180.0f, 880.0f);
7148 ID2D1GeometrySink_BeginFigure(sink, point, D2D1_FIGURE_BEGIN_FILLED);
7149 line_to(sink, 200.0f, 720.0f);
7150 line_to(sink, 220.0f, 880.0f);
7151 ID2D1GeometrySink_EndFigure(sink, D2D1_FIGURE_END_CLOSED);
7153 set_point(&point, 260.0f, 720.0f);
7154 ID2D1GeometrySink_BeginFigure(sink, point, D2D1_FIGURE_BEGIN_FILLED);
7155 line_to(sink, 280.0f, 880.0f);
7156 line_to(sink, 300.0f, 720.0f);
7157 ID2D1GeometrySink_EndFigure(sink, D2D1_FIGURE_END_CLOSED);
7159 ID2D1GeometrySink_SetFillMode(sink, D2D1_FILL_MODE_ALTERNATE);
7160 hr = ID2D1GeometrySink_Close(sink);
7161 ok(SUCCEEDED(hr), "Failed to close geometry sink, hr %#x.\n", hr);
7162 ID2D1GeometrySink_Release(sink);
7164 ID2D1RenderTarget_BeginDraw(rt);
7165 ID2D1RenderTarget_Clear(rt, &color);
7166 ID2D1RenderTarget_FillGeometry(rt, (ID2D1Geometry *)geometry, (ID2D1Brush *)brush, NULL);
7167 hr = ID2D1RenderTarget_EndDraw(rt, NULL, NULL);
7168 ok(SUCCEEDED(hr), "Failed to end draw, hr %#x.\n", hr);
7169 ID2D1PathGeometry_Release(geometry);
7171 match = compare_figure(&ctx, 0, 0, 160, 160, 0xff652e89, 0, "gMgB");
7172 ok(match, "Figure does not match.\n");
7173 match = compare_figure(&ctx, 160, 0, 160, 160, 0xff652e89, 0, "gMgB");
7174 ok(match, "Figure does not match.\n");
7175 match = compare_figure(&ctx, 320, 0, 160, 160, 0xff652e89, 0, "gMgB");
7176 ok(match, "Figure does not match.\n");
7177 match = compare_figure(&ctx, 480, 0, 160, 160, 0xff652e89, 0, "gMgB");
7178 ok(match, "Figure does not match.\n");
7180 match = compare_figure(&ctx, 0, 160, 160, 160, 0xff652e89, 0, "gMgB");
7181 ok(match, "Figure does not match.\n");
7182 match = compare_figure(&ctx, 160, 160, 160, 160, 0xff652e89, 0, "gMgB");
7183 ok(match, "Figure does not match.\n");
7184 match = compare_figure(&ctx, 320, 160, 160, 160, 0xff652e89, 0, "gMgB");
7185 ok(match, "Figure does not match.\n");
7186 match = compare_figure(&ctx, 480, 160, 160, 160, 0xff652e89, 0, "gMgB");
7187 ok(match, "Figure does not match.\n");
7189 match = compare_figure(&ctx, 0, 320, 160, 160, 0xff652e89, 0,
7190 "7zMCngECnQEEnAEEmwEGmgEGmQEImAEIlwEKlgEKlQEMlAEMkwEOkgEOkQEQkAEQjwESjgESjQEU"
7191 "jAEUiwEWigEWiQEYiAEYhwEahgEahQEchAEcgwEeggEegQEggAEgfyJ+In0kfCR7JnomeSh4KHcq"
7192 "dip1LHQscy5yLnEwcDBvMm4ybTRsNGs2ajZpOGg4ZzpmOmU8ZDxjPmI+YUBgQF9CXkJdRFxEW0Za"
7193 "RllIWEhXSlZKVUxUTFNOUk5RUKgy");
7194 ok(match, "Figure does not match.\n");
7195 match = compare_figure(&ctx, 160, 320, 160, 160, 0xff652e89, 0,
7196 "qDJQUU5STlNMVExVSlZKV0hYSFlGWkZbRFxEXUJeQl9AYEBhPmI+YzxkPGU6ZjpnOGg4aTZqNms0"
7197 "bDRtMm4ybzBwMHEuci5zLHQsdSp2KncoeCh5JnomeyR8JH0ifiJ/IIABIIEBHoIBHoMBHIQBHIUB"
7198 "GoYBGocBGIgBGIkBFooBFosBFIwBFI0BEo4BEo8BEJABEJEBDpIBDpMBDJQBDJUBCpYBCpcBCJgB"
7199 "CJkBBpoBBpsBBJwBBJ0BAp4BAu8z");
7200 ok(match, "Figure does not match.\n");
7201 match = compare_figure(&ctx, 320, 320, 160, 160, 0xff652e89, 0,
7202 "7zMCngECnQEEnAEEmwEGmgEGmQEImAEIlwEKlgEKlQEMlAEMkwEOkgEOkQEQkAEQjwESjgESjQEU"
7203 "jAEUiwEWigEWiQEYiAEYhwEahgEahQEchAEcgwEeggEegQEggAEgfyJ+In0kfCR7JnomeSh4KHcq"
7204 "dip1LHQscy5yLnEwcDBvMm4ybTRsNGs2ajZpOGg4ZzpmOmU8ZDxjPmI+YUBgQF9CXkJdRFxEW0Za"
7205 "RllIWEhXSlZKVUxUTFNOUk5RUKgy");
7206 ok(match, "Figure does not match.\n");
7207 match = compare_figure(&ctx, 480, 320, 160, 160, 0xff652e89, 0,
7208 "qDJQUU5STlNMVExVSlZKV0hYSFlGWkZbRFxEXUJeQl9AYEBhPmI+YzxkPGU6ZjpnOGg4aTZqNms0"
7209 "bDRtMm4ybzBwMHEuci5zLHQsdSp2KncoeCh5JnomeyR8JH0ifiJ/IIABIIEBHoIBHoMBHIQBHIUB"
7210 "GoYBGocBGIgBGIkBFooBFosBFIwBFI0BEo4BEo8BEJABEJEBDpIBDpMBDJQBDJUBCpYBCpcBCJgB"
7211 "CJkBBpoBBpsBBJwBBJ0BAp4BAu8z");
7212 ok(match, "Figure does not match.\n");
7214 set_rect(&rect, 20.0f, 80.0f, 60.0f, 240.0f);
7215 hr = ID2D1Factory_CreateRectangleGeometry(factory, &rect, &rect_geometry[0]);
7216 ok(SUCCEEDED(hr), "Failed to create geometry, hr %#x.\n", hr);
7218 set_rect(&rect, -1.0f, -1.0f, 1.0f, 1.0f);
7219 hr = ID2D1Factory_CreateRectangleGeometry(factory, &rect, &rect_geometry[1]);
7220 ok(SUCCEEDED(hr), "Failed to create geometry, hr %#x.\n", hr);
7222 set_matrix_identity(&matrix);
7223 translate_matrix(&matrix, 160.0f, 640.0f);
7224 scale_matrix(&matrix, 40.0f, 160.0f);
7225 rotate_matrix(&matrix, M_PI / -5.0f);
7226 hr = ID2D1Factory_CreateTransformedGeometry(factory,
7227 (ID2D1Geometry *)rect_geometry[1], &matrix, &transformed_geometry[0]);
7228 ok(SUCCEEDED(hr), "Failed to create geometry, hr %#x.\n", hr);
7230 set_matrix_identity(&matrix);
7231 scale_matrix(&matrix, 0.5f, 1.0f);
7232 translate_matrix(&matrix, -80.0f, 0.0f);
7233 hr = ID2D1Factory_CreateTransformedGeometry(factory,
7234 (ID2D1Geometry *)transformed_geometry[0], &matrix, &transformed_geometry[1]);
7235 ok(SUCCEEDED(hr), "Failed to create geometry, hr %#x.\n", hr);
7237 set_matrix_identity(&matrix);
7238 rotate_matrix(&matrix, M_PI / 2.0f);
7239 translate_matrix(&matrix, 80.0f, -320.0f);
7240 scale_matrix(&matrix, 2.0f, 0.25f);
7241 hr = ID2D1Factory_CreateTransformedGeometry(factory,
7242 (ID2D1Geometry *)transformed_geometry[1], &matrix, &transformed_geometry[2]);
7243 ok(SUCCEEDED(hr), "Failed to create geometry, hr %#x.\n", hr);
7245 ID2D1RenderTarget_BeginDraw(rt);
7246 ID2D1RenderTarget_Clear(rt, &color);
7247 ID2D1RenderTarget_FillGeometry(rt, (ID2D1Geometry *)rect_geometry[0], (ID2D1Brush *)brush, NULL);
7248 ID2D1RenderTarget_FillGeometry(rt, (ID2D1Geometry *)transformed_geometry[0], (ID2D1Brush *)brush, NULL);
7249 ID2D1RenderTarget_FillGeometry(rt, (ID2D1Geometry *)transformed_geometry[1], (ID2D1Brush *)brush, NULL);
7250 ID2D1RenderTarget_FillGeometry(rt, (ID2D1Geometry *)transformed_geometry[2], (ID2D1Brush *)brush, NULL);
7251 hr = ID2D1RenderTarget_EndDraw(rt, NULL, NULL);
7252 ok(SUCCEEDED(hr), "Failed to end draw, hr %#x.\n", hr);
7253 ID2D1TransformedGeometry_Release(transformed_geometry[2]);
7254 ID2D1TransformedGeometry_Release(transformed_geometry[1]);
7255 ID2D1TransformedGeometry_Release(transformed_geometry[0]);
7256 ID2D1RectangleGeometry_Release(rect_geometry[1]);
7257 ID2D1RectangleGeometry_Release(rect_geometry[0]);
7259 match = compare_figure(&ctx, 0, 0, 160, 160, 0xff652e89, 0,
7260 "qDJQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQ"
7261 "UFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQ"
7262 "UFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFCoMgAA");
7263 ok(match, "Figure does not match.\n");
7264 match = compare_figure(&ctx, 160, 0, 320, 160, 0xff652e89, 32,
7265 "sIMBA7cCDK8CFKYCHZ4CJJYCLY4CNYUCPv0BRvQBT+wBV+MBYNsBaNIBccoBecEBgQG6AYkBsQGS"
7266 "AakBmgGgAaMBmAGrAY8BtAGHAbwBfsUBfcYBfcYBfcUBfsUBfcYBfcYBfcYBfcYBfcUBfr0BhgG0"
7267 "AY8BrAGXAaMBoAGbAagBkgGwAYsBuAGCAcEBeskBcdIBadoBYOMBWOsBT/QBR/wBPoUCNowCLpUC"
7268 "Jp0CHaYCFa4CDLcCBK+DAQAA");
7269 ok(match, "Figure does not match.\n");
7270 match = compare_figure(&ctx, 0, 160, 160, 320, 0xff652e89, 32,
7271 "+D0BngEDnQEDnAEEmwEGmgEGmQEHmAEJlwEJlgELlAEMkwENkwEOkQEPkAEQkAERjgESjQETjQEU"
7272 "iwEVigEXiQEXiAEYhwEahgEahQEbhAEdggEeggEegQEgfyF/In0jfCR8JXomeSd5KHcpdip2K3Qs"
7273 "cy5xL3EvcDFuMm4ybTRrNWs1ajdoOGg5ZjplO2U8Yz1iPmFAYEBfQV5DXUNcRVpGWkZZSFdJV0lW"
7274 "S1RMVExTTlFPUFFPUU5STVRMVEtVSldJV0hYR1pGWkVcQ11CXkJfQGA/YT9iPWM+Yj5jPWM+Yz1j"
7275 "PWM+Yz1jPmI+Yz1jPmI+Yz1jPmM9Yz1jPmM9Yz5iPmM9Yz5iPmM9Yz5jPWM9Yz5jPWM+Yj5jPWM+"
7276 "Yj5jPWI/YT9gQF9CXkJdRFtFW0VaR1hIV0lXSlVLVExUTVJOUVBQUE9RTlNNU0xUS1ZKVklXSFlG"
7277 "WkZaRVxDXUNeQV9AYEBhPmI9Yz1kO2U6ZjpnOGg3ajVrNWs0bTJuMm4xcC9xL3Eucyx0LHUqdil3"
7278 "KXgneSZ6JXwkfCN9In8hfyCBAR6CAR6CAR2EARuFARuFARqHARiIAReJAReKARWLARSNARONARKO"
7279 "ARGQARCQAQ+RAQ6TAQ2TAQyUAQuWAQqWAQmYAQeZAQaaAQabAQScAQOdAQOeAQH4PQAA");
7280 ok(match, "Figure does not match.\n");
7281 match = compare_figure(&ctx, 160, 160, 320, 320, 0xff652e89, 32,
7282 "sXkBvgIDvAIEugIHuAIJtgILswINsgIPrwISrQITrAIVqQIYpwIapQIbowIeoQIgngIjnAIkmwIm"
7283 "mAIplgIqlQIskgIvkAIxjQIzjAI1igI3hwI5hgI7hAI9gQJA/wFB/QFE+wFG+QFI9gFK9QFM8wFO"
7284 "8AFQ7wFS7AFV6gFX6AFY5gFb5AFd4gFf3wFh3gFj2wFm2QFn2AFp1QFs0wFu0QFvzwFyzQF0ygF3"
7285 "yAF4xwF6xAF9wgF+wAGBAb4BgwG8AYUBuQGHAbgBiQG2AYsBswGOAbEBjwGvAZIBrQGUAasBlQGp"
7286 "AZgBpwGaAaUBnAGiAZ4BoQGgAZ4BowGcAaUBmgGmAZgBqQGWAasBlAGsAZIBrwGQAbEBjQG0AYsB"
7287 "tQGKAbcBhwG6AYUBvAGDAb0BgQHAAX/CAXzEAXvGAXvGAXvGAXvFAXvGAXvGAXvGAXvFAXvGAXvG"
7288 "AXvFAXvGAXvGAXvGAXvFAXvGAXvGAXvFAXzFAXvGAXvGAXvFAXvGAXvGAXvGAXvFAXvGAXvGAXvF"
7289 "AXzFAXvGAXvGAXvFAXvGAXvGAXvGAXvEAXzCAX/AAYEBvgGCAbwBhQG6AYcBtwGKAbUBiwG0AY0B"
7290 "sQGQAa8BkgGtAZMBqwGWAakBmAGmAZoBpQGcAaMBngGgAaEBngGiAZ0BpAGaAacBmAGpAZUBqwGU"
7291 "Aa0BkgGvAY8BsQGOAbMBjAG1AYkBuAGHAbkBhQG8AYMBvgGBAcABfsIBfcQBe8YBeMgBd8oBdM0B"
7292 "cs8BcNABbtMBbNUBatcBZ9kBZtsBY94BYd8BYOEBXeQBW+YBWOgBV+oBVewBUu8BUPABT/IBTPUB"
7293 "SvYBSPkBRvsBRP0BQf8BQIECPoMCO4YCOYcCN4oCNYwCM40CMZACL5ICLZQCKpYCKZgCJpsCJJ0C"
7294 "Ip4CIKECHqMCHKQCGqcCGKkCFawCE60CEq8CD7ICDbMCDLUCCbgCB7oCBLwCA74CAbF5");
7295 ok(match, "Figure does not match.\n");
7297 hr = ID2D1Factory_CreatePathGeometry(factory, &geometry);
7298 ok(SUCCEEDED(hr), "Failed to create path geometry, hr %#x.\n", hr);
7299 hr = ID2D1PathGeometry_Open(geometry, &sink);
7300 ok(SUCCEEDED(hr), "Failed to open geometry sink, hr %#x.\n", hr);
7302 set_point(&point, 20.0f, 80.0f);
7303 ID2D1GeometrySink_BeginFigure(sink, point, D2D1_FIGURE_BEGIN_FILLED);
7304 quadratic_to(sink, 40.0f, 80.0f, 60.0f, 80.0f);
7305 quadratic_to(sink, 60.0f, 160.0f, 60.0f, 240.0f);
7306 quadratic_to(sink, 40.0f, 240.0f, 20.0f, 240.0f);
7307 quadratic_to(sink, 20.0f, 160.0f, 20.0f, 80.0f);
7308 ID2D1GeometrySink_EndFigure(sink, D2D1_FIGURE_END_CLOSED);
7310 set_point(&point, 100.0f, 80.0f);
7311 ID2D1GeometrySink_BeginFigure(sink, point, D2D1_FIGURE_BEGIN_FILLED);
7312 quadratic_to(sink, 105.0f, 80.0f, 140.0f, 80.0f);
7313 quadratic_to(sink, 140.0f, 100.0f, 140.0f, 240.0f);
7314 quadratic_to(sink, 135.0f, 240.0f, 100.0f, 240.0f);
7315 quadratic_to(sink, 100.0f, 220.0f, 100.0f, 80.0f);
7316 ID2D1GeometrySink_EndFigure(sink, D2D1_FIGURE_END_CLOSED);
7318 set_point(&point, 180.0f, 80.0f);
7319 ID2D1GeometrySink_BeginFigure(sink, point, D2D1_FIGURE_BEGIN_FILLED);
7320 quadratic_to(sink, 215.0f, 80.0f, 220.0f, 80.0f);
7321 quadratic_to(sink, 220.0f, 220.0f, 220.0f, 240.0f);
7322 quadratic_to(sink, 185.0f, 240.0f, 180.0f, 240.0f);
7323 quadratic_to(sink, 180.0f, 100.0f, 180.0f, 80.0f);
7324 ID2D1GeometrySink_EndFigure(sink, D2D1_FIGURE_END_CLOSED);
7326 set_point(&point, 260.0f, 80.0f);
7327 ID2D1GeometrySink_BeginFigure(sink, point, D2D1_FIGURE_BEGIN_FILLED);
7328 quadratic_to(sink, 280.0f, 80.0f, 300.0f, 80.0f);
7329 quadratic_to(sink, 300.0f, 160.0f, 300.0f, 240.0f);
7330 quadratic_to(sink, 280.0f, 240.0f, 260.0f, 240.0f);
7331 quadratic_to(sink, 260.0f, 160.0f, 260.0f, 80.0f);
7332 ID2D1GeometrySink_EndFigure(sink, D2D1_FIGURE_END_OPEN);
7334 set_point(&point, 20.0f, 400.0f);
7335 ID2D1GeometrySink_BeginFigure(sink, point, D2D1_FIGURE_BEGIN_FILLED);
7336 quadratic_to(sink, 40.0f, 420.0f, 60.0f, 400.0f);
7337 quadratic_to(sink, 55.0f, 480.0f, 60.0f, 560.0f);
7338 quadratic_to(sink, 40.0f, 540.0f, 20.0f, 560.0f);
7339 quadratic_to(sink, 25.0f, 480.0f, 20.0f, 400.0f);
7340 ID2D1GeometrySink_EndFigure(sink, D2D1_FIGURE_END_CLOSED);
7342 set_point(&point, 100.0f, 400.0f);
7343 ID2D1GeometrySink_BeginFigure(sink, point, D2D1_FIGURE_BEGIN_FILLED);
7344 quadratic_to(sink, 105.0f, 420.0f, 140.0f, 400.0f);
7345 quadratic_to(sink, 135.0f, 420.0f, 140.0f, 560.0f);
7346 quadratic_to(sink, 135.0f, 540.0f, 100.0f, 560.0f);
7347 quadratic_to(sink, 105.0f, 540.0f, 100.0f, 400.0f);
7348 ID2D1GeometrySink_EndFigure(sink, D2D1_FIGURE_END_CLOSED);
7350 set_point(&point, 180.0f, 400.0f);
7351 ID2D1GeometrySink_BeginFigure(sink, point, D2D1_FIGURE_BEGIN_FILLED);
7352 quadratic_to(sink, 215.0f, 420.0f, 220.0f, 400.0f);
7353 quadratic_to(sink, 215.0f, 540.0f, 220.0f, 560.0f);
7354 quadratic_to(sink, 185.0f, 540.0f, 180.0f, 560.0f);
7355 quadratic_to(sink, 185.0f, 420.0f, 180.0f, 400.0f);
7356 ID2D1GeometrySink_EndFigure(sink, D2D1_FIGURE_END_CLOSED);
7358 set_point(&point, 260.0f, 400.0f);
7359 ID2D1GeometrySink_BeginFigure(sink, point, D2D1_FIGURE_BEGIN_FILLED);
7360 quadratic_to(sink, 280.0f, 420.0f, 300.0f, 400.0f);
7361 quadratic_to(sink, 295.0f, 480.0f, 300.0f, 560.0f);
7362 quadratic_to(sink, 280.0f, 540.0f, 260.0f, 560.0f);
7363 quadratic_to(sink, 265.0f, 480.0f, 260.0f, 400.0f);
7364 ID2D1GeometrySink_EndFigure(sink, D2D1_FIGURE_END_OPEN);
7366 set_point(&point, 20.0f, 720.0f);
7367 ID2D1GeometrySink_BeginFigure(sink, point, D2D1_FIGURE_BEGIN_FILLED);
7368 quadratic_to(sink, 40.0f, 700.0f, 60.0f, 720.0f);
7369 quadratic_to(sink, 65.0f, 800.0f, 60.0f, 880.0f);
7370 quadratic_to(sink, 40.0f, 900.0f, 20.0f, 880.0f);
7371 quadratic_to(sink, 15.0f, 800.0f, 20.0f, 720.0f);
7372 ID2D1GeometrySink_EndFigure(sink, D2D1_FIGURE_END_CLOSED);
7374 set_point(&point, 100.0f, 720.0f);
7375 ID2D1GeometrySink_BeginFigure(sink, point, D2D1_FIGURE_BEGIN_FILLED);
7376 quadratic_to(sink, 105.0f, 700.0f, 140.0f, 720.0f);
7377 quadratic_to(sink, 145.0f, 740.0f, 140.0f, 880.0f);
7378 quadratic_to(sink, 135.0f, 900.0f, 100.0f, 880.0f);
7379 quadratic_to(sink, 95.0f, 860.0f, 100.0f, 720.0f);
7380 ID2D1GeometrySink_EndFigure(sink, D2D1_FIGURE_END_CLOSED);
7382 set_point(&point, 180.0f, 720.0f);
7383 ID2D1GeometrySink_BeginFigure(sink, point, D2D1_FIGURE_BEGIN_FILLED);
7384 quadratic_to(sink, 215.0f, 700.0f, 220.0f, 720.0f);
7385 quadratic_to(sink, 225.0f, 860.0f, 220.0f, 880.0f);
7386 quadratic_to(sink, 185.0f, 900.0f, 180.0f, 880.0f);
7387 quadratic_to(sink, 175.0f, 740.0f, 180.0f, 720.0f);
7388 ID2D1GeometrySink_EndFigure(sink, D2D1_FIGURE_END_CLOSED);
7390 set_point(&point, 260.0f, 720.0f);
7391 ID2D1GeometrySink_BeginFigure(sink, point, D2D1_FIGURE_BEGIN_FILLED);
7392 quadratic_to(sink, 280.0f, 700.0f, 300.0f, 720.0f);
7393 quadratic_to(sink, 305.0f, 800.0f, 300.0f, 880.0f);
7394 quadratic_to(sink, 280.0f, 900.0f, 260.0f, 880.0f);
7395 quadratic_to(sink, 255.0f, 800.0f, 260.0f, 720.0f);
7396 ID2D1GeometrySink_EndFigure(sink, D2D1_FIGURE_END_OPEN);
7398 hr = ID2D1GeometrySink_Close(sink);
7399 ok(SUCCEEDED(hr), "Failed to close geometry sink, hr %#x.\n", hr);
7400 ID2D1GeometrySink_Release(sink);
7402 ID2D1RenderTarget_BeginDraw(rt);
7403 ID2D1RenderTarget_Clear(rt, &color);
7404 ID2D1RenderTarget_FillGeometry(rt, (ID2D1Geometry *)geometry, (ID2D1Brush *)brush, NULL);
7405 hr = ID2D1RenderTarget_EndDraw(rt, NULL, NULL);
7406 ok(SUCCEEDED(hr), "Failed to end draw, hr %#x.\n", hr);
7407 ID2D1PathGeometry_Release(geometry);
7409 match = compare_figure(&ctx, 0, 0, 160, 160, 0xff652e89, 0,
7410 "qDJQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQ"
7411 "UFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQ"
7412 "UFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFCoMgAA");
7413 ok(match, "Figure does not match.\n");
7414 match = compare_figure(&ctx, 160, 0, 160, 160, 0xff652e89, 0,
7415 "qDJQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQ"
7416 "UFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQ"
7417 "UFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFCoMgAA");
7418 match = compare_figure(&ctx, 320, 0, 160, 160, 0xff652e89, 0,
7419 "qDJQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQ"
7420 "UFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQ"
7421 "UFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFCoMgAA");
7422 ok(match, "Figure does not match.\n");
7423 match = compare_figure(&ctx, 480, 0, 160, 160, 0xff652e89, 0,
7424 "qDJQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQ"
7425 "UFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQ"
7426 "UFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFCoMgAA");
7427 ok(match, "Figure does not match.\n");
7429 match = compare_figure(&ctx, 0, 160, 160, 160, 0xff652e89, 16,
7430 "qDICTAJQB0IHUQs4C1IRLBFSGxgbUk5STlNMVExUTFRMVExVSlZKVkpWSlZKVkpXSFhIWEhYSFhI"
7431 "WEhYSFhIWEhYSFlGWkZaRlpGWkZaRlpGWkZaRlpGWkZaRlpGWkZaRlpGWkZaRlpGWkZaRlpGWkZa"
7432 "RllIWEhYSFhIWEhYSFhIWEhYSFhIV0pWSlZKVkpWSlZKVUxUTFRMVExUTFNOUk5SGxgbUhEsEVIL"
7433 "OAtRB0IHUAJMAqgy");
7434 ok(match, "Figure does not match.\n");
7435 match = compare_figure(&ctx, 160, 160, 160, 160, 0xff652e89, 16,
7436 "qDIBSwRQAkMKUQQ5EVIIKxtTDRkmVExUTFRMVEtVS1VLVkpWSlZKVklXSVdJV0lXSVhIWEhYSFhI"
7437 "WEhYSFhIWEhYSFhIWUdZR1lHWUdZR1lHWUdZR1lHWUdZSFhIWUdZR1lHWUdZR1lHWUdZR1lHWUdZ"
7438 "SFhIWEhYSFhIWEhYSFhIWEhYSFhJV0lXSVdJV0lWSlZKVkpWS1VLVUtUTFRMVExUJhkNUxsrCFIR"
7439 "OQRRCkMCUARLAagy");
7440 ok(match, "Figure does not match.\n");
7441 match = compare_figure(&ctx, 320, 160, 160, 160, 0xff652e89, 16,
7442 "qDIESwFRCkMCUhE5BFIbKwhTJhkNVExUTFRMVUtVS1VLVUpWSlZKV0lXSVdJV0lXSVdIWEhYSFhI"
7443 "WEhYSFhIWEhYSFhIWEdZR1lHWUdZR1lHWUdZR1lHWUdYSFhIWEdZR1lHWUdZR1lHWUdZR1lHWUdY"
7444 "SFhIWEhYSFhIWEhYSFhIWEhYSFdJV0lXSVdJV0lXSlZKVkpVS1VLVUtVTFRMVExUDRkmUwgrG1IE"
7445 "ORFSAkMKUQFLBKgy");
7446 ok(match, "Figure does not match.\n");
7447 match = compare_figure(&ctx, 480, 160, 160, 160, 0xff652e89, 16,
7448 "qDICTAJQB0IHUQs4C1IRLBFSGxgbUk5STlNMVExUTFRMVExVSlZKVkpWSlZKVkpXSFhIWEhYSFhI"
7449 "WEhYSFhIWEhYSFlGWkZaRlpGWkZaRlpGWkZaRlpGWkZaRlpGWkZaRlpGWkZaRlpGWkZaRlpGWkZa"
7450 "RllIWEhYSFhIWEhYSFhIWEhYSFhIV0pWSlZKVkpWSlZKVUxUTFRMVExUTFNOUk5SGxgbUhEsEVIL"
7451 "OAtRB0IHUAJMAqgy");
7452 ok(match, "Figure does not match.\n");
7454 match = compare_figure(&ctx, 0, 320, 160, 160, 0xff652e89, 16,
7455 "pCwYfixuOGNCWUxSUFBQT1JOUk5STlJOUk1UTFRMVExUTFRLVkpWSlZKVkpWSlZJWEhYSFhIWEhY"
7456 "SFhIWEhYSFhIWEdaRlpGWkZaRlpGWkZaRlpGWkZaRlpGWkZaRlpGWkZaRlpGWkZaRlpGWkZaRlpG"
7457 "WkdYSFhIWEhYSFhIWEhYSFhIWEhYSVZKVkpWSlZKVkpWS1RMVExUTFRMVE1STlJOUk5STlJPUFBQ"
7458 "UkxZQmM4bix+GKQs");
7459 ok(match, "Figure does not match.\n");
7460 match = compare_figure(&ctx, 160, 320, 160, 160, 0xff652e89, 16,
7461 "liwZgQErcTllQ1xLVFBQUU9STlJNVExUTFRMVExVS1VLVUpWSlZKVkpXSVdJV0lXSVdIWEhYSFhI"
7462 "WEhYSFhIWEhYSFhIWEdZR1lHWUdZR1lHWUdZR1lHWUdZR1hIWEdZR1lHWUdZR1lHWUdZR1lHWUdZ"
7463 "R1hIWEhYSFhIWEhYSFhIWEhYSFhIV0lXSVdJV0lXSlZKVkpWSlVLVUtVTFRMVExUTFRNUk5ST1FQ"
7464 "UFRLXENlOXErgQEZliwA");
7465 ok(match, "Figure does not match.\n");
7466 match = compare_figure(&ctx, 320, 320, 160, 160, 0xff652e89, 16,
7467 "sSwZeytrOV9DVktRUE9RTlJOUk1UTFRMVExUS1VLVUtVS1ZKVkpWSVdJV0lXSVdJV0lYSFhIWEhY"
7468 "SFhIWEhYSFhIWEhYSFlHWUdZR1lHWUdZR1lHWUdZR1lIWEhYSFlHWUdZR1lHWUdZR1lHWUdZR1lI"
7469 "WEhYSFhIWEhYSFhIWEhYSFhIWElXSVdJV0lXSVdJVkpWSlZLVUtVS1VLVExUTFRMVE1STlJOUU9Q"
7470 "UUtWQ185ayt7GbEs");
7471 ok(match, "Figure does not match.\n");
7472 match = compare_figure(&ctx, 480, 320, 160, 160, 0xff652e89, 16,
7473 "pCwYfixuOGNCWUxSUFBQT1JOUk5STlJOUk1UTFRMVExUTFRLVkpWSlZKVkpWSlZJWEhYSFhIWEhY"
7474 "SFhIWEhYSFhIWEdaRlpGWkZaRlpGWkZaRlpGWkZaRlpGWkZaRlpGWkZaRlpGWkZaRlpGWkZaRlpG"
7475 "WkdYSFhIWEhYSFhIWEhYSFhIWEhYSVZKVkpWSlZKVkpWS1RMVExUTFRMVE1STlJOUk5STlJPUFBQ"
7476 "UkxZQmM4bix+GKQs");
7477 ok(match, "Figure does not match.\n");
7479 hr = ID2D1Factory_CreatePathGeometry(factory, &geometry);
7480 ok(SUCCEEDED(hr), "Failed to create path geometry, hr %#x.\n", hr);
7481 hr = ID2D1PathGeometry_Open(geometry, &sink);
7482 ok(SUCCEEDED(hr), "Failed to open geometry sink, hr %#x.\n", hr);
7484 set_point(&point, -0.402914f, 0.915514f);
7485 ID2D1GeometrySink_BeginFigure(sink, point, D2D1_FIGURE_BEGIN_FILLED);
7486 quadratic_to(sink, -0.310379f, 0.882571f, -0.116057f, 0.824000f);
7487 quadratic_to(sink, 0.008350f, 0.693614f, -0.052343f, 0.448886f);
7488 quadratic_to(sink, -0.154236f, 0.246072f, -0.279229f, 0.025343f);
7489 quadratic_to(sink, -0.370064f, -0.588586f, -0.383029f, -0.924114f);
7490 quadratic_to(sink, -0.295479f, -0.958764f, -0.017086f, -0.988400f);
7491 quadratic_to(sink, 0.208836f, -0.954157f, 0.272200f, -0.924114f);
7492 quadratic_to(sink, 0.295614f, -0.569071f, 0.230143f, 0.022886f);
7493 quadratic_to(sink, 0.101664f, 0.220643f, 0.012057f, 0.451571f);
7494 quadratic_to(sink, -0.028764f, 0.709014f, 0.104029f, 0.833943f);
7495 quadratic_to(sink, 0.319414f, 0.913057f, 0.403229f, 0.942628f);
7496 quadratic_to(sink, 0.317721f, 1.023450f, -0.017086f, 1.021771f);
7497 quadratic_to(sink, -0.310843f, 1.007472f, -0.402914f, 0.915514f);
7498 ID2D1GeometrySink_EndFigure(sink, D2D1_FIGURE_END_CLOSED);
7500 hr = ID2D1GeometrySink_Close(sink);
7501 ok(SUCCEEDED(hr), "Failed to close geometry sink, hr %#x.\n", hr);
7502 ID2D1GeometrySink_Release(sink);
7504 set_matrix_identity(&matrix);
7505 translate_matrix(&matrix, 40.0f, 160.0f);
7506 scale_matrix(&matrix, 20.0f, 80.0f);
7507 hr = ID2D1Factory_CreateTransformedGeometry(factory,
7508 (ID2D1Geometry *)geometry, &matrix, &transformed_geometry[0]);
7509 ok(SUCCEEDED(hr), "Failed to create geometry, hr %#x.\n", hr);
7511 set_matrix_identity(&matrix);
7512 translate_matrix(&matrix, 160.0f, 640.0f);
7513 scale_matrix(&matrix, 40.0f, 160.0f);
7514 rotate_matrix(&matrix, M_PI / -5.0f);
7515 hr = ID2D1Factory_CreateTransformedGeometry(factory,
7516 (ID2D1Geometry *)geometry, &matrix, &transformed_geometry[1]);
7517 ok(SUCCEEDED(hr), "Failed to create geometry, hr %#x.\n", hr);
7518 ID2D1PathGeometry_Release(geometry);
7520 set_matrix_identity(&matrix);
7521 scale_matrix(&matrix, 0.5f, 1.0f);
7522 translate_matrix(&matrix, -80.0f, 0.0f);
7523 hr = ID2D1Factory_CreateTransformedGeometry(factory,
7524 (ID2D1Geometry *)transformed_geometry[1], &matrix, &transformed_geometry[2]);
7525 ok(SUCCEEDED(hr), "Failed to create geometry, hr %#x.\n", hr);
7527 set_matrix_identity(&matrix);
7528 rotate_matrix(&matrix, M_PI / 2.0f);
7529 translate_matrix(&matrix, 80.0f, -320.0f);
7530 scale_matrix(&matrix, 2.0f, 0.25f);
7531 hr = ID2D1Factory_CreateTransformedGeometry(factory,
7532 (ID2D1Geometry *)transformed_geometry[2], &matrix, &transformed_geometry[3]);
7533 ok(SUCCEEDED(hr), "Failed to create geometry, hr %#x.\n", hr);
7535 ID2D1RenderTarget_BeginDraw(rt);
7536 ID2D1RenderTarget_Clear(rt, &color);
7537 ID2D1RenderTarget_FillGeometry(rt, (ID2D1Geometry *)transformed_geometry[0], (ID2D1Brush *)brush, NULL);
7538 ID2D1RenderTarget_FillGeometry(rt, (ID2D1Geometry *)transformed_geometry[1], (ID2D1Brush *)brush, NULL);
7539 ID2D1RenderTarget_FillGeometry(rt, (ID2D1Geometry *)transformed_geometry[2], (ID2D1Brush *)brush, NULL);
7540 ID2D1RenderTarget_FillGeometry(rt, (ID2D1Geometry *)transformed_geometry[3], (ID2D1Brush *)brush, NULL);
7541 hr = ID2D1RenderTarget_EndDraw(rt, NULL, NULL);
7542 ok(SUCCEEDED(hr), "Failed to end draw, hr %#x.\n", hr);
7543 ID2D1TransformedGeometry_Release(transformed_geometry[3]);
7544 ID2D1TransformedGeometry_Release(transformed_geometry[2]);
7545 ID2D1TransformedGeometry_Release(transformed_geometry[1]);
7546 ID2D1TransformedGeometry_Release(transformed_geometry[0]);
7548 match = compare_figure(&ctx, 0, 0, 160, 160, 0xff652e89, 32,
7549 "6DMNjgEWiAEahgEahgEahgEahgEahgEahgEahgEahgEahgEahgEahwEZhwEZhwEZhwEZhwEZhwEZ"
7550 "hwEZhwEZhwEZiAEYiAEYiAEYiAEYiAEXiQEXiQEXiQEXigEWigEWigEWigEWigEWigEWigEWiwEU"
7551 "jAEUjAEUjAEUjQESjgESjwEQkAEQkQEOkgENlAEMlQEKlgEKlwEImAEImQEHmQEGmwEFmwEEnQED"
7552 "nQECngECngECnwEBnwEBnwEBnwEBnwEBnwECnQEDnQEDnQEEmwEFmgEHmQEHlwELkQERjAEXhgEd"
7553 "hAEfgwEchgEXjwEMqTEA");
7554 ok(match, "Figure does not match.\n");
7555 match = compare_figure(&ctx, 160, 0, 320, 160, 0xff652e89, 32,
7556 "h58BBrYCDq0CF6QCIJwCKJMCMIwCNoUCPf8BQ/kBSPQBTu4BTe8BTPEBSfUBRvgBQf0BPYECOYUC"
7557 "NIoCMI4CK+UBAS0W/AEHIwiPAgsaBZcCEAwIngIepAIaqAIWrAITsAIRsgIPtQIMtwILugIHwAIB"
7558 "ypwB");
7559 ok(match, "Figure does not match.\n");
7560 match = compare_figure(&ctx, 0, 160, 160, 320, 0xff652e89, 32,
7561 "wW4DnAEEmwEFmgEHmAEIlwEKlQELlAEMkwEOkQEPkAEQkAERjgESjgETjAEUjAEUiwEWigEWiQEX"
7562 "iQEYhwEZhwEZhgEbhQEbhAEchAEdggEeggEeggEfgAEggAEggAEhgAEggAEggQEggAEggAEggQEg"
7563 "gAEggQEfgQEfggEfgQEfgQEfggEfgQEfggEeggEfggEeggEegwEdgwEeggEegwEdgwEegwEdgwEd"
7564 "hAEchAEdhAEchAEchAEdhAEchAEchQEbhQEbhgEahgEahwEZhwEZiAEYiAEYiQEYiAEYiQEXiQEX"
7565 "igEWigEWiwEViwEViwEVjAEUjAEUjQETjQETjgESjgETjgESjwERkAEQkQEPkwENlAEMlQELlgEK"
7566 "lwEKlwEJmAEImQEHmgEGmwEFnAEEnQEEnQEDnQEDngECngEDngECngECnwECngECnwECngECngED"
7567 "ngECEgGLAQMQAosBAw4EjAEDCwaMAQQJBo0BBQYIjQEHAgqNARKOARKPARCQARCQARCQAQ+RAQ6S"
7568 "AQ6SAQ2TAQ2SAQ2TAQ2TAQyTAQyUAQyUAQuUAQuVAQuUAQuVAQqWAQmWAQqWAQmXAQiXAQiYAQeY"
7569 "AQeZAQWbAQSDZwAA");
7570 ok(match, "Figure does not match.\n");
7571 match = compare_figure(&ctx, 160, 160, 320, 320, 0xff652e89, 32,
7572 "g90BBLkCCLYCC7ICDrACEa0CFKoCF6cCGqQCHKMCHqECIJ8CIpwCJJsCJpkCKJcCKZYCK5QCLZIC"
7573 "L5ACMI8CMo0CNIsCNYoCN4gCOYcCOYYCO4QCPYICPoECQIACQYACQIECQIACQIECQIECQIECP4IC"
7574 "P4ICP4ECP4ICP4ICPoMCPoMCPoMCPYQCPYMCPYQCPYQCPYQCPIUCPIUCPIUCO4YCO4YCOoYCO4YC"
7575 "OocCOocCOocCOYgCOYgCOIkCOIkCN4oCNosCNYwCNI0CM44CMo4CM44CMo8CMZACMJECL5ICLpMC"
7576 "LZQCLJUCK5YCK5YCKpcCKZgCKJkCJ5oCJpsCJpsCJZwCJJ4CIqACIKICH6MCHaUCG6cCGakCF6wC"
7577 "Fa0CE68CEbECD7MCDrQCDLYCCrgCCbkCB7sCBrsCBbwCBbwCBL0CBL0CBL0CBL0CA70CBL0CBL0C"
7578 "BLwCBSUBlgIFIQSXAgYbCJcCBxcKmQIIEQ6ZAgoMEJoCDQUTnAIknAIjnQIingIhnwIgoAIfoQIe"
7579 "ogIdowIcpAIbpQIapQIZpgIZpgIZpwIYpwIXqAIXqAIXqQIVqgIVqgIUqwITrQISrQIRrgIQsAIO"
7580 "sQIMswILtQIIhs4B");
7581 ok(match, "Figure does not match.\n");
7583 hr = ID2D1Factory_CreatePathGeometry(factory, &geometry);
7584 ok(SUCCEEDED(hr), "Failed to create path geometry, hr %#x.\n", hr);
7585 hr = ID2D1PathGeometry_Open(geometry, &sink);
7586 ok(SUCCEEDED(hr), "Failed to open geometry sink, hr %#x.\n", hr);
7588 set_point(&point, -0.402914f, 0.915514f);
7589 ID2D1GeometrySink_BeginFigure(sink, point, D2D1_FIGURE_BEGIN_HOLLOW);
7590 quadratic_to(sink, -0.310379f, 0.882571f, -0.116057f, 0.824000f);
7591 quadratic_to(sink, 0.008350f, 0.693614f, -0.052343f, 0.448886f);
7592 quadratic_to(sink, -0.154236f, 0.246072f, -0.279229f, 0.025343f);
7593 quadratic_to(sink, -0.370064f, -0.588586f, -0.383029f, -0.924114f);
7594 quadratic_to(sink, -0.295479f, -0.958764f, -0.017086f, -0.988400f);
7595 quadratic_to(sink, 0.208836f, -0.954157f, 0.272200f, -0.924114f);
7596 quadratic_to(sink, 0.295614f, -0.569071f, 0.230143f, 0.022886f);
7597 quadratic_to(sink, 0.101664f, 0.220643f, 0.012057f, 0.451571f);
7598 quadratic_to(sink, -0.028764f, 0.709014f, 0.104029f, 0.833943f);
7599 quadratic_to(sink, 0.319414f, 0.913057f, 0.403229f, 0.942628f);
7600 quadratic_to(sink, 0.317721f, 1.023450f, -0.017086f, 1.021771f);
7601 quadratic_to(sink, -0.310843f, 1.007472f, -0.402914f, 0.915514f);
7602 ID2D1GeometrySink_EndFigure(sink, D2D1_FIGURE_END_CLOSED);
7604 hr = ID2D1GeometrySink_Close(sink);
7605 ok(SUCCEEDED(hr), "Failed to close geometry sink, hr %#x.\n", hr);
7606 ID2D1GeometrySink_Release(sink);
7608 set_matrix_identity(&matrix);
7609 translate_matrix(&matrix, 40.0f, 160.0f);
7610 scale_matrix(&matrix, 20.0f, 80.0f);
7611 hr = ID2D1Factory_CreateTransformedGeometry(factory,
7612 (ID2D1Geometry *)geometry, &matrix, &transformed_geometry[0]);
7613 ok(SUCCEEDED(hr), "Failed to create geometry, hr %#x.\n", hr);
7615 set_matrix_identity(&matrix);
7616 translate_matrix(&matrix, 160.0f, 640.0f);
7617 scale_matrix(&matrix, 40.0f, 160.0f);
7618 rotate_matrix(&matrix, M_PI / -5.0f);
7619 hr = ID2D1Factory_CreateTransformedGeometry(factory,
7620 (ID2D1Geometry *)geometry, &matrix, &transformed_geometry[1]);
7621 ok(SUCCEEDED(hr), "Failed to create geometry, hr %#x.\n", hr);
7622 ID2D1PathGeometry_Release(geometry);
7624 set_matrix_identity(&matrix);
7625 scale_matrix(&matrix, 0.5f, 1.0f);
7626 translate_matrix(&matrix, -80.0f, 0.0f);
7627 hr = ID2D1Factory_CreateTransformedGeometry(factory,
7628 (ID2D1Geometry *)transformed_geometry[1], &matrix, &transformed_geometry[2]);
7629 ok(SUCCEEDED(hr), "Failed to create geometry, hr %#x.\n", hr);
7631 set_matrix_identity(&matrix);
7632 rotate_matrix(&matrix, M_PI / 2.0f);
7633 translate_matrix(&matrix, 80.0f, -320.0f);
7634 scale_matrix(&matrix, 2.0f, 0.25f);
7635 hr = ID2D1Factory_CreateTransformedGeometry(factory,
7636 (ID2D1Geometry *)transformed_geometry[2], &matrix, &transformed_geometry[3]);
7637 ok(SUCCEEDED(hr), "Failed to create geometry, hr %#x.\n", hr);
7639 ID2D1RenderTarget_BeginDraw(rt);
7640 ID2D1RenderTarget_Clear(rt, &color);
7641 ID2D1RenderTarget_FillGeometry(rt, (ID2D1Geometry *)transformed_geometry[0], (ID2D1Brush *)brush, NULL);
7642 ID2D1RenderTarget_FillGeometry(rt, (ID2D1Geometry *)transformed_geometry[1], (ID2D1Brush *)brush, NULL);
7643 ID2D1RenderTarget_FillGeometry(rt, (ID2D1Geometry *)transformed_geometry[2], (ID2D1Brush *)brush, NULL);
7644 ID2D1RenderTarget_FillGeometry(rt, (ID2D1Geometry *)transformed_geometry[3], (ID2D1Brush *)brush, NULL);
7645 hr = ID2D1RenderTarget_EndDraw(rt, NULL, NULL);
7646 ok(SUCCEEDED(hr), "Failed to end draw, hr %#x.\n", hr);
7647 ID2D1TransformedGeometry_Release(transformed_geometry[3]);
7648 ID2D1TransformedGeometry_Release(transformed_geometry[2]);
7649 ID2D1TransformedGeometry_Release(transformed_geometry[1]);
7650 ID2D1TransformedGeometry_Release(transformed_geometry[0]);
7652 match = compare_figure(&ctx, 0, 0, 160, 160, 0xff652e89, 0, "gMgB");
7653 ok(match, "Figure does not match.\n");
7654 match = compare_figure(&ctx, 160, 0, 320, 160, 0xff652e89, 0, "gJAD");
7655 ok(match, "Figure does not match.\n");
7656 match = compare_figure(&ctx, 0, 160, 160, 320, 0xff652e89, 0, "gJAD");
7657 ok(match, "Figure does not match.\n");
7658 match = compare_figure(&ctx, 160, 160, 320, 320, 0xff652e89, 0, "gKAG");
7659 ok(match, "Figure does not match.\n");
7661 ID2D1SolidColorBrush_Release(brush);
7662 ID2D1Factory_Release(factory);
7663 release_test_context(&ctx);
7666 static void test_gdi_interop(BOOL d3d11)
7668 ID2D1GdiInteropRenderTarget *interop;
7669 D2D1_RENDER_TARGET_PROPERTIES desc;
7670 IWICImagingFactory *wic_factory;
7671 struct d2d1_test_context ctx;
7672 IWICBitmapLock *wic_lock;
7673 IWICBitmap *wic_bitmap;
7674 ID2D1RenderTarget *rt;
7675 ID2D1Factory *factory;
7676 D2D1_COLOR_F color;
7677 HRESULT hr;
7678 BOOL match;
7679 RECT rect;
7680 HDC dc;
7682 if (!init_test_context(&ctx, d3d11))
7683 return;
7685 hr = D2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED, &IID_ID2D1Factory, NULL, (void **)&factory);
7686 ok(SUCCEEDED(hr), "Failed to create factory, hr %#x.\n", hr);
7688 CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
7689 hr = CoCreateInstance(&CLSID_WICImagingFactory, NULL, CLSCTX_INPROC_SERVER,
7690 &IID_IWICImagingFactory, (void **)&wic_factory);
7691 ok(SUCCEEDED(hr), "Failed to create WIC imaging factory, hr %#x.\n", hr);
7692 hr = IWICImagingFactory_CreateBitmap(wic_factory, 16, 16,
7693 &GUID_WICPixelFormat32bppPBGRA, WICBitmapCacheOnDemand, &wic_bitmap);
7694 ok(SUCCEEDED(hr), "Failed to create bitmap, hr %#x.\n", hr);
7695 IWICImagingFactory_Release(wic_factory);
7697 /* WIC target, default usage */
7698 desc.type = D2D1_RENDER_TARGET_TYPE_DEFAULT;
7699 desc.pixelFormat.format = DXGI_FORMAT_UNKNOWN;
7700 desc.pixelFormat.alphaMode = D2D1_ALPHA_MODE_PREMULTIPLIED;
7701 desc.dpiX = 0.0f;
7702 desc.dpiY = 0.0f;
7703 desc.usage = D2D1_RENDER_TARGET_USAGE_NONE;
7704 desc.minLevel = D2D1_FEATURE_LEVEL_DEFAULT;
7706 hr = ID2D1Factory_CreateWicBitmapRenderTarget(factory, wic_bitmap, &desc, &rt);
7707 ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr);
7709 hr = ID2D1RenderTarget_QueryInterface(rt, &IID_ID2D1GdiInteropRenderTarget, (void **)&interop);
7710 ok(SUCCEEDED(hr), "Failed to get gdi interop interface, hr %#x.\n", hr);
7712 ID2D1RenderTarget_BeginDraw(rt);
7713 dc = (void *)0xdeadbeef;
7714 hr = ID2D1GdiInteropRenderTarget_GetDC(interop, D2D1_DC_INITIALIZE_MODE_COPY, &dc);
7715 ok(FAILED(hr), "GetDC() was expected to fail, hr %#x.\n", hr);
7716 todo_wine
7717 ok(dc == NULL, "Expected NULL dc, got %p.\n", dc);
7718 ID2D1GdiInteropRenderTarget_Release(interop);
7719 hr = ID2D1RenderTarget_EndDraw(rt, NULL, NULL);
7720 ok(SUCCEEDED(hr), "Failed to end draw, hr %#x.\n", hr);
7722 ID2D1RenderTarget_Release(rt);
7724 /* WIC target, gdi compatible */
7725 desc.usage = D2D1_RENDER_TARGET_USAGE_GDI_COMPATIBLE;
7727 hr = ID2D1Factory_CreateWicBitmapRenderTarget(factory, wic_bitmap, &desc, &rt);
7728 ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr);
7730 hr = ID2D1RenderTarget_QueryInterface(rt, &IID_ID2D1GdiInteropRenderTarget, (void **)&interop);
7731 ok(SUCCEEDED(hr), "Failed to get gdi interop interface, hr %#x.\n", hr);
7733 ID2D1RenderTarget_BeginDraw(rt);
7734 dc = NULL;
7735 hr = ID2D1GdiInteropRenderTarget_GetDC(interop, D2D1_DC_INITIALIZE_MODE_COPY, &dc);
7736 ok(SUCCEEDED(hr), "GetDC() was expected to succeed, hr %#x.\n", hr);
7737 ok(dc != NULL, "Expected NULL dc, got %p.\n", dc);
7738 ID2D1GdiInteropRenderTarget_ReleaseDC(interop, NULL);
7739 hr = ID2D1RenderTarget_EndDraw(rt, NULL, NULL);
7740 ok(SUCCEEDED(hr), "EndDraw() failed, hr %#x.\n", hr);
7742 ID2D1RenderTarget_BeginDraw(rt);
7743 set_color(&color, 1.0f, 0.0f, 0.0f, 1.0f);
7744 ID2D1RenderTarget_Clear(rt, &color);
7745 hr = ID2D1RenderTarget_EndDraw(rt, NULL, NULL);
7746 ok(SUCCEEDED(hr), "EndDraw() failed, hr %#x.\n", hr);
7748 match = compare_wic_bitmap(wic_bitmap, "54034063dbc1c1bb61cb60ec57e4498678dc2b13");
7749 ok(match, "Bitmap does not match.\n");
7751 /* Do solid fill using GDI */
7752 ID2D1RenderTarget_BeginDraw(rt);
7754 hr = ID2D1GdiInteropRenderTarget_GetDC(interop, D2D1_DC_INITIALIZE_MODE_COPY, &dc);
7755 ok(SUCCEEDED(hr), "GetDC() was expected to succeed, hr %#x.\n", hr);
7757 SetRect(&rect, 0, 0, 16, 16);
7758 FillRect(dc, &rect, GetStockObject(BLACK_BRUSH));
7759 ID2D1GdiInteropRenderTarget_ReleaseDC(interop, NULL);
7761 hr = ID2D1RenderTarget_EndDraw(rt, NULL, NULL);
7762 ok(SUCCEEDED(hr), "EndDraw() failed, hr %#x.\n", hr);
7764 match = compare_wic_bitmap(wic_bitmap, "60cacbf3d72e1e7834203da608037b1bf83b40e8");
7765 ok(match, "Bitmap does not match.\n");
7767 /* Bitmap is locked at BeginDraw(). */
7768 hr = IWICBitmap_Lock(wic_bitmap, NULL, WICBitmapLockRead, &wic_lock);
7769 ok(SUCCEEDED(hr), "Expected bitmap to be unlocked, hr %#x.\n", hr);
7770 IWICBitmapLock_Release(wic_lock);
7772 ID2D1RenderTarget_BeginDraw(rt);
7773 hr = IWICBitmap_Lock(wic_bitmap, NULL, WICBitmapLockRead, &wic_lock);
7774 todo_wine
7775 ok(hr == WINCODEC_ERR_ALREADYLOCKED, "Expected bitmap to be locked, hr %#x.\n", hr);
7776 if (SUCCEEDED(hr))
7777 IWICBitmapLock_Release(wic_lock);
7778 hr = ID2D1RenderTarget_EndDraw(rt, NULL, NULL);
7779 ok(SUCCEEDED(hr), "EndDraw() failed, hr %#x.\n", hr);
7781 /* Lock before BeginDraw(). */
7782 hr = IWICBitmap_Lock(wic_bitmap, NULL, WICBitmapLockRead, &wic_lock);
7783 ok(SUCCEEDED(hr), "Expected bitmap to be unlocked, hr %#x.\n", hr);
7784 ID2D1RenderTarget_BeginDraw(rt);
7785 hr = ID2D1RenderTarget_EndDraw(rt, NULL, NULL);
7786 todo_wine
7787 ok(hr == WINCODEC_ERR_ALREADYLOCKED, "Unexpected hr %#x.\n", hr);
7788 IWICBitmapLock_Release(wic_lock);
7790 ID2D1GdiInteropRenderTarget_Release(interop);
7791 ID2D1RenderTarget_Release(rt);
7793 IWICBitmap_Release(wic_bitmap);
7794 ID2D1Factory_Release(factory);
7795 release_test_context(&ctx);
7798 static void test_layer(BOOL d3d11)
7800 ID2D1Factory *factory, *layer_factory;
7801 struct d2d1_test_context ctx;
7802 ID2D1RenderTarget *rt;
7803 ID2D1Layer *layer;
7804 D2D1_SIZE_F size;
7805 HRESULT hr;
7807 if (!init_test_context(&ctx, d3d11))
7808 return;
7810 rt = ctx.rt;
7811 ID2D1RenderTarget_GetFactory(rt, &factory);
7813 ID2D1RenderTarget_SetDpi(rt, 192.0f, 48.0f);
7814 ID2D1RenderTarget_SetAntialiasMode(rt, D2D1_ANTIALIAS_MODE_ALIASED);
7816 hr = ID2D1RenderTarget_CreateLayer(rt, NULL, &layer);
7817 ok(SUCCEEDED(hr), "Failed to create layer, hr %#x.\n", hr);
7818 ID2D1Layer_GetFactory(layer, &layer_factory);
7819 ok(layer_factory == factory, "Got unexpected layer factory %p, expected %p.\n", layer_factory, factory);
7820 ID2D1Factory_Release(layer_factory);
7821 size = ID2D1Layer_GetSize(layer);
7822 ok(size.width == 0.0f, "Got unexpected width %.8e.\n", size.width);
7823 ok(size.height == 0.0f, "Got unexpected height %.8e.\n", size.height);
7824 ID2D1Layer_Release(layer);
7826 set_size_f(&size, 800.0f, 600.0f);
7827 hr = ID2D1RenderTarget_CreateLayer(rt, &size, &layer);
7828 ok(SUCCEEDED(hr), "Failed to create layer, hr %#x.\n", hr);
7829 size = ID2D1Layer_GetSize(layer);
7830 ok(size.width == 800.0f, "Got unexpected width %.8e.\n", size.width);
7831 ok(size.height == 600.0f, "Got unexpected height %.8e.\n", size.height);
7832 ID2D1Layer_Release(layer);
7834 ID2D1Factory_Release(factory);
7835 release_test_context(&ctx);
7838 static void test_bezier_intersect(BOOL d3d11)
7840 D2D1_POINT_2F point = {0.0f, 0.0f};
7841 struct d2d1_test_context ctx;
7842 ID2D1SolidColorBrush *brush;
7843 ID2D1PathGeometry *geometry;
7844 ID2D1GeometrySink *sink;
7845 ID2D1RenderTarget *rt;
7846 ID2D1Factory *factory;
7847 D2D1_COLOR_F color;
7848 HRESULT hr;
7849 BOOL match;
7851 if (!init_test_context(&ctx, d3d11))
7852 return;
7854 rt = ctx.rt;
7855 ID2D1RenderTarget_GetFactory(rt, &factory);
7857 ID2D1RenderTarget_SetDpi(rt, 192.0f, 48.0f);
7858 ID2D1RenderTarget_SetAntialiasMode(rt, D2D1_ANTIALIAS_MODE_ALIASED);
7859 set_color(&color, 0.890f, 0.851f, 0.600f, 1.0f);
7860 hr = ID2D1RenderTarget_CreateSolidColorBrush(rt, &color, NULL, &brush);
7861 ok(SUCCEEDED(hr), "Failed to create brush, hr %#x.\n", hr);
7863 hr = ID2D1Factory_CreatePathGeometry(factory, &geometry);
7864 ok(SUCCEEDED(hr), "Failed to create path geometry, hr %#x.\n", hr);
7865 hr = ID2D1PathGeometry_Open(geometry, &sink);
7866 ok(SUCCEEDED(hr), "Failed to open geometry sink, hr %#x.\n", hr);
7868 set_point(&point, 160.0f, 720.0f);
7869 ID2D1GeometrySink_BeginFigure(sink, point, D2D1_FIGURE_BEGIN_FILLED);
7870 cubic_to(sink, 119.0f, 720.0f, 83.0f, 600.0f, 80.0f, 474.0f);
7871 cubic_to(sink, 78.0f, 349.0f, 108.0f, 245.0f, 135.0f, 240.0f);
7872 cubic_to(sink, 163.0f, 235.0f, 180.0f, 318.0f, 176.0f, 370.0f);
7873 cubic_to(sink, 171.0f, 422.0f, 149.0f, 422.0f, 144.0f, 370.0f);
7874 cubic_to(sink, 140.0f, 318.0f, 157.0f, 235.0f, 185.0f, 240.0f);
7875 cubic_to(sink, 212.0f, 245.0f, 242.0f, 349.0f, 240.0f, 474.0f);
7876 cubic_to(sink, 238.0f, 600.0f, 201.0f, 720.0f, 160.0f, 720.0f);
7877 ID2D1GeometrySink_EndFigure(sink, D2D1_FIGURE_END_CLOSED);
7879 set_point(&point, 160.0f, 240.0f);
7880 ID2D1GeometrySink_BeginFigure(sink, point, D2D1_FIGURE_BEGIN_FILLED);
7881 line_to(sink, 240.0f, 240.0f);
7882 line_to(sink, 240.0f, 720.0f);
7883 line_to(sink, 160.0f, 720.0f);
7884 ID2D1GeometrySink_EndFigure(sink, D2D1_FIGURE_END_CLOSED);
7886 hr = ID2D1GeometrySink_Close(sink);
7887 ok(SUCCEEDED(hr), "Failed to close geometry sink, hr %#x.\n", hr);
7888 ID2D1GeometrySink_Release(sink);
7890 ID2D1RenderTarget_BeginDraw(rt);
7891 set_color(&color, 0.396f, 0.180f, 0.537f, 1.0f);
7892 ID2D1RenderTarget_Clear(rt, &color);
7893 ID2D1RenderTarget_FillGeometry(rt, (ID2D1Geometry *)geometry, (ID2D1Brush *)brush, NULL);
7894 hr = ID2D1RenderTarget_EndDraw(rt, NULL, NULL);
7895 ok(SUCCEEDED(hr), "Failed to end draw, hr %#x.\n", hr);
7896 ID2D1PathGeometry_Release(geometry);
7898 match = compare_figure(&ctx, 160, 120, 320, 240, 0xff652e89, 2048,
7899 "aRQjIxRpYiIcHCJiXSwXFyxdWTQTEzRZVTsQEDtVUkIMDEJST0cKCkdPTUsICEtNSlEFBVFKSFUD"
7900 "A1VIRlkBAVlGRFsBAVtEQlwCAlxCQFwEBFxAPl0FBV0+PF0HB108Ol4ICF46OV0KCl05N14LC143"
7901 "Nl4MDF42NF8NDV80M14PD14zMV8QEF8xMF8REV8wL18SEl8vLWATE2AtLGAUFGAsK2EUFGErKWIV"
7902 "FWIpKGIWFmIoJ2IXF2InJmIYGGImJWMYGGMlJGMZGWMkI2MaGmMjImQaGmQiIWQbG2QhIGQcHGQg"
7903 "H2UcHGUfHmUdHWUeHWYdHWYdHGcdHWccG2ceHmcbGmgeHmgaGWgfH2gZGWgfH2gZGGkfH2kYF2kg"
7904 "IGkXFmogIGoWFmogIGoWFWsgIGsVFGshIWsUE2whIWwTE2whIWwTEm0hIW0SEW4hIW4REW4hIW4R"
7905 "EG8hIW8QD3AhIXAPD3AhIXAPDnEhIXEODnEhIXEODXIhIXINDHQgIHQMDHQgIHQMC3UgIHULC3Yf"
7906 "H3YLCncfH3cKCngeHngKCXkeHnkJCXodHXoJCXscHHsJCHwcHHwICH0bG30IB38aGn8HB4ABGRmA"
7907 "AQcHgQEYGIEBBwaEARYWhAEGBoUBFRWFAQYFiAETE4gBBQWKARERigEFBYwBDw+MAQUEkAEMDJAB"
7908 "BASTAQkJkwEEBJwBnAEEA50BnQEDA50BnQEDA50BnQEDA50BnQEDAp4BngECAp4BngECAp4BngEC"
7909 "Ap4BngECAp4BngECAZ8BnwEBAZ8BnwEBAZ8BnwEBAZ8BnwEBAZ8BnwEBAZ8BnwEBAZ8BnwGhAaAB"
7910 "oAGgAaABoAGgAaABoAGgAaABoAGgAaABoAGgAaABoAGgAaABoAGgAaABoAGgAaABoAGgAaABoAGg"
7911 "AaABoAGgAaABoAGgAaABoAGhAZ8BoQGfAZ8BAQGfAZ8BAQGfAZ8BAQGfAZ8BAQGfAZ8BAQKeAZ8B"
7912 "AQKeAZ4BAgKeAZ4BAgKeAZ4BAgOdAZ4BAgOdAZ4BAgOdAZ0BAwScAZ0BAwScAZ0BAwScAZ0BAwSc"
7913 "AZwBBAWbAZwBBAWbAZwBBAWbAZsBBQaaAZsBBQaaAZoBBgeZAZoBBgeZAZoBBgeZAZkBBwiYAZkB"
7914 "BwiYAZgBCAmXAZgBCAmXAZgBCAmXAZcBCQqWAZcBCQqWAZYBCguVAZYBCguVAZUBCwyUAZUBCw2T"
7915 "AZQBDA2TAZQBDA6SAZMBDQ6SAZMBDQ+RAZIBDg+RAZIBDhCQAZEBDxCQAZABEBGPAZABEBKOAY8B"
7916 "ERONAY4BEhONAY4BEhSMAY0BExWLAYwBFBWLAYwBFBaKAYsBFReJAYoBFheJAYoBFhiIAYkBFxmH"
7917 "AYgBGBqGAYcBGRuFAYYBGhuFAYUBGxyEAYUBGx2DAYQBHB6CAYMBHR+BAYIBHiCAAYEBHyF/gAEg"
7918 "In5/ISJ+fiIjfX0jJHx8JCV7eyUmenomJ3l5Jyh4eCgpd3cpK3V2Kix0dSstc3QsLnJzLS9xci4w"
7919 "cHAwMm5vMTNtbjI0bG0zNWtrNTdpajY4aGk3OmZnOTtlZjo8ZGQ8PmJjPT9hYj5BX2BAQl5eQkRc"
7920 "XUNGWltFR1lZR0lXWEhLVVZKTVNUTE9RUk5RT1BQUk5OUlRMTFRWSkpWWUdIWFtFRVteQkNdYEBA"
7921 "YGI+PmJlOztlaDg4aGs1NWtuMjJuci4vcXUrK3V6JiZ6fiIifoMBHR2DAYsBFRWLAZUBCwuVAQAA");
7922 ok(match, "Figure does not match.\n");
7924 hr = ID2D1Factory_CreatePathGeometry(factory, &geometry);
7925 ok(SUCCEEDED(hr), "Failed to create path geometry, hr %#x.\n", hr);
7926 hr = ID2D1PathGeometry_Open(geometry, &sink);
7927 ok(SUCCEEDED(hr), "Failed to open geometry sink, hr %#x.\n", hr);
7929 set_point(&point, 240.0f, 720.0f);
7930 ID2D1GeometrySink_BeginFigure(sink, point, D2D1_FIGURE_BEGIN_FILLED);
7931 cubic_to(sink, 152.0f, 720.0f, 80.0f, 613.0f, 80.0f, 480.0f);
7932 cubic_to(sink, 80.0f, 347.0f, 152.0f, 240.0f, 240.0f, 240.0f);
7933 cubic_to(sink, 152.0f, 339.0f, 134.0f, 528.0f, 200.0f, 660.0f);
7934 cubic_to(sink, 212.0f, 683.0f, 225.0f, 703.0f, 240.0f, 720.0f);
7935 ID2D1GeometrySink_EndFigure(sink, D2D1_FIGURE_END_CLOSED);
7937 hr = ID2D1GeometrySink_Close(sink);
7938 ok(SUCCEEDED(hr), "Failed to close geometry sink, hr %#x.\n", hr);
7939 ID2D1GeometrySink_Release(sink);
7941 ID2D1RenderTarget_BeginDraw(rt);
7942 ID2D1RenderTarget_Clear(rt, &color);
7943 ID2D1RenderTarget_FillGeometry(rt, (ID2D1Geometry *)geometry, (ID2D1Brush *)brush, NULL);
7944 hr = ID2D1RenderTarget_EndDraw(rt, NULL, NULL);
7945 ok(SUCCEEDED(hr), "Failed to end draw, hr %#x.\n", hr);
7946 ID2D1PathGeometry_Release(geometry);
7948 match = compare_figure(&ctx, 160, 120, 320, 240, 0xff652e89, 2048,
7949 "pQIZkgIrhAI5/QE/9gFH7wFO6wFS5wFW4gFb3gFf2wFi2AFl1gFn1AFp0gFszwFuzQFxywFyyQF1"
7950 "xwF2xgF4xAF5xAF6wgF8wAF+vwF+vwF/vQGBAbwBggG7AYMBugGEAbkBhQG4AYYBtwGHAbcBiAG1"
7951 "AYkBtAGKAbQBigGzAYsBswGMAbEBjQGxAY0BsQGOAa8BjwGvAZABrgGQAa4BkQGtAZEBrQGSAawB"
7952 "kgGsAZMBqwGTAasBlAGrAZQBqgGVAakBlQGqAZUBqQGWAagBlwGoAZYBqAGXAagBlwGnAZgBpwGY"
7953 "AaYBmQGmAZkBpgGZAaUBmgGlAZoBpQGaAaUBmgGkAZsBpAGbAaQBmwGkAZsBpAGcAaMBnAGjAZwB"
7954 "owGcAaMBnAGjAZ0BogGdAaIBnQGiAZ4BoQGeAaEBngGiAZ4BoQGeAaEBnwGgAZ8BoQGeAaEBnwGh"
7955 "AZ4BoQGfAaABnwGhAZ8BoAGgAaABnwGgAaABoAGfAaABoAGgAaABnwGgAaABoAGgAaABnwGgAaAB"
7956 "oAGgAaABnwGhAZ8BoQGfAaABoAGgAaABoAGfAaEBnwGhAZ8BoQGfAaEBnwGhAZ8BoQGfAaABoAGg"
7957 "AaABoAGgAaEBnwGhAZ8BoQGfAaEBnwGhAaABoAGgAaABoAGgAaABoAGgAaEBoAGgAaABoAGgAaAB"
7958 "oQGgAaABoAGgAaABoQGfAaEBoAGhAZ8BoQGfAaIBnwGhAZ8BogGfAaEBnwGiAZ8BogGeAaIBnwGi"
7959 "AZ4BogGfAaIBngGjAZ4BowGdAaMBngGjAZ4BowGdAaQBnQGkAZ0BpAGcAaUBnAGlAZwBpQGcAaUB"
7960 "mwGmAZsBpgGbAaYBmwGmAZsBpgGbAacBmgGnAZkBqAGZAagBmQGpAZgBqQGZAagBmQGpAZgBqQGY"
7961 "AaoBlwGqAZcBqwGWAasBlgGsAZUBrQGVAawBlQGtAZQBrgGUAa0BlAGuAZMBrwGTAa8BkgGwAZEB"
7962 "sQGRAbEBkAGyAZABsgGPAbMBjwG0AY4BtAGNAbUBjQG2AYwBtgGLAbgBigG4AYoBuQGJAboBhwG7"
7963 "AYcBvAGGAb0BhQG+AYQBvwGDAcABggHBAYIBwgGAAcMBf8QBfsYBfMgBe8gBesoBeMwBd80BddAB"
7964 "c9EBcdQBb9YBbNkBatsBaN0BZeEBYuQBX+gBW+0BVvEBUvUBTvwBR4QCQIoCOZgCK6oCGQIA");
7965 ok(match, "Figure does not match.\n");
7967 ID2D1SolidColorBrush_Release(brush);
7968 ID2D1Factory_Release(factory);
7969 release_test_context(&ctx);
7972 static void test_create_device(BOOL d3d11)
7974 D2D1_CREATION_PROPERTIES properties = {0};
7975 struct d2d1_test_context ctx;
7976 ID2D1Factory1 *factory;
7977 ID2D1Factory *factory2;
7978 ID2D1Device *device;
7979 ULONG refcount;
7980 HRESULT hr;
7982 if (!init_test_context(&ctx, d3d11))
7983 return;
7985 if (FAILED(D2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED, &IID_ID2D1Factory1, NULL, (void **)&factory)))
7987 win_skip("ID2D1Factory1 is not supported.\n");
7988 release_test_context(&ctx);
7989 return;
7992 hr = ID2D1Factory1_CreateDevice(factory, ctx.device, &device);
7993 ok(SUCCEEDED(hr), "Failed to get ID2D1Device, hr %#x.\n", hr);
7995 ID2D1Device_GetFactory(device, &factory2);
7996 ok(factory2 == (ID2D1Factory *)factory, "Got unexpected factory %p, expected %p.\n", factory2, factory);
7997 ID2D1Factory_Release(factory2);
7998 ID2D1Device_Release(device);
8000 if (pD2D1CreateDevice)
8002 hr = pD2D1CreateDevice(ctx.device, NULL, &device);
8003 ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
8004 ID2D1Device_Release(device);
8006 hr = pD2D1CreateDevice(ctx.device, &properties, &device);
8007 ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
8008 ID2D1Device_Release(device);
8010 else
8011 win_skip("D2D1CreateDevice() is unavailable.\n");
8013 release_test_context(&ctx);
8015 refcount = ID2D1Factory1_Release(factory);
8016 ok(!refcount, "Factory has %u references left.\n", refcount);
8019 #define check_rt_bitmap_surface(r, s, o) check_rt_bitmap_surface_(__LINE__, r, s, o)
8020 static void check_rt_bitmap_surface_(unsigned int line, ID2D1RenderTarget *rt, BOOL has_surface, DWORD options)
8022 ID2D1BitmapRenderTarget *compatible_rt;
8023 D2D1_BITMAP_PROPERTIES bitmap_desc;
8024 IWICImagingFactory *wic_factory;
8025 ID2D1Bitmap *bitmap, *bitmap2;
8026 ID2D1DeviceContext *context;
8027 ID2D1DCRenderTarget *dc_rt;
8028 IWICBitmap *wic_bitmap;
8029 ID2D1Image *target;
8030 D2D1_SIZE_U size;
8031 HRESULT hr;
8033 static const DWORD bitmap_data[] =
8035 0x7f7f0000,
8038 /* Raw data bitmap. */
8039 set_size_u(&size, 1, 1);
8040 bitmap_desc.pixelFormat.format = DXGI_FORMAT_B8G8R8A8_UNORM;
8041 bitmap_desc.pixelFormat.alphaMode = D2D1_ALPHA_MODE_IGNORE;
8042 bitmap_desc.dpiX = 96.0f;
8043 bitmap_desc.dpiY = 96.0f;
8044 hr = ID2D1RenderTarget_CreateBitmap(rt, size, bitmap_data, sizeof(*bitmap_data), &bitmap_desc, &bitmap);
8045 ok_(__FILE__, line)(SUCCEEDED(hr), "Failed to create bitmap, hr %#x.\n", hr);
8047 check_bitmap_surface_(line, bitmap, has_surface, options);
8049 ID2D1Bitmap_Release(bitmap);
8051 /* Zero sized bitmaps. */
8052 set_size_u(&size, 0, 0);
8053 hr = ID2D1RenderTarget_CreateBitmap(rt, size, NULL, 0, &bitmap_desc, &bitmap);
8054 ok_(__FILE__, line)(SUCCEEDED(hr), "Failed to create bitmap, hr %#x.\n", hr);
8055 check_bitmap_surface_(line, bitmap, has_surface, options);
8056 ID2D1Bitmap_Release(bitmap);
8058 set_size_u(&size, 2, 0);
8059 hr = ID2D1RenderTarget_CreateBitmap(rt, size, NULL, 0, &bitmap_desc, &bitmap);
8060 ok_(__FILE__, line)(SUCCEEDED(hr), "Failed to create bitmap, hr %#x.\n", hr);
8061 check_bitmap_surface_(line, bitmap, has_surface, options);
8062 ID2D1Bitmap_Release(bitmap);
8064 set_size_u(&size, 0, 2);
8065 hr = ID2D1RenderTarget_CreateBitmap(rt, size, NULL, 0, &bitmap_desc, &bitmap);
8066 ok_(__FILE__, line)(SUCCEEDED(hr), "Failed to create bitmap, hr %#x.\n", hr);
8067 check_bitmap_surface_(line, bitmap, has_surface, options);
8068 ID2D1Bitmap_Release(bitmap);
8070 /* WIC bitmap. */
8071 CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
8073 hr = CoCreateInstance(&CLSID_WICImagingFactory, NULL, CLSCTX_INPROC_SERVER,
8074 &IID_IWICImagingFactory, (void **)&wic_factory);
8075 ok_(__FILE__, line)(SUCCEEDED(hr), "Failed to create WIC imaging factory, hr %#x.\n", hr);
8077 hr = IWICImagingFactory_CreateBitmap(wic_factory, 16, 16,
8078 &GUID_WICPixelFormat32bppPBGRA, WICBitmapCacheOnDemand, &wic_bitmap);
8079 ok_(__FILE__, line)(SUCCEEDED(hr), "Failed to create WIC bitmap, hr %#x.\n", hr);
8080 IWICImagingFactory_Release(wic_factory);
8082 hr = ID2D1RenderTarget_CreateBitmapFromWicBitmap(rt, (IWICBitmapSource *)wic_bitmap, NULL, &bitmap);
8083 ok_(__FILE__, line)(SUCCEEDED(hr), "Failed to create bitmap from WIC source, hr %#x.\n", hr);
8085 check_bitmap_surface_(line, bitmap, has_surface, options);
8087 ID2D1Bitmap_Release(bitmap);
8089 CoUninitialize();
8091 /* Compatible target follows its parent. */
8092 hr = ID2D1RenderTarget_QueryInterface(rt, &IID_ID2D1DeviceContext, (void **)&context);
8093 ok_(__FILE__, line)(SUCCEEDED(hr), "Failed to get device context, hr %#x.\n", hr);
8095 dc_rt = NULL;
8096 ID2D1RenderTarget_QueryInterface(rt, &IID_ID2D1DCRenderTarget, (void **)&dc_rt);
8098 bitmap = NULL;
8099 target = NULL;
8100 ID2D1DeviceContext_GetTarget(context, &target);
8101 if (target && FAILED(ID2D1Image_QueryInterface(target, &IID_ID2D1Bitmap, (void **)&bitmap)))
8103 ID2D1Image_Release(target);
8104 target = NULL;
8106 if (bitmap)
8108 D2D1_PIXEL_FORMAT rt_format, bitmap_format;
8110 rt_format = ID2D1RenderTarget_GetPixelFormat(rt);
8111 bitmap_format = ID2D1Bitmap_GetPixelFormat(bitmap);
8112 ok_(__FILE__, line)(!memcmp(&rt_format, &bitmap_format, sizeof(rt_format)), "Unexpected bitmap format.\n");
8114 ID2D1Bitmap_Release(bitmap);
8117 /* Pixel format is not defined until target is set, for DC target it's specified on creation. */
8118 if (target || dc_rt)
8120 ID2D1Device *device, *device2;
8121 ID2D1DeviceContext *context2;
8123 ID2D1DeviceContext_GetDevice(context, &device);
8125 hr = ID2D1RenderTarget_CreateCompatibleRenderTarget(rt, NULL, NULL, NULL,
8126 D2D1_COMPATIBLE_RENDER_TARGET_OPTIONS_NONE, &compatible_rt);
8127 ok_(__FILE__, line)(SUCCEEDED(hr), "Failed to create compatible render target, hr %#x.\n", hr);
8129 hr = ID2D1BitmapRenderTarget_QueryInterface(compatible_rt, &IID_ID2D1DeviceContext, (void **)&context2);
8130 ok_(__FILE__, line)(SUCCEEDED(hr), "Failed to get device context, hr %#x.\n", hr);
8132 ID2D1DeviceContext_GetDevice(context2, &device2);
8133 ok_(__FILE__, line)(device == device2, "Unexpected device.\n");
8135 ID2D1Device_Release(device);
8136 ID2D1Device_Release(device2);
8138 hr = ID2D1BitmapRenderTarget_CreateBitmap(compatible_rt, size,
8139 bitmap_data, sizeof(*bitmap_data), &bitmap_desc, &bitmap);
8140 ok_(__FILE__, line)(SUCCEEDED(hr), "Failed to create bitmap, hr %#x.\n", hr);
8141 check_bitmap_surface_(line, bitmap, has_surface, options);
8142 ID2D1Bitmap_Release(bitmap);
8144 hr = ID2D1BitmapRenderTarget_GetBitmap(compatible_rt, &bitmap);
8145 ok_(__FILE__, line)(SUCCEEDED(hr), "Failed to get compatible target bitmap, hr %#x.\n", hr);
8147 bitmap2 = NULL;
8148 ID2D1DeviceContext_GetTarget(context2, (ID2D1Image **)&bitmap2);
8149 ok_(__FILE__, line)(bitmap2 == bitmap, "Unexpected bitmap.\n");
8151 check_bitmap_surface_(line, bitmap, has_surface, D2D1_BITMAP_OPTIONS_TARGET);
8152 ID2D1Bitmap_Release(bitmap2);
8153 ID2D1Bitmap_Release(bitmap);
8155 ID2D1BitmapRenderTarget_Release(compatible_rt);
8156 ID2D1DeviceContext_Release(context2);
8158 else
8160 hr = ID2D1RenderTarget_CreateCompatibleRenderTarget(rt, NULL, NULL, NULL,
8161 D2D1_COMPATIBLE_RENDER_TARGET_OPTIONS_NONE, &compatible_rt);
8162 ok_(__FILE__, line)(hr == WINCODEC_ERR_UNSUPPORTEDPIXELFORMAT, "Unexpected hr %#x.\n", hr);
8165 ID2D1DeviceContext_Release(context);
8166 if (target)
8167 ID2D1Image_Release(target);
8168 if (dc_rt)
8169 ID2D1DCRenderTarget_Release(dc_rt);
8172 static IDXGISurface *create_surface(IDXGIDevice *dxgi_device, DXGI_FORMAT format)
8174 D3D10_TEXTURE2D_DESC texture_desc;
8175 ID3D10Texture2D *texture;
8176 ID3D10Device *d3d_device;
8177 IDXGISurface *surface;
8178 HRESULT hr;
8180 texture_desc.Width = 1;
8181 texture_desc.Height = 1;
8182 texture_desc.MipLevels = 1;
8183 texture_desc.ArraySize = 1;
8184 texture_desc.Format = format;
8185 texture_desc.SampleDesc.Count = 1;
8186 texture_desc.SampleDesc.Quality = 0;
8187 texture_desc.Usage = D3D10_USAGE_DEFAULT;
8188 texture_desc.BindFlags = D3D10_BIND_SHADER_RESOURCE;
8189 texture_desc.CPUAccessFlags = 0;
8190 texture_desc.MiscFlags = 0;
8192 hr = IDXGIDevice_QueryInterface(dxgi_device, &IID_ID3D10Device, (void **)&d3d_device);
8193 ok(SUCCEEDED(hr), "Failed to get device interface, hr %#x.\n", hr);
8195 hr = ID3D10Device_CreateTexture2D(d3d_device, &texture_desc, NULL, &texture);
8196 ok(SUCCEEDED(hr), "Failed to create a texture, hr %#x.\n", hr);
8198 hr = ID3D10Texture2D_QueryInterface(texture, &IID_IDXGISurface, (void **)&surface);
8199 ok(SUCCEEDED(hr), "Failed to get surface interface, hr %#x.\n", hr);
8201 ID3D10Device_Release(d3d_device);
8202 ID3D10Texture2D_Release(texture);
8204 return surface;
8207 static void test_bitmap_surface(BOOL d3d11)
8209 static const struct bitmap_format_test
8211 D2D1_PIXEL_FORMAT original;
8212 D2D1_PIXEL_FORMAT result;
8213 HRESULT hr;
8215 bitmap_format_tests[] =
8217 { { DXGI_FORMAT_UNKNOWN, D2D1_ALPHA_MODE_PREMULTIPLIED },
8218 { DXGI_FORMAT_B8G8R8A8_UNORM, D2D1_ALPHA_MODE_PREMULTIPLIED } },
8220 { { DXGI_FORMAT_B8G8R8A8_UNORM, D2D1_ALPHA_MODE_STRAIGHT }, { 0 }, WINCODEC_ERR_UNSUPPORTEDPIXELFORMAT },
8222 { { DXGI_FORMAT_UNKNOWN, D2D1_ALPHA_MODE_IGNORE },
8223 { DXGI_FORMAT_B8G8R8A8_UNORM, D2D1_ALPHA_MODE_IGNORE } },
8225 { { DXGI_FORMAT_UNKNOWN, D2D1_ALPHA_MODE_UNKNOWN }, { 0 }, WINCODEC_ERR_UNSUPPORTEDPIXELFORMAT },
8227 { { DXGI_FORMAT_B8G8R8A8_UNORM, D2D1_ALPHA_MODE_UNKNOWN }, { 0 }, WINCODEC_ERR_UNSUPPORTEDPIXELFORMAT },
8229 { { DXGI_FORMAT_B8G8R8A8_UNORM, D2D1_ALPHA_MODE_IGNORE },
8230 { DXGI_FORMAT_B8G8R8A8_UNORM, D2D1_ALPHA_MODE_IGNORE } },
8232 { { DXGI_FORMAT_UNKNOWN, D2D1_ALPHA_MODE_STRAIGHT }, { 0 }, WINCODEC_ERR_UNSUPPORTEDPIXELFORMAT },
8234 D2D1_HWND_RENDER_TARGET_PROPERTIES hwnd_rt_desc;
8235 D2D1_RENDER_TARGET_PROPERTIES rt_desc;
8236 D2D1_BITMAP_PROPERTIES1 bitmap_desc;
8237 ID2D1DeviceContext *device_context;
8238 IDXGISurface *surface2;
8239 D2D1_PIXEL_FORMAT pixel_format;
8240 struct d2d1_test_context ctx;
8241 ID2D1Factory1 *factory;
8242 ID2D1RenderTarget *rt;
8243 ID2D1Bitmap1 *bitmap;
8244 ID2D1Device *device;
8245 ID2D1Image *target;
8246 D2D1_SIZE_U size;
8247 D2D1_TAG t1, t2;
8248 unsigned int i;
8249 HRESULT hr;
8251 IWICBitmap *wic_bitmap;
8252 IWICImagingFactory *wic_factory;
8254 if (!init_test_context(&ctx, d3d11))
8255 return;
8257 if (FAILED(D2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED, &IID_ID2D1Factory1, NULL, (void **)&factory)))
8259 win_skip("ID2D1Factory1 is not supported.\n");
8260 release_test_context(&ctx);
8261 return;
8264 /* DXGI target */
8265 hr = ID2D1RenderTarget_QueryInterface(ctx.rt, &IID_ID2D1DeviceContext, (void **)&device_context);
8266 ok(SUCCEEDED(hr), "Failed to get device context, hr %#x.\n", hr);
8268 bitmap = NULL;
8269 ID2D1DeviceContext_GetTarget(device_context, (ID2D1Image **)&bitmap);
8270 ok(!!bitmap, "Unexpected target.\n");
8271 check_bitmap_surface((ID2D1Bitmap *)bitmap, TRUE, D2D1_BITMAP_OPTIONS_TARGET | D2D1_BITMAP_OPTIONS_CANNOT_DRAW);
8272 ID2D1Bitmap1_Release(bitmap);
8274 check_rt_bitmap_surface(ctx.rt, TRUE, D2D1_BITMAP_OPTIONS_NONE);
8276 ID2D1DeviceContext_Release(device_context);
8278 /* Bitmap created from DXGI surface. */
8279 hr = ID2D1Factory1_CreateDevice(factory, ctx.device, &device);
8280 ok(SUCCEEDED(hr), "Failed to get ID2D1Device, hr %#x.\n", hr);
8282 hr = ID2D1Device_CreateDeviceContext(device, D2D1_DEVICE_CONTEXT_OPTIONS_NONE, &device_context);
8283 ok(SUCCEEDED(hr), "Failed to create device context, hr %#x.\n", hr);
8285 for (i = 0; i < ARRAY_SIZE(bitmap_format_tests); ++i)
8287 memset(&bitmap_desc, 0, sizeof(bitmap_desc));
8288 bitmap_desc.pixelFormat = bitmap_format_tests[i].original;
8289 bitmap_desc.bitmapOptions = D2D1_BITMAP_OPTIONS_TARGET | D2D1_BITMAP_OPTIONS_CANNOT_DRAW;
8291 hr = ID2D1DeviceContext_CreateBitmapFromDxgiSurface(device_context, ctx.surface, &bitmap_desc, &bitmap);
8292 todo_wine_if(bitmap_format_tests[i].hr == WINCODEC_ERR_UNSUPPORTEDPIXELFORMAT)
8293 ok(hr == bitmap_format_tests[i].hr, "%u: unexpected hr %#x.\n", i, hr);
8295 if (SUCCEEDED(bitmap_format_tests[i].hr))
8297 pixel_format = ID2D1Bitmap1_GetPixelFormat(bitmap);
8299 ok(pixel_format.format == bitmap_format_tests[i].result.format, "%u: unexpected pixel format %#x.\n",
8300 i, pixel_format.format);
8301 ok(pixel_format.alphaMode == bitmap_format_tests[i].result.alphaMode, "%u: unexpected alpha mode %d.\n",
8302 i, pixel_format.alphaMode);
8304 ID2D1Bitmap1_Release(bitmap);
8308 /* A8 surface */
8309 surface2 = create_surface(ctx.device, DXGI_FORMAT_A8_UNORM);
8311 hr = ID2D1DeviceContext_CreateBitmapFromDxgiSurface(device_context, surface2, NULL, &bitmap);
8312 ok(SUCCEEDED(hr) || broken(hr == WINCODEC_ERR_UNSUPPORTEDPIXELFORMAT) /* Win7 */,
8313 "Failed to create a bitmap, hr %#x.\n", hr);
8315 if (SUCCEEDED(hr))
8317 pixel_format = ID2D1Bitmap1_GetPixelFormat(bitmap);
8318 ok(pixel_format.alphaMode == D2D1_ALPHA_MODE_PREMULTIPLIED,
8319 "Unexpected alpha mode %#x.\n", pixel_format.alphaMode);
8321 ID2D1Bitmap1_Release(bitmap);
8324 IDXGISurface_Release(surface2);
8326 hr = ID2D1DeviceContext_CreateBitmapFromDxgiSurface(device_context, ctx.surface, NULL, &bitmap);
8327 ok(SUCCEEDED(hr), "Failed to create a bitmap, hr %#x.\n", hr);
8329 pixel_format = ID2D1Bitmap1_GetPixelFormat(bitmap);
8330 ok(pixel_format.alphaMode == D2D1_ALPHA_MODE_PREMULTIPLIED,
8331 "Unexpected alpha mode %#x.\n", pixel_format.alphaMode);
8333 check_bitmap_surface((ID2D1Bitmap *)bitmap, TRUE, D2D1_BITMAP_OPTIONS_TARGET | D2D1_BITMAP_OPTIONS_CANNOT_DRAW);
8334 check_rt_bitmap_surface((ID2D1RenderTarget *)device_context, TRUE, D2D1_BITMAP_OPTIONS_NONE);
8336 ID2D1DeviceContext_SetTarget(device_context, (ID2D1Image *)bitmap);
8337 ID2D1DeviceContext_GetTarget(device_context, &target);
8338 ok(target == (ID2D1Image *)bitmap, "Unexpected target.\n");
8340 check_rt_bitmap_surface((ID2D1RenderTarget *)device_context, TRUE, D2D1_BITMAP_OPTIONS_NONE);
8342 ID2D1Bitmap1_Release(bitmap);
8344 /* Without D2D1_BITMAP_OPTIONS_TARGET. */
8345 memset(&bitmap_desc, 0, sizeof(bitmap_desc));
8346 bitmap_desc.pixelFormat = ID2D1DeviceContext_GetPixelFormat(device_context);
8347 size.width = size.height = 4;
8348 hr = ID2D1DeviceContext_CreateBitmap(device_context, size, NULL, 0, &bitmap_desc, &bitmap);
8349 ok(SUCCEEDED(hr), "Failed to create a bitmap, hr %#x.\n", hr);
8350 check_bitmap_surface((ID2D1Bitmap *)bitmap, TRUE, D2D1_BITMAP_OPTIONS_NONE);
8351 ID2D1DeviceContext_SetTags(device_context, 1, 2);
8353 ID2D1DeviceContext_BeginDraw(device_context);
8354 ID2D1DeviceContext_SetTarget(device_context, (ID2D1Image *)bitmap);
8355 hr = ID2D1DeviceContext_EndDraw(device_context, &t1, &t2);
8356 ok(hr == D2DERR_INVALID_TARGET, "Unexpected hr %#x.\n", hr);
8357 ok(t1 == 1 && t2 == 2, "Unexpected tags %s:%s.\n", wine_dbgstr_longlong(t1), wine_dbgstr_longlong(t2));
8359 ID2D1Bitmap1_Release(bitmap);
8361 ID2D1DeviceContext_GetTarget(device_context, (ID2D1Image **)&bitmap);
8362 ok(!!bitmap, "Expected target bitmap.\n");
8363 ID2D1Bitmap1_Release(bitmap);
8365 bitmap_desc.bitmapOptions = D2D1_BITMAP_OPTIONS_TARGET;
8366 hr = ID2D1DeviceContext_CreateBitmap(device_context, size, NULL, 0, &bitmap_desc, &bitmap);
8367 ok(SUCCEEDED(hr), "Failed to create a bitmap, hr %#x.\n", hr);
8368 check_bitmap_surface((ID2D1Bitmap *)bitmap, TRUE, D2D1_BITMAP_OPTIONS_TARGET);
8369 ID2D1DeviceContext_SetTarget(device_context, NULL);
8370 ID2D1DeviceContext_SetTags(device_context, 3, 4);
8372 ID2D1DeviceContext_BeginDraw(device_context);
8373 ID2D1DeviceContext_SetTarget(device_context, (ID2D1Image *)bitmap);
8374 hr = ID2D1DeviceContext_EndDraw(device_context, &t1, &t2);
8375 ok(SUCCEEDED(hr), "Failed to end draw, hr %#x.\n", hr);
8376 ok(!t1 && !t2, "Unexpected tags %s:%s.\n", wine_dbgstr_longlong(t1), wine_dbgstr_longlong(t2));
8378 ID2D1Bitmap1_Release(bitmap);
8380 ID2D1DeviceContext_Release(device_context);
8382 ID2D1Device_Release(device);
8384 /* DC target */
8385 rt_desc.type = D2D1_RENDER_TARGET_TYPE_DEFAULT;
8386 rt_desc.pixelFormat.format = DXGI_FORMAT_B8G8R8A8_UNORM;
8387 rt_desc.pixelFormat.alphaMode = D2D1_ALPHA_MODE_PREMULTIPLIED;
8388 rt_desc.dpiX = 96.0f;
8389 rt_desc.dpiY = 96.0f;
8390 rt_desc.usage = D2D1_RENDER_TARGET_USAGE_NONE;
8391 rt_desc.minLevel = D2D1_FEATURE_LEVEL_DEFAULT;
8392 hr = ID2D1Factory1_CreateDCRenderTarget(factory, &rt_desc, (ID2D1DCRenderTarget **)&rt);
8393 ok(SUCCEEDED(hr), "Failed to create target, hr %#x.\n", hr);
8395 hr = ID2D1RenderTarget_QueryInterface(rt, &IID_ID2D1DeviceContext, (void **)&device_context);
8396 ok(SUCCEEDED(hr), "Failed to get device context, hr %#x.\n", hr);
8398 ID2D1DeviceContext_GetTarget(device_context, (ID2D1Image **)&bitmap);
8399 ok(!bitmap, "Unexpected target.\n");
8401 ID2D1DeviceContext_Release(device_context);
8402 ID2D1RenderTarget_Release(rt);
8404 /* HWND target */
8405 hwnd_rt_desc.hwnd = NULL;
8406 hwnd_rt_desc.pixelSize.width = 64;
8407 hwnd_rt_desc.pixelSize.height = 64;
8408 hwnd_rt_desc.presentOptions = D2D1_PRESENT_OPTIONS_NONE;
8409 hwnd_rt_desc.hwnd = CreateWindowA("static", "d2d_test", 0, 0, 0, 0, 0, 0, 0, 0, 0);
8410 ok(!!hwnd_rt_desc.hwnd, "Failed to create target window.\n");
8412 hr = ID2D1Factory1_CreateHwndRenderTarget(factory, &rt_desc, &hwnd_rt_desc, (ID2D1HwndRenderTarget **)&rt);
8413 ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr);
8415 check_rt_bitmap_surface(rt, FALSE, D2D1_BITMAP_OPTIONS_NONE);
8416 ID2D1RenderTarget_Release(rt);
8417 DestroyWindow(hwnd_rt_desc.hwnd);
8419 /* WIC target */
8420 CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
8422 hr = CoCreateInstance(&CLSID_WICImagingFactory, NULL, CLSCTX_INPROC_SERVER,
8423 &IID_IWICImagingFactory, (void **)&wic_factory);
8424 ok(SUCCEEDED(hr), "Failed to create WIC imaging factory, hr %#x.\n", hr);
8425 hr = IWICImagingFactory_CreateBitmap(wic_factory, 16, 16,
8426 &GUID_WICPixelFormat32bppPBGRA, WICBitmapCacheOnDemand, &wic_bitmap);
8427 ok(SUCCEEDED(hr), "Failed to create bitmap, hr %#x.\n", hr);
8428 IWICImagingFactory_Release(wic_factory);
8430 hr = ID2D1Factory1_CreateWicBitmapRenderTarget(factory, wic_bitmap, &rt_desc, &rt);
8431 ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr);
8433 check_rt_bitmap_surface(rt, FALSE, D2D1_BITMAP_OPTIONS_NONE);
8434 ID2D1RenderTarget_Release(rt);
8436 CoUninitialize();
8438 ID2D1Factory1_Release(factory);
8439 release_test_context(&ctx);
8442 static void test_device_context(BOOL d3d11)
8444 D2D1_HWND_RENDER_TARGET_PROPERTIES hwnd_rt_desc;
8445 D2D1_RENDER_TARGET_PROPERTIES rt_desc;
8446 ID2D1DeviceContext *device_context;
8447 IDXGISurface *surface, *surface2;
8448 ID2D1Device *device, *device2;
8449 struct d2d1_test_context ctx;
8450 D2D1_BITMAP_OPTIONS options;
8451 ID2D1DCRenderTarget *dc_rt;
8452 D2D1_UNIT_MODE unit_mode;
8453 ID2D1Factory1 *factory;
8454 ID2D1RenderTarget *rt;
8455 ID2D1Bitmap1 *bitmap;
8456 ID2D1Image *target;
8457 HRESULT hr;
8458 RECT rect;
8459 HDC hdc;
8461 IWICBitmap *wic_bitmap;
8462 IWICImagingFactory *wic_factory;
8464 if (!init_test_context(&ctx, d3d11))
8465 return;
8467 if (FAILED(D2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED, &IID_ID2D1Factory1, NULL, (void **)&factory)))
8469 win_skip("ID2D1Factory1 is not supported.\n");
8470 release_test_context(&ctx);
8471 return;
8474 hr = ID2D1Factory1_CreateDevice(factory, ctx.device, &device);
8475 ok(SUCCEEDED(hr), "Failed to get ID2D1Device, hr %#x.\n", hr);
8477 hr = ID2D1Device_CreateDeviceContext(device, D2D1_DEVICE_CONTEXT_OPTIONS_NONE, &device_context);
8478 ok(SUCCEEDED(hr), "Failed to create device context, hr %#x.\n", hr);
8480 ID2D1DeviceContext_GetDevice(device_context, &device2);
8481 ok(device2 == device, "Unexpected device instance.\n");
8482 ID2D1Device_Release(device2);
8484 target = (void *)0xdeadbeef;
8485 ID2D1DeviceContext_GetTarget(device_context, &target);
8486 ok(target == NULL, "Unexpected target instance %p.\n", target);
8488 unit_mode = ID2D1DeviceContext_GetUnitMode(device_context);
8489 ok(unit_mode == D2D1_UNIT_MODE_DIPS, "Unexpected unit mode %d.\n", unit_mode);
8491 ID2D1DeviceContext_Release(device_context);
8493 /* DXGI target */
8494 rt = ctx.rt;
8495 hr = ID2D1RenderTarget_QueryInterface(rt, &IID_ID2D1DeviceContext, (void **)&device_context);
8496 ok(SUCCEEDED(hr), "Failed to get device context interface, hr %#x.\n", hr);
8497 ID2D1DeviceContext_GetTarget(device_context, (ID2D1Image **)&bitmap);
8498 options = ID2D1Bitmap1_GetOptions(bitmap);
8499 ok(options == (D2D1_BITMAP_OPTIONS_TARGET | D2D1_BITMAP_OPTIONS_CANNOT_DRAW),
8500 "Unexpected bitmap options %#x.\n", options);
8501 hr = ID2D1Bitmap1_GetSurface(bitmap, &surface2);
8502 ok(SUCCEEDED(hr), "Failed to get bitmap surface, hr %#x.\n", hr);
8503 ok(surface2 == ctx.surface, "Unexpected surface instance.\n");
8504 IDXGISurface_Release(surface2);
8506 ID2D1DeviceContext_BeginDraw(device_context);
8507 hr = ID2D1Bitmap1_GetSurface(bitmap, &surface2);
8508 ok(SUCCEEDED(hr), "Failed to get bitmap surface, hr %#x.\n", hr);
8509 ok(surface2 == ctx.surface, "Unexpected surface instance.\n");
8510 IDXGISurface_Release(surface2);
8511 ID2D1DeviceContext_EndDraw(device_context, NULL, NULL);
8512 ID2D1Bitmap1_Release(bitmap);
8514 ID2D1DeviceContext_SetTarget(device_context, NULL);
8515 ID2D1DeviceContext_GetTarget(device_context, (ID2D1Image **)&bitmap);
8516 ok(bitmap == NULL, "Unexpected target instance.\n");
8518 ID2D1DeviceContext_Release(device_context);
8520 /* WIC target */
8521 CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
8523 hr = CoCreateInstance(&CLSID_WICImagingFactory, NULL, CLSCTX_INPROC_SERVER,
8524 &IID_IWICImagingFactory, (void **)&wic_factory);
8525 ok(SUCCEEDED(hr), "Failed to create WIC imaging factory, hr %#x.\n", hr);
8526 hr = IWICImagingFactory_CreateBitmap(wic_factory, 16, 16,
8527 &GUID_WICPixelFormat32bppPBGRA, WICBitmapCacheOnDemand, &wic_bitmap);
8528 ok(SUCCEEDED(hr), "Failed to create bitmap, hr %#x.\n", hr);
8529 IWICImagingFactory_Release(wic_factory);
8531 rt_desc.type = D2D1_RENDER_TARGET_TYPE_DEFAULT;
8532 rt_desc.pixelFormat.format = DXGI_FORMAT_B8G8R8A8_UNORM;
8533 rt_desc.pixelFormat.alphaMode = D2D1_ALPHA_MODE_PREMULTIPLIED;
8534 rt_desc.dpiX = 96.0f;
8535 rt_desc.dpiY = 96.0f;
8536 rt_desc.usage = D2D1_RENDER_TARGET_USAGE_NONE;
8537 rt_desc.minLevel = D2D1_FEATURE_LEVEL_DEFAULT;
8538 hr = ID2D1Factory1_CreateWicBitmapRenderTarget(factory, wic_bitmap, &rt_desc, &rt);
8539 ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr);
8541 hr = ID2D1RenderTarget_QueryInterface(rt, &IID_ID2D1DeviceContext, (void **)&device_context);
8542 ok(SUCCEEDED(hr), "Failed to get device context interface, hr %#x.\n", hr);
8543 ID2D1DeviceContext_GetTarget(device_context, (ID2D1Image **)&bitmap);
8544 options = ID2D1Bitmap1_GetOptions(bitmap);
8545 ok(options == (D2D1_BITMAP_OPTIONS_TARGET | D2D1_BITMAP_OPTIONS_CANNOT_DRAW),
8546 "Unexpected bitmap options %#x.\n", options);
8547 hr = ID2D1Bitmap1_GetSurface(bitmap, &surface);
8548 todo_wine
8549 ok(hr == E_FAIL, "Unexpected hr %#x.\n", hr);
8550 ID2D1Bitmap1_Release(bitmap);
8552 ID2D1DeviceContext_SetTarget(device_context, NULL);
8553 ID2D1DeviceContext_GetTarget(device_context, (ID2D1Image **)&bitmap);
8554 ok(bitmap == NULL, "Unexpected target instance.\n");
8556 ID2D1DeviceContext_Release(device_context);
8557 ID2D1RenderTarget_Release(rt);
8559 CoUninitialize();
8561 /* HWND target */
8562 hwnd_rt_desc.hwnd = NULL;
8563 hwnd_rt_desc.pixelSize.width = 64;
8564 hwnd_rt_desc.pixelSize.height = 64;
8565 hwnd_rt_desc.presentOptions = D2D1_PRESENT_OPTIONS_NONE;
8566 hwnd_rt_desc.hwnd = CreateWindowA("static", "d2d_test", 0, 0, 0, 0, 0, 0, 0, 0, 0);
8567 ok(!!hwnd_rt_desc.hwnd, "Failed to create target window.\n");
8569 hr = ID2D1Factory1_CreateHwndRenderTarget(factory, &rt_desc, &hwnd_rt_desc, (ID2D1HwndRenderTarget **)&rt);
8570 ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr);
8572 hr = ID2D1RenderTarget_QueryInterface(rt, &IID_ID2D1DeviceContext, (void **)&device_context);
8573 ok(SUCCEEDED(hr), "Failed to get device context interface, hr %#x.\n", hr);
8574 ID2D1DeviceContext_GetTarget(device_context, (ID2D1Image **)&bitmap);
8575 options = ID2D1Bitmap1_GetOptions(bitmap);
8576 ok(options == (D2D1_BITMAP_OPTIONS_TARGET | D2D1_BITMAP_OPTIONS_CANNOT_DRAW),
8577 "Unexpected bitmap options %#x.\n", options);
8578 hr = ID2D1Bitmap1_GetSurface(bitmap, &surface);
8579 ok(hr == D2DERR_INVALID_CALL, "Unexpected hr %#x.\n", hr);
8580 ID2D1Bitmap1_Release(bitmap);
8582 ID2D1DeviceContext_SetTarget(device_context, NULL);
8583 ID2D1DeviceContext_GetTarget(device_context, (ID2D1Image **)&bitmap);
8584 ok(bitmap == NULL, "Unexpected target instance.\n");
8586 ID2D1DeviceContext_Release(device_context);
8587 ID2D1RenderTarget_Release(rt);
8588 DestroyWindow(hwnd_rt_desc.hwnd);
8590 /* DC target */
8591 hr = ID2D1Factory1_CreateDCRenderTarget(factory, &rt_desc, &dc_rt);
8592 ok(SUCCEEDED(hr), "Failed to create target, hr %#x.\n", hr);
8594 hr = ID2D1DCRenderTarget_QueryInterface(dc_rt, &IID_ID2D1DeviceContext, (void **)&device_context);
8595 ok(SUCCEEDED(hr), "Failed to get device context interface, hr %#x.\n", hr);
8596 ID2D1DeviceContext_GetTarget(device_context, (ID2D1Image **)&bitmap);
8597 ok(bitmap == NULL, "Unexpected bitmap instance.\n");
8599 hdc = CreateCompatibleDC(NULL);
8600 ok(hdc != NULL, "Failed to create an HDC.\n");
8602 create_target_dibsection(hdc, 16, 16);
8604 SetRect(&rect, 0, 0, 16, 16);
8605 hr = ID2D1DCRenderTarget_BindDC(dc_rt, hdc, &rect);
8606 ok(SUCCEEDED(hr), "BindDC() failed, hr %#x.\n", hr);
8608 ID2D1DeviceContext_GetTarget(device_context, (ID2D1Image **)&bitmap);
8609 options = ID2D1Bitmap1_GetOptions(bitmap);
8610 ok(options == (D2D1_BITMAP_OPTIONS_TARGET | D2D1_BITMAP_OPTIONS_CANNOT_DRAW | D2D1_BITMAP_OPTIONS_GDI_COMPATIBLE),
8611 "Unexpected bitmap options %#x.\n", options);
8612 hr = ID2D1Bitmap1_GetSurface(bitmap, &surface);
8613 ok(hr == D2DERR_INVALID_CALL, "Unexpected hr %#x.\n", hr);
8614 ID2D1Bitmap1_Release(bitmap);
8616 ID2D1DeviceContext_SetTarget(device_context, NULL);
8617 ID2D1DeviceContext_GetTarget(device_context, (ID2D1Image **)&bitmap);
8618 ok(bitmap == NULL, "Unexpected target instance.\n");
8620 ID2D1DeviceContext_Release(device_context);
8621 ID2D1DCRenderTarget_Release(dc_rt);
8622 DeleteDC(hdc);
8624 ID2D1Device_Release(device);
8625 ID2D1Factory1_Release(factory);
8626 release_test_context(&ctx);
8629 static void test_invert_matrix(BOOL d3d11)
8631 static const struct
8633 D2D1_MATRIX_3X2_F matrix;
8634 D2D1_MATRIX_3X2_F inverse;
8635 BOOL invertible;
8637 invert_tests[] =
8639 { {{{ 0 }}}, {{{ 0 }}}, FALSE },
8642 1.0f, 2.0f,
8643 1.0f, 2.0f,
8644 4.0f, 8.0f
8645 }}},
8647 1.0f, 2.0f,
8648 1.0f, 2.0f,
8649 4.0f, 8.0f
8650 }}},
8651 FALSE
8655 2.0f, 0.0f,
8656 0.0f, 2.0f,
8657 4.0f, 8.0f
8658 }}},
8660 0.5f, -0.0f,
8661 -0.0f, 0.5f,
8662 -2.0f, -4.0f
8663 }}},
8664 TRUE
8668 2.0f, 1.0f,
8669 2.0f, 2.0f,
8670 4.0f, 8.0f
8671 }}},
8673 1.0f, -0.5f,
8674 -1.0f, 1.0f,
8675 4.0f, -6.0f
8676 }}},
8677 TRUE
8681 2.0f, 1.0f,
8682 3.0f, 1.0f,
8683 4.0f, 8.0f
8684 }}},
8686 -1.0f, 1.0f,
8687 3.0f, -2.0f,
8688 -20.0f, 12.0f
8689 }}},
8690 TRUE
8693 unsigned int i;
8695 for (i = 0; i < ARRAY_SIZE(invert_tests); ++i)
8697 D2D1_MATRIX_3X2_F m;
8698 BOOL ret;
8700 m = invert_tests[i].matrix;
8701 ret = D2D1InvertMatrix(&m);
8702 ok(ret == invert_tests[i].invertible, "%u: unexpected return value %d.\n", i, ret);
8703 ok(!memcmp(&m, &invert_tests[i].inverse, sizeof(m)),
8704 "%u: unexpected matrix value {%.8e, %.8e, %.8e, %.8e, %.8e, %.8e}.\n", i,
8705 m._11, m._12, m._21, m._22, m._31, m._32);
8707 ret = D2D1IsMatrixInvertible(&invert_tests[i].matrix);
8708 ok(ret == invert_tests[i].invertible, "%u: unexpected return value %d.\n", i, ret);
8712 static void test_skew_matrix(BOOL d3d11)
8714 static const struct
8716 float angle_x;
8717 float angle_y;
8718 D2D1_POINT_2F center;
8719 D2D1_MATRIX_3X2_F matrix;
8721 skew_tests[] =
8723 { 0.0f, 0.0f, { 0.0f, 0.0f }, {{{ 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f }}} },
8724 { 45.0f, 0.0f, { 0.0f, 0.0f }, {{{ 1.0f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f }}} },
8725 { 0.0f, 0.0f, { 10.0f, -3.0f }, {{{ 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f }}} },
8726 { -45.0f, 45.0f, { 0.1f, 0.5f }, {{{ 1.0f, 1.0f, -1.0f, 1.0f, 0.5f, -0.1f }}} },
8727 { -45.0f, 45.0f, { 1.0f, 2.0f }, {{{ 1.0f, 1.0f, -1.0f, 1.0f, 2.0f, -1.0f }}} },
8728 { 45.0f, -45.0f, { 1.0f, 2.0f }, {{{ 1.0f, -1.0f, 1.0f, 1.0f, -2.0f, 1.0f }}} },
8729 { 30.0f, -60.0f, { 12.0f, -5.0f }, {{{ 1.0f, -1.7320509f, 0.577350259f, 1.0f, 2.88675117f, 20.7846107f }}} },
8731 unsigned int i;
8733 for (i = 0; i < ARRAY_SIZE(skew_tests); ++i)
8735 const D2D1_MATRIX_3X2_F *expected = &skew_tests[i].matrix;
8736 D2D1_MATRIX_3X2_F m;
8737 BOOL ret;
8739 D2D1MakeSkewMatrix(skew_tests[i].angle_x, skew_tests[i].angle_y, skew_tests[i].center, &m);
8740 ret = compare_float(m._11, expected->_11, 3) && compare_float(m._12, expected->_12, 3)
8741 && compare_float(m._21, expected->_21, 3) && compare_float(m._22, expected->_22, 3)
8742 && compare_float(m._31, expected->_31, 3) && compare_float(m._32, expected->_32, 3);
8744 ok(ret, "%u: unexpected matrix value {%.8e, %.8e, %.8e, %.8e, %.8e, %.8e}, expected "
8745 "{%.8e, %.8e, %.8e, %.8e, %.8e, %.8e}.\n", i, m._11, m._12, m._21, m._22, m._31, m._32,
8746 expected->_11, expected->_12, expected->_21, expected->_22, expected->_31, expected->_32);
8750 static ID2D1DeviceContext *create_device_context(ID2D1Factory1 *factory, IDXGIDevice *dxgi_device, BOOL d3d11)
8752 ID2D1DeviceContext *device_context;
8753 ID2D1Device *device;
8754 HRESULT hr;
8756 hr = ID2D1Factory1_CreateDevice(factory, dxgi_device, &device);
8757 ok(SUCCEEDED(hr), "Failed to get ID2D1Device, hr %#x.\n", hr);
8759 hr = ID2D1Device_CreateDeviceContext(device, D2D1_DEVICE_CONTEXT_OPTIONS_NONE, &device_context);
8760 ok(SUCCEEDED(hr), "Failed to create device context, hr %#x.\n", hr);
8761 ID2D1Device_Release(device);
8763 return device_context;
8766 static void test_command_list(BOOL d3d11)
8768 static const DWORD bitmap_data[] =
8770 0xffff0000, 0xffffff00, 0xff00ff00, 0xff00ffff,
8772 static const D2D1_GRADIENT_STOP stops[] =
8774 {0.0f, {1.0f, 0.0f, 0.0f, 1.0f}},
8775 {0.5f, {0.0f, 1.0f, 0.0f, 1.0f}},
8776 {1.0f, {0.0f, 0.0f, 1.0f, 1.0f}},
8778 D2D1_RADIAL_GRADIENT_BRUSH_PROPERTIES radial_gradient_properties;
8779 D2D1_LINEAR_GRADIENT_BRUSH_PROPERTIES linear_gradient_properties;
8780 ID2D1DeviceContext *device_context, *device_context2;
8781 D2D1_STROKE_STYLE_PROPERTIES stroke_desc;
8782 ID2D1GradientStopCollection *gradient;
8783 D2D1_BITMAP_PROPERTIES bitmap_desc;
8784 ID2D1StrokeStyle *stroke_style;
8785 ID2D1CommandList *command_list;
8786 struct d2d1_test_context ctx;
8787 ID2D1Geometry *geometry;
8788 ID2D1Factory1 *factory;
8789 ID2D1RenderTarget *rt;
8790 D2D1_POINT_2F p0, p1;
8791 ID2D1Bitmap *bitmap;
8792 ID2D1Image *target;
8793 D2D1_COLOR_F color;
8794 ID2D1Brush *brush;
8795 D2D1_RECT_F rect;
8796 D2D_SIZE_U size;
8797 ULONG refcount;
8798 HRESULT hr;
8800 if (!init_test_context(&ctx, d3d11))
8801 return;
8803 if (FAILED(D2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED, &IID_ID2D1Factory1, NULL, (void **)&factory)))
8805 win_skip("ID2D1Factory1 is not supported.\n");
8806 release_test_context(&ctx);
8807 return;
8810 device_context = create_device_context(factory, ctx.device, d3d11);
8811 ok(device_context != NULL, "Failed to create device context.\n");
8813 hr = ID2D1DeviceContext_CreateCommandList(device_context, &command_list);
8814 todo_wine
8815 ok(SUCCEEDED(hr), "Failed to create command list, hr %#x.\n", hr);
8817 if (FAILED(hr))
8819 ID2D1DeviceContext_Release(device_context);
8820 ID2D1Factory1_Release(factory);
8821 return;
8824 ID2D1DeviceContext_SetTarget(device_context, (ID2D1Image *)command_list);
8825 ID2D1DeviceContext_BeginDraw(device_context);
8827 hr = ID2D1DeviceContext_QueryInterface(device_context, &IID_ID2D1RenderTarget, (void **)&rt);
8828 ok(SUCCEEDED(hr), "Failed to get rt interface, hr %#x.\n", hr);
8830 /* Test how resources are referenced by the list. */
8832 /* Bitmap. */
8833 set_size_u(&size, 4, 1);
8834 bitmap_desc.pixelFormat.format = DXGI_FORMAT_B8G8R8A8_UNORM;
8835 bitmap_desc.pixelFormat.alphaMode = D2D1_ALPHA_MODE_IGNORE;
8836 bitmap_desc.dpiX = 96.0f;
8837 bitmap_desc.dpiY = 96.0f;
8838 hr = ID2D1RenderTarget_CreateBitmap(rt, size, bitmap_data, 4 * sizeof(*bitmap_data), &bitmap_desc, &bitmap);
8839 ok(SUCCEEDED(hr), "Failed to create bitmap, hr %#x.\n", hr);
8841 ID2D1RenderTarget_DrawBitmap(rt, bitmap, NULL, 0.25f, D2D1_BITMAP_INTERPOLATION_MODE_NEAREST_NEIGHBOR, NULL);
8843 refcount = ID2D1Bitmap_Release(bitmap);
8844 ok(refcount == 1, "Got unexpected refcount %u.\n", refcount);
8846 /* Solid color brush. */
8847 set_color(&color, 0.0f, 0.0f, 0.0f, 0.0f);
8848 hr = ID2D1RenderTarget_CreateSolidColorBrush(rt, &color, NULL, (ID2D1SolidColorBrush **)&brush);
8849 ok(SUCCEEDED(hr), "Failed to create a brush, hr %#x.\n", hr);
8851 set_rect(&rect, 0.0f, 0.0f, 16.0f, 16.0f);
8852 ID2D1RenderTarget_FillRectangle(rt, &rect, brush);
8854 refcount = ID2D1Brush_Release(brush);
8855 ok(refcount == 0, "Got unexpected refcount %u.\n", refcount);
8857 /* Bitmap brush. */
8858 hr = ID2D1RenderTarget_CreateBitmap(rt, size, bitmap_data, 4 * sizeof(*bitmap_data), &bitmap_desc, &bitmap);
8859 ok(SUCCEEDED(hr), "Failed to create bitmap, hr %#x.\n", hr);
8861 hr = ID2D1RenderTarget_CreateBitmapBrush(rt, bitmap, NULL, NULL, (ID2D1BitmapBrush **)&brush);
8862 ok(SUCCEEDED(hr), "Failed to create bitmap brush, hr %#x.\n", hr);
8864 set_rect(&rect, 0.0f, 0.0f, 16.0f, 16.0f);
8865 ID2D1RenderTarget_FillRectangle(rt, &rect, brush);
8867 refcount = ID2D1Brush_Release(brush);
8868 ok(refcount == 0, "Got unexpected refcount %u.\n", refcount);
8870 refcount = ID2D1Bitmap_Release(bitmap);
8871 ok(refcount == 1, "Got unexpected refcount %u.\n", refcount);
8873 /* Linear gradient brush. */
8874 hr = ID2D1RenderTarget_CreateGradientStopCollection(rt, stops, ARRAY_SIZE(stops),
8875 D2D1_GAMMA_2_2, D2D1_EXTEND_MODE_CLAMP, &gradient);
8876 ok(SUCCEEDED(hr), "Failed to create stop collection, hr %#x.\n", hr);
8878 set_point(&linear_gradient_properties.startPoint, 320.0f, 0.0f);
8879 set_point(&linear_gradient_properties.endPoint, 0.0f, 960.0f);
8880 hr = ID2D1RenderTarget_CreateLinearGradientBrush(rt, &linear_gradient_properties, NULL, gradient,
8881 (ID2D1LinearGradientBrush **)&brush);
8882 ok(SUCCEEDED(hr), "Failed to create brush, hr %#x.\n", hr);
8884 set_rect(&rect, -1.0f, -1.0f, 1.0f, 1.0f);
8885 hr = ID2D1Factory1_CreateRectangleGeometry(factory, &rect, (ID2D1RectangleGeometry **)&geometry);
8886 ok(SUCCEEDED(hr), "Failed to create geometry, hr %#x.\n", hr);
8888 ID2D1RenderTarget_FillGeometry(rt, geometry, brush, NULL);
8890 refcount = ID2D1Brush_Release(brush);
8891 ok(refcount == 0, "Got unexpected refcount %u.\n", refcount);
8893 refcount = ID2D1Geometry_Release(geometry);
8894 ok(refcount == 1, "Got unexpected refcount %u.\n", refcount);
8896 refcount = ID2D1GradientStopCollection_Release(gradient);
8897 ok(refcount == 1, "Got unexpected refcount %u.\n", refcount);
8899 /* Radial gradient brush. */
8900 hr = ID2D1RenderTarget_CreateGradientStopCollection(rt, stops, ARRAY_SIZE(stops),
8901 D2D1_GAMMA_2_2, D2D1_EXTEND_MODE_CLAMP, &gradient);
8902 ok(SUCCEEDED(hr), "Failed to create stop collection, hr %#x.\n", hr);
8904 set_point(&radial_gradient_properties.center, 160.0f, 480.0f);
8905 set_point(&radial_gradient_properties.gradientOriginOffset, 40.0f, -120.0f);
8906 radial_gradient_properties.radiusX = 160.0f;
8907 radial_gradient_properties.radiusY = 480.0f;
8908 hr = ID2D1RenderTarget_CreateRadialGradientBrush(rt, &radial_gradient_properties, NULL, gradient,
8909 (ID2D1RadialGradientBrush **)&brush);
8910 ok(SUCCEEDED(hr), "Failed to create brush, hr %#x.\n", hr);
8912 set_rect(&rect, -1.0f, -1.0f, 1.0f, 1.0f);
8913 hr = ID2D1Factory1_CreateRectangleGeometry(factory, &rect, (ID2D1RectangleGeometry **)&geometry);
8914 ok(SUCCEEDED(hr), "Failed to create geometry, hr %#x.\n", hr);
8916 ID2D1RenderTarget_FillGeometry(rt, geometry, brush, NULL);
8918 refcount = ID2D1Brush_Release(brush);
8919 ok(refcount == 0, "Got unexpected refcount %u.\n", refcount);
8921 refcount = ID2D1Geometry_Release(geometry);
8922 ok(refcount == 1, "Got unexpected refcount %u.\n", refcount);
8924 refcount = ID2D1GradientStopCollection_Release(gradient);
8925 ok(refcount == 1, "Got unexpected refcount %u.\n", refcount);
8927 /* Geometry. */
8928 set_rect(&rect, -1.0f, -1.0f, 1.0f, 1.0f);
8929 hr = ID2D1Factory1_CreateRectangleGeometry(factory, &rect, (ID2D1RectangleGeometry **)&geometry);
8930 ok(SUCCEEDED(hr), "Failed to create geometry, hr %#x.\n", hr);
8932 set_color(&color, 0.0f, 0.0f, 0.0f, 0.0f);
8933 hr = ID2D1RenderTarget_CreateSolidColorBrush(rt, &color, NULL, (ID2D1SolidColorBrush **)&brush);
8934 ok(SUCCEEDED(hr), "Failed to create a brush, hr %#x.\n", hr);
8936 ID2D1RenderTarget_FillGeometry(rt, geometry, brush, NULL);
8938 refcount = ID2D1Brush_Release(brush);
8939 ok(refcount == 0, "Got unexpected refcount %u.\n", refcount);
8941 refcount = ID2D1Geometry_Release(geometry);
8942 ok(refcount == 1, "Got unexpected refcount %u.\n", refcount);
8944 /* Stroke style. */
8945 stroke_desc.startCap = D2D1_CAP_STYLE_SQUARE;
8946 stroke_desc.endCap = D2D1_CAP_STYLE_ROUND;
8947 stroke_desc.dashCap = D2D1_CAP_STYLE_TRIANGLE;
8948 stroke_desc.lineJoin = D2D1_LINE_JOIN_BEVEL;
8949 stroke_desc.miterLimit = 1.5f;
8950 stroke_desc.dashStyle = D2D1_DASH_STYLE_DOT;
8951 stroke_desc.dashOffset = -1.0f;
8953 hr = ID2D1Factory_CreateStrokeStyle((ID2D1Factory *)factory, &stroke_desc, NULL, 0, &stroke_style);
8954 ok(SUCCEEDED(hr), "Failed to create stroke style, %#x.\n", hr);
8956 set_color(&color, 0.0f, 0.0f, 0.0f, 0.0f);
8957 hr = ID2D1RenderTarget_CreateSolidColorBrush(rt, &color, NULL, (ID2D1SolidColorBrush **)&brush);
8958 ok(SUCCEEDED(hr), "Failed to create a brush, hr %#x.\n", hr);
8960 set_point(&p0, 100.0f, 160.0f);
8961 set_point(&p1, 140.0f, 160.0f);
8962 ID2D1RenderTarget_DrawLine(rt, p0, p1, brush, 1.0f, stroke_style);
8964 refcount = ID2D1Brush_Release(brush);
8965 ok(refcount == 0, "Got unexpected refcount %u.\n", refcount);
8967 refcount = ID2D1StrokeStyle_Release(stroke_style);
8968 ok(refcount == 1, "Got unexpected refcount %u.\n", refcount);
8970 /* Close on attached list. */
8971 ID2D1DeviceContext_GetTarget(device_context, &target);
8972 ok(target == (ID2D1Image *)command_list, "Unexpected context target.\n");
8973 ID2D1Image_Release(target);
8975 hr = ID2D1CommandList_Close(command_list);
8976 ok(SUCCEEDED(hr), "Failed to close a list, hr %#x.\n", hr);
8978 ID2D1DeviceContext_GetTarget(device_context, &target);
8979 ok(target == NULL, "Unexpected context target.\n");
8981 hr = ID2D1CommandList_Close(command_list);
8982 ok(hr == D2DERR_WRONG_STATE, "Unexpected hr %#x.\n", hr);
8984 ID2D1CommandList_Release(command_list);
8986 /* Close empty list. */
8987 hr = ID2D1DeviceContext_CreateCommandList(device_context, &command_list);
8988 ok(SUCCEEDED(hr), "Failed to create command list, hr %#x.\n", hr);
8990 hr = ID2D1CommandList_Close(command_list);
8991 ok(SUCCEEDED(hr), "Failed to close a list, hr %#x.\n", hr);
8993 ID2D1CommandList_Release(command_list);
8995 /* List created with different context. */
8996 device_context2 = create_device_context(factory, ctx.device, d3d11);
8997 ok(device_context2 != NULL, "Failed to create device context.\n");
8999 hr = ID2D1DeviceContext_CreateCommandList(device_context, &command_list);
9000 ok(SUCCEEDED(hr), "Failed to create command list, hr %#x.\n", hr);
9002 ID2D1DeviceContext_SetTarget(device_context2, (ID2D1Image *)command_list);
9003 ID2D1DeviceContext_GetTarget(device_context2, &target);
9004 ok(target == NULL, "Unexpected target.\n");
9006 ID2D1CommandList_Release(command_list);
9007 ID2D1DeviceContext_Release(device_context2);
9009 ID2D1RenderTarget_Release(rt);
9010 ID2D1DeviceContext_Release(device_context);
9011 ID2D1Factory1_Release(factory);
9012 release_test_context(&ctx);
9015 static void test_max_bitmap_size(BOOL d3d11)
9017 D2D1_RENDER_TARGET_PROPERTIES desc;
9018 D2D1_BITMAP_PROPERTIES bitmap_desc;
9019 IDXGISwapChain *swapchain;
9020 ID2D1Factory *factory;
9021 IDXGISurface *surface;
9022 ID2D1RenderTarget *rt;
9023 ID3D10Device1 *device;
9024 ID2D1Bitmap *bitmap;
9025 UINT32 bitmap_size;
9026 unsigned int i, j;
9027 HWND window;
9028 HRESULT hr;
9030 static const struct
9032 const char *name;
9033 DWORD type;
9035 device_types[] =
9037 { "HW", D3D10_DRIVER_TYPE_HARDWARE },
9038 { "WARP", D3D10_DRIVER_TYPE_WARP },
9039 { "REF", D3D10_DRIVER_TYPE_REFERENCE },
9041 static const struct
9043 const char *name;
9044 DWORD type;
9046 target_types[] =
9048 { "DEFAULT", D2D1_RENDER_TARGET_TYPE_DEFAULT },
9049 { "HW", D2D1_RENDER_TARGET_TYPE_HARDWARE },
9052 hr = D2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED, &IID_ID2D1Factory, NULL, (void **)&factory);
9053 ok(SUCCEEDED(hr), "Failed to create factory, hr %#x.\n", hr);
9055 for (i = 0; i < ARRAY_SIZE(device_types); ++i)
9057 if (FAILED(hr = D3D10CreateDevice1(NULL, device_types[i].type, NULL, D3D10_CREATE_DEVICE_BGRA_SUPPORT,
9058 D3D10_FEATURE_LEVEL_10_0, D3D10_1_SDK_VERSION, &device)))
9060 skip("Failed to create %s d3d device, hr %#x.\n", device_types[i].name, hr);
9061 continue;
9064 window = create_window();
9065 swapchain = create_d3d10_swapchain(device, window, TRUE);
9066 hr = IDXGISwapChain_GetBuffer(swapchain, 0, &IID_IDXGISurface, (void **)&surface);
9067 ok(SUCCEEDED(hr), "Failed to get buffer, hr %#x.\n", hr);
9069 for (j = 0; j < ARRAY_SIZE(target_types); ++j)
9071 D3D10_TEXTURE2D_DESC texture_desc;
9072 ID3D10Texture2D *texture;
9073 D2D1_SIZE_U size;
9075 desc.type = target_types[j].type;
9076 desc.pixelFormat.format = DXGI_FORMAT_UNKNOWN;
9077 desc.pixelFormat.alphaMode = D2D1_ALPHA_MODE_PREMULTIPLIED;
9078 desc.dpiX = 0.0f;
9079 desc.dpiY = 0.0f;
9080 desc.usage = D2D1_RENDER_TARGET_USAGE_NONE;
9081 desc.minLevel = D2D1_FEATURE_LEVEL_DEFAULT;
9083 hr = ID2D1Factory_CreateDxgiSurfaceRenderTarget(factory, surface, &desc, &rt);
9084 ok(SUCCEEDED(hr), "%s/%s: failed to create render target, hr %#x.\n", device_types[i].name,
9085 target_types[j].name, hr);
9087 bitmap_size = ID2D1RenderTarget_GetMaximumBitmapSize(rt);
9088 ok(bitmap_size >= D3D10_REQ_TEXTURE2D_U_OR_V_DIMENSION, "%s/%s: unexpected bitmap size %u.\n",
9089 device_types[i].name, target_types[j].name, bitmap_size);
9091 bitmap_desc.dpiX = 96.0f;
9092 bitmap_desc.dpiY = 96.0f;
9093 bitmap_desc.pixelFormat.format = DXGI_FORMAT_B8G8R8A8_UNORM;
9094 bitmap_desc.pixelFormat.alphaMode = D2D1_ALPHA_MODE_PREMULTIPLIED;
9096 size.width = bitmap_size;
9097 size.height = 1;
9098 hr = ID2D1RenderTarget_CreateBitmap(rt, size, NULL, 0, &bitmap_desc, &bitmap);
9099 ok(SUCCEEDED(hr), "Failed to create a bitmap, hr %#x.\n", hr);
9100 ID2D1Bitmap_Release(bitmap);
9102 ID2D1RenderTarget_Release(rt);
9104 texture_desc.Width = bitmap_size;
9105 texture_desc.Height = 1;
9106 texture_desc.MipLevels = 1;
9107 texture_desc.ArraySize = 1;
9108 texture_desc.Format = DXGI_FORMAT_B8G8R8A8_UNORM;
9109 texture_desc.SampleDesc.Count = 1;
9110 texture_desc.SampleDesc.Quality = 0;
9111 texture_desc.Usage = D3D10_USAGE_DEFAULT;
9112 texture_desc.BindFlags = 0;
9113 texture_desc.CPUAccessFlags = 0;
9114 texture_desc.MiscFlags = 0;
9116 hr = ID3D10Device1_CreateTexture2D(device, &texture_desc, NULL, &texture);
9117 ok(SUCCEEDED(hr) || broken(hr == E_INVALIDARG && device_types[i].type == D3D10_DRIVER_TYPE_WARP) /* Vista */,
9118 "%s/%s: failed to create texture, hr %#x.\n", device_types[i].name, target_types[j].name, hr);
9119 if (SUCCEEDED(hr))
9120 ID3D10Texture2D_Release(texture);
9123 IDXGISurface_Release(surface);
9124 IDXGISwapChain_Release(swapchain);
9125 DestroyWindow(window);
9127 ID3D10Device1_Release(device);
9130 ID2D1Factory_Release(factory);
9133 static void test_dpi(BOOL d3d11)
9135 D2D1_BITMAP_PROPERTIES1 bitmap_desc;
9136 ID2D1DeviceContext *device_context;
9137 IWICImagingFactory *wic_factory;
9138 struct d2d1_test_context ctx;
9139 ID2D1Factory1 *factory;
9140 ID2D1Bitmap1 *bitmap;
9141 float dpi_x, dpi_y;
9142 HRESULT hr;
9144 static const struct
9146 float dpi_x, dpi_y;
9147 HRESULT hr;
9149 create_dpi_tests[] =
9151 { 0.0f, 0.0f, S_OK},
9152 {192.0f, 0.0f, E_INVALIDARG},
9153 { 0.0f, 192.0f, E_INVALIDARG},
9154 {192.0f, -10.0f, E_INVALIDARG},
9155 {-10.0f, 192.0f, E_INVALIDARG},
9156 {-10.0f, -10.0f, E_INVALIDARG},
9157 { 48.0f, 96.0f, S_OK},
9158 { 96.0f, 48.0f, S_OK},
9160 static const float init_dpi_x = 60.0f, init_dpi_y = 288.0f;
9161 static const float dc_dpi_x = 120.0f, dc_dpi_y = 144.0f;
9162 unsigned int i;
9164 if (!init_test_context(&ctx, d3d11))
9165 return;
9167 if (FAILED(D2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED, &IID_ID2D1Factory1, NULL, (void **)&factory)))
9169 win_skip("ID2D1Factory1 is not supported.\n");
9170 release_test_context(&ctx);
9171 return;
9175 device_context = create_device_context(factory, ctx.device, d3d11);
9176 ok(!!device_context, "Failed to create device context.\n");
9178 ID2D1DeviceContext_GetDpi(device_context, &dpi_x, &dpi_y);
9179 ok(dpi_x == 96.0f, "Got unexpected dpi_x %.8e.\n", dpi_x);
9180 ok(dpi_y == 96.0f, "Got unexpected dpi_y %.8e.\n", dpi_y);
9182 /* DXGI surface */
9183 for (i = 0; i < ARRAY_SIZE(create_dpi_tests); ++i)
9185 ID2D1DeviceContext_SetDpi(device_context, init_dpi_x, init_dpi_y);
9187 bitmap_desc.pixelFormat.format = DXGI_FORMAT_UNKNOWN;
9188 bitmap_desc.pixelFormat.alphaMode = D2D1_ALPHA_MODE_PREMULTIPLIED;
9189 bitmap_desc.dpiX = create_dpi_tests[i].dpi_x;
9190 bitmap_desc.dpiY = create_dpi_tests[i].dpi_y;
9191 bitmap_desc.bitmapOptions = D2D1_BITMAP_OPTIONS_TARGET | D2D1_BITMAP_OPTIONS_CANNOT_DRAW;
9192 bitmap_desc.colorContext = NULL;
9193 hr = ID2D1DeviceContext_CreateBitmapFromDxgiSurface(device_context, ctx.surface, &bitmap_desc, &bitmap);
9194 /* Native accepts negative DPI values for DXGI surface bitmap. */
9195 ok(hr == S_OK, "Test %u: Got unexpected hr %#x.\n", i, hr);
9197 ID2D1DeviceContext_SetDpi(device_context, dc_dpi_x, dc_dpi_y);
9199 ID2D1Bitmap1_GetDpi(bitmap, &dpi_x, &dpi_y);
9200 todo_wine_if(bitmap_desc.dpiX == 0.0f)
9201 ok(dpi_x == bitmap_desc.dpiX, "Test %u: Got unexpected dpi_x %.8e, expected %.8e.\n",
9202 i, dpi_x, bitmap_desc.dpiX);
9203 todo_wine_if(bitmap_desc.dpiY == 0.0f)
9204 ok(dpi_y == bitmap_desc.dpiY, "Test %u: Got unexpected dpi_y %.8e, expected %.8e.\n",
9205 i, dpi_y, bitmap_desc.dpiY);
9207 ID2D1DeviceContext_BeginDraw(device_context);
9208 ID2D1DeviceContext_SetTarget(device_context, (ID2D1Image *)bitmap);
9209 hr = ID2D1DeviceContext_EndDraw(device_context, NULL, NULL);
9210 ok(hr == S_OK, "Test %u: Got unexpected hr %#x.\n", i, hr);
9212 /* Device context DPI values aren't updated by SetTarget. */
9213 ID2D1DeviceContext_GetDpi(device_context, &dpi_x, &dpi_y);
9214 ok(dpi_x == dc_dpi_x, "Test %u: Got unexpected dpi_x %.8e, expected %.8e.\n", i, dpi_x, dc_dpi_x);
9215 ok(dpi_y == dc_dpi_y, "Test %u: Got unexpected dpi_y %.8e, expected %.8e.\n", i, dpi_y, dc_dpi_y);
9217 ID2D1Bitmap1_Release(bitmap);
9220 /* WIC bitmap */
9221 CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
9222 hr = CoCreateInstance(&CLSID_WICImagingFactory, NULL, CLSCTX_INPROC_SERVER,
9223 &IID_IWICImagingFactory, (void **)&wic_factory);
9224 ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
9225 for (i = 0; i < ARRAY_SIZE(create_dpi_tests); ++i)
9227 IWICBitmapSource *wic_bitmap_src;
9228 IWICBitmap *wic_bitmap;
9230 ID2D1DeviceContext_SetDpi(device_context, init_dpi_x, init_dpi_y);
9232 hr = IWICImagingFactory_CreateBitmap(wic_factory, 16, 16,
9233 &GUID_WICPixelFormat32bppPBGRA, WICBitmapCacheOnDemand, &wic_bitmap);
9234 ok(hr == S_OK, "Test %u: Got unexpected hr %#x.\n", i, hr);
9235 hr = IWICBitmap_QueryInterface(wic_bitmap, &IID_IWICBitmapSource, (void **)&wic_bitmap_src);
9236 ok(hr == S_OK, "Test %u: Got unexpected hr %#x.\n", i, hr);
9237 IWICBitmap_Release(wic_bitmap);
9239 bitmap_desc.pixelFormat.format = DXGI_FORMAT_UNKNOWN;
9240 bitmap_desc.pixelFormat.alphaMode = D2D1_ALPHA_MODE_PREMULTIPLIED;
9241 bitmap_desc.dpiX = create_dpi_tests[i].dpi_x;
9242 bitmap_desc.dpiY = create_dpi_tests[i].dpi_y;
9243 bitmap_desc.bitmapOptions = D2D1_BITMAP_OPTIONS_TARGET | D2D1_BITMAP_OPTIONS_CANNOT_DRAW;
9244 bitmap_desc.colorContext = NULL;
9245 hr = ID2D1DeviceContext_CreateBitmapFromWicBitmap(device_context, wic_bitmap_src, &bitmap_desc, &bitmap);
9246 ok(hr == create_dpi_tests[i].hr, "Test %u: Got unexpected hr %#x, expected %#x.\n",
9247 i, hr, create_dpi_tests[i].hr);
9248 IWICBitmapSource_Release(wic_bitmap_src);
9250 if (FAILED(hr))
9251 continue;
9253 ID2D1DeviceContext_SetDpi(device_context, dc_dpi_x, dc_dpi_y);
9255 ID2D1Bitmap1_GetDpi(bitmap, &dpi_x, &dpi_y);
9256 if (bitmap_desc.dpiX == 0.0f && bitmap_desc.dpiY == 0.0f)
9258 /* Bitmap DPI values are inherited at creation time. */
9259 ok(dpi_x == init_dpi_x, "Test %u: Got unexpected dpi_x %.8e, expected %.8e.\n", i, dpi_x, init_dpi_x);
9260 ok(dpi_y == init_dpi_y, "Test %u: Got unexpected dpi_y %.8e, expected %.8e.\n", i, dpi_y, init_dpi_y);
9262 else
9264 ok(dpi_x == bitmap_desc.dpiX, "Test %u: Got unexpected dpi_x %.8e, expected %.8e.\n",
9265 i, dpi_x, bitmap_desc.dpiX);
9266 ok(dpi_y == bitmap_desc.dpiY, "Test %u: Got unexpected dpi_y %.8e, expected %.8e.\n",
9267 i, dpi_y, bitmap_desc.dpiY);
9270 ID2D1DeviceContext_BeginDraw(device_context);
9271 ID2D1DeviceContext_SetTarget(device_context, (ID2D1Image *)bitmap);
9272 hr = ID2D1DeviceContext_EndDraw(device_context, NULL, NULL);
9273 ok(hr == S_OK, "Test %u: Got unexpected hr %#x.\n", i, hr);
9275 /* Device context DPI values aren't updated by SetTarget. */
9276 ID2D1DeviceContext_GetDpi(device_context, &dpi_x, &dpi_y);
9277 ok(dpi_x == dc_dpi_x, "Test %u: Got unexpected dpi_x %.8e, expected %.8e.\n", i, dpi_x, dc_dpi_x);
9278 ok(dpi_y == dc_dpi_y, "Test %u: Got unexpected dpi_y %.8e, expected %.8e.\n", i, dpi_y, dc_dpi_y);
9280 ID2D1Bitmap1_Release(bitmap);
9282 IWICImagingFactory_Release(wic_factory);
9283 CoUninitialize();
9285 /* D2D bitmap */
9286 for (i = 0; i < ARRAY_SIZE(create_dpi_tests); ++i)
9288 const D2D1_SIZE_U size = {16, 16};
9290 ID2D1DeviceContext_SetDpi(device_context, init_dpi_x, init_dpi_y);
9292 bitmap_desc.pixelFormat.format = DXGI_FORMAT_B8G8R8A8_UNORM;
9293 bitmap_desc.pixelFormat.alphaMode = D2D1_ALPHA_MODE_PREMULTIPLIED;
9294 bitmap_desc.dpiX = create_dpi_tests[i].dpi_x;
9295 bitmap_desc.dpiY = create_dpi_tests[i].dpi_y;
9296 bitmap_desc.bitmapOptions = D2D1_BITMAP_OPTIONS_TARGET | D2D1_BITMAP_OPTIONS_CANNOT_DRAW;
9297 bitmap_desc.colorContext = NULL;
9298 hr = ID2D1DeviceContext_CreateBitmap(device_context, size, NULL, 0, &bitmap_desc, &bitmap);
9299 ok(hr == create_dpi_tests[i].hr, "Test %u: Got unexpected hr %#x, expected %#x.\n",
9300 i, hr, create_dpi_tests[i].hr);
9302 if (FAILED(hr))
9303 continue;
9305 ID2D1DeviceContext_SetDpi(device_context, dc_dpi_x, dc_dpi_y);
9307 ID2D1Bitmap1_GetDpi(bitmap, &dpi_x, &dpi_y);
9308 if (bitmap_desc.dpiX == 0.0f && bitmap_desc.dpiY == 0.0f)
9310 /* Bitmap DPI values are inherited at creation time. */
9311 ok(dpi_x == init_dpi_x, "Test %u: Got unexpected dpi_x %.8e, expected %.8e.\n", i, dpi_x, init_dpi_x);
9312 ok(dpi_y == init_dpi_y, "Test %u: Got unexpected dpi_y %.8e, expected %.8e.\n", i, dpi_y, init_dpi_y);
9314 else
9316 ok(dpi_x == bitmap_desc.dpiX, "Test %u: Got unexpected dpi_x %.8e, expected %.8e.\n",
9317 i, dpi_x, bitmap_desc.dpiX);
9318 ok(dpi_y == bitmap_desc.dpiY, "Test %u: Got unexpected dpi_y %.8e, expected %.8e.\n",
9319 i, dpi_y, bitmap_desc.dpiY);
9322 ID2D1DeviceContext_BeginDraw(device_context);
9323 ID2D1DeviceContext_SetTarget(device_context, (ID2D1Image *)bitmap);
9324 hr = ID2D1DeviceContext_EndDraw(device_context, NULL, NULL);
9325 ok(hr == S_OK, "Test %u: Got unexpected hr %#x.\n", i, hr);
9327 /* Device context DPI values aren't updated by SetTarget. */
9328 ID2D1DeviceContext_GetDpi(device_context, &dpi_x, &dpi_y);
9329 ok(dpi_x == dc_dpi_x, "Test %u: Got unexpected dpi_x %.8e, expected %.8e.\n", i, dpi_x, dc_dpi_x);
9330 ok(dpi_y == dc_dpi_y, "Test %u: Got unexpected dpi_y %.8e, expected %.8e.\n", i, dpi_y, dc_dpi_y);
9332 ID2D1Bitmap1_Release(bitmap);
9335 ID2D1DeviceContext_SetTarget(device_context, NULL);
9336 ID2D1DeviceContext_GetDpi(device_context, &dpi_x, &dpi_y);
9337 ok(dpi_x == dc_dpi_x, "Got unexpected dpi_x %.8e, expected %.8e.\n", dpi_x, dc_dpi_x);
9338 ok(dpi_y == dc_dpi_y, "Got unexpected dpi_y %.8e, expected %.8e.\n", dpi_y, dc_dpi_y);
9340 ID2D1DeviceContext_Release(device_context);
9341 ID2D1Factory1_Release(factory);
9342 release_test_context(&ctx);
9345 static void test_wic_bitmap_format(BOOL d3d11)
9347 IWICImagingFactory *wic_factory;
9348 struct d2d1_test_context ctx;
9349 D2D1_PIXEL_FORMAT format;
9350 IWICBitmap *wic_bitmap;
9351 ID2D1RenderTarget *rt;
9352 ID2D1Bitmap *bitmap;
9353 unsigned int i;
9354 HRESULT hr;
9356 static const struct
9358 const WICPixelFormatGUID *wic;
9359 D2D1_PIXEL_FORMAT d2d;
9361 tests[] =
9363 {&GUID_WICPixelFormat32bppPBGRA, {DXGI_FORMAT_B8G8R8A8_UNORM, D2D1_ALPHA_MODE_PREMULTIPLIED}},
9364 {&GUID_WICPixelFormat32bppPRGBA, {DXGI_FORMAT_R8G8B8A8_UNORM, D2D1_ALPHA_MODE_PREMULTIPLIED}},
9365 {&GUID_WICPixelFormat32bppBGR, {DXGI_FORMAT_B8G8R8A8_UNORM, D2D1_ALPHA_MODE_IGNORE}},
9368 if (!init_test_context(&ctx, d3d11))
9369 return;
9371 rt = ctx.rt;
9372 CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
9374 hr = CoCreateInstance(&CLSID_WICImagingFactory, NULL, CLSCTX_INPROC_SERVER,
9375 &IID_IWICImagingFactory, (void **)&wic_factory);
9376 ok(hr == S_OK, "Failed to create WIC imaging factory, hr %#x.\n", hr);
9378 for (i = 0; i < ARRAY_SIZE(tests); ++i)
9380 hr = IWICImagingFactory_CreateBitmap(wic_factory, 16, 16,
9381 tests[i].wic, WICBitmapCacheOnDemand, &wic_bitmap);
9382 ok(hr == S_OK, "%s: Failed to create WIC bitmap, hr %#x.\n", debugstr_guid(tests[i].wic), hr);
9384 hr = ID2D1RenderTarget_CreateBitmapFromWicBitmap(rt, (IWICBitmapSource *)wic_bitmap, NULL, &bitmap);
9385 ok(hr == S_OK, "%s: Failed to create bitmap from WIC source, hr %#x.\n", debugstr_guid(tests[i].wic), hr);
9387 format = ID2D1Bitmap_GetPixelFormat(bitmap);
9388 ok(format.format == tests[i].d2d.format, "%s: Got unexpected DXGI format %#x.\n",
9389 debugstr_guid(tests[i].wic), format.format);
9390 ok(format.alphaMode == tests[i].d2d.alphaMode, "%s: Got unexpected alpha mode %#x.\n",
9391 debugstr_guid(tests[i].wic), format.alphaMode);
9393 ID2D1Bitmap_Release(bitmap);
9394 IWICBitmap_Release(wic_bitmap);
9397 IWICImagingFactory_Release(wic_factory);
9398 CoUninitialize();
9399 release_test_context(&ctx);
9402 static void test_math(BOOL d3d11)
9404 float s, c, t, l;
9405 unsigned int i;
9407 static const struct
9409 float x;
9410 float s;
9411 float c;
9413 sc_data[] =
9415 {0.0f, 0.0f, 1.0f},
9416 {1.0f, 8.41470957e-001f, 5.40302277e-001f},
9417 {2.0f, 9.09297407e-001f, -4.16146845e-001f},
9418 {M_PI / 2.0f, 1.0f, -4.37113883e-008f},
9419 {M_PI, -8.74227766e-008f, -1.0f},
9422 static const struct
9424 float x;
9425 float t;
9427 t_data[] =
9429 {0.0f, 0.0f},
9430 {1.0f, 1.55740774f},
9431 {2.0f, -2.18503976f},
9432 {M_PI / 2.0f, -2.28773320e+007f},
9433 {M_PI, 8.74227766e-008f},
9436 static const struct
9438 float x;
9439 float y;
9440 float z;
9441 float l;
9443 l_data[] =
9445 {0.0f, 0.0f, 0.0f, 0.0f},
9446 {1.0f, 0.0f, 0.0f, 1.0f},
9447 {0.0f, 1.0f, 0.0f, 1.0f},
9448 {0.0f, 0.0f, 1.0f, 1.0f},
9449 {1.0f, 1.0f, 1.0f, 1.73205078f},
9450 {1.0f, 2.0f, 2.0f, 3.0f},
9451 {1.0f, 2.0f, 3.0f, 3.74165750f},
9454 if (!pD2D1SinCos || !pD2D1Tan || !pD2D1Vec3Length)
9456 win_skip("D2D1SinCos/D2D1Tan/D2D1Vec3Length not available, skipping test.\n");
9457 return;
9460 for (i = 0; i < ARRAY_SIZE(sc_data); ++i)
9462 pD2D1SinCos(sc_data[i].x, &s, &c);
9463 ok(compare_float(s, sc_data[i].s, 0),
9464 "Test %u: Got unexpected sin %.8e, expected %.8e.\n", i, s, sc_data[i].s);
9465 ok(compare_float(c, sc_data[i].c, 0),
9466 "Test %u: Got unexpected cos %.8e, expected %.8e.\n", i, c, sc_data[i].c);
9469 for (i = 0; i < ARRAY_SIZE(t_data); ++i)
9471 t = pD2D1Tan(t_data[i].x);
9472 ok(compare_float(t, t_data[i].t, 1),
9473 "Test %u: Got unexpected tan %.8e, expected %.8e.\n", i, t, t_data[i].t);
9476 for (i = 0; i < ARRAY_SIZE(l_data); ++i)
9478 l = pD2D1Vec3Length(l_data[i].x, l_data[i].y, l_data[i].z);
9479 ok(compare_float(l, l_data[i].l, 0),
9480 "Test %u: Got unexpected length %.8e, expected %.8e.\n", i, l, l_data[i].l);
9484 static void test_colour_space(BOOL d3d11)
9486 D2D1_COLOR_F src_colour, dst_colour, expected;
9487 D2D1_COLOR_SPACE src_space, dst_space;
9488 unsigned i, j, k;
9490 static const D2D1_COLOR_SPACE colour_spaces[] =
9492 D2D1_COLOR_SPACE_CUSTOM,
9493 D2D1_COLOR_SPACE_SRGB,
9494 D2D1_COLOR_SPACE_SCRGB,
9496 static struct
9498 D2D1_COLOR_F srgb;
9499 D2D1_COLOR_F scrgb;
9501 const test_data[] =
9503 {{0.0f, 0.0f, 0.0f, 0.0f}, {0.0f, 0.0f, 0.0f, 0.0f}},
9504 {{0.0f, 0.0f, 0.0f, 1.0f}, {0.0f, 0.0f, 0.0f, 1.0f}},
9505 {{1.0f, 1.0f, 1.0f, 1.0f}, {1.0f, 1.0f, 1.0f, 1.0f}},
9506 /* Samples in the non-linear region. */
9507 {{0.2f, 0.4f, 0.6f, 0.8f}, {0.0331047624f, 0.132868335f, 0.318546832f, 0.8f}},
9508 {{0.3f, 0.5f, 0.7f, 0.9f}, {0.0732389688f, 0.214041144f, 0.447988421f, 0.9f}},
9509 /* Samples in the linear region. */
9510 {{0.0002f, 0.0004f, 0.0006f, 0.0008f}, {1.54798763e-005f, 3.09597526e-005f, 4.64396289e-005f, 0.0008f}},
9511 {{0.0003f, 0.0005f, 0.0007f, 0.0009f}, {2.32198145e-005f, 3.86996908e-005f, 5.41795634e-005f, 0.0009f}},
9512 /* Out of range samples */
9513 {{-0.3f, 1.5f, -0.7f, 2.0f}, { 0.0f, 1.0f, 0.0f, 2.0f}},
9514 {{ 1.5f, -0.3f, 2.0f, -0.7f}, { 1.0f, 0.0f, 1.0f, -0.7f}},
9515 {{ 0.0f, 1.0f, 0.0f, 1.5f}, {-0.7f, 2.0f, -0.3f, 1.5f}},
9516 {{ 1.0f, 0.0f, 1.0f, -0.3f}, { 2.0f, -0.7f, 1.5f, -0.3f}},
9519 if (!pD2D1ConvertColorSpace)
9521 win_skip("D2D1ConvertColorSpace() not available, skipping test.\n");
9522 return;
9525 for (i = 0; i < ARRAY_SIZE(colour_spaces); ++i)
9527 src_space = colour_spaces[i];
9528 for (j = 0; j < ARRAY_SIZE(colour_spaces); ++j)
9530 dst_space = colour_spaces[j];
9531 for (k = 0; k < ARRAY_SIZE(test_data); ++k)
9533 if (src_space == D2D1_COLOR_SPACE_SCRGB)
9534 src_colour = test_data[k].scrgb;
9535 else
9536 src_colour = test_data[k].srgb;
9538 if (dst_space == D2D1_COLOR_SPACE_SCRGB)
9539 expected = test_data[k].scrgb;
9540 else
9541 expected = test_data[k].srgb;
9543 if (src_space == D2D1_COLOR_SPACE_CUSTOM || dst_space == D2D1_COLOR_SPACE_CUSTOM)
9545 set_color(&expected, 0.0f, 0.0f, 0.0f, 0.0f);
9547 else if (src_space != dst_space)
9549 expected.r = clamp_float(expected.r, 0.0f, 1.0f);
9550 expected.g = clamp_float(expected.g, 0.0f, 1.0f);
9551 expected.b = clamp_float(expected.b, 0.0f, 1.0f);
9554 dst_colour = pD2D1ConvertColorSpace(src_space, dst_space, &src_colour);
9555 ok(compare_colour_f(&dst_colour, expected.r, expected.g, expected.b, expected.a, 1),
9556 "Got unexpected destination colour {%.8e, %.8e, %.8e, %.8e}, "
9557 "expected destination colour {%.8e, %.8e, %.8e, %.8e} for "
9558 "source colour {%.8e, %.8e, %.8e, %.8e}, "
9559 "source colour space %#x, destination colour space %#x.\n",
9560 dst_colour.r, dst_colour.g, dst_colour.b, dst_colour.a,
9561 expected.r, expected.g, expected.b, expected.a,
9562 src_colour.r, src_colour.g, src_colour.b, src_colour.a,
9563 src_space, dst_space);
9569 static void test_geometry_group(BOOL d3d11)
9571 ID2D1Factory *factory;
9572 ID2D1GeometryGroup *group;
9573 ID2D1Geometry *geometries[2];
9574 D2D1_RECT_F rect;
9575 HRESULT hr;
9576 D2D1_MATRIX_3X2_F matrix;
9577 BOOL match;
9579 hr = D2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED, &IID_ID2D1Factory, NULL, (void **)&factory);
9580 ok(SUCCEEDED(hr), "Failed to create factory, hr %#x.\n", hr);
9582 set_rect(&rect, -1.0f, -1.0f, 1.0f, 1.0f);
9583 hr = ID2D1Factory_CreateRectangleGeometry(factory, &rect, (ID2D1RectangleGeometry **)&geometries[0]);
9584 ok(SUCCEEDED(hr), "Failed to create geometry, hr %#x.\n", hr);
9586 set_rect(&rect, -2.0f, -2.0f, 0.0f, 2.0f);
9587 hr = ID2D1Factory_CreateRectangleGeometry(factory, &rect, (ID2D1RectangleGeometry **)&geometries[1]);
9588 ok(SUCCEEDED(hr), "Failed to create geometry, hr %#x.\n", hr);
9590 hr = ID2D1Factory_CreateGeometryGroup(factory, D2D1_FILL_MODE_ALTERNATE, geometries, 2, &group);
9591 ok(SUCCEEDED(hr), "Failed to create geometry group, hr %#x.\n", hr);
9593 set_rect(&rect, 0.0f, 0.0f, 0.0f, 0.0f);
9594 hr = ID2D1GeometryGroup_GetBounds(group, NULL, &rect);
9595 ok(SUCCEEDED(hr), "Failed to get geometry group bounds, hr %#x.\n", hr);
9596 match = compare_rect(&rect, -2.0f, -2.0f, 1.0f, 2.0f, 0);
9597 ok(match, "Got unexpected rectangle {%.8e, %.8e, %.8e, %.8e}.\n",
9598 rect.left, rect.top, rect.right, rect.bottom);
9600 set_matrix_identity(&matrix);
9601 translate_matrix(&matrix, 80.0f, 640.0f);
9602 scale_matrix(&matrix, 2.0f, 0.5f);
9603 hr = ID2D1GeometryGroup_GetBounds(group, &matrix, &rect);
9604 ok(SUCCEEDED(hr), "Failed to get geometry group bounds, hr %#x.\n", hr);
9605 match = compare_rect(&rect, 76.0f, 639.0f, 82.0f, 641.0f, 0);
9606 ok(match, "Got unexpected rectangle {%.8e, %.8e, %.8e, %.8e}.\n",
9607 rect.left, rect.top, rect.right, rect.bottom);
9609 ID2D1GeometryGroup_Release(group);
9611 ID2D1Geometry_Release(geometries[0]);
9612 ID2D1Geometry_Release(geometries[1]);
9614 ID2D1Factory_Release(factory);
9617 static DWORD WINAPI mt_factory_test_thread_func(void *param)
9619 ID2D1Multithread *multithread = param;
9621 ID2D1Multithread_Enter(multithread);
9623 return 0;
9626 static void test_mt_factory(BOOL d3d11)
9628 ID2D1Multithread *multithread;
9629 ID2D1Factory *factory;
9630 HANDLE thread;
9631 HRESULT hr;
9632 DWORD ret;
9634 hr = D2D1CreateFactory(D2D1_FACTORY_TYPE_MULTI_THREADED + 1, &IID_ID2D1Factory, NULL, (void **)&factory);
9635 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
9637 hr = D2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED, &IID_ID2D1Factory, NULL, (void **)&factory);
9638 ok(SUCCEEDED(hr), "Failed to create factory, hr %#x.\n", hr);
9640 hr = ID2D1Factory_QueryInterface(factory, &IID_ID2D1Multithread, (void **)&multithread);
9641 if (hr == E_NOINTERFACE)
9643 win_skip("ID2D1Multithread is not supported.\n");
9644 ID2D1Factory_Release(factory);
9645 return;
9647 ok(SUCCEEDED(hr), "Failed to get interface, hr %#x.\n", hr);
9649 ret = ID2D1Multithread_GetMultithreadProtected(multithread);
9650 ok(!ret, "Unexpected return value.\n");
9652 ID2D1Multithread_Enter(multithread);
9653 thread = CreateThread(NULL, 0, mt_factory_test_thread_func, multithread, 0, NULL);
9654 ok(!!thread, "Failed to create a thread.\n");
9655 WaitForSingleObject(thread, INFINITE);
9656 CloseHandle(thread);
9658 ID2D1Multithread_Release(multithread);
9659 ID2D1Factory_Release(factory);
9661 hr = D2D1CreateFactory(D2D1_FACTORY_TYPE_MULTI_THREADED, &IID_ID2D1Factory, NULL, (void **)&factory);
9662 ok(SUCCEEDED(hr), "Failed to create factory, hr %#x.\n", hr);
9664 hr = ID2D1Factory_QueryInterface(factory, &IID_ID2D1Multithread, (void **)&multithread);
9665 ok(SUCCEEDED(hr), "Failed to get interface, hr %#x.\n", hr);
9667 ret = ID2D1Multithread_GetMultithreadProtected(multithread);
9668 ok(!!ret, "Unexpected return value.\n");
9670 ID2D1Multithread_Enter(multithread);
9671 thread = CreateThread(NULL, 0, mt_factory_test_thread_func, multithread, 0, NULL);
9672 ok(!!thread, "Failed to create a thread.\n");
9673 ret = WaitForSingleObject(thread, 10);
9674 ok(ret == WAIT_TIMEOUT, "Expected timeout.\n");
9675 ID2D1Multithread_Leave(multithread);
9676 WaitForSingleObject(thread, INFINITE);
9677 CloseHandle(thread);
9679 ID2D1Multithread_Release(multithread);
9681 ID2D1Factory_Release(factory);
9684 START_TEST(d2d1)
9686 HMODULE d2d1_dll = GetModuleHandleA("d2d1.dll");
9687 unsigned int argc, i;
9688 char **argv;
9690 pD2D1CreateDevice = (void *)GetProcAddress(d2d1_dll, "D2D1CreateDevice");
9691 pD2D1SinCos = (void *)GetProcAddress(d2d1_dll, "D2D1SinCos");
9692 pD2D1Tan = (void *)GetProcAddress(d2d1_dll, "D2D1Tan");
9693 pD2D1Vec3Length = (void *)GetProcAddress(d2d1_dll, "D2D1Vec3Length");
9694 pD2D1ConvertColorSpace = (void *)GetProcAddress(d2d1_dll, "D2D1ConvertColorSpace");
9696 use_mt = !getenv("WINETEST_NO_MT_D3D");
9698 argc = winetest_get_mainargs(&argv);
9699 for (i = 2; i < argc; ++i)
9701 if (!strcmp(argv[i], "--single"))
9702 use_mt = FALSE;
9705 queue_test(test_clip);
9706 queue_test(test_state_block);
9707 queue_test(test_color_brush);
9708 queue_test(test_bitmap_brush);
9709 queue_test(test_linear_brush);
9710 queue_test(test_radial_brush);
9711 queue_test(test_path_geometry);
9712 queue_d3d10_test(test_rectangle_geometry);
9713 queue_d3d10_test(test_rounded_rectangle_geometry);
9714 queue_test(test_bitmap_formats);
9715 queue_test(test_alpha_mode);
9716 queue_test(test_shared_bitmap);
9717 queue_test(test_bitmap_updates);
9718 queue_test(test_opacity_brush);
9719 queue_test(test_create_target);
9720 queue_test(test_draw_text_layout);
9721 queue_test(test_dc_target);
9722 queue_test(test_hwnd_target);
9723 queue_test(test_bitmap_target);
9724 queue_d3d10_test(test_desktop_dpi);
9725 queue_d3d10_test(test_stroke_style);
9726 queue_test(test_gradient);
9727 queue_test(test_draw_geometry);
9728 queue_test(test_fill_geometry);
9729 queue_test(test_gdi_interop);
9730 queue_test(test_layer);
9731 queue_test(test_bezier_intersect);
9732 queue_test(test_create_device);
9733 queue_test(test_bitmap_surface);
9734 queue_test(test_device_context);
9735 queue_d3d10_test(test_invert_matrix);
9736 queue_d3d10_test(test_skew_matrix);
9737 queue_test(test_command_list);
9738 queue_d3d10_test(test_max_bitmap_size);
9739 queue_test(test_dpi);
9740 queue_test(test_wic_bitmap_format);
9741 queue_d3d10_test(test_math);
9742 queue_d3d10_test(test_colour_space);
9743 queue_test(test_geometry_group);
9744 queue_test(test_mt_factory);
9746 run_queued_tests();