d2d1: Implement D2D1Tan().
[wine.git] / dlls / d2d1 / tests / d2d1.c
blobb269770365f80cb019e772ce03e7c4cae8cadde3
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 "wincrypt.h"
25 #include "wine/test.h"
26 #include "initguid.h"
27 #include "dwrite.h"
28 #include "wincodec.h"
29 #include "wine/heap.h"
31 static HRESULT (WINAPI *pD2D1CreateDevice)(IDXGIDevice *dxgi_device,
32 const D2D1_CREATION_PROPERTIES *properties, ID2D1Device **device);
34 static BOOL use_mt = TRUE;
36 static struct test_entry
38 void (*test)(void);
39 } *mt_tests;
40 size_t mt_tests_size, mt_test_count;
42 struct resource_readback
44 ID3D10Resource *resource;
45 D3D10_MAPPED_TEXTURE2D map_desc;
46 unsigned int width, height;
49 struct figure
51 unsigned int *spans;
52 unsigned int spans_size;
53 unsigned int span_count;
56 struct geometry_sink
58 ID2D1SimplifiedGeometrySink ID2D1SimplifiedGeometrySink_iface;
60 struct geometry_figure
62 D2D1_FIGURE_BEGIN begin;
63 D2D1_FIGURE_END end;
64 D2D1_POINT_2F start_point;
65 struct geometry_segment
67 enum
69 SEGMENT_BEZIER,
70 SEGMENT_LINE,
71 } type;
72 union
74 D2D1_BEZIER_SEGMENT bezier;
75 D2D1_POINT_2F line;
76 } u;
77 DWORD flags;
78 } *segments;
79 unsigned int segments_size;
80 unsigned int segment_count;
81 } *figures;
82 unsigned int figures_size;
83 unsigned int figure_count;
85 D2D1_FILL_MODE fill_mode;
86 DWORD segment_flags;
87 BOOL closed;
90 struct expected_geometry_figure
92 D2D1_FIGURE_BEGIN begin;
93 D2D1_FIGURE_END end;
94 D2D1_POINT_2F start_point;
95 unsigned int segment_count;
96 const struct geometry_segment *segments;
99 static void queue_test(void (*test)(void))
101 if (mt_test_count >= mt_tests_size)
103 mt_tests_size = max(16, mt_tests_size * 2);
104 mt_tests = heap_realloc(mt_tests, mt_tests_size * sizeof(*mt_tests));
106 mt_tests[mt_test_count++].test = test;
109 static DWORD WINAPI thread_func(void *ctx)
111 LONG *i = ctx, j;
113 while (*i < mt_test_count)
115 j = *i;
116 if (InterlockedCompareExchange(i, j + 1, j) == j)
117 mt_tests[j].test();
120 return 0;
123 static void run_queued_tests(void)
125 unsigned int thread_count, i;
126 HANDLE *threads;
127 SYSTEM_INFO si;
128 LONG test_idx;
130 if (!use_mt)
132 for (i = 0; i < mt_test_count; ++i)
134 mt_tests[i].test();
137 return;
140 GetSystemInfo(&si);
141 thread_count = si.dwNumberOfProcessors;
142 threads = heap_calloc(thread_count, sizeof(*threads));
143 for (i = 0, test_idx = 0; i < thread_count; ++i)
145 threads[i] = CreateThread(NULL, 0, thread_func, &test_idx, 0, NULL);
146 ok(!!threads[i], "Failed to create thread %u.\n", i);
148 WaitForMultipleObjects(thread_count, threads, TRUE, INFINITE);
149 for (i = 0; i < thread_count; ++i)
151 CloseHandle(threads[i]);
153 heap_free(threads);
156 static void set_point(D2D1_POINT_2F *point, float x, float y)
158 point->x = x;
159 point->y = y;
162 static void set_quadratic(D2D1_QUADRATIC_BEZIER_SEGMENT *quadratic, float x1, float y1, float x2, float y2)
164 quadratic->point1.x = x1;
165 quadratic->point1.y = y1;
166 quadratic->point2.x = x2;
167 quadratic->point2.y = y2;
170 static void set_rect(D2D1_RECT_F *rect, float left, float top, float right, float bottom)
172 rect->left = left;
173 rect->top = top;
174 rect->right = right;
175 rect->bottom = bottom;
178 static void set_rounded_rect(D2D1_ROUNDED_RECT *rect, float left, float top, float right, float bottom,
179 float radius_x, float radius_y)
181 set_rect(&rect->rect, left, top, right, bottom);
182 rect->radiusX = radius_x;
183 rect->radiusY = radius_y;
186 static void set_rect_u(D2D1_RECT_U *rect, UINT32 left, UINT32 top, UINT32 right, UINT32 bottom)
188 rect->left = left;
189 rect->top = top;
190 rect->right = right;
191 rect->bottom = bottom;
194 static void set_ellipse(D2D1_ELLIPSE *ellipse, float x, float y, float rx, float ry)
196 set_point(&ellipse->point, x, y);
197 ellipse->radiusX = rx;
198 ellipse->radiusY = ry;
201 static void set_color(D2D1_COLOR_F *color, float r, float g, float b, float a)
203 color->r = r;
204 color->g = g;
205 color->b = b;
206 color->a = a;
209 static void set_size_u(D2D1_SIZE_U *size, unsigned int w, unsigned int h)
211 size->width = w;
212 size->height = h;
215 static void set_size_f(D2D1_SIZE_F *size, float w, float h)
217 size->width = w;
218 size->height = h;
221 static void set_matrix_identity(D2D1_MATRIX_3X2_F *matrix)
223 matrix->_11 = 1.0f;
224 matrix->_12 = 0.0f;
225 matrix->_21 = 0.0f;
226 matrix->_22 = 1.0f;
227 matrix->_31 = 0.0f;
228 matrix->_32 = 0.0f;
231 static void rotate_matrix(D2D1_MATRIX_3X2_F *matrix, float theta)
233 float sin_theta, cos_theta, tmp_11, tmp_12;
235 sin_theta = sinf(theta);
236 cos_theta = cosf(theta);
237 tmp_11 = matrix->_11;
238 tmp_12 = matrix->_12;
240 matrix->_11 = cos_theta * tmp_11 + sin_theta * matrix->_21;
241 matrix->_12 = cos_theta * tmp_12 + sin_theta * matrix->_22;
242 matrix->_21 = -sin_theta * tmp_11 + cos_theta * matrix->_21;
243 matrix->_22 = -sin_theta * tmp_12 + cos_theta * matrix->_22;
246 static void skew_matrix(D2D1_MATRIX_3X2_F *matrix, float x, float y)
248 float tmp_11, tmp_12;
250 tmp_11 = matrix->_11;
251 tmp_12 = matrix->_12;
253 matrix->_11 += y * matrix->_21;
254 matrix->_12 += y * matrix->_22;
255 matrix->_21 += x * tmp_11;
256 matrix->_22 += x * tmp_12;
259 static void scale_matrix(D2D1_MATRIX_3X2_F *matrix, float x, float y)
261 matrix->_11 *= x;
262 matrix->_12 *= x;
263 matrix->_21 *= y;
264 matrix->_22 *= y;
267 static void translate_matrix(D2D1_MATRIX_3X2_F *matrix, float x, float y)
269 matrix->_31 += x * matrix->_11 + y * matrix->_21;
270 matrix->_32 += x * matrix->_12 + y * matrix->_22;
273 static void line_to(ID2D1GeometrySink *sink, float x, float y)
275 D2D1_POINT_2F point;
277 set_point(&point, x, y);
278 ID2D1GeometrySink_AddLine(sink, point);
281 static void quadratic_to(ID2D1GeometrySink *sink, float x1, float y1, float x2, float y2)
283 D2D1_QUADRATIC_BEZIER_SEGMENT quadratic;
285 set_quadratic(&quadratic, x1, y1, x2, y2);
286 ID2D1GeometrySink_AddQuadraticBezier(sink, &quadratic);
289 static void cubic_to(ID2D1GeometrySink *sink, float x1, float y1, float x2, float y2, float x3, float y3)
291 D2D1_BEZIER_SEGMENT b;
293 b.point1.x = x1;
294 b.point1.y = y1;
295 b.point2.x = x2;
296 b.point2.y = y2;
297 b.point3.x = x3;
298 b.point3.y = y3;
299 ID2D1GeometrySink_AddBezier(sink, &b);
302 static void get_surface_readback(IDXGISurface *surface, struct resource_readback *rb)
304 D3D10_TEXTURE2D_DESC texture_desc;
305 DXGI_SURFACE_DESC surface_desc;
306 ID3D10Resource *src_resource;
307 ID3D10Device *device;
308 HRESULT hr;
310 hr = IDXGISurface_GetDevice(surface, &IID_ID3D10Device, (void **)&device);
311 ok(SUCCEEDED(hr), "Failed to get device, hr %#x.\n", hr);
312 hr = IDXGISurface_QueryInterface(surface, &IID_ID3D10Resource, (void **)&src_resource);
313 ok(SUCCEEDED(hr), "Failed to query resource interface, hr %#x.\n", hr);
315 hr = IDXGISurface_GetDesc(surface, &surface_desc);
316 ok(SUCCEEDED(hr), "Failed to get surface desc, hr %#x.\n", hr);
317 texture_desc.Width = surface_desc.Width;
318 texture_desc.Height = surface_desc.Height;
319 texture_desc.MipLevels = 1;
320 texture_desc.ArraySize = 1;
321 texture_desc.Format = surface_desc.Format;
322 texture_desc.SampleDesc = surface_desc.SampleDesc;
323 texture_desc.Usage = D3D10_USAGE_STAGING;
324 texture_desc.BindFlags = 0;
325 texture_desc.CPUAccessFlags = D3D10_CPU_ACCESS_READ;
326 texture_desc.MiscFlags = 0;
327 hr = ID3D10Device_CreateTexture2D(device, &texture_desc, NULL, (ID3D10Texture2D **)&rb->resource);
328 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
330 rb->width = texture_desc.Width;
331 rb->height = texture_desc.Height;
333 ID3D10Device_CopyResource(device, rb->resource, src_resource);
334 ID3D10Resource_Release(src_resource);
335 ID3D10Device_Release(device);
337 hr = ID3D10Texture2D_Map((ID3D10Texture2D *)rb->resource, 0, D3D10_MAP_READ, 0, &rb->map_desc);
338 ok(SUCCEEDED(hr), "Failed to map texture, hr %#x.\n", hr);
341 static void release_resource_readback(struct resource_readback *rb)
343 ID3D10Texture2D_Unmap((ID3D10Texture2D *)rb->resource, 0);
344 ID3D10Resource_Release(rb->resource);
347 static DWORD get_readback_colour(struct resource_readback *rb, unsigned int x, unsigned int y)
349 return ((DWORD *)((BYTE *)rb->map_desc.pData + y * rb->map_desc.RowPitch))[x];
352 static BOOL compare_uint(unsigned int x, unsigned int y, unsigned int max_diff)
354 unsigned int diff = x > y ? x - y : y - x;
356 return diff <= max_diff;
359 static BOOL compare_colour(DWORD c1, DWORD c2, BYTE max_diff)
361 return compare_uint(c1 & 0xff, c2 & 0xff, max_diff)
362 && compare_uint((c1 >> 8) & 0xff, (c2 >> 8) & 0xff, max_diff)
363 && compare_uint((c1 >> 16) & 0xff, (c2 >> 16) & 0xff, max_diff)
364 && compare_uint((c1 >> 24) & 0xff, (c2 >> 24) & 0xff, max_diff);
367 static BOOL compare_float(float f, float g, unsigned int ulps)
369 int x = *(int *)&f;
370 int y = *(int *)&g;
372 if (x < 0)
373 x = INT_MIN - x;
374 if (y < 0)
375 y = INT_MIN - y;
377 if (abs(x - y) > ulps)
378 return FALSE;
380 return TRUE;
383 static BOOL compare_point(const D2D1_POINT_2F *point, float x, float y, unsigned int ulps)
385 return compare_float(point->x, x, ulps)
386 && compare_float(point->y, y, ulps);
389 static BOOL compare_rect(const D2D1_RECT_F *rect, float left, float top, float right, float bottom, unsigned int ulps)
391 return compare_float(rect->left, left, ulps)
392 && compare_float(rect->top, top, ulps)
393 && compare_float(rect->right, right, ulps)
394 && compare_float(rect->bottom, bottom, ulps);
397 static BOOL compare_bezier_segment(const D2D1_BEZIER_SEGMENT *b, float x1, float y1,
398 float x2, float y2, float x3, float y3, unsigned int ulps)
400 return compare_point(&b->point1, x1, y1, ulps)
401 && compare_point(&b->point2, x2, y2, ulps)
402 && compare_point(&b->point3, x3, y3, ulps);
405 static BOOL compare_sha1(void *data, unsigned int pitch, unsigned int bpp,
406 unsigned int w, unsigned int h, const char *ref_sha1)
408 static const char hex_chars[] = "0123456789abcdef";
409 HCRYPTPROV provider;
410 BYTE hash_data[20];
411 HCRYPTHASH hash;
412 unsigned int i;
413 char sha1[41];
414 BOOL ret;
416 ret = CryptAcquireContextW(&provider, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT);
417 ok(ret, "Failed to acquire crypt context.\n");
418 ret = CryptCreateHash(provider, CALG_SHA1, 0, 0, &hash);
419 ok(ret, "Failed to create hash.\n");
421 for (i = 0; i < h; ++i)
423 if (!(ret = CryptHashData(hash, (BYTE *)data + pitch * i, w * bpp, 0)))
424 break;
426 ok(ret, "Failed to hash data.\n");
428 i = sizeof(hash_data);
429 ret = CryptGetHashParam(hash, HP_HASHVAL, hash_data, &i, 0);
430 ok(ret, "Failed to get hash value.\n");
431 ok(i == sizeof(hash_data), "Got unexpected hash size %u.\n", i);
433 ret = CryptDestroyHash(hash);
434 ok(ret, "Failed to destroy hash.\n");
435 ret = CryptReleaseContext(provider, 0);
436 ok(ret, "Failed to release crypt context.\n");
438 for (i = 0; i < 20; ++i)
440 sha1[i * 2] = hex_chars[hash_data[i] >> 4];
441 sha1[i * 2 + 1] = hex_chars[hash_data[i] & 0xf];
443 sha1[40] = 0;
445 return !strcmp(ref_sha1, (char *)sha1);
448 static BOOL compare_surface(IDXGISurface *surface, const char *ref_sha1)
450 struct resource_readback rb;
451 BOOL ret;
453 get_surface_readback(surface, &rb);
454 ret = compare_sha1(rb.map_desc.pData, rb.map_desc.RowPitch, 4,
455 rb.width, rb.height, ref_sha1);
456 release_resource_readback(&rb);
458 return ret;
461 static BOOL compare_wic_bitmap(IWICBitmap *bitmap, const char *ref_sha1)
463 UINT stride, width, height, buffer_size;
464 IWICBitmapLock *lock;
465 BYTE *data;
466 HRESULT hr;
467 BOOL ret;
469 hr = IWICBitmap_Lock(bitmap, NULL, WICBitmapLockRead, &lock);
470 ok(SUCCEEDED(hr), "Failed to lock bitmap, hr %#x.\n", hr);
472 hr = IWICBitmapLock_GetDataPointer(lock, &buffer_size, &data);
473 ok(SUCCEEDED(hr), "Failed to get bitmap data, hr %#x.\n", hr);
475 hr = IWICBitmapLock_GetStride(lock, &stride);
476 ok(SUCCEEDED(hr), "Failed to get bitmap stride, hr %#x.\n", hr);
478 hr = IWICBitmapLock_GetSize(lock, &width, &height);
479 ok(SUCCEEDED(hr), "Failed to get bitmap size, hr %#x.\n", hr);
481 ret = compare_sha1(data, stride, 4, width, height, ref_sha1);
483 IWICBitmapLock_Release(lock);
485 return ret;
488 static void serialize_figure(struct figure *figure)
490 static const char lookup[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
491 unsigned int i, j, k, span;
492 char output[76];
493 char t[3];
494 char *p;
496 for (i = 0, j = 0, k = 0, p = output; i < figure->span_count; ++i)
498 span = figure->spans[i];
499 while (span)
501 t[j] = span & 0x7f;
502 if (span > 0x7f)
503 t[j] |= 0x80;
504 span >>= 7;
505 if (++j == 3)
507 p[0] = lookup[(t[0] & 0xfc) >> 2];
508 p[1] = lookup[((t[0] & 0x03) << 4) | ((t[1] & 0xf0) >> 4)];
509 p[2] = lookup[((t[1] & 0x0f) << 2) | ((t[2] & 0xc0) >> 6)];
510 p[3] = lookup[t[2] & 0x3f];
511 p += 4;
512 if (++k == 19)
514 trace("%.76s\n", output);
515 p = output;
516 k = 0;
518 j = 0;
522 if (j)
524 for (i = j; i < 3; ++i)
525 t[i] = 0;
526 p[0] = lookup[(t[0] & 0xfc) >> 2];
527 p[1] = lookup[((t[0] & 0x03) << 4) | ((t[1] & 0xf0) >> 4)];
528 p[2] = lookup[((t[1] & 0x0f) << 2) | ((t[2] & 0xc0) >> 6)];
529 p[3] = lookup[t[2] & 0x3f];
530 ++k;
532 if (k)
533 trace("%.*s\n", k * 4, output);
536 static void figure_add_span(struct figure *figure, unsigned int span)
538 if (figure->span_count == figure->spans_size)
540 figure->spans_size *= 2;
541 figure->spans = HeapReAlloc(GetProcessHeap(), 0, figure->spans,
542 figure->spans_size * sizeof(*figure->spans));
545 figure->spans[figure->span_count++] = span;
548 static void deserialize_span(struct figure *figure, unsigned int *current, unsigned int *shift, unsigned int c)
550 *current |= (c & 0x7f) << *shift;
551 if (c & 0x80)
553 *shift += 7;
554 return;
557 if (*current)
558 figure_add_span(figure, *current);
559 *current = 0;
560 *shift = 0;
563 static void deserialize_figure(struct figure *figure, const BYTE *s)
565 static const BYTE lookup[] =
567 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
568 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
569 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3e, 0xff, 0xff, 0xff, 0x3f,
570 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
571 0xff, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e,
572 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0xff, 0xff, 0xff, 0xff, 0xff,
573 0xff, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28,
574 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x31, 0x32, 0x33, 0xff, 0xff, 0xff, 0xff, 0xff,
576 unsigned int current = 0, shift = 0;
577 const BYTE *ptr;
578 BYTE x, y;
580 figure->span_count = 0;
581 figure->spans_size = 64;
582 figure->spans = HeapAlloc(GetProcessHeap(), 0, figure->spans_size * sizeof(*figure->spans));
584 for (ptr = s; *ptr; ptr += 4)
586 x = lookup[ptr[0]];
587 y = lookup[ptr[1]];
588 deserialize_span(figure, &current, &shift, ((x & 0x3f) << 2) | ((y & 0x3f) >> 4));
589 x = lookup[ptr[2]];
590 deserialize_span(figure, &current, &shift, ((y & 0x0f) << 4) | ((x & 0x3f) >> 2));
591 y = lookup[ptr[3]];
592 deserialize_span(figure, &current, &shift, ((x & 0x03) << 6) | (y & 0x3f));
596 static void read_figure(struct figure *figure, BYTE *data, unsigned int pitch,
597 unsigned int x, unsigned int y, unsigned int w, unsigned int h, DWORD prev)
599 unsigned int i, j, span;
601 figure->span_count = 0;
602 for (i = 0, span = 0; i < h; ++i)
604 const DWORD *row = (DWORD *)&data[(y + i) * pitch + x * 4];
605 for (j = 0; j < w; ++j, ++span)
607 if ((i || j) && prev != row[j])
609 figure_add_span(figure, span);
610 prev = row[j];
611 span = 0;
615 if (span)
616 figure_add_span(figure, span);
619 static BOOL compare_figure(IDXGISurface *surface, unsigned int x, unsigned int y,
620 unsigned int w, unsigned int h, DWORD prev, unsigned int max_diff, const char *ref)
622 struct figure ref_figure, figure;
623 unsigned int i, j, span, diff;
624 struct resource_readback rb;
626 get_surface_readback(surface, &rb);
628 figure.span_count = 0;
629 figure.spans_size = 64;
630 figure.spans = HeapAlloc(GetProcessHeap(), 0, figure.spans_size * sizeof(*figure.spans));
632 read_figure(&figure, rb.map_desc.pData, rb.map_desc.RowPitch, x, y, w, h, prev);
634 deserialize_figure(&ref_figure, (BYTE *)ref);
635 span = w * h;
636 for (i = 0; i < ref_figure.span_count; ++i)
638 span -= ref_figure.spans[i];
640 if (span)
641 figure_add_span(&ref_figure, span);
643 for (i = 0, j = 0, diff = 0; i < figure.span_count && j < ref_figure.span_count;)
645 if (figure.spans[i] == ref_figure.spans[j])
647 if ((i ^ j) & 1)
648 diff += ref_figure.spans[j];
649 ++i;
650 ++j;
652 else if (figure.spans[i] > ref_figure.spans[j])
654 if ((i ^ j) & 1)
655 diff += ref_figure.spans[j];
656 figure.spans[i] -= ref_figure.spans[j];
657 ++j;
659 else
661 if ((i ^ j) & 1)
662 diff += figure.spans[i];
663 ref_figure.spans[j] -= figure.spans[i];
664 ++i;
667 if (diff > max_diff)
669 trace("diff %u > max_diff %u.\n", diff, max_diff);
670 read_figure(&figure, rb.map_desc.pData, rb.map_desc.RowPitch, x, y, w, h, prev);
671 serialize_figure(&figure);
674 HeapFree(GetProcessHeap(), 0, ref_figure.spans);
675 HeapFree(GetProcessHeap(), 0, figure.spans);
676 release_resource_readback(&rb);
678 return diff <= max_diff;
681 static ID3D10Device1 *create_device(void)
683 ID3D10Device1 *device;
685 if (SUCCEEDED(D3D10CreateDevice1(NULL, D3D10_DRIVER_TYPE_HARDWARE, NULL,
686 D3D10_CREATE_DEVICE_BGRA_SUPPORT, D3D10_FEATURE_LEVEL_10_0, D3D10_1_SDK_VERSION, &device)))
687 return device;
688 if (SUCCEEDED(D3D10CreateDevice1(NULL, D3D10_DRIVER_TYPE_WARP, NULL,
689 D3D10_CREATE_DEVICE_BGRA_SUPPORT, D3D10_FEATURE_LEVEL_10_0, D3D10_1_SDK_VERSION, &device)))
690 return device;
691 if (SUCCEEDED(D3D10CreateDevice1(NULL, D3D10_DRIVER_TYPE_REFERENCE, NULL,
692 D3D10_CREATE_DEVICE_BGRA_SUPPORT, D3D10_FEATURE_LEVEL_10_0, D3D10_1_SDK_VERSION, &device)))
693 return device;
695 return NULL;
698 static HWND create_window(void)
700 RECT r = {0, 0, 640, 480};
702 AdjustWindowRect(&r, WS_OVERLAPPEDWINDOW | WS_VISIBLE, FALSE);
704 return CreateWindowA("static", "d2d1_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
705 0, 0, r.right - r.left, r.bottom - r.top, NULL, NULL, NULL, NULL);
708 static IDXGISwapChain *create_swapchain(ID3D10Device1 *device, HWND window, BOOL windowed)
710 IDXGISwapChain *swapchain;
711 DXGI_SWAP_CHAIN_DESC desc;
712 IDXGIDevice *dxgi_device;
713 IDXGIAdapter *adapter;
714 IDXGIFactory *factory;
715 HRESULT hr;
717 hr = ID3D10Device1_QueryInterface(device, &IID_IDXGIDevice, (void **)&dxgi_device);
718 ok(SUCCEEDED(hr), "Failed to get DXGI device, hr %#x.\n", hr);
719 hr = IDXGIDevice_GetAdapter(dxgi_device, &adapter);
720 ok(SUCCEEDED(hr), "Failed to get adapter, hr %#x.\n", hr);
721 IDXGIDevice_Release(dxgi_device);
722 hr = IDXGIAdapter_GetParent(adapter, &IID_IDXGIFactory, (void **)&factory);
723 ok(SUCCEEDED(hr), "Failed to get factory, hr %#x.\n", hr);
724 IDXGIAdapter_Release(adapter);
726 desc.BufferDesc.Width = 640;
727 desc.BufferDesc.Height = 480;
728 desc.BufferDesc.RefreshRate.Numerator = 60;
729 desc.BufferDesc.RefreshRate.Denominator = 1;
730 desc.BufferDesc.Format = DXGI_FORMAT_B8G8R8A8_UNORM;
731 desc.BufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED;
732 desc.BufferDesc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED;
733 desc.SampleDesc.Count = 1;
734 desc.SampleDesc.Quality = 0;
735 desc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
736 desc.BufferCount = 1;
737 desc.OutputWindow = window;
738 desc.Windowed = windowed;
739 desc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD;
740 desc.Flags = 0;
742 hr = IDXGIFactory_CreateSwapChain(factory, (IUnknown *)device, &desc, &swapchain);
743 ok(SUCCEEDED(hr), "Failed to create swapchain, hr %#x.\n", hr);
744 IDXGIFactory_Release(factory);
746 return swapchain;
749 static ID2D1RenderTarget *create_render_target_desc(IDXGISurface *surface, const D2D1_RENDER_TARGET_PROPERTIES *desc)
751 ID2D1RenderTarget *render_target;
752 ID2D1Factory *factory;
753 HRESULT hr;
755 hr = D2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED, &IID_ID2D1Factory, NULL, (void **)&factory);
756 ok(SUCCEEDED(hr), "Failed to create factory, hr %#x.\n", hr);
757 hr = ID2D1Factory_CreateDxgiSurfaceRenderTarget(factory, surface, desc, &render_target);
758 ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr);
759 ID2D1Factory_Release(factory);
761 return render_target;
764 static ID2D1RenderTarget *create_render_target(IDXGISurface *surface)
766 D2D1_RENDER_TARGET_PROPERTIES desc;
768 desc.type = D2D1_RENDER_TARGET_TYPE_DEFAULT;
769 desc.pixelFormat.format = DXGI_FORMAT_UNKNOWN;
770 desc.pixelFormat.alphaMode = D2D1_ALPHA_MODE_PREMULTIPLIED;
771 desc.dpiX = 0.0f;
772 desc.dpiY = 0.0f;
773 desc.usage = D2D1_RENDER_TARGET_USAGE_NONE;
774 desc.minLevel = D2D1_FEATURE_LEVEL_DEFAULT;
776 return create_render_target_desc(surface, &desc);
779 #define check_bitmap_surface(b, s, o) check_bitmap_surface_(__LINE__, b, s, o)
780 static void check_bitmap_surface_(unsigned int line, ID2D1Bitmap *bitmap, BOOL has_surface, DWORD expected_options)
782 D2D1_BITMAP_OPTIONS options;
783 IDXGISurface *surface;
784 ID2D1Bitmap1 *bitmap1;
785 HRESULT hr;
787 hr = ID2D1Bitmap_QueryInterface(bitmap, &IID_ID2D1Bitmap1, (void **)&bitmap1);
788 if (FAILED(hr))
789 return;
791 options = ID2D1Bitmap1_GetOptions(bitmap1);
792 ok_(__FILE__, line)(options == expected_options, "Unexpected bitmap options %#x, expected %#x.\n",
793 options, expected_options);
795 surface = (void *)0xdeadbeef;
796 hr = ID2D1Bitmap1_GetSurface(bitmap1, &surface);
797 if (has_surface)
799 D3D10_TEXTURE2D_DESC desc;
800 ID3D10Texture2D *texture;
801 D2D1_SIZE_U pixel_size;
802 DWORD bind_flags = 0;
804 ok_(__FILE__, line)(SUCCEEDED(hr), "Failed to get bitmap surface, hr %#x.\n", hr);
805 ok_(__FILE__, line)(!!surface, "Expected surface instance.\n");
807 /* Correlate with resource configuration. */
808 hr = IDXGISurface_QueryInterface(surface, &IID_ID3D10Texture2D, (void **)&texture);
809 ok_(__FILE__, line)(SUCCEEDED(hr), "Failed to get texture pointer, hr %#x.\n", hr);
811 ID3D10Texture2D_GetDesc(texture, &desc);
812 ok_(__FILE__, line)(desc.Usage == 0, "Unexpected usage %#x.\n", desc.Usage);
814 if (options & D2D1_BITMAP_OPTIONS_TARGET)
815 bind_flags |= D3D10_BIND_RENDER_TARGET;
816 if (!(options & D2D1_BITMAP_OPTIONS_CANNOT_DRAW))
817 bind_flags |= D3D10_BIND_SHADER_RESOURCE;
819 ok_(__FILE__, line)(desc.BindFlags == bind_flags, "Unexpected bind flags %#x for bitmap options %#x.\n",
820 desc.BindFlags, options);
821 ok_(__FILE__, line)(!desc.CPUAccessFlags, "Unexpected cpu access flags %#x.\n", desc.CPUAccessFlags);
822 ok_(__FILE__, line)(!desc.MiscFlags, "Unexpected misc flags %#x.\n", desc.MiscFlags);
824 pixel_size = ID2D1Bitmap_GetPixelSize(bitmap);
825 if (!pixel_size.width || !pixel_size.height)
826 pixel_size.width = pixel_size.height = 1;
827 ok_(__FILE__, line)(desc.Width == pixel_size.width, "Got width %u, expected %u.\n",
828 desc.Width, pixel_size.width);
829 ok_(__FILE__, line)(desc.Height == pixel_size.height, "Got height %u, expected %u.\n",
830 desc.Height, pixel_size.height);
832 ID3D10Texture2D_Release(texture);
834 IDXGISurface_Release(surface);
836 else
838 ok_(__FILE__, line)(hr == D2DERR_INVALID_CALL, "Unexpected hr %#x.\n", hr);
839 ok_(__FILE__, line)(!surface, "Unexpected surface instance.\n");
842 ID2D1Bitmap1_Release(bitmap1);
845 static inline struct geometry_sink *impl_from_ID2D1SimplifiedGeometrySink(ID2D1SimplifiedGeometrySink *iface)
847 return CONTAINING_RECORD(iface, struct geometry_sink, ID2D1SimplifiedGeometrySink_iface);
850 static HRESULT STDMETHODCALLTYPE geometry_sink_QueryInterface(ID2D1SimplifiedGeometrySink *iface,
851 REFIID iid, void **out)
853 if (IsEqualGUID(iid, &IID_ID2D1SimplifiedGeometrySink)
854 || IsEqualGUID(iid, &IID_IUnknown))
856 *out = iface;
857 return S_OK;
860 *out = NULL;
861 return E_NOINTERFACE;
864 static ULONG STDMETHODCALLTYPE geometry_sink_AddRef(ID2D1SimplifiedGeometrySink *iface)
866 return 0;
869 static ULONG STDMETHODCALLTYPE geometry_sink_Release(ID2D1SimplifiedGeometrySink *iface)
871 return 0;
874 static void STDMETHODCALLTYPE geometry_sink_SetFillMode(ID2D1SimplifiedGeometrySink *iface, D2D1_FILL_MODE mode)
876 struct geometry_sink *sink = impl_from_ID2D1SimplifiedGeometrySink(iface);
878 sink->fill_mode = mode;
881 static void STDMETHODCALLTYPE geometry_sink_SetSegmentFlags(ID2D1SimplifiedGeometrySink *iface,
882 D2D1_PATH_SEGMENT flags)
884 struct geometry_sink *sink = impl_from_ID2D1SimplifiedGeometrySink(iface);
886 sink->segment_flags = flags;
889 static void STDMETHODCALLTYPE geometry_sink_BeginFigure(ID2D1SimplifiedGeometrySink *iface,
890 D2D1_POINT_2F start_point, D2D1_FIGURE_BEGIN figure_begin)
892 struct geometry_sink *sink = impl_from_ID2D1SimplifiedGeometrySink(iface);
893 struct geometry_figure *figure;
895 if (sink->figure_count == sink->figures_size)
897 sink->figures_size *= 2;
898 sink->figures = HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sink->figures,
899 sink->figures_size * sizeof(*sink->figures));
901 figure = &sink->figures[sink->figure_count++];
903 figure->begin = figure_begin;
904 figure->start_point = start_point;
905 figure->segments_size = 4;
906 figure->segments = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
907 figure->segments_size * sizeof(*figure->segments));
910 static struct geometry_segment *geometry_figure_add_segment(struct geometry_figure *figure)
912 if (figure->segment_count == figure->segments_size)
914 figure->segments_size *= 2;
915 figure->segments = HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, figure->segments,
916 figure->segments_size * sizeof(*figure->segments));
918 return &figure->segments[figure->segment_count++];
921 static void STDMETHODCALLTYPE geometry_sink_AddLines(ID2D1SimplifiedGeometrySink *iface,
922 const D2D1_POINT_2F *points, UINT32 count)
924 struct geometry_sink *sink = impl_from_ID2D1SimplifiedGeometrySink(iface);
925 struct geometry_figure *figure = &sink->figures[sink->figure_count - 1];
926 struct geometry_segment *segment;
927 unsigned int i;
929 for (i = 0; i < count; ++i)
931 segment = geometry_figure_add_segment(figure);
932 segment->type = SEGMENT_LINE;
933 segment->u.line = points[i];
934 segment->flags = sink->segment_flags;
938 static void STDMETHODCALLTYPE geometry_sink_AddBeziers(ID2D1SimplifiedGeometrySink *iface,
939 const D2D1_BEZIER_SEGMENT *beziers, UINT32 count)
941 struct geometry_sink *sink = impl_from_ID2D1SimplifiedGeometrySink(iface);
942 struct geometry_figure *figure = &sink->figures[sink->figure_count - 1];
943 struct geometry_segment *segment;
944 unsigned int i;
946 for (i = 0; i < count; ++i)
948 segment = geometry_figure_add_segment(figure);
949 segment->type = SEGMENT_BEZIER;
950 segment->u.bezier = beziers[i];
951 segment->flags = sink->segment_flags;
955 static void STDMETHODCALLTYPE geometry_sink_EndFigure(ID2D1SimplifiedGeometrySink *iface,
956 D2D1_FIGURE_END figure_end)
958 struct geometry_sink *sink = impl_from_ID2D1SimplifiedGeometrySink(iface);
959 struct geometry_figure *figure = &sink->figures[sink->figure_count - 1];
961 figure->end = figure_end;
964 static HRESULT STDMETHODCALLTYPE geometry_sink_Close(ID2D1SimplifiedGeometrySink *iface)
966 struct geometry_sink *sink = impl_from_ID2D1SimplifiedGeometrySink(iface);
968 sink->closed = TRUE;
970 return S_OK;
973 static const struct ID2D1SimplifiedGeometrySinkVtbl geometry_sink_vtbl =
975 geometry_sink_QueryInterface,
976 geometry_sink_AddRef,
977 geometry_sink_Release,
978 geometry_sink_SetFillMode,
979 geometry_sink_SetSegmentFlags,
980 geometry_sink_BeginFigure,
981 geometry_sink_AddLines,
982 geometry_sink_AddBeziers,
983 geometry_sink_EndFigure,
984 geometry_sink_Close,
987 static void geometry_sink_init(struct geometry_sink *sink)
989 memset(sink, 0, sizeof(*sink));
990 sink->ID2D1SimplifiedGeometrySink_iface.lpVtbl = &geometry_sink_vtbl;
991 sink->figures_size = 4;
992 sink->figures = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
993 sink->figures_size * sizeof(*sink->figures));
996 static void geometry_sink_cleanup(struct geometry_sink *sink)
998 unsigned int i;
1000 for (i = 0; i < sink->figure_count; ++i)
1002 HeapFree(GetProcessHeap(), 0, sink->figures[i].segments);
1004 HeapFree(GetProcessHeap(), 0, sink->figures);
1007 #define geometry_sink_check(a, b, c, d, e) geometry_sink_check_(__LINE__, a, b, c, d, e)
1008 static void geometry_sink_check_(unsigned int line, const struct geometry_sink *sink, D2D1_FILL_MODE fill_mode,
1009 unsigned int figure_count, const struct expected_geometry_figure *expected_figures, unsigned int ulps)
1011 const struct geometry_segment *segment, *expected_segment;
1012 const struct expected_geometry_figure *expected_figure;
1013 const struct geometry_figure *figure;
1014 unsigned int i, j;
1015 BOOL match;
1017 ok_(__FILE__, line)(sink->fill_mode == fill_mode,
1018 "Got unexpected fill mode %#x.\n", sink->fill_mode);
1019 ok_(__FILE__, line)(sink->figure_count == figure_count,
1020 "Got unexpected figure count %u, expected %u.\n", sink->figure_count, figure_count);
1021 ok_(__FILE__, line)(!sink->closed, "Sink is closed.\n");
1023 for (i = 0; i < figure_count; ++i)
1025 expected_figure = &expected_figures[i];
1026 figure = &sink->figures[i];
1028 ok_(__FILE__, line)(figure->begin == expected_figure->begin,
1029 "Got unexpected figure %u begin %#x, expected %#x.\n",
1030 i, figure->begin, expected_figure->begin);
1031 ok_(__FILE__, line)(figure->end == expected_figure->end,
1032 "Got unexpected figure %u end %#x, expected %#x.\n",
1033 i, figure->end, expected_figure->end);
1034 match = compare_point(&figure->start_point,
1035 expected_figure->start_point.x, expected_figure->start_point.y, ulps);
1036 ok_(__FILE__, line)(match, "Got unexpected figure %u start point {%.8e, %.8e}, expected {%.8e, %.8e}.\n",
1037 i, figure->start_point.x, figure->start_point.y,
1038 expected_figure->start_point.x, expected_figure->start_point.y);
1039 ok_(__FILE__, line)(figure->segment_count == expected_figure->segment_count,
1040 "Got unexpected figure %u segment count %u, expected %u.\n",
1041 i, figure->segment_count, expected_figure->segment_count);
1043 for (j = 0; j < figure->segment_count; ++j)
1045 expected_segment = &expected_figure->segments[j];
1046 segment = &figure->segments[j];
1047 ok_(__FILE__, line)(segment->type == expected_segment->type,
1048 "Got unexpected figure %u, segment %u type %#x, expected %#x.\n",
1049 i, j, segment->type, expected_segment->type);
1050 ok_(__FILE__, line)(segment->flags == expected_segment->flags,
1051 "Got unexpected figure %u, segment %u flags %#x, expected %#x.\n",
1052 i, j, segment->flags, expected_segment->flags);
1053 switch (segment->type)
1055 case SEGMENT_LINE:
1056 match = compare_point(&segment->u.line,
1057 expected_segment->u.line.x, expected_segment->u.line.y, ulps);
1058 ok_(__FILE__, line)(match, "Got unexpected figure %u segment %u {%.8e, %.8e}, "
1059 "expected {%.8e, %.8e}.\n",
1060 i, j, segment->u.line.x, segment->u.line.y,
1061 expected_segment->u.line.x, expected_segment->u.line.y);
1062 break;
1064 case SEGMENT_BEZIER:
1065 match = compare_bezier_segment(&segment->u.bezier,
1066 expected_segment->u.bezier.point1.x, expected_segment->u.bezier.point1.y,
1067 expected_segment->u.bezier.point2.x, expected_segment->u.bezier.point2.y,
1068 expected_segment->u.bezier.point3.x, expected_segment->u.bezier.point3.y,
1069 ulps);
1070 ok_(__FILE__, line)(match, "Got unexpected figure %u segment %u "
1071 "{%.8e, %.8e, %.8e, %.8e, %.8e, %.8e}, "
1072 "expected {%.8e, %.8e, %.8e, %.8e, %.8e, %.8e}.\n",
1073 i, j, segment->u.bezier.point1.x, segment->u.bezier.point1.y,
1074 segment->u.bezier.point2.x, segment->u.bezier.point2.y,
1075 segment->u.bezier.point3.x, segment->u.bezier.point3.y,
1076 expected_segment->u.bezier.point1.x, expected_segment->u.bezier.point1.y,
1077 expected_segment->u.bezier.point2.x, expected_segment->u.bezier.point2.y,
1078 expected_segment->u.bezier.point3.x, expected_segment->u.bezier.point3.y);
1079 break;
1085 static void test_clip(void)
1087 IDXGISwapChain *swapchain;
1088 D2D1_MATRIX_3X2_F matrix;
1089 D2D1_SIZE_U pixel_size;
1090 ID2D1RenderTarget *rt;
1091 ID3D10Device1 *device;
1092 IDXGISurface *surface;
1093 D2D1_POINT_2F point;
1094 D2D1_COLOR_F color;
1095 float dpi_x, dpi_y;
1096 D2D1_RECT_F rect;
1097 D2D1_SIZE_F size;
1098 HWND window;
1099 HRESULT hr;
1100 BOOL match;
1101 static const D2D1_MATRIX_3X2_F identity =
1103 1.0f, 0.0f,
1104 0.0f, 1.0f,
1105 0.0f, 0.0f,
1106 }}};
1108 if (!(device = create_device()))
1110 skip("Failed to create device, skipping tests.\n");
1111 return;
1113 window = create_window();
1114 swapchain = create_swapchain(device, window, TRUE);
1115 hr = IDXGISwapChain_GetBuffer(swapchain, 0, &IID_IDXGISurface, (void **)&surface);
1116 ok(SUCCEEDED(hr), "Failed to get buffer, hr %#x.\n", hr);
1117 rt = create_render_target(surface);
1118 ok(!!rt, "Failed to create render target.\n");
1120 ID2D1RenderTarget_GetDpi(rt, &dpi_x, &dpi_y);
1121 ok(dpi_x == 96.0f, "Got unexpected dpi_x %.8e.\n", dpi_x);
1122 ok(dpi_y == 96.0f, "Got unexpected dpi_x %.8e.\n", dpi_y);
1123 size = ID2D1RenderTarget_GetSize(rt);
1124 ok(size.width == 640.0f, "Got unexpected width %.8e.\n", size.width);
1125 ok(size.height == 480.0f, "Got unexpected height %.8e.\n", size.height);
1126 pixel_size = ID2D1RenderTarget_GetPixelSize(rt);
1127 ok(pixel_size.width == 640, "Got unexpected width %u.\n", pixel_size.width);
1128 ok(pixel_size.height == 480, "Got unexpected height %u.\n", pixel_size.height);
1130 ID2D1RenderTarget_GetTransform(rt, &matrix);
1131 ok(!memcmp(&matrix, &identity, sizeof(matrix)),
1132 "Got unexpected matrix {%.8e, %.8e, %.8e, %.8e, %.8e, %.8e}.\n",
1133 matrix._11, matrix._12, matrix._21, matrix._22, matrix._31, matrix._32);
1135 ID2D1RenderTarget_BeginDraw(rt);
1137 set_color(&color, 1.0f, 1.0f, 0.0f, 1.0f);
1138 ID2D1RenderTarget_Clear(rt, &color);
1140 ID2D1RenderTarget_SetDpi(rt, 48.0f, 192.0f);
1141 ID2D1RenderTarget_GetDpi(rt, &dpi_x, &dpi_y);
1142 ok(dpi_x == 48.0f, "Got unexpected dpi_x %.8e.\n", dpi_x);
1143 ok(dpi_y == 192.0f, "Got unexpected dpi_x %.8e.\n", dpi_y);
1144 size = ID2D1RenderTarget_GetSize(rt);
1145 ok(size.width == 1280.0f, "Got unexpected width %.8e.\n", size.width);
1146 ok(size.height == 240.0f, "Got unexpected height %.8e.\n", size.height);
1147 pixel_size = ID2D1RenderTarget_GetPixelSize(rt);
1148 ok(pixel_size.width == 640, "Got unexpected width %u.\n", pixel_size.width);
1149 ok(pixel_size.height == 480, "Got unexpected height %u.\n", pixel_size.height);
1151 /* The effective clip rect is the intersection of all currently pushed
1152 * clip rects. Clip rects are in DIPs. */
1153 set_rect(&rect, 0.0f, 0.0f, 1280.0f, 80.0f);
1154 ID2D1RenderTarget_PushAxisAlignedClip(rt, &rect, D2D1_ANTIALIAS_MODE_ALIASED);
1155 set_rect(&rect, 0.0f, 0.0f, 426.0f, 240.0f);
1156 ID2D1RenderTarget_PushAxisAlignedClip(rt, &rect, D2D1_ANTIALIAS_MODE_ALIASED);
1158 set_color(&color, 0.0f, 1.0f, 0.0f, 1.0f);
1159 ID2D1RenderTarget_Clear(rt, &color);
1160 ID2D1RenderTarget_PopAxisAlignedClip(rt);
1161 ID2D1RenderTarget_PopAxisAlignedClip(rt);
1163 ID2D1RenderTarget_SetDpi(rt, 0.0f, 0.0f);
1164 ID2D1RenderTarget_GetDpi(rt, &dpi_x, &dpi_y);
1165 ok(dpi_x == 96.0f, "Got unexpected dpi_x %.8e.\n", dpi_x);
1166 ok(dpi_y == 96.0f, "Got unexpected dpi_y %.8e.\n", dpi_y);
1168 ID2D1RenderTarget_SetDpi(rt, 192.0f, 192.0f);
1169 ID2D1RenderTarget_SetDpi(rt, 0.0f, 96.0f);
1170 ID2D1RenderTarget_GetDpi(rt, &dpi_x, &dpi_y);
1171 ok(dpi_x == 192.0f, "Got unexpected dpi_x %.8e.\n", dpi_x);
1172 ok(dpi_y == 192.0f, "Got unexpected dpi_y %.8e.\n", dpi_y);
1174 ID2D1RenderTarget_SetDpi(rt, -10.0f, 96.0f);
1175 ID2D1RenderTarget_GetDpi(rt, &dpi_x, &dpi_y);
1176 ok(dpi_x == 192.0f, "Got unexpected dpi_x %.8e.\n", dpi_x);
1177 ok(dpi_y == 192.0f, "Got unexpected dpi_y %.8e.\n", dpi_y);
1179 ID2D1RenderTarget_SetDpi(rt, 96.0f, -10.0f);
1180 ID2D1RenderTarget_GetDpi(rt, &dpi_x, &dpi_y);
1181 ok(dpi_x == 192.0f, "Got unexpected dpi_x %.8e.\n", dpi_x);
1182 ok(dpi_y == 192.0f, "Got unexpected dpi_y %.8e.\n", dpi_y);
1184 ID2D1RenderTarget_SetDpi(rt, 96.0f, 0.0f);
1185 ID2D1RenderTarget_GetDpi(rt, &dpi_x, &dpi_y);
1186 ok(dpi_x == 192.0f, "Got unexpected dpi_x %.8e.\n", dpi_x);
1187 ok(dpi_y == 192.0f, "Got unexpected dpi_y %.8e.\n", dpi_y);
1189 ID2D1RenderTarget_SetDpi(rt, 96.0f, 96.0f);
1191 /* Transformations apply to clip rects, the effective clip rect is the
1192 * (axis-aligned) bounding box of the transformed clip rect. */
1193 set_point(&point, 320.0f, 240.0f);
1194 D2D1MakeRotateMatrix(30.0f, point, &matrix);
1195 ID2D1RenderTarget_SetTransform(rt, &matrix);
1196 set_rect(&rect, 215.0f, 208.0f, 425.0f, 272.0f);
1197 ID2D1RenderTarget_PushAxisAlignedClip(rt, &rect, D2D1_ANTIALIAS_MODE_ALIASED);
1198 set_color(&color, 1.0f, 1.0f, 1.0f, 1.0f);
1199 ID2D1RenderTarget_Clear(rt, &color);
1200 ID2D1RenderTarget_PopAxisAlignedClip(rt);
1202 /* Transformations are applied when pushing the clip rect, transformations
1203 * set afterwards have no effect on the current clip rect. This includes
1204 * SetDpi(). */
1205 ID2D1RenderTarget_SetTransform(rt, &identity);
1206 set_rect(&rect, 427.0f, 320.0f, 640.0f, 480.0f);
1207 ID2D1RenderTarget_PushAxisAlignedClip(rt, &rect, D2D1_ANTIALIAS_MODE_ALIASED);
1208 ID2D1RenderTarget_SetTransform(rt, &matrix);
1209 ID2D1RenderTarget_SetDpi(rt, 48.0f, 192.0f);
1210 set_color(&color, 1.0f, 0.0f, 0.0f, 1.0f);
1211 ID2D1RenderTarget_Clear(rt, &color);
1212 ID2D1RenderTarget_PopAxisAlignedClip(rt);
1214 hr = ID2D1RenderTarget_EndDraw(rt, NULL, NULL);
1215 ok(SUCCEEDED(hr), "Failed to end draw, hr %#x.\n", hr);
1216 match = compare_surface(surface, "035a44d4198d6e422e9de6185b5b2c2bac5e33c9");
1217 ok(match, "Surface does not match.\n");
1219 /* Fractional clip rectangle coordinates, aliased mode. */
1220 set_matrix_identity(&matrix);
1221 ID2D1RenderTarget_SetTransform(rt, &matrix);
1222 ID2D1RenderTarget_SetDpi(rt, 96.0f, 96.0f);
1224 ID2D1RenderTarget_BeginDraw(rt);
1226 set_color(&color, 0.0f, 0.0f, 0.0f, 1.0f);
1227 ID2D1RenderTarget_Clear(rt, &color);
1229 scale_matrix(&matrix, 2.0f, 2.0f);
1230 ID2D1RenderTarget_SetTransform(rt, &matrix);
1231 set_rect(&rect, 0.0f, 0.5f, 200.0f, 100.5f);
1232 set_color(&color, 1.0f, 0.0f, 1.0f, 1.0f);
1233 ID2D1RenderTarget_PushAxisAlignedClip(rt, &rect, D2D1_ANTIALIAS_MODE_ALIASED);
1234 ID2D1RenderTarget_Clear(rt, &color);
1235 ID2D1RenderTarget_PopAxisAlignedClip(rt);
1237 set_matrix_identity(&matrix);
1238 ID2D1RenderTarget_SetTransform(rt, &matrix);
1239 set_rect(&rect, 0.0f, 0.5f, 100.0f, 200.5f);
1240 set_color(&color, 1.0f, 0.0f, 0.0f, 1.0f);
1241 ID2D1RenderTarget_PushAxisAlignedClip(rt, &rect, D2D1_ANTIALIAS_MODE_ALIASED);
1242 ID2D1RenderTarget_Clear(rt, &color);
1243 ID2D1RenderTarget_PopAxisAlignedClip(rt);
1245 ID2D1RenderTarget_SetTransform(rt, &matrix);
1246 set_rect(&rect, 0.5f, 250.0f, 100.5f, 300.0f);
1247 set_color(&color, 1.0f, 1.0f, 0.0f, 1.0f);
1248 ID2D1RenderTarget_PushAxisAlignedClip(rt, &rect, D2D1_ANTIALIAS_MODE_ALIASED);
1249 ID2D1RenderTarget_Clear(rt, &color);
1250 ID2D1RenderTarget_PopAxisAlignedClip(rt);
1252 translate_matrix(&matrix, 0.1f, 0.0f);
1253 ID2D1RenderTarget_SetTransform(rt, &matrix);
1254 set_rect(&rect, 110.0f, 250.25f, 150.0f, 300.25f);
1255 set_color(&color, 0.0f, 1.0f, 0.0f, 1.0f);
1256 ID2D1RenderTarget_PushAxisAlignedClip(rt, &rect, D2D1_ANTIALIAS_MODE_ALIASED);
1257 ID2D1RenderTarget_Clear(rt, &color);
1258 ID2D1RenderTarget_PopAxisAlignedClip(rt);
1260 set_rect(&rect, 160.0f, 250.75f, 200.0f, 300.75f);
1261 set_color(&color, 0.0f, 0.0f, 1.0f, 1.0f);
1262 ID2D1RenderTarget_PushAxisAlignedClip(rt, &rect, D2D1_ANTIALIAS_MODE_ALIASED);
1263 ID2D1RenderTarget_Clear(rt, &color);
1264 ID2D1RenderTarget_PopAxisAlignedClip(rt);
1266 ID2D1RenderTarget_SetDpi(rt, 48.0f, 192.0f);
1267 set_rect(&rect, 160.25f, 0.0f, 200.25f, 100.0f);
1268 set_color(&color, 1.0f, 0.0f, 1.0f, 1.0f);
1269 ID2D1RenderTarget_PushAxisAlignedClip(rt, &rect, D2D1_ANTIALIAS_MODE_ALIASED);
1270 ID2D1RenderTarget_Clear(rt, &color);
1271 ID2D1RenderTarget_PopAxisAlignedClip(rt);
1273 ID2D1RenderTarget_SetDpi(rt, 192.0f, 48.0f);
1274 set_rect(&rect, 160.75f, 100.0f, 200.75f, 120.0f);
1275 set_color(&color, 0.0f, 1.0f, 1.0f, 1.0f);
1276 ID2D1RenderTarget_PushAxisAlignedClip(rt, &rect, D2D1_ANTIALIAS_MODE_ALIASED);
1277 ID2D1RenderTarget_Clear(rt, &color);
1278 ID2D1RenderTarget_PopAxisAlignedClip(rt);
1280 hr = ID2D1RenderTarget_EndDraw(rt, NULL, NULL);
1281 ok(SUCCEEDED(hr), "Failed to end draw, hr %#x.\n", hr);
1282 match = compare_surface(surface, "cb418ec4a7c8407b5e36db06fc6292a06bb8476c");
1283 ok(match, "Surface does not match.\n");
1285 ID2D1RenderTarget_Release(rt);
1286 IDXGISurface_Release(surface);
1287 IDXGISwapChain_Release(swapchain);
1288 ID3D10Device1_Release(device);
1289 DestroyWindow(window);
1292 static void test_state_block(void)
1294 IDWriteRenderingParams *text_rendering_params1, *text_rendering_params2;
1295 D2D1_DRAWING_STATE_DESCRIPTION drawing_state;
1296 ID2D1DrawingStateBlock *state_block;
1297 IDWriteFactory *dwrite_factory;
1298 IDXGISwapChain *swapchain;
1299 ID2D1Factory1 *factory1;
1300 ID2D1RenderTarget *rt;
1301 ID3D10Device1 *device;
1302 IDXGISurface *surface;
1303 ID2D1Factory *factory;
1304 ULONG refcount;
1305 HWND window;
1306 HRESULT hr;
1307 static const D2D1_MATRIX_3X2_F identity =
1309 1.0f, 0.0f,
1310 0.0f, 1.0f,
1311 0.0f, 0.0f,
1312 }}};
1313 static const D2D1_MATRIX_3X2_F transform1 =
1315 1.0f, 2.0f,
1316 3.0f, 4.0f,
1317 5.0f, 6.0f,
1318 }}};
1319 static const D2D1_MATRIX_3X2_F transform2 =
1321 7.0f, 8.0f,
1322 9.0f, 10.0f,
1323 11.0f, 12.0f,
1324 }}};
1326 if (!(device = create_device()))
1328 skip("Failed to create device, skipping tests.\n");
1329 return;
1331 window = create_window();
1332 swapchain = create_swapchain(device, window, TRUE);
1333 hr = IDXGISwapChain_GetBuffer(swapchain, 0, &IID_IDXGISurface, (void **)&surface);
1334 ok(SUCCEEDED(hr), "Failed to get buffer, hr %#x.\n", hr);
1335 rt = create_render_target(surface);
1336 ok(!!rt, "Failed to create render target.\n");
1337 ID2D1RenderTarget_GetFactory(rt, &factory);
1338 hr = DWriteCreateFactory(DWRITE_FACTORY_TYPE_SHARED, &IID_IDWriteFactory, (IUnknown **)&dwrite_factory);
1339 ok(SUCCEEDED(hr), "Failed to create dwrite factory, hr %#x.\n", hr);
1340 hr = IDWriteFactory_CreateRenderingParams(dwrite_factory, &text_rendering_params1);
1341 ok(SUCCEEDED(hr), "Failed to create dwrite rendering params, hr %#x.\n", hr);
1342 IDWriteFactory_Release(dwrite_factory);
1344 drawing_state.antialiasMode = ID2D1RenderTarget_GetAntialiasMode(rt);
1345 ok(drawing_state.antialiasMode == D2D1_ANTIALIAS_MODE_PER_PRIMITIVE,
1346 "Got unexpected antialias mode %#x.\n", drawing_state.antialiasMode);
1347 drawing_state.textAntialiasMode = ID2D1RenderTarget_GetTextAntialiasMode(rt);
1348 ok(drawing_state.textAntialiasMode == D2D1_TEXT_ANTIALIAS_MODE_DEFAULT,
1349 "Got unexpected text antialias mode %#x.\n", drawing_state.textAntialiasMode);
1350 ID2D1RenderTarget_GetTags(rt, &drawing_state.tag1, &drawing_state.tag2);
1351 ok(!drawing_state.tag1 && !drawing_state.tag2, "Got unexpected tags %s:%s.\n",
1352 wine_dbgstr_longlong(drawing_state.tag1), wine_dbgstr_longlong(drawing_state.tag2));
1353 ID2D1RenderTarget_GetTransform(rt, &drawing_state.transform);
1354 ok(!memcmp(&drawing_state.transform, &identity, sizeof(drawing_state.transform)),
1355 "Got unexpected matrix {%.8e, %.8e, %.8e, %.8e, %.8e, %.8e}.\n",
1356 drawing_state.transform._11, drawing_state.transform._12, drawing_state.transform._21,
1357 drawing_state.transform._22, drawing_state.transform._31, drawing_state.transform._32);
1358 ID2D1RenderTarget_GetTextRenderingParams(rt, &text_rendering_params2);
1359 ok(!text_rendering_params2, "Got unexpected text rendering params %p.\n", text_rendering_params2);
1361 hr = ID2D1Factory_CreateDrawingStateBlock(factory, NULL, NULL, &state_block);
1362 ok(SUCCEEDED(hr), "Failed to create drawing state block, hr %#x\n", hr);
1363 ID2D1DrawingStateBlock_GetDescription(state_block, &drawing_state);
1364 ok(drawing_state.antialiasMode == D2D1_ANTIALIAS_MODE_PER_PRIMITIVE,
1365 "Got unexpected antialias mode %#x.\n", drawing_state.antialiasMode);
1366 ok(drawing_state.textAntialiasMode == D2D1_TEXT_ANTIALIAS_MODE_DEFAULT,
1367 "Got unexpected text antialias mode %#x.\n", drawing_state.textAntialiasMode);
1368 ok(!drawing_state.tag1 && !drawing_state.tag2, "Got unexpected tags %s:%s.\n",
1369 wine_dbgstr_longlong(drawing_state.tag1), wine_dbgstr_longlong(drawing_state.tag2));
1370 ok(!memcmp(&drawing_state.transform, &identity, sizeof(drawing_state.transform)),
1371 "Got unexpected matrix {%.8e, %.8e, %.8e, %.8e, %.8e, %.8e}.\n",
1372 drawing_state.transform._11, drawing_state.transform._12, drawing_state.transform._21,
1373 drawing_state.transform._22, drawing_state.transform._31, drawing_state.transform._32);
1374 ID2D1DrawingStateBlock_GetTextRenderingParams(state_block, &text_rendering_params2);
1375 ok(!text_rendering_params2, "Got unexpected text rendering params %p.\n", text_rendering_params2);
1376 ID2D1DrawingStateBlock_Release(state_block);
1378 drawing_state.antialiasMode = D2D1_ANTIALIAS_MODE_ALIASED;
1379 drawing_state.textAntialiasMode = D2D1_TEXT_ANTIALIAS_MODE_ALIASED;
1380 drawing_state.tag1 = 0xdead;
1381 drawing_state.tag2 = 0xbeef;
1382 drawing_state.transform = transform1;
1383 hr = ID2D1Factory_CreateDrawingStateBlock(factory, &drawing_state, text_rendering_params1, &state_block);
1384 ok(SUCCEEDED(hr), "Failed to create drawing state block, hr %#x\n", hr);
1386 ID2D1DrawingStateBlock_GetDescription(state_block, &drawing_state);
1387 ok(drawing_state.antialiasMode == D2D1_ANTIALIAS_MODE_ALIASED,
1388 "Got unexpected antialias mode %#x.\n", drawing_state.antialiasMode);
1389 ok(drawing_state.textAntialiasMode == D2D1_TEXT_ANTIALIAS_MODE_ALIASED,
1390 "Got unexpected text antialias mode %#x.\n", drawing_state.textAntialiasMode);
1391 ok(drawing_state.tag1 == 0xdead && drawing_state.tag2 == 0xbeef, "Got unexpected tags %s:%s.\n",
1392 wine_dbgstr_longlong(drawing_state.tag1), wine_dbgstr_longlong(drawing_state.tag2));
1393 ok(!memcmp(&drawing_state.transform, &transform1, sizeof(drawing_state.transform)),
1394 "Got unexpected matrix {%.8e, %.8e, %.8e, %.8e, %.8e, %.8e}.\n",
1395 drawing_state.transform._11, drawing_state.transform._12, drawing_state.transform._21,
1396 drawing_state.transform._22, drawing_state.transform._31, drawing_state.transform._32);
1397 ID2D1DrawingStateBlock_GetTextRenderingParams(state_block, &text_rendering_params2);
1398 ok(text_rendering_params2 == text_rendering_params1, "Got unexpected text rendering params %p, expected %p.\n",
1399 text_rendering_params2, text_rendering_params1);
1400 IDWriteRenderingParams_Release(text_rendering_params2);
1402 ID2D1RenderTarget_RestoreDrawingState(rt, state_block);
1404 drawing_state.antialiasMode = ID2D1RenderTarget_GetAntialiasMode(rt);
1405 ok(drawing_state.antialiasMode == D2D1_ANTIALIAS_MODE_ALIASED,
1406 "Got unexpected antialias mode %#x.\n", drawing_state.antialiasMode);
1407 drawing_state.textAntialiasMode = ID2D1RenderTarget_GetTextAntialiasMode(rt);
1408 ok(drawing_state.textAntialiasMode == D2D1_TEXT_ANTIALIAS_MODE_ALIASED,
1409 "Got unexpected text antialias mode %#x.\n", drawing_state.textAntialiasMode);
1410 ID2D1RenderTarget_GetTags(rt, &drawing_state.tag1, &drawing_state.tag2);
1411 ok(drawing_state.tag1 == 0xdead && drawing_state.tag2 == 0xbeef, "Got unexpected tags %s:%s.\n",
1412 wine_dbgstr_longlong(drawing_state.tag1), wine_dbgstr_longlong(drawing_state.tag2));
1413 ID2D1RenderTarget_GetTransform(rt, &drawing_state.transform);
1414 ok(!memcmp(&drawing_state.transform, &transform1, sizeof(drawing_state.transform)),
1415 "Got unexpected matrix {%.8e, %.8e, %.8e, %.8e, %.8e, %.8e}.\n",
1416 drawing_state.transform._11, drawing_state.transform._12, drawing_state.transform._21,
1417 drawing_state.transform._22, drawing_state.transform._31, drawing_state.transform._32);
1418 ID2D1RenderTarget_GetTextRenderingParams(rt, &text_rendering_params2);
1419 ok(text_rendering_params2 == text_rendering_params1, "Got unexpected text rendering params %p, expected %p.\n",
1420 text_rendering_params2, text_rendering_params1);
1421 IDWriteRenderingParams_Release(text_rendering_params2);
1423 ID2D1RenderTarget_SetAntialiasMode(rt, D2D1_ANTIALIAS_MODE_PER_PRIMITIVE);
1424 ID2D1RenderTarget_SetTextAntialiasMode(rt, D2D1_TEXT_ANTIALIAS_MODE_GRAYSCALE);
1425 ID2D1RenderTarget_SetTags(rt, 1, 2);
1426 ID2D1RenderTarget_SetTransform(rt, &transform2);
1427 ID2D1RenderTarget_SetTextRenderingParams(rt, NULL);
1429 drawing_state.antialiasMode = ID2D1RenderTarget_GetAntialiasMode(rt);
1430 ok(drawing_state.antialiasMode == D2D1_ANTIALIAS_MODE_PER_PRIMITIVE,
1431 "Got unexpected antialias mode %#x.\n", drawing_state.antialiasMode);
1432 drawing_state.textAntialiasMode = ID2D1RenderTarget_GetTextAntialiasMode(rt);
1433 ok(drawing_state.textAntialiasMode == D2D1_TEXT_ANTIALIAS_MODE_GRAYSCALE,
1434 "Got unexpected text antialias mode %#x.\n", drawing_state.textAntialiasMode);
1435 ID2D1RenderTarget_GetTags(rt, &drawing_state.tag1, &drawing_state.tag2);
1436 ok(drawing_state.tag1 == 1 && drawing_state.tag2 == 2, "Got unexpected tags %s:%s.\n",
1437 wine_dbgstr_longlong(drawing_state.tag1), wine_dbgstr_longlong(drawing_state.tag2));
1438 ID2D1RenderTarget_GetTransform(rt, &drawing_state.transform);
1439 ok(!memcmp(&drawing_state.transform, &transform2, sizeof(drawing_state.transform)),
1440 "Got unexpected matrix {%.8e, %.8e, %.8e, %.8e, %.8e, %.8e}.\n",
1441 drawing_state.transform._11, drawing_state.transform._12, drawing_state.transform._21,
1442 drawing_state.transform._22, drawing_state.transform._31, drawing_state.transform._32);
1443 ID2D1RenderTarget_GetTextRenderingParams(rt, &text_rendering_params2);
1444 ok(!text_rendering_params2, "Got unexpected text rendering params %p.\n", text_rendering_params2);
1446 ID2D1RenderTarget_SaveDrawingState(rt, state_block);
1448 ID2D1DrawingStateBlock_GetDescription(state_block, &drawing_state);
1449 ok(drawing_state.antialiasMode == D2D1_ANTIALIAS_MODE_PER_PRIMITIVE,
1450 "Got unexpected antialias mode %#x.\n", drawing_state.antialiasMode);
1451 ok(drawing_state.textAntialiasMode == D2D1_TEXT_ANTIALIAS_MODE_GRAYSCALE,
1452 "Got unexpected text antialias mode %#x.\n", drawing_state.textAntialiasMode);
1453 ok(drawing_state.tag1 == 1 && drawing_state.tag2 == 2, "Got unexpected tags %s:%s.\n",
1454 wine_dbgstr_longlong(drawing_state.tag1), wine_dbgstr_longlong(drawing_state.tag2));
1455 ok(!memcmp(&drawing_state.transform, &transform2, sizeof(drawing_state.transform)),
1456 "Got unexpected matrix {%.8e, %.8e, %.8e, %.8e, %.8e, %.8e}.\n",
1457 drawing_state.transform._11, drawing_state.transform._12, drawing_state.transform._21,
1458 drawing_state.transform._22, drawing_state.transform._31, drawing_state.transform._32);
1459 ID2D1DrawingStateBlock_GetTextRenderingParams(state_block, &text_rendering_params2);
1460 ok(!text_rendering_params2, "Got unexpected text rendering params %p.\n", text_rendering_params2);
1462 drawing_state.antialiasMode = D2D1_ANTIALIAS_MODE_ALIASED;
1463 drawing_state.textAntialiasMode = D2D1_TEXT_ANTIALIAS_MODE_CLEARTYPE;
1464 drawing_state.tag1 = 3;
1465 drawing_state.tag2 = 4;
1466 drawing_state.transform = transform1;
1467 ID2D1DrawingStateBlock_SetDescription(state_block, &drawing_state);
1468 ID2D1DrawingStateBlock_SetTextRenderingParams(state_block, text_rendering_params1);
1470 ID2D1DrawingStateBlock_GetDescription(state_block, &drawing_state);
1471 ok(drawing_state.antialiasMode == D2D1_ANTIALIAS_MODE_ALIASED,
1472 "Got unexpected antialias mode %#x.\n", drawing_state.antialiasMode);
1473 ok(drawing_state.textAntialiasMode == D2D1_TEXT_ANTIALIAS_MODE_CLEARTYPE,
1474 "Got unexpected text antialias mode %#x.\n", drawing_state.textAntialiasMode);
1475 ok(drawing_state.tag1 == 3 && drawing_state.tag2 == 4, "Got unexpected tags %s:%s.\n",
1476 wine_dbgstr_longlong(drawing_state.tag1), wine_dbgstr_longlong(drawing_state.tag2));
1477 ok(!memcmp(&drawing_state.transform, &transform1, sizeof(drawing_state.transform)),
1478 "Got unexpected matrix {%.8e, %.8e, %.8e, %.8e, %.8e, %.8e}.\n",
1479 drawing_state.transform._11, drawing_state.transform._12, drawing_state.transform._21,
1480 drawing_state.transform._22, drawing_state.transform._31, drawing_state.transform._32);
1481 ID2D1DrawingStateBlock_GetTextRenderingParams(state_block, &text_rendering_params2);
1482 ok(text_rendering_params2 == text_rendering_params1, "Got unexpected text rendering params %p, expected %p.\n",
1483 text_rendering_params2, text_rendering_params1);
1484 IDWriteRenderingParams_Release(text_rendering_params2);
1486 if (SUCCEEDED(ID2D1Factory_QueryInterface(factory, &IID_ID2D1Factory1, (void **)&factory1)))
1488 D2D1_DRAWING_STATE_DESCRIPTION1 drawing_state1;
1489 ID2D1DrawingStateBlock1 *state_block1;
1491 hr = ID2D1DrawingStateBlock_QueryInterface(state_block, &IID_ID2D1DrawingStateBlock1, (void **)&state_block1);
1492 ok(SUCCEEDED(hr), "Failed to get ID2D1DrawingStateBlock1 interface, hr %#x.\n", hr);
1494 ID2D1DrawingStateBlock1_GetDescription(state_block1, &drawing_state1);
1495 ok(drawing_state1.antialiasMode == D2D1_ANTIALIAS_MODE_ALIASED,
1496 "Got unexpected antialias mode %#x.\n", drawing_state1.antialiasMode);
1497 ok(drawing_state1.textAntialiasMode == D2D1_TEXT_ANTIALIAS_MODE_CLEARTYPE,
1498 "Got unexpected text antialias mode %#x.\n", drawing_state1.textAntialiasMode);
1499 ok(drawing_state1.tag1 == 3 && drawing_state1.tag2 == 4, "Got unexpected tags %s:%s.\n",
1500 wine_dbgstr_longlong(drawing_state1.tag1), wine_dbgstr_longlong(drawing_state1.tag2));
1501 ok(!memcmp(&drawing_state1.transform, &transform1, sizeof(drawing_state1.transform)),
1502 "Got unexpected matrix {%.8e, %.8e, %.8e, %.8e, %.8e, %.8e}.\n",
1503 drawing_state1.transform._11, drawing_state1.transform._12, drawing_state1.transform._21,
1504 drawing_state1.transform._22, drawing_state1.transform._31, drawing_state1.transform._32);
1505 ok(drawing_state1.primitiveBlend == D2D1_PRIMITIVE_BLEND_SOURCE_OVER,
1506 "Got unexpected primitive blend mode %#x.\n", drawing_state1.primitiveBlend);
1507 ok(drawing_state1.unitMode == D2D1_UNIT_MODE_DIPS, "Got unexpected unit mode %#x.\n", drawing_state1.unitMode);
1508 ID2D1DrawingStateBlock1_GetTextRenderingParams(state_block1, &text_rendering_params2);
1509 ok(text_rendering_params2 == text_rendering_params1, "Got unexpected text rendering params %p, expected %p.\n",
1510 text_rendering_params2, text_rendering_params1);
1511 IDWriteRenderingParams_Release(text_rendering_params2);
1513 drawing_state1.primitiveBlend = D2D1_PRIMITIVE_BLEND_COPY;
1514 drawing_state1.unitMode = D2D1_UNIT_MODE_PIXELS;
1515 ID2D1DrawingStateBlock1_SetDescription(state_block1, &drawing_state1);
1516 ID2D1DrawingStateBlock1_GetDescription(state_block1, &drawing_state1);
1517 ok(drawing_state1.primitiveBlend == D2D1_PRIMITIVE_BLEND_COPY,
1518 "Got unexpected primitive blend mode %#x.\n", drawing_state1.primitiveBlend);
1519 ok(drawing_state1.unitMode == D2D1_UNIT_MODE_PIXELS,
1520 "Got unexpected unit mode %#x.\n", drawing_state1.unitMode);
1522 ID2D1DrawingStateBlock_SetDescription(state_block, &drawing_state);
1523 ID2D1DrawingStateBlock1_GetDescription(state_block1, &drawing_state1);
1524 ok(drawing_state1.primitiveBlend == D2D1_PRIMITIVE_BLEND_COPY,
1525 "Got unexpected primitive blend mode %#x.\n", drawing_state1.primitiveBlend);
1526 ok(drawing_state1.unitMode == D2D1_UNIT_MODE_PIXELS,
1527 "Got unexpected unit mode %#x.\n", drawing_state1.unitMode);
1529 ID2D1DrawingStateBlock1_Release(state_block1);
1531 hr = ID2D1Factory1_CreateDrawingStateBlock(factory1, NULL, NULL, &state_block1);
1532 ok(SUCCEEDED(hr), "Failed to create drawing state block, hr %#x\n", hr);
1533 ID2D1DrawingStateBlock1_GetDescription(state_block1, &drawing_state1);
1534 ok(drawing_state1.antialiasMode == D2D1_ANTIALIAS_MODE_PER_PRIMITIVE,
1535 "Got unexpected antialias mode %#x.\n", drawing_state1.antialiasMode);
1536 ok(drawing_state1.textAntialiasMode == D2D1_TEXT_ANTIALIAS_MODE_DEFAULT,
1537 "Got unexpected text antialias mode %#x.\n", drawing_state1.textAntialiasMode);
1538 ok(drawing_state1.tag1 == 0 && drawing_state1.tag2 == 0, "Got unexpected tags %s:%s.\n",
1539 wine_dbgstr_longlong(drawing_state1.tag1), wine_dbgstr_longlong(drawing_state1.tag2));
1540 ok(!memcmp(&drawing_state1.transform, &identity, sizeof(drawing_state1.transform)),
1541 "Got unexpected matrix {%.8e, %.8e, %.8e, %.8e, %.8e, %.8e}.\n",
1542 drawing_state1.transform._11, drawing_state1.transform._12, drawing_state1.transform._21,
1543 drawing_state1.transform._22, drawing_state1.transform._31, drawing_state1.transform._32);
1544 ok(drawing_state1.primitiveBlend == D2D1_PRIMITIVE_BLEND_SOURCE_OVER,
1545 "Got unexpected primitive blend mode %#x.\n", drawing_state1.primitiveBlend);
1546 ok(drawing_state1.unitMode == D2D1_UNIT_MODE_DIPS, "Got unexpected unit mode %#x.\n", drawing_state1.unitMode);
1547 ID2D1DrawingStateBlock1_GetTextRenderingParams(state_block1, &text_rendering_params2);
1548 ok(!text_rendering_params2, "Got unexpected text rendering params %p.\n", text_rendering_params2);
1549 ID2D1DrawingStateBlock1_Release(state_block1);
1551 ID2D1Factory1_Release(factory1);
1554 ID2D1DrawingStateBlock_Release(state_block);
1556 refcount = IDWriteRenderingParams_Release(text_rendering_params1);
1557 ok(!refcount, "Rendering params %u references left.\n", refcount);
1558 ID2D1Factory_Release(factory);
1559 ID2D1RenderTarget_Release(rt);
1560 IDXGISurface_Release(surface);
1561 IDXGISwapChain_Release(swapchain);
1562 ID3D10Device1_Release(device);
1563 DestroyWindow(window);
1566 static void test_color_brush(void)
1568 D2D1_MATRIX_3X2_F matrix, tmp_matrix;
1569 D2D1_BRUSH_PROPERTIES brush_desc;
1570 D2D1_COLOR_F color, tmp_color;
1571 ID2D1SolidColorBrush *brush;
1572 IDXGISwapChain *swapchain;
1573 ID2D1RenderTarget *rt;
1574 ID3D10Device1 *device;
1575 IDXGISurface *surface;
1576 D2D1_RECT_F rect;
1577 float opacity;
1578 HWND window;
1579 HRESULT hr;
1580 BOOL match;
1582 if (!(device = create_device()))
1584 skip("Failed to create device, skipping tests.\n");
1585 return;
1587 window = create_window();
1588 swapchain = create_swapchain(device, window, TRUE);
1589 hr = IDXGISwapChain_GetBuffer(swapchain, 0, &IID_IDXGISurface, (void **)&surface);
1590 ok(SUCCEEDED(hr), "Failed to get buffer, hr %#x.\n", hr);
1591 rt = create_render_target(surface);
1592 ok(!!rt, "Failed to create render target.\n");
1594 ID2D1RenderTarget_SetDpi(rt, 192.0f, 48.0f);
1595 ID2D1RenderTarget_SetAntialiasMode(rt, D2D1_ANTIALIAS_MODE_ALIASED);
1597 set_color(&color, 0.0f, 0.0f, 0.0f, 0.0f);
1598 hr = ID2D1RenderTarget_CreateSolidColorBrush(rt, &color, NULL, &brush);
1599 ok(SUCCEEDED(hr), "Failed to create brush, hr %#x.\n", hr);
1600 opacity = ID2D1SolidColorBrush_GetOpacity(brush);
1601 ok(opacity == 1.0f, "Got unexpected opacity %.8e.\n", opacity);
1602 set_matrix_identity(&matrix);
1603 ID2D1SolidColorBrush_GetTransform(brush, &tmp_matrix);
1604 ok(!memcmp(&tmp_matrix, &matrix, sizeof(matrix)),
1605 "Got unexpected matrix {%.8e, %.8e, %.8e, %.8e, %.8e, %.8e}.\n",
1606 tmp_matrix._11, tmp_matrix._12, tmp_matrix._21,
1607 tmp_matrix._22, tmp_matrix._31, tmp_matrix._32);
1608 tmp_color = ID2D1SolidColorBrush_GetColor(brush);
1609 ok(!memcmp(&tmp_color, &color, sizeof(color)),
1610 "Got unexpected color {%.8e, %.8e, %.8e, %.8e}.\n",
1611 tmp_color.r, tmp_color.g, tmp_color.b, tmp_color.a);
1612 ID2D1SolidColorBrush_Release(brush);
1614 set_color(&color, 0.0f, 1.0f, 0.0f, 0.8f);
1615 brush_desc.opacity = 0.3f;
1616 set_matrix_identity(&matrix);
1617 scale_matrix(&matrix, 2.0f, 2.0f);
1618 brush_desc.transform = matrix;
1619 hr = ID2D1RenderTarget_CreateSolidColorBrush(rt, &color, &brush_desc, &brush);
1620 ok(SUCCEEDED(hr), "Failed to create brush, hr %#x.\n", hr);
1621 opacity = ID2D1SolidColorBrush_GetOpacity(brush);
1622 ok(opacity == 0.3f, "Got unexpected opacity %.8e.\n", opacity);
1623 ID2D1SolidColorBrush_GetTransform(brush, &tmp_matrix);
1624 ok(!memcmp(&tmp_matrix, &matrix, sizeof(matrix)),
1625 "Got unexpected matrix {%.8e, %.8e, %.8e, %.8e, %.8e, %.8e}.\n",
1626 tmp_matrix._11, tmp_matrix._12, tmp_matrix._21,
1627 tmp_matrix._22, tmp_matrix._31, tmp_matrix._32);
1628 tmp_color = ID2D1SolidColorBrush_GetColor(brush);
1629 ok(!memcmp(&tmp_color, &color, sizeof(color)),
1630 "Got unexpected color {%.8e, %.8e, %.8e, %.8e}.\n",
1631 tmp_color.r, tmp_color.g, tmp_color.b, tmp_color.a);
1633 ID2D1RenderTarget_BeginDraw(rt);
1635 set_color(&color, 0.0f, 0.0f, 1.0f, 1.0f);
1636 ID2D1RenderTarget_Clear(rt, &color);
1638 ID2D1SolidColorBrush_SetOpacity(brush, 1.0f);
1639 set_rect(&rect, 40.0f, 120.0f, 120.0f, 360.0f);
1640 ID2D1RenderTarget_FillRectangle(rt, &rect, (ID2D1Brush *)brush);
1642 set_matrix_identity(&matrix);
1643 scale_matrix(&matrix, 0.5f, 2.0f);
1644 translate_matrix(&matrix, 320.0f, 240.0f);
1645 rotate_matrix(&matrix, M_PI / 4.0f);
1646 ID2D1RenderTarget_SetTransform(rt, &matrix);
1647 set_color(&color, 1.0f, 0.0f, 0.0f, 0.625f);
1648 ID2D1SolidColorBrush_SetColor(brush, &color);
1649 ID2D1SolidColorBrush_SetOpacity(brush, 0.75f);
1650 set_rect(&rect, -80.0f, -60.0f, 80.0f, 60.0f);
1651 ID2D1RenderTarget_FillRectangle(rt, &rect, (ID2D1Brush *)brush);
1653 hr = ID2D1RenderTarget_EndDraw(rt, NULL, NULL);
1654 ok(SUCCEEDED(hr), "Failed to end draw, hr %#x.\n", hr);
1655 match = compare_surface(surface, "6d1218fca5e21fb7e287b3a439d60dbc251f5ceb");
1656 ok(match, "Surface does not match.\n");
1658 ID2D1SolidColorBrush_Release(brush);
1659 ID2D1RenderTarget_Release(rt);
1660 IDXGISurface_Release(surface);
1661 IDXGISwapChain_Release(swapchain);
1662 ID3D10Device1_Release(device);
1663 DestroyWindow(window);
1666 static void test_bitmap_brush(void)
1668 D2D1_BITMAP_INTERPOLATION_MODE interpolation_mode;
1669 ID2D1TransformedGeometry *transformed_geometry;
1670 ID2D1RectangleGeometry *rectangle_geometry;
1671 D2D1_MATRIX_3X2_F matrix, tmp_matrix;
1672 D2D1_BITMAP_PROPERTIES bitmap_desc;
1673 ID2D1Bitmap *bitmap, *tmp_bitmap;
1674 D2D1_RECT_F src_rect, dst_rect;
1675 D2D1_EXTEND_MODE extend_mode;
1676 IDXGISwapChain *swapchain;
1677 ID2D1BitmapBrush1 *brush1;
1678 ID2D1BitmapBrush *brush;
1679 ID2D1RenderTarget *rt;
1680 ID3D10Device1 *device;
1681 IDXGISurface *surface;
1682 ID2D1Factory *factory;
1683 D2D1_COLOR_F color;
1684 ID2D1Image *image;
1685 D2D1_SIZE_U size;
1686 unsigned int i;
1687 ULONG refcount;
1688 float opacity;
1689 HWND window;
1690 HRESULT hr;
1691 BOOL match;
1693 static const struct
1695 D2D1_EXTEND_MODE extend_mode_x;
1696 D2D1_EXTEND_MODE extend_mode_y;
1697 float translate_x;
1698 float translate_y;
1699 D2D1_RECT_F rect;
1701 extend_mode_tests[] =
1703 {D2D1_EXTEND_MODE_MIRROR, D2D1_EXTEND_MODE_MIRROR, -7.0f, 1.0f, {-4.0f, 0.0f, -8.0f, 4.0f}},
1704 {D2D1_EXTEND_MODE_WRAP, D2D1_EXTEND_MODE_MIRROR, -3.0f, 1.0f, {-4.0f, 4.0f, 0.0f, 0.0f}},
1705 {D2D1_EXTEND_MODE_CLAMP, D2D1_EXTEND_MODE_MIRROR, 1.0f, 1.0f, { 4.0f, 0.0f, 0.0f, 4.0f}},
1706 {D2D1_EXTEND_MODE_MIRROR, D2D1_EXTEND_MODE_WRAP, -7.0f, 5.0f, {-8.0f, 8.0f, -4.0f, 4.0f}},
1707 {D2D1_EXTEND_MODE_WRAP, D2D1_EXTEND_MODE_WRAP, -3.0f, 5.0f, { 0.0f, 4.0f, -4.0f, 8.0f}},
1708 {D2D1_EXTEND_MODE_CLAMP, D2D1_EXTEND_MODE_WRAP, 1.0f, 5.0f, { 0.0f, 8.0f, 4.0f, 4.0f}},
1709 {D2D1_EXTEND_MODE_MIRROR, D2D1_EXTEND_MODE_CLAMP, -7.0f, 9.0f, {-4.0f, 8.0f, -8.0f, 12.0f}},
1710 {D2D1_EXTEND_MODE_WRAP, D2D1_EXTEND_MODE_CLAMP, -3.0f, 9.0f, {-4.0f, 12.0f, 0.0f, 8.0f}},
1711 {D2D1_EXTEND_MODE_CLAMP, D2D1_EXTEND_MODE_CLAMP, 1.0f, 9.0f, { 4.0f, 8.0f, 0.0f, 12.0f}},
1713 static const DWORD bitmap_data[] =
1715 0xffff0000, 0xffffff00, 0xff00ff00, 0xff00ffff,
1716 0xff0000ff, 0xffff00ff, 0xff000000, 0xff7f7f7f,
1717 0xffffffff, 0xffffffff, 0xffffffff, 0xff000000,
1718 0xffffffff, 0xff000000, 0xff000000, 0xff000000,
1721 if (!(device = create_device()))
1723 skip("Failed to create device, skipping tests.\n");
1724 return;
1726 window = create_window();
1727 swapchain = create_swapchain(device, window, TRUE);
1728 hr = IDXGISwapChain_GetBuffer(swapchain, 0, &IID_IDXGISurface, (void **)&surface);
1729 ok(SUCCEEDED(hr), "Failed to get buffer, hr %#x.\n", hr);
1730 rt = create_render_target(surface);
1731 ok(!!rt, "Failed to create render target.\n");
1733 ID2D1RenderTarget_SetDpi(rt, 192.0f, 48.0f);
1734 ID2D1RenderTarget_SetAntialiasMode(rt, D2D1_ANTIALIAS_MODE_ALIASED);
1736 set_size_u(&size, 4, 4);
1737 bitmap_desc.pixelFormat.format = DXGI_FORMAT_B8G8R8A8_UNORM;
1738 bitmap_desc.pixelFormat.alphaMode = D2D1_ALPHA_MODE_IGNORE;
1739 bitmap_desc.dpiX = 96.0f;
1740 bitmap_desc.dpiY = 96.0f;
1741 hr = ID2D1RenderTarget_CreateBitmap(rt, size, bitmap_data, 4 * sizeof(*bitmap_data), &bitmap_desc, &bitmap);
1742 ok(SUCCEEDED(hr), "Failed to create bitmap, hr %#x.\n", hr);
1744 hr = ID2D1Bitmap_QueryInterface(bitmap, &IID_ID2D1Image, (void **)&image);
1745 ok(SUCCEEDED(hr) || broken(hr == E_NOINTERFACE) /* Vista */, "Failed to get ID2D1Image, hr %#x.\n", hr);
1746 if (hr == S_OK)
1747 ID2D1Image_Release(image);
1749 /* Creating a brush with a NULL bitmap crashes on Vista, but works fine on
1750 * Windows 7+. */
1751 hr = ID2D1RenderTarget_CreateBitmapBrush(rt, bitmap, NULL, NULL, &brush);
1752 ok(SUCCEEDED(hr), "Failed to create brush, hr %#x.\n", hr);
1753 ID2D1BitmapBrush_GetBitmap(brush, &tmp_bitmap);
1754 ok(tmp_bitmap == bitmap, "Got unexpected bitmap %p, expected %p.\n", tmp_bitmap, bitmap);
1755 ID2D1Bitmap_Release(tmp_bitmap);
1756 opacity = ID2D1BitmapBrush_GetOpacity(brush);
1757 ok(opacity == 1.0f, "Got unexpected opacity %.8e.\n", opacity);
1758 set_matrix_identity(&matrix);
1759 ID2D1BitmapBrush_GetTransform(brush, &tmp_matrix);
1760 ok(!memcmp(&tmp_matrix, &matrix, sizeof(matrix)),
1761 "Got unexpected matrix {%.8e, %.8e, %.8e, %.8e, %.8e, %.8e}.\n",
1762 tmp_matrix._11, tmp_matrix._12, tmp_matrix._21,
1763 tmp_matrix._22, tmp_matrix._31, tmp_matrix._32);
1764 extend_mode = ID2D1BitmapBrush_GetExtendModeX(brush);
1765 ok(extend_mode == D2D1_EXTEND_MODE_CLAMP, "Got unexpected extend mode %#x.\n", extend_mode);
1766 extend_mode = ID2D1BitmapBrush_GetExtendModeY(brush);
1767 ok(extend_mode == D2D1_EXTEND_MODE_CLAMP, "Got unexpected extend mode %#x.\n", extend_mode);
1768 interpolation_mode = ID2D1BitmapBrush_GetInterpolationMode(brush);
1769 ok(interpolation_mode == D2D1_BITMAP_INTERPOLATION_MODE_LINEAR,
1770 "Got unexpected interpolation mode %#x.\n", interpolation_mode);
1771 ID2D1BitmapBrush_Release(brush);
1773 hr = ID2D1RenderTarget_CreateBitmapBrush(rt, bitmap, NULL, NULL, &brush);
1774 ok(SUCCEEDED(hr), "Failed to create brush, hr %#x.\n", hr);
1775 set_matrix_identity(&matrix);
1776 translate_matrix(&matrix, 40.0f, 120.0f);
1777 scale_matrix(&matrix, 20.0f, 60.0f);
1778 ID2D1BitmapBrush_SetTransform(brush, &matrix);
1779 ID2D1BitmapBrush_SetInterpolationMode(brush, D2D1_BITMAP_INTERPOLATION_MODE_NEAREST_NEIGHBOR);
1781 ID2D1RenderTarget_BeginDraw(rt);
1783 set_color(&color, 0.0f, 0.0f, 1.0f, 1.0f);
1784 ID2D1RenderTarget_Clear(rt, &color);
1786 set_rect(&dst_rect, 40.0f, 120.0f, 120.0f, 360.0f);
1787 ID2D1RenderTarget_FillRectangle(rt, &dst_rect, (ID2D1Brush *)brush);
1789 set_matrix_identity(&matrix);
1790 scale_matrix(&matrix, 0.5f, 2.0f);
1791 translate_matrix(&matrix, 320.0f, 240.0f);
1792 rotate_matrix(&matrix, M_PI / 4.0f);
1793 ID2D1RenderTarget_SetTransform(rt, &matrix);
1794 set_matrix_identity(&matrix);
1795 translate_matrix(&matrix, -80.0f, -60.0f);
1796 scale_matrix(&matrix, 64.0f, 32.0f);
1797 ID2D1BitmapBrush_SetTransform(brush, &matrix);
1798 ID2D1BitmapBrush_SetOpacity(brush, 0.75f);
1799 set_rect(&dst_rect, -80.0f, -60.0f, 80.0f, 60.0f);
1800 ID2D1RenderTarget_FillRectangle(rt, &dst_rect, (ID2D1Brush *)brush);
1802 set_matrix_identity(&matrix);
1803 translate_matrix(&matrix, 200.0f, 120.0f);
1804 scale_matrix(&matrix, 20.0f, 60.0f);
1805 ID2D1RenderTarget_SetTransform(rt, &matrix);
1806 ID2D1RenderTarget_DrawBitmap(rt, bitmap, NULL, 0.25f,
1807 D2D1_BITMAP_INTERPOLATION_MODE_NEAREST_NEIGHBOR, NULL);
1808 set_rect(&dst_rect, -4.0f, 12.0f, -8.0f, 8.0f);
1809 ID2D1RenderTarget_DrawBitmap(rt, bitmap, &dst_rect, 0.75f,
1810 D2D1_BITMAP_INTERPOLATION_MODE_NEAREST_NEIGHBOR, NULL);
1811 set_rect(&dst_rect, 0.0f, 8.0f, 4.0f, 12.0f);
1812 set_rect(&src_rect, 2.0f, 1.0f, 4.0f, 3.0f);
1813 ID2D1RenderTarget_DrawBitmap(rt, bitmap, &dst_rect, 1.0f,
1814 D2D1_BITMAP_INTERPOLATION_MODE_NEAREST_NEIGHBOR, &src_rect);
1816 hr = ID2D1RenderTarget_EndDraw(rt, NULL, NULL);
1817 ok(SUCCEEDED(hr), "Failed to end draw, hr %#x.\n", hr);
1818 match = compare_surface(surface, "9437f4447d98feaad41a1c4202ee90aadc718ee6");
1819 ok(match, "Surface does not match.\n");
1821 /* Invalid interpolation mode. */
1822 ID2D1RenderTarget_BeginDraw(rt);
1824 set_rect(&dst_rect, 1.0f, 8.0f, 4.0f, 12.0f);
1825 set_rect(&src_rect, 2.0f, 1.0f, 4.0f, 3.0f);
1826 ID2D1RenderTarget_DrawBitmap(rt, bitmap, &dst_rect, 1.0f,
1827 D2D1_BITMAP_INTERPOLATION_MODE_LINEAR + 1, &src_rect);
1829 hr = ID2D1RenderTarget_EndDraw(rt, NULL, NULL);
1830 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
1831 match = compare_surface(surface, "9437f4447d98feaad41a1c4202ee90aadc718ee6");
1832 ok(match, "Surface does not match.\n");
1834 ID2D1RenderTarget_BeginDraw(rt);
1836 ID2D1RenderTarget_Clear(rt, &color);
1838 ID2D1BitmapBrush_SetOpacity(brush, 1.0f);
1839 for (i = 0; i < ARRAY_SIZE(extend_mode_tests); ++i)
1841 ID2D1BitmapBrush_SetExtendModeX(brush, extend_mode_tests[i].extend_mode_x);
1842 extend_mode = ID2D1BitmapBrush_GetExtendModeX(brush);
1843 ok(extend_mode == extend_mode_tests[i].extend_mode_x,
1844 "Test %u: Got unexpected extend mode %#x, expected %#x.\n",
1845 i, extend_mode, extend_mode_tests[i].extend_mode_x);
1846 ID2D1BitmapBrush_SetExtendModeY(brush, extend_mode_tests[i].extend_mode_y);
1847 extend_mode = ID2D1BitmapBrush_GetExtendModeY(brush);
1848 ok(extend_mode == extend_mode_tests[i].extend_mode_y,
1849 "Test %u: Got unexpected extend mode %#x, expected %#x.\n",
1850 i, extend_mode, extend_mode_tests[i].extend_mode_y);
1851 set_matrix_identity(&matrix);
1852 translate_matrix(&matrix, extend_mode_tests[i].translate_x, extend_mode_tests[i].translate_y);
1853 scale_matrix(&matrix, 0.5f, 0.5f);
1854 ID2D1BitmapBrush_SetTransform(brush, &matrix);
1855 ID2D1RenderTarget_FillRectangle(rt, &extend_mode_tests[i].rect, (ID2D1Brush *)brush);
1858 hr = ID2D1RenderTarget_EndDraw(rt, NULL, NULL);
1859 ok(SUCCEEDED(hr), "Failed to end draw, hr %#x.\n", hr);
1860 match = compare_surface(surface, "b4b775afecdae2d26642001f4faff73663bb8b31");
1861 ok(match, "Surface does not match.\n");
1863 ID2D1Bitmap_Release(bitmap);
1864 bitmap_desc.dpiX = 96.0f / 20.0f;
1865 bitmap_desc.dpiY = 96.0f / 60.0f;
1866 hr = ID2D1RenderTarget_CreateBitmap(rt, size, bitmap_data, 4 * sizeof(*bitmap_data), &bitmap_desc, &bitmap);
1867 ok(SUCCEEDED(hr), "Failed to create bitmap, hr %#x.\n", hr);
1868 ID2D1BitmapBrush_SetBitmap(brush, bitmap);
1870 ID2D1RenderTarget_BeginDraw(rt);
1872 ID2D1RenderTarget_Clear(rt, &color);
1874 set_matrix_identity(&matrix);
1875 translate_matrix(&matrix, 40.0f, 120.0f);
1876 skew_matrix(&matrix, 0.125f, 2.0f);
1877 ID2D1RenderTarget_SetTransform(rt, &matrix);
1878 set_matrix_identity(&matrix);
1879 ID2D1BitmapBrush_SetTransform(brush, &matrix);
1880 set_rect(&dst_rect, 0.0f, 0.0f, 80.0f, 240.0f);
1881 ID2D1RenderTarget_FillRectangle(rt, &dst_rect, (ID2D1Brush *)brush);
1883 ID2D1RenderTarget_GetFactory(rt, &factory);
1885 set_rect(&dst_rect, -1.0f, -1.0f, 1.0f, 1.0f);
1886 hr = ID2D1Factory_CreateRectangleGeometry(factory, &dst_rect, &rectangle_geometry);
1887 ok(SUCCEEDED(hr), "Failed to create geometry, hr %#x.\n", hr);
1889 set_matrix_identity(&matrix);
1890 translate_matrix(&matrix, 240.0f, 720.0f);
1891 scale_matrix(&matrix, 40.0f, 120.0f);
1892 hr = ID2D1Factory_CreateTransformedGeometry(factory, (ID2D1Geometry *)rectangle_geometry,
1893 &matrix, &transformed_geometry);
1894 ok(SUCCEEDED(hr), "Failed to create geometry, hr %#x.\n", hr);
1895 ID2D1RectangleGeometry_Release(rectangle_geometry);
1897 set_matrix_identity(&matrix);
1898 ID2D1RenderTarget_SetTransform(rt, &matrix);
1899 set_matrix_identity(&matrix);
1900 translate_matrix(&matrix, 200.0f, 600.0f);
1901 ID2D1BitmapBrush_SetTransform(brush, &matrix);
1902 ID2D1RenderTarget_FillGeometry(rt, (ID2D1Geometry *)transformed_geometry, (ID2D1Brush *)brush, NULL);
1903 ID2D1TransformedGeometry_Release(transformed_geometry);
1905 ID2D1Factory_Release(factory);
1907 hr = ID2D1RenderTarget_EndDraw(rt, NULL, NULL);
1908 ok(SUCCEEDED(hr), "Failed to end draw, hr %#x.\n", hr);
1909 match = compare_surface(surface, "cf7b90ba7b139fdfbe9347e1907d635cfb4ed197");
1910 ok(match, "Surface does not match.\n");
1912 if (SUCCEEDED(ID2D1BitmapBrush_QueryInterface(brush, &IID_ID2D1BitmapBrush1, (void **)&brush1)))
1914 D2D1_INTERPOLATION_MODE interpolation_mode1;
1916 interpolation_mode = ID2D1BitmapBrush1_GetInterpolationMode(brush1);
1917 ok(interpolation_mode == D2D1_BITMAP_INTERPOLATION_MODE_NEAREST_NEIGHBOR,
1918 "Unexpected interpolation mode %#x.\n", interpolation_mode);
1920 interpolation_mode1 = ID2D1BitmapBrush1_GetInterpolationMode1(brush1);
1921 ok(interpolation_mode1 == D2D1_INTERPOLATION_MODE_NEAREST_NEIGHBOR,
1922 "Unexpected interpolation mode %#x.\n", interpolation_mode1);
1924 ID2D1BitmapBrush1_SetInterpolationMode1(brush1, D2D1_INTERPOLATION_MODE_CUBIC);
1925 interpolation_mode = ID2D1BitmapBrush1_GetInterpolationMode(brush1);
1926 ok(interpolation_mode == D2D1_BITMAP_INTERPOLATION_MODE_LINEAR,
1927 "Unexpected interpolation mode %#x.\n", interpolation_mode);
1929 interpolation_mode1 = ID2D1BitmapBrush1_GetInterpolationMode1(brush1);
1930 ok(interpolation_mode1 == D2D1_INTERPOLATION_MODE_CUBIC,
1931 "Unexpected interpolation mode %#x.\n", interpolation_mode1);
1933 ID2D1BitmapBrush1_SetInterpolationMode1(brush1, 100);
1934 interpolation_mode1 = ID2D1BitmapBrush1_GetInterpolationMode1(brush1);
1935 ok(interpolation_mode1 == D2D1_INTERPOLATION_MODE_CUBIC,
1936 "Unexpected interpolation mode %#x.\n", interpolation_mode1);
1938 ID2D1BitmapBrush1_SetInterpolationMode(brush1, 100);
1939 interpolation_mode1 = ID2D1BitmapBrush1_GetInterpolationMode1(brush1);
1940 ok(interpolation_mode1 == D2D1_INTERPOLATION_MODE_CUBIC,
1941 "Unexpected interpolation mode %#x.\n", interpolation_mode1);
1943 ID2D1BitmapBrush1_SetInterpolationMode(brush1, D2D1_BITMAP_INTERPOLATION_MODE_NEAREST_NEIGHBOR);
1944 interpolation_mode = ID2D1BitmapBrush1_GetInterpolationMode(brush1);
1945 ok(interpolation_mode == D2D1_BITMAP_INTERPOLATION_MODE_NEAREST_NEIGHBOR,
1946 "Unexpected interpolation mode %#x.\n", interpolation_mode);
1948 interpolation_mode1 = ID2D1BitmapBrush1_GetInterpolationMode1(brush1);
1949 ok(interpolation_mode1 == D2D1_INTERPOLATION_MODE_NEAREST_NEIGHBOR,
1950 "Unexpected interpolation mode %#x.\n", interpolation_mode1);
1952 ID2D1BitmapBrush1_Release(brush1);
1955 ID2D1BitmapBrush_Release(brush);
1956 refcount = ID2D1Bitmap_Release(bitmap);
1957 ok(!refcount, "Bitmap has %u references left.\n", refcount);
1958 ID2D1RenderTarget_Release(rt);
1959 IDXGISurface_Release(surface);
1960 IDXGISwapChain_Release(swapchain);
1961 ID3D10Device1_Release(device);
1962 DestroyWindow(window);
1965 static void test_linear_brush(void)
1967 D2D1_LINEAR_GRADIENT_BRUSH_PROPERTIES gradient_properties;
1968 ID2D1GradientStopCollection *gradient, *tmp_gradient;
1969 ID2D1TransformedGeometry *transformed_geometry;
1970 ID2D1RectangleGeometry *rectangle_geometry;
1971 D2D1_MATRIX_3X2_F matrix, tmp_matrix;
1972 ID2D1LinearGradientBrush *brush;
1973 struct resource_readback rb;
1974 IDXGISwapChain *swapchain;
1975 ID2D1RenderTarget *rt;
1976 ID3D10Device1 *device;
1977 IDXGISurface *surface;
1978 ID2D1Factory *factory;
1979 D2D1_COLOR_F colour;
1980 D2D1_POINT_2F p;
1981 unsigned int i;
1982 ULONG refcount;
1983 D2D1_RECT_F r;
1984 float opacity;
1985 HWND window;
1986 HRESULT hr;
1988 static const D2D1_GRADIENT_STOP stops[] =
1990 {0.0f, {1.0f, 0.0f, 0.0f, 1.0f}},
1991 {0.5f, {0.0f, 1.0f, 0.0f, 1.0f}},
1992 {1.0f, {0.0f, 0.0f, 1.0f, 1.0f}},
1994 static const struct
1996 unsigned int x, y;
1997 DWORD colour;
1999 test1[] =
2001 {80, 80, 0xff857a00}, {240, 80, 0xff926d00}, {400, 80, 0xff9f6000}, {560, 80, 0xffac5300},
2002 {80, 240, 0xff00eb14}, {240, 240, 0xff00f807}, {400, 240, 0xff06f900}, {560, 240, 0xff13ec00},
2003 {80, 400, 0xff0053ac}, {240, 400, 0xff005fa0}, {400, 400, 0xff006c93}, {560, 400, 0xff007986},
2005 test2[] =
2007 { 40, 30, 0xff005ba4}, {120, 30, 0xffffffff}, { 40, 60, 0xffffffff}, { 80, 60, 0xff00b44b},
2008 {120, 60, 0xff006c93}, {200, 60, 0xffffffff}, { 40, 90, 0xffffffff}, {120, 90, 0xff0ef100},
2009 {160, 90, 0xff00c53a}, {200, 90, 0xffffffff}, { 80, 120, 0xffffffff}, {120, 120, 0xffaf5000},
2010 {160, 120, 0xff679800}, {200, 120, 0xff1fe000}, {240, 120, 0xffffffff}, {160, 150, 0xffffffff},
2011 {200, 150, 0xffc03e00}, {240, 150, 0xffffffff}, {280, 150, 0xffffffff}, {320, 150, 0xffffffff},
2012 {240, 180, 0xffffffff}, {280, 180, 0xffff4040}, {320, 180, 0xffff4040}, {380, 180, 0xffffffff},
2013 {200, 210, 0xffffffff}, {240, 210, 0xffa99640}, {280, 210, 0xffb28d40}, {320, 210, 0xffbb8440},
2014 {360, 210, 0xffc47b40}, {400, 210, 0xffffffff}, {200, 240, 0xffffffff}, {280, 240, 0xff41fe40},
2015 {320, 240, 0xff49f540}, {360, 240, 0xff52ec40}, {440, 240, 0xffffffff}, {240, 270, 0xffffffff},
2016 {280, 270, 0xff408eb0}, {320, 270, 0xff4097a7}, {360, 270, 0xff40a19e}, {440, 270, 0xffffffff},
2017 {280, 300, 0xffffffff}, {320, 300, 0xff4040ff}, {360, 300, 0xff4040ff}, {400, 300, 0xff406ad4},
2018 {440, 300, 0xff4061de}, {480, 300, 0xff4057e7}, {520, 300, 0xff404ef1}, {280, 330, 0xffffffff},
2019 {360, 330, 0xffffffff}, {400, 330, 0xff40c17e}, {440, 330, 0xff40b788}, {480, 330, 0xff40ae91},
2020 {520, 330, 0xff40a49b}, {400, 360, 0xff57e740}, {440, 360, 0xff4ef140}, {480, 360, 0xff44fb40},
2021 {520, 360, 0xff40fa45}, {400, 390, 0xffae9140}, {440, 390, 0xffa49b40}, {480, 390, 0xff9aa540},
2022 {520, 390, 0xff90ae40},
2025 if (!(device = create_device()))
2027 skip("Failed to create device, skipping tests.\n");
2028 return;
2030 window = create_window();
2031 swapchain = create_swapchain(device, window, TRUE);
2032 hr = IDXGISwapChain_GetBuffer(swapchain, 0, &IID_IDXGISurface, (void **)&surface);
2033 ok(SUCCEEDED(hr), "Failed to get buffer, hr %#x.\n", hr);
2034 rt = create_render_target(surface);
2035 ok(!!rt, "Failed to create render target.\n");
2037 ID2D1RenderTarget_SetDpi(rt, 192.0f, 48.0f);
2038 ID2D1RenderTarget_SetAntialiasMode(rt, D2D1_ANTIALIAS_MODE_ALIASED);
2040 hr = ID2D1RenderTarget_CreateGradientStopCollection(rt, stops, ARRAY_SIZE(stops),
2041 D2D1_GAMMA_2_2, D2D1_EXTEND_MODE_CLAMP, &gradient);
2042 ok(SUCCEEDED(hr), "Failed to create stop collection, hr %#x.\n", hr);
2044 set_point(&gradient_properties.startPoint, 320.0f, 0.0f);
2045 set_point(&gradient_properties.endPoint, 0.0f, 960.0f);
2046 hr = ID2D1RenderTarget_CreateLinearGradientBrush(rt, &gradient_properties, NULL, gradient, &brush);
2047 ok(SUCCEEDED(hr), "Failed to create brush, hr %#x.\n", hr);
2049 opacity = ID2D1LinearGradientBrush_GetOpacity(brush);
2050 ok(opacity == 1.0f, "Got unexpected opacity %.8e.\n", opacity);
2051 set_matrix_identity(&matrix);
2052 ID2D1LinearGradientBrush_GetTransform(brush, &tmp_matrix);
2053 ok(!memcmp(&tmp_matrix, &matrix, sizeof(matrix)),
2054 "Got unexpected matrix {%.8e, %.8e, %.8e, %.8e, %.8e, %.8e}.\n",
2055 tmp_matrix._11, tmp_matrix._12, tmp_matrix._21,
2056 tmp_matrix._22, tmp_matrix._31, tmp_matrix._32);
2057 p = ID2D1LinearGradientBrush_GetStartPoint(brush);
2058 ok(compare_point(&p, 320.0f, 0.0f, 0), "Got unexpected start point {%.8e, %.8e}.\n", p.x, p.y);
2059 p = ID2D1LinearGradientBrush_GetEndPoint(brush);
2060 ok(compare_point(&p, 0.0f, 960.0f, 0), "Got unexpected end point {%.8e, %.8e}.\n", p.x, p.y);
2061 ID2D1LinearGradientBrush_GetGradientStopCollection(brush, &tmp_gradient);
2062 ok(tmp_gradient == gradient, "Got unexpected gradient %p, expected %p.\n", tmp_gradient, gradient);
2063 ID2D1GradientStopCollection_Release(tmp_gradient);
2065 ID2D1RenderTarget_BeginDraw(rt);
2067 set_color(&colour, 1.0f, 1.0f, 1.0f, 1.0f);
2068 ID2D1RenderTarget_Clear(rt, &colour);
2070 set_rect(&r, 0.0f, 0.0f, 320.0f, 960.0f);
2071 ID2D1RenderTarget_FillRectangle(rt, &r, (ID2D1Brush *)brush);
2073 hr = ID2D1RenderTarget_EndDraw(rt, NULL, NULL);
2074 ok(SUCCEEDED(hr), "Failed to end draw, hr %#x.\n", hr);
2076 get_surface_readback(surface, &rb);
2077 for (i = 0; i < ARRAY_SIZE(test1); ++i)
2079 DWORD colour;
2081 colour = get_readback_colour(&rb, test1[i].x, test1[i].y);
2082 ok(compare_colour(colour, test1[i].colour, 1),
2083 "Got unexpected colour 0x%08x at position {%u, %u}.\n",
2084 colour, test1[i].x, test1[i].y);
2086 release_resource_readback(&rb);
2088 ID2D1RenderTarget_BeginDraw(rt);
2090 ID2D1RenderTarget_Clear(rt, &colour);
2092 set_matrix_identity(&matrix);
2093 skew_matrix(&matrix, 0.2146f, 1.575f);
2094 ID2D1RenderTarget_SetTransform(rt, &matrix);
2096 set_matrix_identity(&matrix);
2097 translate_matrix(&matrix, 0.0f, 240.0f);
2098 scale_matrix(&matrix, 0.25f, -0.25f);
2099 ID2D1LinearGradientBrush_SetTransform(brush, &matrix);
2101 set_rect(&r, 0.0f, 0.0f, 80.0f, 240.0f);
2102 ID2D1RenderTarget_FillRectangle(rt, &r, (ID2D1Brush *)brush);
2104 set_matrix_identity(&matrix);
2105 scale_matrix(&matrix, 0.5f, 2.0f);
2106 translate_matrix(&matrix, 320.0f, 240.0f);
2107 rotate_matrix(&matrix, M_PI / 4.0f);
2108 ID2D1RenderTarget_SetTransform(rt, &matrix);
2110 set_matrix_identity(&matrix);
2111 translate_matrix(&matrix, 0.0f, -50.0f);
2112 scale_matrix(&matrix, 0.1f, 0.1f);
2113 rotate_matrix(&matrix, -M_PI / 3.0f);
2114 ID2D1LinearGradientBrush_SetTransform(brush, &matrix);
2116 ID2D1LinearGradientBrush_SetOpacity(brush, 0.75f);
2117 set_rect(&r, -80.0f, -60.0f, 80.0f, 60.0f);
2118 ID2D1RenderTarget_FillRectangle(rt, &r, (ID2D1Brush *)brush);
2120 ID2D1RenderTarget_GetFactory(rt, &factory);
2122 set_rect(&r, -1.0f, -1.0f, 1.0f, 1.0f);
2123 hr = ID2D1Factory_CreateRectangleGeometry(factory, &r, &rectangle_geometry);
2124 ok(SUCCEEDED(hr), "Failed to create geometry, hr %#x.\n", hr);
2126 set_matrix_identity(&matrix);
2127 translate_matrix(&matrix, 228.5f, 714.0f);
2128 scale_matrix(&matrix, 40.0f, 120.0f);
2129 hr = ID2D1Factory_CreateTransformedGeometry(factory, (ID2D1Geometry *)rectangle_geometry,
2130 &matrix, &transformed_geometry);
2131 ok(SUCCEEDED(hr), "Failed to create geometry, hr %#x.\n", hr);
2132 ID2D1RectangleGeometry_Release(rectangle_geometry);
2134 set_matrix_identity(&matrix);
2135 ID2D1RenderTarget_SetTransform(rt, &matrix);
2136 ID2D1LinearGradientBrush_SetTransform(brush, &matrix);
2137 set_point(&p, 188.5f, 834.0f);
2138 ID2D1LinearGradientBrush_SetStartPoint(brush, p);
2139 set_point(&p, 268.5f, 594.0f);
2140 ID2D1LinearGradientBrush_SetEndPoint(brush, p);
2141 ID2D1RenderTarget_FillGeometry(rt, (ID2D1Geometry *)transformed_geometry, (ID2D1Brush *)brush, NULL);
2142 ID2D1TransformedGeometry_Release(transformed_geometry);
2144 ID2D1Factory_Release(factory);
2146 hr = ID2D1RenderTarget_EndDraw(rt, NULL, NULL);
2147 ok(SUCCEEDED(hr), "Failed to end draw, hr %#x.\n", hr);
2149 get_surface_readback(surface, &rb);
2150 for (i = 0; i < ARRAY_SIZE(test2); ++i)
2152 DWORD colour;
2154 colour = get_readback_colour(&rb, test2[i].x, test2[i].y);
2155 ok(compare_colour(colour, test2[i].colour, 1),
2156 "Got unexpected colour 0x%08x at position {%u, %u}.\n",
2157 colour, test2[i].x, test2[i].y);
2159 release_resource_readback(&rb);
2161 ID2D1LinearGradientBrush_Release(brush);
2162 refcount = ID2D1GradientStopCollection_Release(gradient);
2163 ok(!refcount, "Gradient has %u references left.\n", refcount);
2164 ID2D1RenderTarget_Release(rt);
2165 IDXGISurface_Release(surface);
2166 IDXGISwapChain_Release(swapchain);
2167 ID3D10Device1_Release(device);
2168 DestroyWindow(window);
2171 static void test_radial_brush(void)
2173 D2D1_RADIAL_GRADIENT_BRUSH_PROPERTIES gradient_properties;
2174 ID2D1GradientStopCollection *gradient, *tmp_gradient;
2175 ID2D1TransformedGeometry *transformed_geometry;
2176 ID2D1RectangleGeometry *rectangle_geometry;
2177 D2D1_MATRIX_3X2_F matrix, tmp_matrix;
2178 ID2D1RadialGradientBrush *brush;
2179 struct resource_readback rb;
2180 IDXGISwapChain *swapchain;
2181 ID2D1RenderTarget *rt;
2182 ID3D10Device1 *device;
2183 IDXGISurface *surface;
2184 ID2D1Factory *factory;
2185 D2D1_COLOR_F colour;
2186 D2D1_POINT_2F p;
2187 unsigned int i;
2188 ULONG refcount;
2189 D2D1_RECT_F r;
2190 HWND window;
2191 HRESULT hr;
2192 float f;
2194 static const D2D1_GRADIENT_STOP stops[] =
2196 {0.0f, {1.0f, 0.0f, 0.0f, 1.0f}},
2197 {0.5f, {0.0f, 1.0f, 0.0f, 1.0f}},
2198 {1.0f, {0.0f, 0.0f, 1.0f, 1.0f}},
2200 static const struct
2202 unsigned int x, y;
2203 DWORD colour;
2205 test1[] =
2207 {80, 80, 0xff0000ff}, {240, 80, 0xff00a857}, {400, 80, 0xff00d728}, {560, 80, 0xff0000ff},
2208 {80, 240, 0xff006699}, {240, 240, 0xff29d600}, {400, 240, 0xff966900}, {560, 240, 0xff00a55a},
2209 {80, 400, 0xff0000ff}, {240, 400, 0xff006e91}, {400, 400, 0xff007d82}, {560, 400, 0xff0000ff},
2211 test2[] =
2213 { 40, 30, 0xff000df2}, {120, 30, 0xffffffff}, { 40, 60, 0xffffffff}, { 80, 60, 0xff00b04f},
2214 {120, 60, 0xff007689}, {200, 60, 0xffffffff}, { 40, 90, 0xffffffff}, {120, 90, 0xff47b800},
2215 {160, 90, 0xff00c13e}, {200, 90, 0xffffffff}, { 80, 120, 0xffffffff}, {120, 120, 0xff0000ff},
2216 {160, 120, 0xff6f9000}, {200, 120, 0xff00718e}, {240, 120, 0xffffffff}, {160, 150, 0xffffffff},
2217 {200, 150, 0xff00609f}, {240, 150, 0xffffffff}, {280, 150, 0xffffffff}, {320, 150, 0xffffffff},
2218 {240, 180, 0xffffffff}, {280, 180, 0xff4040ff}, {320, 180, 0xff40b788}, {380, 180, 0xffffffff},
2219 {200, 210, 0xffffffff}, {240, 210, 0xff4040ff}, {280, 210, 0xff4040ff}, {320, 210, 0xff76c940},
2220 {360, 210, 0xff40cc73}, {400, 210, 0xffffffff}, {200, 240, 0xffffffff}, {280, 240, 0xff4061de},
2221 {320, 240, 0xff9fa040}, {360, 240, 0xff404af5}, {440, 240, 0xffffffff}, {240, 270, 0xffffffff},
2222 {280, 270, 0xff40aa95}, {320, 270, 0xff4ef140}, {360, 270, 0xff4040ff}, {440, 270, 0xffffffff},
2223 {280, 300, 0xffffffff}, {320, 300, 0xff4093ac}, {360, 300, 0xff4040ff}, {400, 300, 0xff4040ff},
2224 {440, 300, 0xff404af5}, {480, 300, 0xff4045fa}, {520, 300, 0xff4040ff}, {280, 330, 0xffffffff},
2225 {360, 330, 0xffffffff}, {400, 330, 0xff4069d6}, {440, 330, 0xff40c579}, {480, 330, 0xff40e956},
2226 {520, 330, 0xff4072cd}, {400, 360, 0xff408ab4}, {440, 360, 0xff49f540}, {480, 360, 0xffb98640},
2227 {520, 360, 0xff40dc62}, {400, 390, 0xff405ee1}, {440, 390, 0xff40d56a}, {480, 390, 0xff62dd40},
2228 {520, 390, 0xff4059e6},
2231 if (!(device = create_device()))
2233 skip("Failed to create device, skipping tests.\n");
2234 return;
2236 window = create_window();
2237 swapchain = create_swapchain(device, window, TRUE);
2238 hr = IDXGISwapChain_GetBuffer(swapchain, 0, &IID_IDXGISurface, (void **)&surface);
2239 ok(SUCCEEDED(hr), "Failed to get buffer, hr %#x.\n", hr);
2240 rt = create_render_target(surface);
2241 ok(!!rt, "Failed to create render target.\n");
2243 ID2D1RenderTarget_SetDpi(rt, 192.0f, 48.0f);
2244 ID2D1RenderTarget_SetAntialiasMode(rt, D2D1_ANTIALIAS_MODE_ALIASED);
2246 hr = ID2D1RenderTarget_CreateGradientStopCollection(rt, stops, ARRAY_SIZE(stops),
2247 D2D1_GAMMA_2_2, D2D1_EXTEND_MODE_CLAMP, &gradient);
2248 ok(SUCCEEDED(hr), "Failed to create stop collection, hr %#x.\n", hr);
2250 set_point(&gradient_properties.center, 160.0f, 480.0f);
2251 set_point(&gradient_properties.gradientOriginOffset, 40.0f, -120.0f);
2252 gradient_properties.radiusX = 160.0f;
2253 gradient_properties.radiusY = 480.0f;
2254 hr = ID2D1RenderTarget_CreateRadialGradientBrush(rt, &gradient_properties, NULL, gradient, &brush);
2255 ok(SUCCEEDED(hr), "Failed to create brush, hr %#x.\n", hr);
2257 f = ID2D1RadialGradientBrush_GetOpacity(brush);
2258 ok(f == 1.0f, "Got unexpected opacity %.8e.\n", f);
2259 set_matrix_identity(&matrix);
2260 ID2D1RadialGradientBrush_GetTransform(brush, &tmp_matrix);
2261 ok(!memcmp(&tmp_matrix, &matrix, sizeof(matrix)),
2262 "Got unexpected matrix {%.8e, %.8e, %.8e, %.8e, %.8e, %.8e}.\n",
2263 tmp_matrix._11, tmp_matrix._12, tmp_matrix._21,
2264 tmp_matrix._22, tmp_matrix._31, tmp_matrix._32);
2265 p = ID2D1RadialGradientBrush_GetCenter(brush);
2266 ok(compare_point(&p, 160.0f, 480.0f, 0), "Got unexpected center {%.8e, %.8e}.\n", p.x, p.y);
2267 p = ID2D1RadialGradientBrush_GetGradientOriginOffset(brush);
2268 ok(compare_point(&p, 40.0f, -120.0f, 0), "Got unexpected origin offset {%.8e, %.8e}.\n", p.x, p.y);
2269 f = ID2D1RadialGradientBrush_GetRadiusX(brush);
2270 ok(compare_float(f, 160.0f, 0), "Got unexpected x-radius %.8e.\n", f);
2271 f = ID2D1RadialGradientBrush_GetRadiusY(brush);
2272 ok(compare_float(f, 480.0f, 0), "Got unexpected y-radius %.8e.\n", f);
2273 ID2D1RadialGradientBrush_GetGradientStopCollection(brush, &tmp_gradient);
2274 ok(tmp_gradient == gradient, "Got unexpected gradient %p, expected %p.\n", tmp_gradient, gradient);
2275 ID2D1GradientStopCollection_Release(tmp_gradient);
2277 ID2D1RenderTarget_BeginDraw(rt);
2279 set_color(&colour, 1.0f, 1.0f, 1.0f, 1.0f);
2280 ID2D1RenderTarget_Clear(rt, &colour);
2282 set_rect(&r, 0.0f, 0.0f, 320.0f, 960.0f);
2283 ID2D1RenderTarget_FillRectangle(rt, &r, (ID2D1Brush *)brush);
2285 hr = ID2D1RenderTarget_EndDraw(rt, NULL, NULL);
2286 ok(SUCCEEDED(hr), "Failed to end draw, hr %#x.\n", hr);
2288 get_surface_readback(surface, &rb);
2289 for (i = 0; i < ARRAY_SIZE(test1); ++i)
2291 DWORD colour;
2293 colour = get_readback_colour(&rb, test1[i].x, test1[i].y);
2294 ok(compare_colour(colour, test1[i].colour, 1),
2295 "Got unexpected colour 0x%08x at position {%u, %u}.\n",
2296 colour, test1[i].x, test1[i].y);
2298 release_resource_readback(&rb);
2300 ID2D1RenderTarget_BeginDraw(rt);
2302 ID2D1RenderTarget_Clear(rt, &colour);
2304 set_matrix_identity(&matrix);
2305 skew_matrix(&matrix, 0.2146f, 1.575f);
2306 ID2D1RenderTarget_SetTransform(rt, &matrix);
2308 set_matrix_identity(&matrix);
2309 translate_matrix(&matrix, 0.0f, 240.0f);
2310 scale_matrix(&matrix, 0.25f, -0.25f);
2311 ID2D1RadialGradientBrush_SetTransform(brush, &matrix);
2313 set_rect(&r, 0.0f, 0.0f, 80.0f, 240.0f);
2314 ID2D1RenderTarget_FillRectangle(rt, &r, (ID2D1Brush *)brush);
2316 set_matrix_identity(&matrix);
2317 scale_matrix(&matrix, 0.5f, 2.0f);
2318 translate_matrix(&matrix, 320.0f, 240.0f);
2319 rotate_matrix(&matrix, M_PI / 4.0f);
2320 ID2D1RenderTarget_SetTransform(rt, &matrix);
2322 set_matrix_identity(&matrix);
2323 translate_matrix(&matrix, -75.0f, -50.0f);
2324 scale_matrix(&matrix, 0.15f, 0.5f);
2325 rotate_matrix(&matrix, -M_PI / 3.0f);
2326 ID2D1RadialGradientBrush_SetTransform(brush, &matrix);
2328 ID2D1RadialGradientBrush_SetOpacity(brush, 0.75f);
2329 set_rect(&r, -80.0f, -60.0f, 80.0f, 60.0f);
2330 ID2D1RenderTarget_FillRectangle(rt, &r, (ID2D1Brush *)brush);
2332 ID2D1RenderTarget_GetFactory(rt, &factory);
2334 set_rect(&r, -1.0f, -1.0f, 1.0f, 1.0f);
2335 hr = ID2D1Factory_CreateRectangleGeometry(factory, &r, &rectangle_geometry);
2336 ok(SUCCEEDED(hr), "Failed to create geometry, hr %#x.\n", hr);
2338 set_matrix_identity(&matrix);
2339 translate_matrix(&matrix, 228.5f, 714.0f);
2340 scale_matrix(&matrix, 40.0f, 120.0f);
2341 hr = ID2D1Factory_CreateTransformedGeometry(factory, (ID2D1Geometry *)rectangle_geometry,
2342 &matrix, &transformed_geometry);
2343 ok(SUCCEEDED(hr), "Failed to create geometry, hr %#x.\n", hr);
2344 ID2D1RectangleGeometry_Release(rectangle_geometry);
2346 set_matrix_identity(&matrix);
2347 ID2D1RenderTarget_SetTransform(rt, &matrix);
2348 ID2D1RadialGradientBrush_SetTransform(brush, &matrix);
2349 set_point(&p, 228.5f, 714.0f);
2350 ID2D1RadialGradientBrush_SetCenter(brush, p);
2351 ID2D1RadialGradientBrush_SetRadiusX(brush, -40.0f);
2352 ID2D1RadialGradientBrush_SetRadiusY(brush, 120.0f);
2353 set_point(&p, 20.0f, 30.0f);
2354 ID2D1RadialGradientBrush_SetGradientOriginOffset(brush, p);
2355 ID2D1RenderTarget_FillGeometry(rt, (ID2D1Geometry *)transformed_geometry, (ID2D1Brush *)brush, NULL);
2356 ID2D1TransformedGeometry_Release(transformed_geometry);
2358 ID2D1Factory_Release(factory);
2360 hr = ID2D1RenderTarget_EndDraw(rt, NULL, NULL);
2361 ok(SUCCEEDED(hr), "Failed to end draw, hr %#x.\n", hr);
2363 get_surface_readback(surface, &rb);
2364 for (i = 0; i < ARRAY_SIZE(test2); ++i)
2366 DWORD colour;
2368 colour = get_readback_colour(&rb, test2[i].x, test2[i].y);
2369 ok(compare_colour(colour, test2[i].colour, 1),
2370 "Got unexpected colour 0x%08x at position {%u, %u}.\n",
2371 colour, test2[i].x, test2[i].y);
2373 release_resource_readback(&rb);
2375 ID2D1RadialGradientBrush_Release(brush);
2376 refcount = ID2D1GradientStopCollection_Release(gradient);
2377 ok(!refcount, "Gradient has %u references left.\n", refcount);
2378 ID2D1RenderTarget_Release(rt);
2379 IDXGISurface_Release(surface);
2380 IDXGISwapChain_Release(swapchain);
2381 ID3D10Device1_Release(device);
2382 DestroyWindow(window);
2385 static void fill_geometry_sink(ID2D1GeometrySink *sink, unsigned int hollow_count)
2387 D2D1_FIGURE_BEGIN begin;
2388 unsigned int idx = 0;
2389 D2D1_POINT_2F point;
2391 set_point(&point, 15.0f, 20.0f);
2392 begin = idx++ < hollow_count ? D2D1_FIGURE_BEGIN_HOLLOW : D2D1_FIGURE_BEGIN_FILLED;
2393 ID2D1GeometrySink_BeginFigure(sink, point, begin);
2394 line_to(sink, 55.0f, 20.0f);
2395 line_to(sink, 55.0f, 220.0f);
2396 line_to(sink, 25.0f, 220.0f);
2397 line_to(sink, 25.0f, 100.0f);
2398 line_to(sink, 75.0f, 100.0f);
2399 line_to(sink, 75.0f, 300.0f);
2400 line_to(sink, 5.0f, 300.0f);
2401 line_to(sink, 5.0f, 60.0f);
2402 line_to(sink, 45.0f, 60.0f);
2403 line_to(sink, 45.0f, 180.0f);
2404 line_to(sink, 35.0f, 180.0f);
2405 line_to(sink, 35.0f, 140.0f);
2406 line_to(sink, 65.0f, 140.0f);
2407 line_to(sink, 65.0f, 260.0f);
2408 line_to(sink, 15.0f, 260.0f);
2409 ID2D1GeometrySink_EndFigure(sink, D2D1_FIGURE_END_CLOSED);
2411 set_point(&point, 155.0f, 300.0f);
2412 begin = idx++ < hollow_count ? D2D1_FIGURE_BEGIN_HOLLOW : D2D1_FIGURE_BEGIN_FILLED;
2413 ID2D1GeometrySink_BeginFigure(sink, point, begin);
2414 line_to(sink, 155.0f, 160.0f);
2415 line_to(sink, 85.0f, 160.0f);
2416 line_to(sink, 85.0f, 300.0f);
2417 line_to(sink, 120.0f, 300.0f);
2418 line_to(sink, 120.0f, 20.0f);
2419 line_to(sink, 155.0f, 20.0f);
2420 line_to(sink, 155.0f, 160.0f);
2421 line_to(sink, 85.0f, 160.0f);
2422 line_to(sink, 85.0f, 20.0f);
2423 line_to(sink, 120.0f, 20.0f);
2424 line_to(sink, 120.0f, 300.0f);
2425 ID2D1GeometrySink_EndFigure(sink, D2D1_FIGURE_END_CLOSED);
2427 set_point(&point, 165.0f, 20.0f);
2428 begin = idx++ < hollow_count ? D2D1_FIGURE_BEGIN_HOLLOW : D2D1_FIGURE_BEGIN_FILLED;
2429 ID2D1GeometrySink_BeginFigure(sink, point, begin);
2430 line_to(sink, 165.0f, 300.0f);
2431 line_to(sink, 235.0f, 300.0f);
2432 line_to(sink, 235.0f, 20.0f);
2433 ID2D1GeometrySink_EndFigure(sink, D2D1_FIGURE_END_CLOSED);
2434 set_point(&point, 225.0f, 60.0f);
2435 begin = idx++ < hollow_count ? D2D1_FIGURE_BEGIN_HOLLOW : D2D1_FIGURE_BEGIN_FILLED;
2436 ID2D1GeometrySink_BeginFigure(sink, point, begin);
2437 line_to(sink, 225.0f, 260.0f);
2438 line_to(sink, 175.0f, 260.0f);
2439 line_to(sink, 175.0f, 60.0f);
2440 ID2D1GeometrySink_EndFigure(sink, D2D1_FIGURE_END_CLOSED);
2441 set_point(&point, 215.0f, 220.0f);
2442 begin = idx++ < hollow_count ? D2D1_FIGURE_BEGIN_HOLLOW : D2D1_FIGURE_BEGIN_FILLED;
2443 ID2D1GeometrySink_BeginFigure(sink, point, begin);
2444 line_to(sink, 185.0f, 220.0f);
2445 line_to(sink, 185.0f, 100.0f);
2446 line_to(sink, 215.0f, 100.0f);
2447 ID2D1GeometrySink_EndFigure(sink, D2D1_FIGURE_END_CLOSED);
2448 set_point(&point, 195.0f, 180.0f);
2449 begin = idx++ < hollow_count ? D2D1_FIGURE_BEGIN_HOLLOW : D2D1_FIGURE_BEGIN_FILLED;
2450 ID2D1GeometrySink_BeginFigure(sink, point, begin);
2451 line_to(sink, 205.0f, 180.0f);
2452 line_to(sink, 205.0f, 140.0f);
2453 line_to(sink, 195.0f, 140.0f);
2454 ID2D1GeometrySink_EndFigure(sink, D2D1_FIGURE_END_CLOSED);
2457 static void fill_geometry_sink_bezier(ID2D1GeometrySink *sink, unsigned int hollow_count)
2459 D2D1_FIGURE_BEGIN begin;
2460 unsigned int idx = 0;
2461 D2D1_POINT_2F point;
2463 set_point(&point, 5.0f, 160.0f);
2464 begin = idx++ < hollow_count ? D2D1_FIGURE_BEGIN_HOLLOW : D2D1_FIGURE_BEGIN_FILLED;
2465 ID2D1GeometrySink_BeginFigure(sink, point, begin);
2466 quadratic_to(sink, 40.0f, 160.0f, 40.0f, 20.0f);
2467 quadratic_to(sink, 40.0f, 160.0f, 75.0f, 160.0f);
2468 quadratic_to(sink, 40.0f, 160.0f, 40.0f, 300.0f);
2469 quadratic_to(sink, 40.0f, 160.0f, 5.0f, 160.0f);
2470 ID2D1GeometrySink_EndFigure(sink, D2D1_FIGURE_END_CLOSED);
2472 set_point(&point, 20.0f, 160.0f);
2473 begin = idx++ < hollow_count ? D2D1_FIGURE_BEGIN_HOLLOW : D2D1_FIGURE_BEGIN_FILLED;
2474 ID2D1GeometrySink_BeginFigure(sink, point, begin);
2475 quadratic_to(sink, 20.0f, 80.0f, 40.0f, 80.0f);
2476 quadratic_to(sink, 60.0f, 80.0f, 60.0f, 160.0f);
2477 quadratic_to(sink, 60.0f, 240.0f, 40.0f, 240.0f);
2478 quadratic_to(sink, 20.0f, 240.0f, 20.0f, 160.0f);
2479 ID2D1GeometrySink_EndFigure(sink, D2D1_FIGURE_END_CLOSED);
2481 set_point(&point, 5.0f, 612.0f);
2482 begin = idx++ < hollow_count ? D2D1_FIGURE_BEGIN_HOLLOW : D2D1_FIGURE_BEGIN_FILLED;
2483 ID2D1GeometrySink_BeginFigure(sink, point, begin);
2484 quadratic_to(sink, 40.0f, 612.0f, 40.0f, 752.0f);
2485 quadratic_to(sink, 40.0f, 612.0f, 75.0f, 612.0f);
2486 quadratic_to(sink, 40.0f, 612.0f, 40.0f, 472.0f);
2487 quadratic_to(sink, 40.0f, 612.0f, 5.0f, 612.0f);
2488 ID2D1GeometrySink_EndFigure(sink, D2D1_FIGURE_END_CLOSED);
2490 set_point(&point, 20.0f, 612.0f);
2491 begin = idx++ < hollow_count ? D2D1_FIGURE_BEGIN_HOLLOW : D2D1_FIGURE_BEGIN_FILLED;
2492 ID2D1GeometrySink_BeginFigure(sink, point, begin);
2493 quadratic_to(sink, 20.0f, 692.0f, 40.0f, 692.0f);
2494 quadratic_to(sink, 60.0f, 692.0f, 60.0f, 612.0f);
2495 quadratic_to(sink, 60.0f, 532.0f, 40.0f, 532.0f);
2496 quadratic_to(sink, 20.0f, 532.0f, 20.0f, 612.0f);
2497 ID2D1GeometrySink_EndFigure(sink, D2D1_FIGURE_END_CLOSED);
2500 static void test_path_geometry(void)
2502 ID2D1TransformedGeometry *transformed_geometry;
2503 D2D1_MATRIX_3X2_F matrix, tmp_matrix;
2504 ID2D1GeometrySink *sink, *tmp_sink;
2505 struct geometry_sink simplify_sink;
2506 D2D1_POINT_2F point = {0.0f, 0.0f};
2507 ID2D1SolidColorBrush *brush;
2508 ID2D1PathGeometry *geometry;
2509 ID2D1Geometry *tmp_geometry;
2510 IDXGISwapChain *swapchain;
2511 ID2D1RenderTarget *rt;
2512 ID3D10Device1 *device;
2513 IDXGISurface *surface;
2514 ID2D1Factory *factory;
2515 BOOL match, contains;
2516 D2D1_COLOR_F color;
2517 D2D1_RECT_F rect;
2518 ULONG refcount;
2519 UINT32 count;
2520 HWND window;
2521 HRESULT hr;
2523 static const struct geometry_segment expected_segments[] =
2525 /* Figure 0. */
2526 {SEGMENT_LINE, {{{ 55.0f, 20.0f}}}},
2527 {SEGMENT_LINE, {{{ 55.0f, 220.0f}}}},
2528 {SEGMENT_LINE, {{{ 25.0f, 220.0f}}}},
2529 {SEGMENT_LINE, {{{ 25.0f, 100.0f}}}},
2530 {SEGMENT_LINE, {{{ 75.0f, 100.0f}}}},
2531 {SEGMENT_LINE, {{{ 75.0f, 300.0f}}}},
2532 {SEGMENT_LINE, {{{ 5.0f, 300.0f}}}},
2533 {SEGMENT_LINE, {{{ 5.0f, 60.0f}}}},
2534 {SEGMENT_LINE, {{{ 45.0f, 60.0f}}}},
2535 {SEGMENT_LINE, {{{ 45.0f, 180.0f}}}},
2536 {SEGMENT_LINE, {{{ 35.0f, 180.0f}}}},
2537 {SEGMENT_LINE, {{{ 35.0f, 140.0f}}}},
2538 {SEGMENT_LINE, {{{ 65.0f, 140.0f}}}},
2539 {SEGMENT_LINE, {{{ 65.0f, 260.0f}}}},
2540 {SEGMENT_LINE, {{{ 15.0f, 260.0f}}}},
2541 /* Figure 1. */
2542 {SEGMENT_LINE, {{{155.0f, 160.0f}}}},
2543 {SEGMENT_LINE, {{{ 85.0f, 160.0f}}}},
2544 {SEGMENT_LINE, {{{ 85.0f, 300.0f}}}},
2545 {SEGMENT_LINE, {{{120.0f, 300.0f}}}},
2546 {SEGMENT_LINE, {{{120.0f, 20.0f}}}},
2547 {SEGMENT_LINE, {{{155.0f, 20.0f}}}},
2548 {SEGMENT_LINE, {{{155.0f, 160.0f}}}},
2549 {SEGMENT_LINE, {{{ 85.0f, 160.0f}}}},
2550 {SEGMENT_LINE, {{{ 85.0f, 20.0f}}}},
2551 {SEGMENT_LINE, {{{120.0f, 20.0f}}}},
2552 {SEGMENT_LINE, {{{120.0f, 300.0f}}}},
2553 /* Figure 2. */
2554 {SEGMENT_LINE, {{{165.0f, 300.0f}}}},
2555 {SEGMENT_LINE, {{{235.0f, 300.0f}}}},
2556 {SEGMENT_LINE, {{{235.0f, 20.0f}}}},
2557 /* Figure 3. */
2558 {SEGMENT_LINE, {{{225.0f, 260.0f}}}},
2559 {SEGMENT_LINE, {{{175.0f, 260.0f}}}},
2560 {SEGMENT_LINE, {{{175.0f, 60.0f}}}},
2561 /* Figure 4. */
2562 {SEGMENT_LINE, {{{185.0f, 220.0f}}}},
2563 {SEGMENT_LINE, {{{185.0f, 100.0f}}}},
2564 {SEGMENT_LINE, {{{215.0f, 100.0f}}}},
2565 /* Figure 5. */
2566 {SEGMENT_LINE, {{{205.0f, 180.0f}}}},
2567 {SEGMENT_LINE, {{{205.0f, 140.0f}}}},
2568 {SEGMENT_LINE, {{{195.0f, 140.0f}}}},
2569 /* Figure 6. */
2570 {SEGMENT_LINE, {{{135.0f, 620.0f}}}},
2571 {SEGMENT_LINE, {{{135.0f, 420.0f}}}},
2572 {SEGMENT_LINE, {{{105.0f, 420.0f}}}},
2573 {SEGMENT_LINE, {{{105.0f, 540.0f}}}},
2574 {SEGMENT_LINE, {{{155.0f, 540.0f}}}},
2575 {SEGMENT_LINE, {{{155.0f, 340.0f}}}},
2576 {SEGMENT_LINE, {{{ 85.0f, 340.0f}}}},
2577 {SEGMENT_LINE, {{{ 85.0f, 580.0f}}}},
2578 {SEGMENT_LINE, {{{125.0f, 580.0f}}}},
2579 {SEGMENT_LINE, {{{125.0f, 460.0f}}}},
2580 {SEGMENT_LINE, {{{115.0f, 460.0f}}}},
2581 {SEGMENT_LINE, {{{115.0f, 500.0f}}}},
2582 {SEGMENT_LINE, {{{145.0f, 500.0f}}}},
2583 {SEGMENT_LINE, {{{145.0f, 380.0f}}}},
2584 {SEGMENT_LINE, {{{ 95.0f, 380.0f}}}},
2585 /* Figure 7. */
2586 {SEGMENT_LINE, {{{235.0f, 480.0f}}}},
2587 {SEGMENT_LINE, {{{165.0f, 480.0f}}}},
2588 {SEGMENT_LINE, {{{165.0f, 340.0f}}}},
2589 {SEGMENT_LINE, {{{200.0f, 340.0f}}}},
2590 {SEGMENT_LINE, {{{200.0f, 620.0f}}}},
2591 {SEGMENT_LINE, {{{235.0f, 620.0f}}}},
2592 {SEGMENT_LINE, {{{235.0f, 480.0f}}}},
2593 {SEGMENT_LINE, {{{165.0f, 480.0f}}}},
2594 {SEGMENT_LINE, {{{165.0f, 620.0f}}}},
2595 {SEGMENT_LINE, {{{200.0f, 620.0f}}}},
2596 {SEGMENT_LINE, {{{200.0f, 340.0f}}}},
2597 /* Figure 8. */
2598 {SEGMENT_LINE, {{{245.0f, 340.0f}}}},
2599 {SEGMENT_LINE, {{{315.0f, 340.0f}}}},
2600 {SEGMENT_LINE, {{{315.0f, 620.0f}}}},
2601 /* Figure 9. */
2602 {SEGMENT_LINE, {{{305.0f, 380.0f}}}},
2603 {SEGMENT_LINE, {{{255.0f, 380.0f}}}},
2604 {SEGMENT_LINE, {{{255.0f, 580.0f}}}},
2605 /* Figure 10. */
2606 {SEGMENT_LINE, {{{265.0f, 420.0f}}}},
2607 {SEGMENT_LINE, {{{265.0f, 540.0f}}}},
2608 {SEGMENT_LINE, {{{295.0f, 540.0f}}}},
2609 /* Figure 11. */
2610 {SEGMENT_LINE, {{{285.0f, 460.0f}}}},
2611 {SEGMENT_LINE, {{{285.0f, 500.0f}}}},
2612 {SEGMENT_LINE, {{{275.0f, 500.0f}}}},
2613 /* Figure 12. */
2614 {SEGMENT_BEZIER, {{{2.83333340e+01f, 1.60000000e+02f},
2615 {4.00000000e+01f, 1.13333336e+02f},
2616 {4.00000000e+01f, 2.00000000e+01f}}}},
2617 {SEGMENT_BEZIER, {{{4.00000000e+01f, 1.13333336e+02f},
2618 {5.16666641e+01f, 1.60000000e+02f},
2619 {7.50000000e+01f, 1.60000000e+02f}}}},
2620 {SEGMENT_BEZIER, {{{5.16666641e+01f, 1.60000000e+02f},
2621 {4.00000000e+01f, 2.06666656e+02f},
2622 {4.00000000e+01f, 3.00000000e+02f}}}},
2623 {SEGMENT_BEZIER, {{{4.00000000e+01f, 2.06666656e+02f},
2624 {2.83333340e+01f, 1.60000000e+02f},
2625 {5.00000000e+00f, 1.60000000e+02f}}}},
2626 /* Figure 13. */
2627 {SEGMENT_BEZIER, {{{2.00000000e+01f, 1.06666664e+02f},
2628 {2.66666660e+01f, 8.00000000e+01f},
2629 {4.00000000e+01f, 8.00000000e+01f}}}},
2630 {SEGMENT_BEZIER, {{{5.33333321e+01f, 8.00000000e+01f},
2631 {6.00000000e+01f, 1.06666664e+02f},
2632 {6.00000000e+01f, 1.60000000e+02f}}}},
2633 {SEGMENT_BEZIER, {{{6.00000000e+01f, 2.13333328e+02f},
2634 {5.33333321e+01f, 2.40000000e+02f},
2635 {4.00000000e+01f, 2.40000000e+02f}}}},
2636 {SEGMENT_BEZIER, {{{2.66666660e+01f, 2.40000000e+02f},
2637 {2.00000000e+01f, 2.13333328e+02f},
2638 {2.00000000e+01f, 1.60000000e+02f}}}},
2639 /* Figure 14. */
2640 {SEGMENT_BEZIER, {{{2.83333340e+01f, 6.12000000e+02f},
2641 {4.00000000e+01f, 6.58666687e+02f},
2642 {4.00000000e+01f, 7.52000000e+02f}}}},
2643 {SEGMENT_BEZIER, {{{4.00000000e+01f, 6.58666687e+02f},
2644 {5.16666641e+01f, 6.12000000e+02f},
2645 {7.50000000e+01f, 6.12000000e+02f}}}},
2646 {SEGMENT_BEZIER, {{{5.16666641e+01f, 6.12000000e+02f},
2647 {4.00000000e+01f, 5.65333313e+02f},
2648 {4.00000000e+01f, 4.72000000e+02f}}}},
2649 {SEGMENT_BEZIER, {{{4.00000000e+01f, 5.65333313e+02f},
2650 {2.83333340e+01f, 6.12000000e+02f},
2651 {5.00000000e+00f, 6.12000000e+02f}}}},
2652 /* Figure 15. */
2653 {SEGMENT_BEZIER, {{{2.00000000e+01f, 6.65333313e+02f},
2654 {2.66666660e+01f, 6.92000000e+02f},
2655 {4.00000000e+01f, 6.92000000e+02f}}}},
2656 {SEGMENT_BEZIER, {{{5.33333321e+01f, 6.92000000e+02f},
2657 {6.00000000e+01f, 6.65333313e+02f},
2658 {6.00000000e+01f, 6.12000000e+02f}}}},
2659 {SEGMENT_BEZIER, {{{6.00000000e+01f, 5.58666687e+02f},
2660 {5.33333321e+01f, 5.32000000e+02f},
2661 {4.00000000e+01f, 5.32000000e+02f}}}},
2662 {SEGMENT_BEZIER, {{{2.66666660e+01f, 5.32000000e+02f},
2663 {2.00000000e+01f, 5.58666687e+02f},
2664 {2.00000000e+01f, 6.12000000e+02f}}}},
2665 /* Figure 16. */
2666 {SEGMENT_BEZIER, {{{1.91750427e+02f, 1.27275856e+02f},
2667 {2.08249573e+02f, 1.27275856e+02f},
2668 {2.24748734e+02f, 6.12792168e+01f}}}},
2669 {SEGMENT_BEZIER, {{{2.08249573e+02f, 1.27275856e+02f},
2670 {2.08249573e+02f, 1.93272476e+02f},
2671 {2.24748734e+02f, 2.59269104e+02f}}}},
2672 {SEGMENT_BEZIER, {{{2.08249573e+02f, 1.93272476e+02f},
2673 {1.91750427e+02f, 1.93272476e+02f},
2674 {1.75251266e+02f, 2.59269104e+02f}}}},
2675 {SEGMENT_BEZIER, {{{1.91750427e+02f, 1.93272476e+02f},
2676 {1.91750427e+02f, 1.27275856e+02f},
2677 {1.75251266e+02f, 6.12792168e+01f}}}},
2678 /* Figure 17. */
2679 {SEGMENT_BEZIER, {{{1.95285950e+02f, 6.59932632e+01f},
2680 {2.04714050e+02f, 6.59932632e+01f},
2681 {2.14142136e+02f, 1.03705627e+02f}}}},
2682 {SEGMENT_BEZIER, {{{2.23570221e+02f, 1.41417984e+02f},
2683 {2.23570221e+02f, 1.79130356e+02f},
2684 {2.14142136e+02f, 2.16842712e+02f}}}},
2685 {SEGMENT_BEZIER, {{{2.04714050e+02f, 2.54555069e+02f},
2686 {1.95285950e+02f, 2.54555069e+02f},
2687 {1.85857864e+02f, 2.16842712e+02f}}}},
2688 {SEGMENT_BEZIER, {{{1.76429779e+02f, 1.79130356e+02f},
2689 {1.76429779e+02f, 1.41417984e+02f},
2690 {1.85857864e+02f, 1.03705627e+02f}}}},
2691 /* Figure 18. */
2692 {SEGMENT_BEZIER, {{{1.11847351e+02f, 4.46888092e+02f},
2693 {1.11847351e+02f, 5.12884705e+02f},
2694 {9.53481979e+01f, 5.78881348e+02f}}}},
2695 {SEGMENT_BEZIER, {{{1.11847351e+02f, 5.12884705e+02f},
2696 {1.28346512e+02f, 5.12884705e+02f},
2697 {1.44845673e+02f, 5.78881348e+02f}}}},
2698 {SEGMENT_BEZIER, {{{1.28346512e+02f, 5.12884705e+02f},
2699 {1.28346512e+02f, 4.46888092e+02f},
2700 {1.44845673e+02f, 3.80891479e+02f}}}},
2701 {SEGMENT_BEZIER, {{{1.28346512e+02f, 4.46888092e+02f},
2702 {1.11847351e+02f, 4.46888092e+02f},
2703 {9.53481979e+01f, 3.80891479e+02f}}}},
2704 /* Figure 19. */
2705 {SEGMENT_BEZIER, {{{9.65267105e+01f, 4.61030243e+02f},
2706 {9.65267105e+01f, 4.98742584e+02f},
2707 {1.05954803e+02f, 5.36454956e+02f}}}},
2708 {SEGMENT_BEZIER, {{{1.15382889e+02f, 5.74167297e+02f},
2709 {1.24810982e+02f, 5.74167297e+02f},
2710 {1.34239075e+02f, 5.36454956e+02f}}}},
2711 {SEGMENT_BEZIER, {{{1.43667160e+02f, 4.98742584e+02f},
2712 {1.43667160e+02f, 4.61030243e+02f},
2713 {1.34239075e+02f, 4.23317871e+02f}}}},
2714 {SEGMENT_BEZIER, {{{1.24810982e+02f, 3.85605499e+02f},
2715 {1.15382889e+02f, 3.85605499e+02f},
2716 {1.05954803e+02f, 4.23317871e+02f}}}},
2717 /* Figure 20. */
2718 {SEGMENT_LINE, {{{ 40.0f, 20.0f}}}},
2719 {SEGMENT_LINE, {{{ 75.0f, 160.0f}}}},
2720 {SEGMENT_LINE, {{{ 40.0f, 300.0f}}}},
2721 {SEGMENT_LINE, {{{ 5.0f, 160.0f}}}},
2722 /* Figure 21. */
2723 {SEGMENT_LINE, {{{ 40.0f, 80.0f}}}},
2724 {SEGMENT_LINE, {{{ 60.0f, 160.0f}}}},
2725 {SEGMENT_LINE, {{{ 40.0f, 240.0f}}}},
2726 {SEGMENT_LINE, {{{ 20.0f, 160.0f}}}},
2727 /* Figure 22. */
2728 {SEGMENT_LINE, {{{ 40.0f, 752.0f}}}},
2729 {SEGMENT_LINE, {{{ 75.0f, 612.0f}}}},
2730 {SEGMENT_LINE, {{{ 40.0f, 472.0f}}}},
2731 {SEGMENT_LINE, {{{ 5.0f, 612.0f}}}},
2732 /* Figure 23. */
2733 {SEGMENT_LINE, {{{ 40.0f, 692.0f}}}},
2734 {SEGMENT_LINE, {{{ 60.0f, 612.0f}}}},
2735 {SEGMENT_LINE, {{{ 40.0f, 532.0f}}}},
2736 {SEGMENT_LINE, {{{ 20.0f, 612.0f}}}},
2737 /* Figure 24. */
2738 {SEGMENT_LINE, {{{2.03125019e+01f, 1.51250000e+02f}}}},
2739 {SEGMENT_LINE, {{{3.12500019e+01f, 1.25000008e+02f}}}, D2D1_PATH_SEGMENT_FORCE_ROUND_LINE_JOIN},
2740 {SEGMENT_LINE, {{{3.78125000e+01f, 8.12500076e+01f}}}, D2D1_PATH_SEGMENT_FORCE_ROUND_LINE_JOIN},
2741 {SEGMENT_LINE, {{{4.00000000e+01f, 2.00000000e+01f}}}, D2D1_PATH_SEGMENT_FORCE_ROUND_LINE_JOIN},
2742 {SEGMENT_LINE, {{{4.21875000e+01f, 8.12500076e+01f}}}},
2743 {SEGMENT_LINE, {{{4.87500000e+01f, 1.25000008e+02f}}}, D2D1_PATH_SEGMENT_FORCE_ROUND_LINE_JOIN},
2744 {SEGMENT_LINE, {{{5.96875000e+01f, 1.51250000e+02f}}}, D2D1_PATH_SEGMENT_FORCE_ROUND_LINE_JOIN},
2745 {SEGMENT_LINE, {{{7.50000000e+01f, 1.60000000e+02f}}}, D2D1_PATH_SEGMENT_FORCE_ROUND_LINE_JOIN},
2746 {SEGMENT_LINE, {{{5.96875000e+01f, 1.68750000e+02f}}}},
2747 {SEGMENT_LINE, {{{4.87500000e+01f, 1.95000000e+02f}}}, D2D1_PATH_SEGMENT_FORCE_ROUND_LINE_JOIN},
2748 {SEGMENT_LINE, {{{4.21875000e+01f, 2.38750000e+02f}}}, D2D1_PATH_SEGMENT_FORCE_ROUND_LINE_JOIN},
2749 {SEGMENT_LINE, {{{4.00000000e+01f, 3.00000000e+02f}}}, D2D1_PATH_SEGMENT_FORCE_ROUND_LINE_JOIN},
2750 {SEGMENT_LINE, {{{3.78125000e+01f, 2.38750000e+02f}}}},
2751 {SEGMENT_LINE, {{{3.12500019e+01f, 1.95000000e+02f}}}, D2D1_PATH_SEGMENT_FORCE_ROUND_LINE_JOIN},
2752 {SEGMENT_LINE, {{{2.03125019e+01f, 1.68750000e+02f}}}, D2D1_PATH_SEGMENT_FORCE_ROUND_LINE_JOIN},
2753 {SEGMENT_LINE, {{{5.00000000e+00f, 1.60000000e+02f}}}, D2D1_PATH_SEGMENT_FORCE_ROUND_LINE_JOIN},
2754 /* Figure 25. */
2755 {SEGMENT_LINE, {{{2.50000000e+01f, 1.00000000e+02f}}}},
2756 {SEGMENT_LINE, {{{4.00000000e+01f, 8.00000000e+01f}}}, D2D1_PATH_SEGMENT_FORCE_ROUND_LINE_JOIN},
2757 {SEGMENT_LINE, {{{5.50000000e+01f, 1.00000000e+02f}}}},
2758 {SEGMENT_LINE, {{{6.00000000e+01f, 1.60000000e+02f}}}, D2D1_PATH_SEGMENT_FORCE_ROUND_LINE_JOIN},
2759 {SEGMENT_LINE, {{{5.50000000e+01f, 2.20000000e+02f}}}},
2760 {SEGMENT_LINE, {{{4.00000000e+01f, 2.40000000e+02f}}}, D2D1_PATH_SEGMENT_FORCE_ROUND_LINE_JOIN},
2761 {SEGMENT_LINE, {{{2.50000000e+01f, 2.20000000e+02f}}}},
2762 {SEGMENT_LINE, {{{2.00000000e+01f, 1.60000000e+02f}}}, D2D1_PATH_SEGMENT_FORCE_ROUND_LINE_JOIN},
2763 /* Figure 26. */
2764 {SEGMENT_LINE, {{{2.03125019e+01f, 6.20750000e+02f}}}},
2765 {SEGMENT_LINE, {{{3.12500019e+01f, 6.47000000e+02f}}}, D2D1_PATH_SEGMENT_FORCE_ROUND_LINE_JOIN},
2766 {SEGMENT_LINE, {{{3.78125000e+01f, 6.90750000e+02f}}}, D2D1_PATH_SEGMENT_FORCE_ROUND_LINE_JOIN},
2767 {SEGMENT_LINE, {{{4.00000000e+01f, 7.52000000e+02f}}}, D2D1_PATH_SEGMENT_FORCE_ROUND_LINE_JOIN},
2768 {SEGMENT_LINE, {{{4.21875000e+01f, 6.90750000e+02f}}}},
2769 {SEGMENT_LINE, {{{4.87500000e+01f, 6.47000000e+02f}}}, D2D1_PATH_SEGMENT_FORCE_ROUND_LINE_JOIN},
2770 {SEGMENT_LINE, {{{5.96875000e+01f, 6.20750000e+02f}}}, D2D1_PATH_SEGMENT_FORCE_ROUND_LINE_JOIN},
2771 {SEGMENT_LINE, {{{7.50000000e+01f, 6.12000000e+02f}}}, D2D1_PATH_SEGMENT_FORCE_ROUND_LINE_JOIN},
2772 {SEGMENT_LINE, {{{5.96875000e+01f, 6.03250000e+02f}}}},
2773 {SEGMENT_LINE, {{{4.87500000e+01f, 5.77000000e+02f}}}, D2D1_PATH_SEGMENT_FORCE_ROUND_LINE_JOIN},
2774 {SEGMENT_LINE, {{{4.21875000e+01f, 5.33250000e+02f}}}, D2D1_PATH_SEGMENT_FORCE_ROUND_LINE_JOIN},
2775 {SEGMENT_LINE, {{{4.00000000e+01f, 4.72000000e+02f}}}, D2D1_PATH_SEGMENT_FORCE_ROUND_LINE_JOIN},
2776 {SEGMENT_LINE, {{{3.78125000e+01f, 5.33250000e+02f}}}},
2777 {SEGMENT_LINE, {{{3.12500019e+01f, 5.77000000e+02f}}}, D2D1_PATH_SEGMENT_FORCE_ROUND_LINE_JOIN},
2778 {SEGMENT_LINE, {{{2.03125019e+01f, 6.03250000e+02f}}}, D2D1_PATH_SEGMENT_FORCE_ROUND_LINE_JOIN},
2779 {SEGMENT_LINE, {{{5.00000000e+00f, 6.12000000e+02f}}}, D2D1_PATH_SEGMENT_FORCE_ROUND_LINE_JOIN},
2780 /* Figure 27. */
2781 {SEGMENT_LINE, {{{2.50000000e+01f, 6.72000000e+02f}}}},
2782 {SEGMENT_LINE, {{{4.00000000e+01f, 6.92000000e+02f}}}, D2D1_PATH_SEGMENT_FORCE_ROUND_LINE_JOIN},
2783 {SEGMENT_LINE, {{{5.50000000e+01f, 6.72000000e+02f}}}},
2784 {SEGMENT_LINE, {{{6.00000000e+01f, 6.12000000e+02f}}}, D2D1_PATH_SEGMENT_FORCE_ROUND_LINE_JOIN},
2785 {SEGMENT_LINE, {{{5.50000000e+01f, 5.52000000e+02f}}}},
2786 {SEGMENT_LINE, {{{4.00000000e+01f, 5.32000000e+02f}}}, D2D1_PATH_SEGMENT_FORCE_ROUND_LINE_JOIN},
2787 {SEGMENT_LINE, {{{2.50000000e+01f, 5.52000000e+02f}}}},
2788 {SEGMENT_LINE, {{{2.00000000e+01f, 6.12000000e+02f}}}, D2D1_PATH_SEGMENT_FORCE_ROUND_LINE_JOIN},
2789 /* Figure 28. */
2790 {SEGMENT_LINE, {{{ 75.0f, 300.0f}}}},
2791 {SEGMENT_LINE, {{{ 5.0f, 300.0f}}}},
2793 static const struct expected_geometry_figure expected_figures[] =
2795 /* 0 */
2796 {D2D1_FIGURE_BEGIN_FILLED, D2D1_FIGURE_END_CLOSED, { 15.0f, 20.0f}, 15, &expected_segments[0]},
2797 {D2D1_FIGURE_BEGIN_FILLED, D2D1_FIGURE_END_CLOSED, {155.0f, 300.0f}, 11, &expected_segments[15]},
2798 {D2D1_FIGURE_BEGIN_FILLED, D2D1_FIGURE_END_CLOSED, {165.0f, 20.0f}, 3, &expected_segments[26]},
2799 {D2D1_FIGURE_BEGIN_FILLED, D2D1_FIGURE_END_CLOSED, {225.0f, 60.0f}, 3, &expected_segments[29]},
2800 {D2D1_FIGURE_BEGIN_FILLED, D2D1_FIGURE_END_CLOSED, {215.0f, 220.0f}, 3, &expected_segments[32]},
2801 {D2D1_FIGURE_BEGIN_FILLED, D2D1_FIGURE_END_CLOSED, {195.0f, 180.0f}, 3, &expected_segments[35]},
2802 /* 6 */
2803 {D2D1_FIGURE_BEGIN_FILLED, D2D1_FIGURE_END_CLOSED, { 95.0f, 620.0f}, 15, &expected_segments[38]},
2804 {D2D1_FIGURE_BEGIN_FILLED, D2D1_FIGURE_END_CLOSED, {235.0f, 340.0f}, 11, &expected_segments[53]},
2805 {D2D1_FIGURE_BEGIN_FILLED, D2D1_FIGURE_END_CLOSED, {245.0f, 620.0f}, 3, &expected_segments[64]},
2806 {D2D1_FIGURE_BEGIN_FILLED, D2D1_FIGURE_END_CLOSED, {305.0f, 580.0f}, 3, &expected_segments[67]},
2807 {D2D1_FIGURE_BEGIN_FILLED, D2D1_FIGURE_END_CLOSED, {295.0f, 420.0f}, 3, &expected_segments[70]},
2808 {D2D1_FIGURE_BEGIN_FILLED, D2D1_FIGURE_END_CLOSED, {275.0f, 460.0f}, 3, &expected_segments[73]},
2809 /* 12 */
2810 {D2D1_FIGURE_BEGIN_FILLED, D2D1_FIGURE_END_CLOSED, { 5.0f, 160.0f}, 4, &expected_segments[76]},
2811 {D2D1_FIGURE_BEGIN_FILLED, D2D1_FIGURE_END_CLOSED, { 20.0f, 160.0f}, 4, &expected_segments[80]},
2812 {D2D1_FIGURE_BEGIN_FILLED, D2D1_FIGURE_END_CLOSED, { 5.0f, 612.0f}, 4, &expected_segments[84]},
2813 {D2D1_FIGURE_BEGIN_FILLED, D2D1_FIGURE_END_CLOSED, { 20.0f, 612.0f}, 4, &expected_segments[88]},
2814 /* 16 */
2815 {D2D1_FIGURE_BEGIN_FILLED, D2D1_FIGURE_END_CLOSED,
2816 {1.75251266e+02f, 6.12792168e+01f}, 4, &expected_segments[92]},
2817 {D2D1_FIGURE_BEGIN_FILLED, D2D1_FIGURE_END_CLOSED,
2818 {1.85857864e+02f, 1.03705627e+02f}, 4, &expected_segments[96]},
2819 {D2D1_FIGURE_BEGIN_FILLED, D2D1_FIGURE_END_CLOSED,
2820 {9.53481979e+01f, 3.80891479e+02f}, 4, &expected_segments[100]},
2821 {D2D1_FIGURE_BEGIN_FILLED, D2D1_FIGURE_END_CLOSED,
2822 {1.05954803e+02f, 4.23317871e+02f}, 4, &expected_segments[104]},
2823 /* 20 */
2824 {D2D1_FIGURE_BEGIN_FILLED, D2D1_FIGURE_END_CLOSED, { 5.0f, 160.0f}, 4, &expected_segments[108]},
2825 {D2D1_FIGURE_BEGIN_FILLED, D2D1_FIGURE_END_CLOSED, { 20.0f, 160.0f}, 4, &expected_segments[112]},
2826 {D2D1_FIGURE_BEGIN_FILLED, D2D1_FIGURE_END_CLOSED, { 5.0f, 612.0f}, 4, &expected_segments[116]},
2827 {D2D1_FIGURE_BEGIN_FILLED, D2D1_FIGURE_END_CLOSED, { 20.0f, 612.0f}, 4, &expected_segments[120]},
2828 /* 24 */
2829 {D2D1_FIGURE_BEGIN_FILLED, D2D1_FIGURE_END_CLOSED, { 5.0f, 160.0f}, 16, &expected_segments[124]},
2830 {D2D1_FIGURE_BEGIN_FILLED, D2D1_FIGURE_END_CLOSED, { 20.0f, 160.0f}, 8, &expected_segments[140]},
2831 {D2D1_FIGURE_BEGIN_FILLED, D2D1_FIGURE_END_CLOSED, { 5.0f, 612.0f}, 16, &expected_segments[148]},
2832 {D2D1_FIGURE_BEGIN_FILLED, D2D1_FIGURE_END_CLOSED, { 20.0f, 612.0f}, 8, &expected_segments[164]},
2833 /* 28 */
2834 {D2D1_FIGURE_BEGIN_HOLLOW, D2D1_FIGURE_END_OPEN, { 40.0f, 20.0f}, 2, &expected_segments[172]},
2837 if (!(device = create_device()))
2839 skip("Failed to create device, skipping tests.\n");
2840 return;
2842 window = create_window();
2843 swapchain = create_swapchain(device, window, TRUE);
2844 hr = IDXGISwapChain_GetBuffer(swapchain, 0, &IID_IDXGISurface, (void **)&surface);
2845 ok(SUCCEEDED(hr), "Failed to get buffer, hr %#x.\n", hr);
2846 rt = create_render_target(surface);
2847 ok(!!rt, "Failed to create render target.\n");
2848 ID2D1RenderTarget_GetFactory(rt, &factory);
2850 ID2D1RenderTarget_SetDpi(rt, 192.0f, 48.0f);
2851 ID2D1RenderTarget_SetAntialiasMode(rt, D2D1_ANTIALIAS_MODE_ALIASED);
2852 set_color(&color, 0.890f, 0.851f, 0.600f, 1.0f);
2853 hr = ID2D1RenderTarget_CreateSolidColorBrush(rt, &color, NULL, &brush);
2854 ok(SUCCEEDED(hr), "Failed to create brush, hr %#x.\n", hr);
2856 /* Close() when closed. */
2857 hr = ID2D1Factory_CreatePathGeometry(factory, &geometry);
2858 ok(SUCCEEDED(hr), "Failed to create path geometry, hr %#x.\n", hr);
2859 hr = ID2D1PathGeometry_GetFigureCount(geometry, &count);
2860 ok(hr == D2DERR_WRONG_STATE, "Got unexpected hr %#x.\n", hr);
2861 hr = ID2D1PathGeometry_GetSegmentCount(geometry, &count);
2862 ok(hr == D2DERR_WRONG_STATE, "Got unexpected hr %#x.\n", hr);
2863 hr = ID2D1PathGeometry_Open(geometry, &sink);
2864 ok(SUCCEEDED(hr), "Failed to open geometry sink, hr %#x.\n", hr);
2865 hr = ID2D1PathGeometry_GetFigureCount(geometry, &count);
2866 ok(hr == D2DERR_WRONG_STATE, "Got unexpected hr %#x.\n", hr);
2867 hr = ID2D1PathGeometry_GetSegmentCount(geometry, &count);
2868 ok(hr == D2DERR_WRONG_STATE, "Got unexpected hr %#x.\n", hr);
2869 hr = ID2D1GeometrySink_Close(sink);
2870 ok(SUCCEEDED(hr), "Failed to close geometry sink, hr %#x.\n", hr);
2871 hr = ID2D1PathGeometry_GetFigureCount(geometry, &count);
2872 ok(SUCCEEDED(hr), "Failed to get figure count, hr %#x.\n", hr);
2873 ok(!count, "Got unexpected figure count %u.\n", count);
2874 hr = ID2D1PathGeometry_GetSegmentCount(geometry, &count);
2875 ok(SUCCEEDED(hr), "Failed to get segment count, hr %#x.\n", hr);
2876 ok(!count, "Got unexpected segment count %u.\n", count);
2877 hr = ID2D1GeometrySink_Close(sink);
2878 ok(hr == D2DERR_WRONG_STATE, "Got unexpected hr %#x.\n", hr);
2879 ID2D1GeometrySink_Release(sink);
2880 hr = ID2D1PathGeometry_GetFigureCount(geometry, &count);
2881 ok(SUCCEEDED(hr), "Failed to get figure count, hr %#x.\n", hr);
2882 ok(!count, "Got unexpected figure count %u.\n", count);
2883 hr = ID2D1PathGeometry_GetSegmentCount(geometry, &count);
2884 ok(SUCCEEDED(hr), "Failed to get segment count, hr %#x.\n", hr);
2885 ok(!count, "Got unexpected segment count %u.\n", count);
2886 ID2D1PathGeometry_Release(geometry);
2888 /* Open() when closed. */
2889 hr = ID2D1Factory_CreatePathGeometry(factory, &geometry);
2890 ok(SUCCEEDED(hr), "Failed to create path geometry, hr %#x.\n", hr);
2891 hr = ID2D1PathGeometry_Open(geometry, &sink);
2892 ok(SUCCEEDED(hr), "Failed to open geometry sink, hr %#x.\n", hr);
2893 hr = ID2D1GeometrySink_Close(sink);
2894 ok(SUCCEEDED(hr), "Failed to close geometry sink, hr %#x.\n", hr);
2895 ID2D1GeometrySink_Release(sink);
2896 hr = ID2D1PathGeometry_Open(geometry, &sink);
2897 ok(hr == D2DERR_WRONG_STATE, "Got unexpected hr %#x.\n", hr);
2898 hr = ID2D1PathGeometry_GetFigureCount(geometry, &count);
2899 ok(SUCCEEDED(hr), "Failed to get figure count, hr %#x.\n", hr);
2900 ok(!count, "Got unexpected figure count %u.\n", count);
2901 hr = ID2D1PathGeometry_GetSegmentCount(geometry, &count);
2902 ok(SUCCEEDED(hr), "Failed to get segment count, hr %#x.\n", hr);
2903 ok(!count, "Got unexpected segment count %u.\n", count);
2904 ID2D1PathGeometry_Release(geometry);
2906 /* Open() when open. */
2907 hr = ID2D1Factory_CreatePathGeometry(factory, &geometry);
2908 ok(SUCCEEDED(hr), "Failed to create path geometry, hr %#x.\n", hr);
2909 hr = ID2D1PathGeometry_Open(geometry, &sink);
2910 ok(SUCCEEDED(hr), "Failed to open geometry sink, hr %#x.\n", hr);
2911 hr = ID2D1PathGeometry_Open(geometry, &tmp_sink);
2912 ok(hr == D2DERR_WRONG_STATE, "Got unexpected hr %#x.\n", hr);
2913 hr = ID2D1GeometrySink_Close(sink);
2914 ok(SUCCEEDED(hr), "Failed to close geometry sink, hr %#x.\n", hr);
2915 ID2D1GeometrySink_Release(sink);
2916 hr = ID2D1PathGeometry_GetFigureCount(geometry, &count);
2917 ok(SUCCEEDED(hr), "Failed to get figure count, hr %#x.\n", hr);
2918 ok(!count, "Got unexpected figure count %u.\n", count);
2919 hr = ID2D1PathGeometry_GetSegmentCount(geometry, &count);
2920 ok(SUCCEEDED(hr), "Failed to get segment count, hr %#x.\n", hr);
2921 ok(!count, "Got unexpected segment count %u.\n", count);
2922 ID2D1PathGeometry_Release(geometry);
2924 /* BeginFigure() without EndFigure(). */
2925 hr = ID2D1Factory_CreatePathGeometry(factory, &geometry);
2926 ok(SUCCEEDED(hr), "Failed to create path geometry, hr %#x.\n", hr);
2927 hr = ID2D1PathGeometry_Open(geometry, &sink);
2928 ok(SUCCEEDED(hr), "Failed to open geometry sink, hr %#x.\n", hr);
2929 ID2D1GeometrySink_BeginFigure(sink, point, D2D1_FIGURE_BEGIN_FILLED);
2930 hr = ID2D1GeometrySink_Close(sink);
2931 ok(hr == D2DERR_WRONG_STATE, "Got unexpected hr %#x.\n", hr);
2932 ID2D1GeometrySink_EndFigure(sink, D2D1_FIGURE_END_CLOSED);
2933 hr = ID2D1GeometrySink_Close(sink);
2934 ok(hr == D2DERR_WRONG_STATE, "Got unexpected hr %#x.\n", hr);
2935 ID2D1GeometrySink_Release(sink);
2936 hr = ID2D1PathGeometry_GetFigureCount(geometry, &count);
2937 ok(hr == D2DERR_WRONG_STATE, "Got unexpected hr %#x.\n", hr);
2938 hr = ID2D1PathGeometry_GetSegmentCount(geometry, &count);
2939 ok(hr == D2DERR_WRONG_STATE, "Got unexpected hr %#x.\n", hr);
2940 ID2D1PathGeometry_Release(geometry);
2942 /* EndFigure() without BeginFigure(). */
2943 hr = ID2D1Factory_CreatePathGeometry(factory, &geometry);
2944 ok(SUCCEEDED(hr), "Failed to create path geometry, hr %#x.\n", hr);
2945 hr = ID2D1PathGeometry_Open(geometry, &sink);
2946 ok(SUCCEEDED(hr), "Failed to open geometry sink, hr %#x.\n", hr);
2947 ID2D1GeometrySink_EndFigure(sink, D2D1_FIGURE_END_CLOSED);
2948 hr = ID2D1GeometrySink_Close(sink);
2949 ok(hr == D2DERR_WRONG_STATE, "Got unexpected hr %#x.\n", hr);
2950 ID2D1GeometrySink_Release(sink);
2951 hr = ID2D1PathGeometry_GetFigureCount(geometry, &count);
2952 ok(hr == D2DERR_WRONG_STATE, "Got unexpected hr %#x.\n", hr);
2953 hr = ID2D1PathGeometry_GetSegmentCount(geometry, &count);
2954 ok(hr == D2DERR_WRONG_STATE, "Got unexpected hr %#x.\n", hr);
2955 ID2D1PathGeometry_Release(geometry);
2957 /* BeginFigure()/EndFigure() mismatch. */
2958 hr = ID2D1Factory_CreatePathGeometry(factory, &geometry);
2959 ok(SUCCEEDED(hr), "Failed to create path geometry, hr %#x.\n", hr);
2960 hr = ID2D1PathGeometry_Open(geometry, &sink);
2961 ok(SUCCEEDED(hr), "Failed to open geometry sink, hr %#x.\n", hr);
2962 ID2D1GeometrySink_BeginFigure(sink, point, D2D1_FIGURE_BEGIN_FILLED);
2963 ID2D1GeometrySink_BeginFigure(sink, point, D2D1_FIGURE_BEGIN_FILLED);
2964 ID2D1GeometrySink_EndFigure(sink, D2D1_FIGURE_END_CLOSED);
2965 ID2D1GeometrySink_EndFigure(sink, D2D1_FIGURE_END_CLOSED);
2966 hr = ID2D1GeometrySink_Close(sink);
2967 ok(hr == D2DERR_WRONG_STATE, "Got unexpected hr %#x.\n", hr);
2968 ID2D1GeometrySink_EndFigure(sink, D2D1_FIGURE_END_CLOSED);
2969 hr = ID2D1GeometrySink_Close(sink);
2970 ok(hr == D2DERR_WRONG_STATE, "Got unexpected hr %#x.\n", hr);
2971 ID2D1GeometrySink_Release(sink);
2972 ID2D1PathGeometry_Release(geometry);
2974 /* AddLine() outside BeginFigure()/EndFigure(). */
2975 hr = ID2D1Factory_CreatePathGeometry(factory, &geometry);
2976 ok(SUCCEEDED(hr), "Failed to create path geometry, hr %#x.\n", hr);
2977 hr = ID2D1PathGeometry_Open(geometry, &sink);
2978 ok(SUCCEEDED(hr), "Failed to open geometry sink, hr %#x.\n", hr);
2979 ID2D1GeometrySink_AddLine(sink, point);
2980 hr = ID2D1GeometrySink_Close(sink);
2981 ok(hr == D2DERR_WRONG_STATE, "Got unexpected hr %#x.\n", hr);
2982 ID2D1GeometrySink_AddLine(sink, point);
2983 ID2D1GeometrySink_Release(sink);
2984 hr = ID2D1PathGeometry_GetFigureCount(geometry, &count);
2985 ok(hr == D2DERR_WRONG_STATE, "Got unexpected hr %#x.\n", hr);
2986 hr = ID2D1PathGeometry_GetSegmentCount(geometry, &count);
2987 ok(hr == D2DERR_WRONG_STATE, "Got unexpected hr %#x.\n", hr);
2988 ID2D1PathGeometry_Release(geometry);
2990 /* Empty figure. */
2991 hr = ID2D1Factory_CreatePathGeometry(factory, &geometry);
2992 ok(SUCCEEDED(hr), "Failed to create path geometry, hr %#x.\n", hr);
2993 hr = ID2D1PathGeometry_Open(geometry, &sink);
2994 ok(SUCCEEDED(hr), "Failed to open geometry sink, hr %#x.\n", hr);
2995 set_point(&point, 123.0f, 456.0f);
2996 ID2D1GeometrySink_BeginFigure(sink, point, D2D1_FIGURE_BEGIN_FILLED);
2997 ID2D1GeometrySink_EndFigure(sink, D2D1_FIGURE_END_CLOSED);
2998 hr = ID2D1GeometrySink_Close(sink);
2999 ok(SUCCEEDED(hr), "Failed to close geometry sink, hr %#x.\n", hr);
3000 ID2D1GeometrySink_Release(sink);
3001 hr = ID2D1PathGeometry_GetFigureCount(geometry, &count);
3002 ok(SUCCEEDED(hr), "Failed to get figure count, hr %#x.\n", hr);
3003 ok(count == 1, "Got unexpected figure count %u.\n", count);
3004 hr = ID2D1PathGeometry_GetSegmentCount(geometry, &count);
3005 ok(SUCCEEDED(hr), "Failed to get segment count, hr %#x.\n", hr);
3006 ok(count == 1, "Got unexpected segment count %u.\n", count);
3008 set_rect(&rect, 0.0f, 0.0f, 0.0f, 0.0f);
3009 hr = ID2D1PathGeometry_GetBounds(geometry, NULL, &rect);
3010 ok(SUCCEEDED(hr), "Failed to get geometry bounds, hr %#x.\n", hr);
3011 match = compare_rect(&rect, 123.0f, 456.0f, 123.0f, 456.0f, 0);
3012 ok(match, "Got unexpected rectangle {%.8e, %.8e, %.8e, %.8e}.\n",
3013 rect.left, rect.top, rect.right, rect.bottom);
3015 set_matrix_identity(&matrix);
3016 translate_matrix(&matrix, 80.0f, 640.0f);
3017 scale_matrix(&matrix, 2.0f, 0.5f);
3018 hr = ID2D1PathGeometry_GetBounds(geometry, &matrix, &rect);
3019 ok(SUCCEEDED(hr), "Failed to get geometry bounds, hr %#x.\n", hr);
3020 match = compare_rect(&rect, 326.0f, 868.0f, 326.0f, 868.0f, 0);
3021 ok(match, "Got unexpected rectangle {%.8e, %.8e, %.8e, %.8e}.\n",
3022 rect.left, rect.top, rect.right, rect.bottom);
3024 ID2D1PathGeometry_Release(geometry);
3026 /* Close right after Open(). */
3027 hr = ID2D1Factory_CreatePathGeometry(factory, &geometry);
3028 ok(SUCCEEDED(hr), "Failed to create path geometry, hr %#x.\n", hr);
3030 /* Not open yet. */
3031 set_rect(&rect, 1.0f, 2.0f, 3.0f, 4.0f);
3032 hr = ID2D1PathGeometry_GetBounds(geometry, NULL, &rect);
3033 ok(hr == D2DERR_WRONG_STATE, "Unexpected hr %#x.\n", hr);
3034 match = compare_rect(&rect, 1.0f, 2.0f, 3.0f, 4.0f, 0);
3035 ok(match, "Got unexpected rectangle {%.8e, %.8e, %.8e, %.8e}.\n",
3036 rect.left, rect.top, rect.right, rect.bottom);
3038 hr = ID2D1PathGeometry_Open(geometry, &sink);
3039 ok(SUCCEEDED(hr), "Failed to open geometry sink, hr %#x.\n", hr);
3041 /* Open, not closed. */
3042 set_rect(&rect, 1.0f, 2.0f, 3.0f, 4.0f);
3043 hr = ID2D1PathGeometry_GetBounds(geometry, NULL, &rect);
3044 ok(hr == D2DERR_WRONG_STATE, "Unexpected hr %#x.\n", hr);
3045 match = compare_rect(&rect, 1.0f, 2.0f, 3.0f, 4.0f, 0);
3046 ok(match, "Got unexpected rectangle {%.8e, %.8e, %.8e, %.8e}.\n",
3047 rect.left, rect.top, rect.right, rect.bottom);
3049 hr = ID2D1GeometrySink_Close(sink);
3050 ok(SUCCEEDED(hr), "Failed to close geometry sink, hr %#x.\n", hr);
3051 ID2D1GeometrySink_Release(sink);
3052 hr = ID2D1PathGeometry_GetFigureCount(geometry, &count);
3053 ok(SUCCEEDED(hr), "Failed to get figure count, hr %#x.\n", hr);
3054 ok(count == 0, "Got unexpected figure count %u.\n", count);
3055 hr = ID2D1PathGeometry_GetSegmentCount(geometry, &count);
3056 ok(SUCCEEDED(hr), "Failed to get segment count, hr %#x.\n", hr);
3057 ok(count == 0, "Got unexpected segment count %u.\n", count);
3059 set_rect(&rect, 0.0f, 0.0f, 0.0f, 0.0f);
3060 hr = ID2D1PathGeometry_GetBounds(geometry, NULL, &rect);
3061 ok(SUCCEEDED(hr), "Failed to get geometry bounds, hr %#x.\n", hr);
3062 ok(rect.left > rect.right && rect.top > rect.bottom,
3063 "Got unexpected rectangle {%.8e, %.8e, %.8e, %.8e}.\n", rect.left, rect.top, rect.right, rect.bottom);
3065 set_matrix_identity(&matrix);
3066 translate_matrix(&matrix, 10.0f, 20.0f);
3067 scale_matrix(&matrix, 10.0f, 20.0f);
3068 set_rect(&rect, 0.0f, 0.0f, 0.0f, 0.0f);
3069 hr = ID2D1PathGeometry_GetBounds(geometry, &matrix, &rect);
3070 ok(SUCCEEDED(hr), "Failed to get geometry bounds, hr %#x.\n", hr);
3071 ok(rect.left > rect.right && rect.top > rect.bottom,
3072 "Got unexpected rectangle {%.8e, %.8e, %.8e, %.8e}.\n", rect.left, rect.top, rect.right, rect.bottom);
3074 ID2D1PathGeometry_Release(geometry);
3076 /* GetBounds() with bezier segments. */
3077 hr = ID2D1Factory_CreatePathGeometry(factory, &geometry);
3078 ok(SUCCEEDED(hr), "Failed to create path geometry, hr %#x.\n", hr);
3079 hr = ID2D1PathGeometry_Open(geometry, &sink);
3080 ok(SUCCEEDED(hr), "Failed to open geometry sink, hr %#x.\n", hr);
3081 fill_geometry_sink_bezier(sink, 0);
3082 hr = ID2D1GeometrySink_Close(sink);
3083 ok(SUCCEEDED(hr), "Failed to close geometry sink, hr %#x.\n", hr);
3084 ID2D1GeometrySink_Release(sink);
3086 set_rect(&rect, 0.0f, 0.0f, 0.0f, 0.0f);
3087 hr = ID2D1PathGeometry_GetBounds(geometry, NULL, &rect);
3088 ok(SUCCEEDED(hr), "Failed to get geometry bounds, hr %#x.\n", hr);
3089 match = compare_rect(&rect, 5.0f, 20.0f, 75.0f, 752.0f, 0);
3090 ok(match, "Got unexpected rectangle {%.8e, %.8e, %.8e, %.8e}.\n",
3091 rect.left, rect.top, rect.right, rect.bottom);
3093 set_matrix_identity(&matrix);
3094 translate_matrix(&matrix, 80.0f, 640.0f);
3095 scale_matrix(&matrix, 2.0f, 0.5f);
3096 set_rect(&rect, 0.0f, 0.0f, 0.0f, 0.0f);
3097 hr = ID2D1PathGeometry_GetBounds(geometry, &matrix, &rect);
3098 ok(SUCCEEDED(hr), "Failed to get geometry bounds, hr %#x.\n", hr);
3099 match = compare_rect(&rect, 90.0f, 650.0f, 230.0f, 1016.0f, 0);
3100 ok(match, "Got unexpected rectangle {%.8e, %.8e, %.8e, %.8e}.\n",
3101 rect.left, rect.top, rect.right, rect.bottom);
3103 ID2D1PathGeometry_Release(geometry);
3105 /* GetBounds() with bezier segments and some hollow components. */
3106 hr = ID2D1Factory_CreatePathGeometry(factory, &geometry);
3107 ok(SUCCEEDED(hr), "Failed to create path geometry, hr %#x.\n", hr);
3108 hr = ID2D1PathGeometry_Open(geometry, &sink);
3109 ok(SUCCEEDED(hr), "Failed to open geometry sink, hr %#x.\n", hr);
3110 fill_geometry_sink_bezier(sink, 2);
3111 hr = ID2D1GeometrySink_Close(sink);
3112 ok(SUCCEEDED(hr), "Failed to close geometry sink, hr %#x.\n", hr);
3113 ID2D1GeometrySink_Release(sink);
3115 set_rect(&rect, 0.0f, 0.0f, 0.0f, 0.0f);
3116 hr = ID2D1PathGeometry_GetBounds(geometry, NULL, &rect);
3117 ok(SUCCEEDED(hr), "Failed to get geometry bounds, hr %#x.\n", hr);
3118 match = compare_rect(&rect, 5.0f, 472.0f, 75.0f, 752.0f, 0);
3119 ok(match, "Got unexpected rectangle {%.8e, %.8e, %.8e, %.8e}.\n",
3120 rect.left, rect.top, rect.right, rect.bottom);
3122 set_matrix_identity(&matrix);
3123 translate_matrix(&matrix, 80.0f, 640.0f);
3124 scale_matrix(&matrix, 2.0f, 0.5f);
3125 set_rect(&rect, 0.0f, 0.0f, 0.0f, 0.0f);
3126 hr = ID2D1PathGeometry_GetBounds(geometry, &matrix, &rect);
3127 ok(SUCCEEDED(hr), "Failed to get geometry bounds, hr %#x.\n", hr);
3128 match = compare_rect(&rect, 90.0f, 876.0f, 230.0f, 1016.0f, 0);
3129 ok(match, "Got unexpected rectangle {%.8e, %.8e, %.8e, %.8e}.\n",
3130 rect.left, rect.top, rect.right, rect.bottom);
3132 ID2D1PathGeometry_Release(geometry);
3134 /* GetBounds() with bezier segments and all hollow components. */
3135 hr = ID2D1Factory_CreatePathGeometry(factory, &geometry);
3136 ok(SUCCEEDED(hr), "Failed to create path geometry, hr %#x.\n", hr);
3137 hr = ID2D1PathGeometry_Open(geometry, &sink);
3138 ok(SUCCEEDED(hr), "Failed to open geometry sink, hr %#x.\n", hr);
3139 fill_geometry_sink_bezier(sink, 4);
3140 hr = ID2D1GeometrySink_Close(sink);
3141 ok(SUCCEEDED(hr), "Failed to close geometry sink, hr %#x.\n", hr);
3142 ID2D1GeometrySink_Release(sink);
3144 set_rect(&rect, 0.0f, 0.0f, 0.0f, 0.0f);
3145 hr = ID2D1PathGeometry_GetBounds(geometry, NULL, &rect);
3146 ok(SUCCEEDED(hr), "Failed to get geometry bounds, hr %#x.\n", hr);
3147 match = compare_rect(&rect, INFINITY, INFINITY, FLT_MAX, FLT_MAX, 0);
3148 ok(match, "Got unexpected rectangle {%.8e, %.8e, %.8e, %.8e}.\n",
3149 rect.left, rect.top, rect.right, rect.bottom);
3151 set_matrix_identity(&matrix);
3152 translate_matrix(&matrix, 80.0f, 640.0f);
3153 scale_matrix(&matrix, 2.0f, 0.5f);
3154 set_rect(&rect, 0.0f, 0.0f, 0.0f, 0.0f);
3155 hr = ID2D1PathGeometry_GetBounds(geometry, &matrix, &rect);
3156 ok(SUCCEEDED(hr), "Failed to get geometry bounds, hr %#x.\n", hr);
3157 match = compare_rect(&rect, INFINITY, INFINITY, FLT_MAX, FLT_MAX, 0);
3158 ok(match, "Got unexpected rectangle {%.8e, %.8e, %.8e, %.8e}.\n",
3159 rect.left, rect.top, rect.right, rect.bottom);
3161 ID2D1PathGeometry_Release(geometry);
3163 hr = ID2D1Factory_CreatePathGeometry(factory, &geometry);
3164 ok(SUCCEEDED(hr), "Failed to create path geometry, hr %#x.\n", hr);
3165 hr = ID2D1PathGeometry_Open(geometry, &sink);
3166 ok(SUCCEEDED(hr), "Failed to open geometry sink, hr %#x.\n", hr);
3167 /* The fillmode that's used is the last one set before the sink is closed. */
3168 ID2D1GeometrySink_SetFillMode(sink, D2D1_FILL_MODE_WINDING);
3169 fill_geometry_sink(sink, 0);
3170 ID2D1GeometrySink_SetFillMode(sink, D2D1_FILL_MODE_ALTERNATE);
3171 hr = ID2D1GeometrySink_Close(sink);
3172 ok(SUCCEEDED(hr), "Failed to close geometry sink, hr %#x.\n", hr);
3173 hr = ID2D1PathGeometry_GetFigureCount(geometry, &count);
3174 ok(SUCCEEDED(hr), "Failed to get figure count, hr %#x.\n", hr);
3175 ok(count == 6, "Got unexpected figure count %u.\n", count);
3176 hr = ID2D1PathGeometry_GetSegmentCount(geometry, &count);
3177 ok(SUCCEEDED(hr), "Failed to get segment count, hr %#x.\n", hr);
3178 /* Intersections don't create extra segments. */
3179 ok(count == 44, "Got unexpected segment count %u.\n", count);
3180 ID2D1GeometrySink_SetFillMode(sink, D2D1_FILL_MODE_WINDING);
3181 ID2D1GeometrySink_Release(sink);
3183 geometry_sink_init(&simplify_sink);
3184 hr = ID2D1PathGeometry_Simplify(geometry, D2D1_GEOMETRY_SIMPLIFICATION_OPTION_LINES,
3185 NULL, 0.0f, &simplify_sink.ID2D1SimplifiedGeometrySink_iface);
3186 ok(SUCCEEDED(hr), "Failed to simplify geometry, hr %#x.\n", hr);
3187 geometry_sink_check(&simplify_sink, D2D1_FILL_MODE_ALTERNATE, 6, &expected_figures[0], 0);
3188 geometry_sink_cleanup(&simplify_sink);
3189 geometry_sink_init(&simplify_sink);
3190 hr = ID2D1PathGeometry_Simplify(geometry, D2D1_GEOMETRY_SIMPLIFICATION_OPTION_CUBICS_AND_LINES,
3191 NULL, 0.0f, &simplify_sink.ID2D1SimplifiedGeometrySink_iface);
3192 ok(SUCCEEDED(hr), "Failed to simplify geometry, hr %#x.\n", hr);
3193 geometry_sink_check(&simplify_sink, D2D1_FILL_MODE_ALTERNATE, 6, &expected_figures[0], 0);
3194 geometry_sink_cleanup(&simplify_sink);
3196 set_matrix_identity(&matrix);
3197 translate_matrix(&matrix, 80.0f, 640.0f);
3198 scale_matrix(&matrix, 1.0f, -1.0f);
3199 hr = ID2D1Factory_CreateTransformedGeometry(factory, (ID2D1Geometry *)geometry, &matrix, &transformed_geometry);
3200 ok(SUCCEEDED(hr), "Failed to create transformed geometry, hr %#x.\n", hr);
3202 geometry_sink_init(&simplify_sink);
3203 hr = ID2D1TransformedGeometry_Simplify(transformed_geometry, D2D1_GEOMETRY_SIMPLIFICATION_OPTION_LINES,
3204 NULL, 0.0f, &simplify_sink.ID2D1SimplifiedGeometrySink_iface);
3205 ok(SUCCEEDED(hr), "Failed to simplify geometry, hr %#x.\n", hr);
3206 geometry_sink_check(&simplify_sink, D2D1_FILL_MODE_ALTERNATE, 6, &expected_figures[6], 0);
3207 geometry_sink_cleanup(&simplify_sink);
3209 ID2D1TransformedGeometry_GetSourceGeometry(transformed_geometry, &tmp_geometry);
3210 ok(tmp_geometry == (ID2D1Geometry *)geometry,
3211 "Got unexpected source geometry %p, expected %p.\n", tmp_geometry, geometry);
3212 ID2D1TransformedGeometry_GetTransform(transformed_geometry, &tmp_matrix);
3213 ok(!memcmp(&tmp_matrix, &matrix, sizeof(matrix)),
3214 "Got unexpected matrix {%.8e, %.8e, %.8e, %.8e, %.8e, %.8e}.\n",
3215 tmp_matrix._11, tmp_matrix._12, tmp_matrix._21,
3216 tmp_matrix._22, tmp_matrix._31, tmp_matrix._32);
3217 geometry_sink_init(&simplify_sink);
3218 hr = ID2D1Geometry_Simplify(tmp_geometry, D2D1_GEOMETRY_SIMPLIFICATION_OPTION_LINES,
3219 &tmp_matrix, 0.0f, &simplify_sink.ID2D1SimplifiedGeometrySink_iface);
3220 ok(SUCCEEDED(hr), "Failed to simplify geometry, hr %#x.\n", hr);
3221 geometry_sink_check(&simplify_sink, D2D1_FILL_MODE_ALTERNATE, 6, &expected_figures[6], 0);
3222 geometry_sink_cleanup(&simplify_sink);
3223 ID2D1Geometry_Release(tmp_geometry);
3225 ID2D1RenderTarget_BeginDraw(rt);
3226 set_color(&color, 0.396f, 0.180f, 0.537f, 1.0f);
3227 ID2D1RenderTarget_Clear(rt, &color);
3228 ID2D1RenderTarget_FillGeometry(rt, (ID2D1Geometry *)geometry, (ID2D1Brush *)brush, NULL);
3229 ID2D1RenderTarget_FillGeometry(rt, (ID2D1Geometry *)transformed_geometry, (ID2D1Brush *)brush, NULL);
3230 hr = ID2D1RenderTarget_EndDraw(rt, NULL, NULL);
3231 ok(SUCCEEDED(hr), "Failed to end draw, hr %#x.\n", hr);
3232 match = compare_surface(surface, "3aace1b22aae111cb577614fed16e4eb1650dba5");
3233 ok(match, "Surface does not match.\n");
3235 /* Edge test. */
3236 set_point(&point, 94.0f, 620.0f);
3237 contains = TRUE;
3238 hr = ID2D1TransformedGeometry_FillContainsPoint(transformed_geometry, point, NULL, 0.0f, &contains);
3239 ok(hr == S_OK, "FillContainsPoint failed, hr %#x.\n", hr);
3240 ok(!contains, "Got unexpected contains %#x.\n", contains);
3242 set_point(&point, 95.0f, 620.0f);
3243 contains = FALSE;
3244 hr = ID2D1TransformedGeometry_FillContainsPoint(transformed_geometry, point, NULL, 0.0f, &contains);
3245 ok(hr == S_OK, "FillContainsPoint failed, hr %#x.\n", hr);
3246 ok(contains == TRUE, "Got unexpected contains %#x.\n", contains);
3248 /* With transformation matrix. */
3249 set_matrix_identity(&matrix);
3250 translate_matrix(&matrix, -10.0f, 0.0f);
3251 set_point(&point, 85.0f, 620.0f);
3252 contains = FALSE;
3253 hr = ID2D1TransformedGeometry_FillContainsPoint(transformed_geometry, point, &matrix, 0.0f, &contains);
3254 ok(hr == S_OK, "FillContainsPoint failed, hr %#x.\n", hr);
3255 ok(contains == TRUE, "Got unexpected contains %#x.\n", contains);
3257 ID2D1TransformedGeometry_Release(transformed_geometry);
3258 ID2D1PathGeometry_Release(geometry);
3260 hr = ID2D1Factory_CreatePathGeometry(factory, &geometry);
3261 ok(SUCCEEDED(hr), "Failed to create path geometry, hr %#x.\n", hr);
3262 hr = ID2D1PathGeometry_Open(geometry, &sink);
3263 ok(SUCCEEDED(hr), "Failed to open geometry sink, hr %#x.\n", hr);
3264 fill_geometry_sink(sink, 0);
3265 ID2D1GeometrySink_SetFillMode(sink, D2D1_FILL_MODE_WINDING);
3266 hr = ID2D1GeometrySink_Close(sink);
3267 ok(SUCCEEDED(hr), "Failed to close geometry sink, hr %#x.\n", hr);
3268 hr = ID2D1PathGeometry_GetFigureCount(geometry, &count);
3269 ok(SUCCEEDED(hr), "Failed to get figure count, hr %#x.\n", hr);
3270 ok(count == 6, "Got unexpected figure count %u.\n", count);
3271 hr = ID2D1PathGeometry_GetSegmentCount(geometry, &count);
3272 ok(SUCCEEDED(hr), "Failed to get segment count, hr %#x.\n", hr);
3273 ok(count == 44, "Got unexpected segment count %u.\n", count);
3274 ID2D1GeometrySink_Release(sink);
3276 set_rect(&rect, 0.0f, 0.0f, 0.0f, 0.0f);
3277 hr = ID2D1PathGeometry_GetBounds(geometry, NULL, &rect);
3278 ok(SUCCEEDED(hr), "Failed to get geometry bounds, hr %#x.\n", hr);
3279 match = compare_rect(&rect, 5.0f, 20.0f, 235.0f, 300.0f, 0);
3280 ok(match, "Got unexpected rectangle {%.8e, %.8e, %.8e, %.8e}.\n",
3281 rect.left, rect.top, rect.right, rect.bottom);
3283 set_matrix_identity(&matrix);
3284 translate_matrix(&matrix, 100.0f, 50.0f);
3285 scale_matrix(&matrix, 2.0f, 1.5f);
3286 rotate_matrix(&matrix, M_PI / 4.0f);
3287 set_rect(&rect, 0.0f, 0.0f, 0.0f, 0.0f);
3288 hr = ID2D1PathGeometry_GetBounds(geometry, &matrix, &rect);
3289 ok(SUCCEEDED(hr), "Failed to get geometry bounds, hr %#x.\n", hr);
3290 match = compare_rect(&rect, -3.17192993e+02f, 8.71231079e+01f, 4.04055908e+02f, 6.17453125e+02f, 1);
3291 ok(match, "Got unexpected rectangle {%.8e, %.8e, %.8e, %.8e}.\n",
3292 rect.left, rect.top, rect.right, rect.bottom);
3294 geometry_sink_init(&simplify_sink);
3295 hr = ID2D1PathGeometry_Simplify(geometry, D2D1_GEOMETRY_SIMPLIFICATION_OPTION_LINES,
3296 NULL, 0.0f, &simplify_sink.ID2D1SimplifiedGeometrySink_iface);
3297 ok(SUCCEEDED(hr), "Failed to simplify geometry, hr %#x.\n", hr);
3298 geometry_sink_check(&simplify_sink, D2D1_FILL_MODE_WINDING, 6, &expected_figures[0], 0);
3299 geometry_sink_cleanup(&simplify_sink);
3301 set_matrix_identity(&matrix);
3302 translate_matrix(&matrix, 320.0f, 320.0f);
3303 scale_matrix(&matrix, -1.0f, 1.0f);
3304 hr = ID2D1Factory_CreateTransformedGeometry(factory, (ID2D1Geometry *)geometry, &matrix, &transformed_geometry);
3305 ok(SUCCEEDED(hr), "Failed to create transformed geometry, hr %#x.\n", hr);
3307 ID2D1RenderTarget_BeginDraw(rt);
3308 ID2D1RenderTarget_Clear(rt, &color);
3309 ID2D1RenderTarget_FillGeometry(rt, (ID2D1Geometry *)geometry, (ID2D1Brush *)brush, NULL);
3310 ID2D1RenderTarget_FillGeometry(rt, (ID2D1Geometry *)transformed_geometry, (ID2D1Brush *)brush, NULL);
3311 hr = ID2D1RenderTarget_EndDraw(rt, NULL, NULL);
3312 ok(SUCCEEDED(hr), "Failed to end draw, hr %#x.\n", hr);
3313 match = compare_surface(surface, "bfb40a1f007694fa07dbd3b854f3f5d9c3e1d76b");
3314 ok(match, "Surface does not match.\n");
3315 ID2D1TransformedGeometry_Release(transformed_geometry);
3316 ID2D1PathGeometry_Release(geometry);
3318 hr = ID2D1Factory_CreatePathGeometry(factory, &geometry);
3319 ok(SUCCEEDED(hr), "Failed to create path geometry, hr %#x.\n", hr);
3320 hr = ID2D1PathGeometry_Open(geometry, &sink);
3321 ok(SUCCEEDED(hr), "Failed to open geometry sink, hr %#x.\n", hr);
3322 fill_geometry_sink_bezier(sink, 0);
3323 hr = ID2D1GeometrySink_Close(sink);
3324 ok(SUCCEEDED(hr), "Failed to close geometry sink, hr %#x.\n", hr);
3325 hr = ID2D1PathGeometry_GetFigureCount(geometry, &count);
3326 ok(SUCCEEDED(hr), "Failed to get figure count, hr %#x.\n", hr);
3327 ok(count == 4, "Got unexpected figure count %u.\n", count);
3328 hr = ID2D1PathGeometry_GetSegmentCount(geometry, &count);
3329 ok(SUCCEEDED(hr), "Failed to get segment count, hr %#x.\n", hr);
3330 ok(count == 20, "Got unexpected segment count %u.\n", count);
3331 ID2D1GeometrySink_Release(sink);
3333 geometry_sink_init(&simplify_sink);
3334 hr = ID2D1PathGeometry_Simplify(geometry, D2D1_GEOMETRY_SIMPLIFICATION_OPTION_CUBICS_AND_LINES,
3335 NULL, 0.0f, &simplify_sink.ID2D1SimplifiedGeometrySink_iface);
3336 ok(SUCCEEDED(hr), "Failed to simplify geometry, hr %#x.\n", hr);
3337 geometry_sink_check(&simplify_sink, D2D1_FILL_MODE_ALTERNATE, 4, &expected_figures[12], 1);
3338 geometry_sink_cleanup(&simplify_sink);
3339 geometry_sink_init(&simplify_sink);
3340 hr = ID2D1PathGeometry_Simplify(geometry, D2D1_GEOMETRY_SIMPLIFICATION_OPTION_LINES,
3341 NULL, 100.0f, &simplify_sink.ID2D1SimplifiedGeometrySink_iface);
3342 ok(SUCCEEDED(hr), "Failed to simplify geometry, hr %#x.\n", hr);
3343 geometry_sink_check(&simplify_sink, D2D1_FILL_MODE_ALTERNATE, 4, &expected_figures[20], 1);
3344 geometry_sink_cleanup(&simplify_sink);
3345 geometry_sink_init(&simplify_sink);
3346 hr = ID2D1PathGeometry_Simplify(geometry, D2D1_GEOMETRY_SIMPLIFICATION_OPTION_LINES,
3347 NULL, 10.0f, &simplify_sink.ID2D1SimplifiedGeometrySink_iface);
3348 ok(SUCCEEDED(hr), "Failed to simplify geometry, hr %#x.\n", hr);
3349 geometry_sink_check(&simplify_sink, D2D1_FILL_MODE_ALTERNATE, 4, &expected_figures[24], 1);
3350 geometry_sink_cleanup(&simplify_sink);
3352 set_matrix_identity(&matrix);
3353 scale_matrix(&matrix, 0.5f, 2.0f);
3354 translate_matrix(&matrix, 400.0f, -33.0f);
3355 rotate_matrix(&matrix, M_PI / 4.0f);
3356 scale_matrix(&matrix, 2.0f, 0.5f);
3357 hr = ID2D1Factory_CreateTransformedGeometry(factory, (ID2D1Geometry *)geometry, &matrix, &transformed_geometry);
3358 ok(SUCCEEDED(hr), "Failed to create transformed geometry, hr %#x.\n", hr);
3360 geometry_sink_init(&simplify_sink);
3361 hr = ID2D1TransformedGeometry_Simplify(transformed_geometry, D2D1_GEOMETRY_SIMPLIFICATION_OPTION_CUBICS_AND_LINES,
3362 NULL, 0.0f, &simplify_sink.ID2D1SimplifiedGeometrySink_iface);
3363 ok(SUCCEEDED(hr), "Failed to simplify geometry, hr %#x.\n", hr);
3364 geometry_sink_check(&simplify_sink, D2D1_FILL_MODE_ALTERNATE, 4, &expected_figures[16], 4);
3365 geometry_sink_cleanup(&simplify_sink);
3367 ID2D1RenderTarget_BeginDraw(rt);
3368 ID2D1RenderTarget_Clear(rt, &color);
3369 ID2D1RenderTarget_FillGeometry(rt, (ID2D1Geometry *)geometry, (ID2D1Brush *)brush, NULL);
3370 ID2D1RenderTarget_FillGeometry(rt, (ID2D1Geometry *)transformed_geometry, (ID2D1Brush *)brush, NULL);
3371 hr = ID2D1RenderTarget_EndDraw(rt, NULL, NULL);
3372 ok(SUCCEEDED(hr), "Failed to end draw, hr %#x.\n", hr);
3373 match = compare_figure(surface, 0, 0, 160, 160, 0xff652e89, 64,
3374 "7xoCngECngECngECngECngECngECngECnQEEnAEEnAEEnAEEnAEEmwEGmgEGmgEGmgEGmQEImAEI"
3375 "lAEECASLAQgKCIEBDQoMew8KD3YQDBByEgwSbhMOEmwUDhRpFBAUZxUQFWUVEhVjFhIWYRYUFl8X"
3376 "FBddFxYWXRYYFlsXGBdaFhoWWRYcFlgVHhVXFSAVVhQiFFUUIxRVEyYTVBIoElQRKhFUECwQUxAu"
3377 "EFIOMg5SDTQNUgs4C1IJPAlRCEAIUAZEBlAESARQAU4BTgJQAkgGUAY/C1ALMhNQEyoTUBMyC1AL"
3378 "PwZQBkgCUAJOAU4BUARIBFAGRAZQCEAIUQk8CVILOAtSDTQNUg4yDlIQLhBTECwQVBEqEVQSKBJU"
3379 "EyYTVBQjFFYUIhRWFSAVVxUeFVgWHBZZFhoWWhcYF1sWGBZcFxYWXhcUF18WFBZhFhIWYxUSFWUV"
3380 "EBVnFBAUaRQOFGsTDhJvEgwSchAMEHYPCg96DQoMggEICgiLAQQIBJQBCJgBCJkBBpoBBpoBBpoB"
3381 "BpsBBJwBBJwBBJwBBJwBBJ0BAp4BAp4BAp4BAp4BAp4BAp4BAp4BAgAA");
3382 ok(match, "Figure does not match.\n");
3383 match = compare_figure(surface, 0, 226, 160, 160, 0xff652e89, 64,
3384 "7xoCngECngECngECngECngECngECngECnQEEnAEEnAEEnAEEnAEEmwEGmgEGmgEGmgEGmQEImAEI"
3385 "lAEECASLAQgKCIEBDQoMew8KD3YQDBByEgwSbhMOEmwUDhRpFBAUZxUQFWUVEhVjFhIWYRYUFl8X"
3386 "FBddFxYWXRYYFlsXGBdaFhoWWRYcFlgVHhVXFSAVVhQiFFUUIxRVEyYTVBIoElQRKhFUECwQUxAu"
3387 "EFIOMg5SDTQNUgs4C1IJPAlRCEAIUAZEBlAESARQAU4BTgJQAkgGUAY/C1ALMhNQEyoTUBMyC1AL"
3388 "PwZQBkgCUAJOAU4BUARIBFAGRAZQCEAIUQk8CVILOAtSDTQNUg4yDlIQLhBTECwQVBEqEVQSKBJU"
3389 "EyYTVBQjFFYUIhRWFSAVVxUeFVgWHBZZFhoWWhcYF1sWGBZcFxYWXhcUF18WFBZhFhIWYxUSFWUV"
3390 "EBVnFBAUaRQOFGsTDhJvEgwSchAMEHYPCg96DQoMggEICgiLAQQIBJQBCJgBCJkBBpoBBpoBBpoB"
3391 "BpsBBJwBBJwBBJwBBJwBBJ0BAp4BAp4BAp4BAp4BAp4BAp4BAp4BAgAA");
3392 ok(match, "Figure does not match.\n");
3393 match = compare_figure(surface, 160, 0, 320, 160, 0xff652e89, 64,
3394 "gVQBwAIBWgHlAQFYAecBAVYB6QEBVAHrAQEjDCMB7AECHhQeAu0BAxoYGgPvAQMWHhYD8QEDFCAU"
3395 "A/MBBBAkEAT0AQUOJw0F9QEGCioKBvcBBggsCAb4AQgFLgUI+QEJATIBCfsBCAIwAgj8AQcFLAUH"
3396 "/QEFCCgIBf4BBAwiDAT/AQIQHBAClwISlwIBPgGAAgI8Av8BAzwD/QEEPAT7AQY6BvkBBzoH+AEI"
3397 "OAj3AQk4CfYBCTgK9AELNgvzAQw2DPIBDDYM8QEONA7wAQ40DvABDjQO7wEPNA/uAQ80D+4BEDIQ"
3398 "7QERMhHsAREyEewBETIR7AERMhHsAREyEewBETIR7AERMhHsAREyEewBETIR7AERMhHsAREyEewB"
3399 "ETIR7AERMhHsAREyEe0BEDIQ7gEQMw/uAQ80D+4BDzQP7wEONA7wAQ40DvEBDDYM8gEMNgzzAQs2"
3400 "C/QBCzcK9QEJOAn3AQg4CfcBBzoH+QEGOgb7AQU6BfwBBDwE/QEDPAP/AQE+AZkCDpkCAhIYEgKA"
3401 "AgMNIA0D/wEFCSYJBf4BBgYqBgf8AQgDLgMI+wFG+gEIAzADCPkBBwYuBgf3AQYKKgoG9gEFDCgM"
3402 "BfUBBBAlDwTzAQQSIhIE8QEDFh4WA/ABAhkaGQLvAQIcFhwC7QECIBAgAusBASgEKAHpAQFWAecB"
3403 "AVgB5QEBWgHAAgHhUgAA");
3404 ok(match, "Figure does not match.\n");
3405 match = compare_figure(surface, 160, 160, 320, 160, 0xff652e89, 64,
3406 "/VUB5QEBWAHnAQFWAekBAVQB6wECIQ8hAe0BAh0VHQLuAQIZGhkD7wEDFh4WA/EBBBMhEwPzAQQQ"
3407 "JQ8F9AEFDCgNBfUBBgoqCgb3AQcHLQcG+QEIBC8ECPkBPAEJ+wEIAy8CCP0BBgYrBQf9AQUJJgkF"
3408 "/wEDDSANBP8BAhEaEQKYAhAXAYACAT4BgAICPQL+AQM8BPwBBTsE+wEGOgb6AQc5B/gBCDgJ9gEJ"
3409 "OAn2AQo3CvQBCzcK8wEMNgzyAQ01DPIBDTUN8AEONA7wAQ40D+4BDzQP7gEQMw/uARAzEO0BEDIR"
3410 "7AERMhHsAREyEewBETIR7AERMhLrAREyEusBETIS6wERMhLrAREyEusBETIS6wERMhHsAREyEewB"
3411 "ETIR7QEQMhHtARAzEO0BEDMP7gEPNA/vAQ40D+8BDjQO8QENNQ3xAQ01DPMBCzYM8wELNwr1AQo3"
3412 "CvUBCTgJ9wEIOAn4AQc5B/kBBjoG+wEFOwT9AQM8BP4BAj0C/wEBPgGYAhAXAYACAhEaEQKAAgMN"
3413 "IA0E/gEFCSYJBf4BBgYrBQf8AQgDLwII+wE8AQn6AQgELwQI+AEHBy0HBvcBBgoqCgb2AQUNJw0F"
3414 "9AEEECQQBfIBBBMhEwPxAQMWHhYD8AECGRoZA+4BAh0VHQLsAQIhDiIB6wEBVAHpAQFWAecBAVgB"
3415 "wAIBwlYA");
3416 ok(match, "Figure does not match.\n");
3417 ID2D1TransformedGeometry_Release(transformed_geometry);
3418 ID2D1PathGeometry_Release(geometry);
3420 hr = ID2D1Factory_CreatePathGeometry(factory, &geometry);
3421 ok(SUCCEEDED(hr), "Failed to create path geometry, hr %#x.\n", hr);
3422 hr = ID2D1PathGeometry_Open(geometry, &sink);
3423 ok(SUCCEEDED(hr), "Failed to open geometry sink, hr %#x.\n", hr);
3424 fill_geometry_sink_bezier(sink, 0);
3425 ID2D1GeometrySink_SetFillMode(sink, D2D1_FILL_MODE_WINDING);
3426 hr = ID2D1GeometrySink_Close(sink);
3427 ok(SUCCEEDED(hr), "Failed to close geometry sink, hr %#x.\n", hr);
3428 hr = ID2D1PathGeometry_GetFigureCount(geometry, &count);
3429 ok(SUCCEEDED(hr), "Failed to get figure count, hr %#x.\n", hr);
3430 ok(count == 4, "Got unexpected figure count %u.\n", count);
3431 hr = ID2D1PathGeometry_GetSegmentCount(geometry, &count);
3432 ok(SUCCEEDED(hr), "Failed to get segment count, hr %#x.\n", hr);
3433 ok(count == 20, "Got unexpected segment count %u.\n", count);
3434 ID2D1GeometrySink_Release(sink);
3436 geometry_sink_init(&simplify_sink);
3437 hr = ID2D1PathGeometry_Simplify(geometry, D2D1_GEOMETRY_SIMPLIFICATION_OPTION_CUBICS_AND_LINES,
3438 NULL, 0.0f, &simplify_sink.ID2D1SimplifiedGeometrySink_iface);
3439 ok(SUCCEEDED(hr), "Failed to simplify geometry, hr %#x.\n", hr);
3440 geometry_sink_check(&simplify_sink, D2D1_FILL_MODE_WINDING, 4, &expected_figures[12], 1);
3441 geometry_sink_cleanup(&simplify_sink);
3442 geometry_sink_init(&simplify_sink);
3443 hr = ID2D1PathGeometry_Simplify(geometry, D2D1_GEOMETRY_SIMPLIFICATION_OPTION_LINES,
3444 NULL, 100.0f, &simplify_sink.ID2D1SimplifiedGeometrySink_iface);
3445 ok(SUCCEEDED(hr), "Failed to simplify geometry, hr %#x.\n", hr);
3446 geometry_sink_check(&simplify_sink, D2D1_FILL_MODE_WINDING, 4, &expected_figures[20], 1);
3447 geometry_sink_cleanup(&simplify_sink);
3448 geometry_sink_init(&simplify_sink);
3449 hr = ID2D1PathGeometry_Simplify(geometry, D2D1_GEOMETRY_SIMPLIFICATION_OPTION_LINES,
3450 NULL, 10.0f, &simplify_sink.ID2D1SimplifiedGeometrySink_iface);
3451 ok(SUCCEEDED(hr), "Failed to simplify geometry, hr %#x.\n", hr);
3452 geometry_sink_check(&simplify_sink, D2D1_FILL_MODE_WINDING, 4, &expected_figures[24], 1);
3453 geometry_sink_cleanup(&simplify_sink);
3455 set_matrix_identity(&matrix);
3456 scale_matrix(&matrix, 0.5f, 2.0f);
3457 translate_matrix(&matrix, 127.0f, 80.0f);
3458 rotate_matrix(&matrix, M_PI / -4.0f);
3459 scale_matrix(&matrix, 2.0f, 0.5f);
3460 hr = ID2D1Factory_CreateTransformedGeometry(factory, (ID2D1Geometry *)geometry, &matrix, &transformed_geometry);
3461 ok(SUCCEEDED(hr), "Failed to create transformed geometry, hr %#x.\n", hr);
3463 ID2D1RenderTarget_BeginDraw(rt);
3464 ID2D1RenderTarget_Clear(rt, &color);
3465 ID2D1RenderTarget_FillGeometry(rt, (ID2D1Geometry *)geometry, (ID2D1Brush *)brush, NULL);
3466 ID2D1RenderTarget_FillGeometry(rt, (ID2D1Geometry *)transformed_geometry, (ID2D1Brush *)brush, NULL);
3467 hr = ID2D1RenderTarget_EndDraw(rt, NULL, NULL);
3468 ok(SUCCEEDED(hr), "Failed to end draw, hr %#x.\n", hr);
3469 match = compare_figure(surface, 0, 0, 160, 160, 0xff652e89, 64,
3470 "7xoCngECngECngECngECngECngECngECnQEEnAEEnAEEnAEEnAEEmwEGmgEGmgEGmgEGmQEImAEI"
3471 "lAEQiwEagQEjeyh2LHIwbjNsNmk4ZzplPGM+YUBfQl1DXURbRlpGWUhYSFdKVkpVS1VMVExUTFRM"
3472 "U05STlJOUk5STlFQUFBQUFBQTlRIXD9mMnYqdjJmP1xIVE5QUFBQUFBQUU5STlJOUk5STlNMVExU"
3473 "TFRMVEtWSlZKV0hYSFlGWkZbRFxDXkJfQGE+YzxlOmc4aTZrM28wcix2KHojggEaiwEQlAEImAEI"
3474 "mQEGmgEGmgEGmgEGmwEEnAEEnAEEnAEEnAEEnQECngECngECngECngECngECngECngEC");
3475 ok(match, "Figure does not match.\n");
3476 match = compare_figure(surface, 0, 226, 160, 160, 0xff652e89, 64,
3477 "7xoCngECngECngECngECngECngECngECnQEEnAEEnAEEnAEEnAEEmwEGmgEGmgEGmgEGmQEImAEI"
3478 "lAEQiwEagQEjeyh2LHIwbjNsNmk4ZzplPGM+YUBfQl1DXURbRlpGWUhYSFdKVkpVS1VMVExUTFRM"
3479 "U05STlJOUk5STlFQUFBQUFBQTlRIXD9mMnYqdjJmP1xIVE5QUFBQUFBQUU5STlJOUk5STlNMVExU"
3480 "TFRMVEtWSlZKV0hYSFlGWkZbRFxDXkJfQGE+YzxlOmc4aTZrM28wcix2KHojggEaiwEQlAEImAEI"
3481 "mQEGmgEGmgEGmgEGmwEEnAEEnAEEnAEEnAEEnQECngECngECngECngECngECngECngEC");
3482 ok(match, "Figure does not match.\n");
3483 match = compare_figure(surface, 160, 0, 320, 160, 0xff652e89, 64,
3484 "4VIBwAIBWgHlAQFYAecBAVYB6QEBVAHrAQIhDiIB7QECHRUdAu4BAhkaGQPvAQMWHhYD8QEEEyET"
3485 "A/MBBBAkEAT1AQUMKA0F9QEGCioKBvcBBwctBwb5AQgELwQI+QEJATIBCfsBRP0BQ/0BQv8BQf8B"
3486 "QIECP4ACQIACQf4BQ/wBRPsBRvoBR/gBSPcBSvYBS/QBTPMBTvIBTvIBT/ABUPABUe4BUu4BUu4B"
3487 "U+0BU+wBVOwBVOwBVOwBVOwBVesBVesBVesBVesBVOwBVOwBVOwBVO0BU+0BU+0BUu4BUu8BUe8B"
3488 "UPEBT/EBTvIBTvMBTPUBS/UBSvcBSfcBSPkBRvsBRP0BQ/4BQf8BQIECP4ACQIACQf4BQv4BQ/wB"
3489 "RPsBCQEyAQn6AQgELwQI+AEHBy0GB/cBBgoqCgb2AQUMKA0F9AEEECUPBPMBBBIiEwPxAQMWHhYD"
3490 "8AECGRoZA+4BAh0VHQLsAQIhDiIB6wEBVAHpAQFWAecBAVgB5QEBWgHAAgEA");
3491 ok(match, "Figure does not match.\n");
3492 match = compare_figure(surface, 160, 160, 320, 160, 0xff652e89, 64,
3493 "gVQBXAHjAQFaAeUBAVgB5wEBVgHpAQEpAikB6wECIBAgAu0BAhwWHALvAQIZGhkC8AEDFh4WA/EB"
3494 "BBIiEgTzAQQPJRAE9QEFDCgMBfYBBgoqCgb3AQcGLgYH+QEIAzADCPoBRvsBRPwBRP0BQv8BQIAC"
3495 "QIECPoECQP8BQv0BRPwBRPsBRvkBSPgBSPcBSvUBTPQBTPMBTvIBTvEBUPABUO8BUu4BUu4BUu4B"
3496 "Uu0BVOwBVOwBVOwBVOwBVOwBVOwBVOwBVOwBVOwBVOwBVOwBVOwBVOwBVO0BUu4BUu4BUu8BUPAB"
3497 "UPABUPEBTvIBTvMBTPQBS/YBSvcBSPgBSPkBRvsBRP0BQv8BQIACQIECPoECQP8BQv4BQv0BRPwB"
3498 "RPsBCQEyAQn5AQgFLgUI+AEGCCwIBvcBBgoqCgb1AQUNJw4F9AEEECQQBPMBAxQgFAPxAQMWHhYD"
3499 "7wEDGhgaA+0BAh4UHgLsAQEjDCMB6wEBVAHpAQFWAecBAVgB5QEBWgGiVQAA");
3500 ok(match, "Figure does not match.\n");
3501 ID2D1TransformedGeometry_Release(transformed_geometry);
3502 ID2D1PathGeometry_Release(geometry);
3504 hr = ID2D1Factory_CreatePathGeometry(factory, &geometry);
3505 ok(SUCCEEDED(hr), "Failed to create path geometry, hr %#x.\n", hr);
3506 hr = ID2D1PathGeometry_Open(geometry, &sink);
3507 ok(SUCCEEDED(hr), "Failed to open geometry sink, hr %#x.\n", hr);
3509 set_point(&point, 40.0f, 20.0f);
3510 ID2D1GeometrySink_BeginFigure(sink, point, D2D1_FIGURE_BEGIN_FILLED);
3511 line_to(sink, 75.0f, 300.0f);
3512 line_to(sink, 5.0f, 300.0f);
3513 ID2D1GeometrySink_EndFigure(sink, D2D1_FIGURE_END_CLOSED);
3515 set_point(&point, 40.0f, 290.0f);
3516 ID2D1GeometrySink_BeginFigure(sink, point, D2D1_FIGURE_BEGIN_FILLED);
3517 line_to(sink, 55.0f, 160.0f);
3518 line_to(sink, 25.0f, 160.0f);
3519 ID2D1GeometrySink_EndFigure(sink, D2D1_FIGURE_END_CLOSED);
3521 hr = ID2D1GeometrySink_Close(sink);
3522 ok(SUCCEEDED(hr), "Failed to close geometry sink, hr %#x.\n", hr);
3523 hr = ID2D1PathGeometry_GetFigureCount(geometry, &count);
3524 ok(SUCCEEDED(hr), "Failed to get figure count, hr %#x.\n", hr);
3525 ok(count == 2, "Got unexpected figure count %u.\n", count);
3526 hr = ID2D1PathGeometry_GetSegmentCount(geometry, &count);
3527 ok(SUCCEEDED(hr), "Failed to get segment count, hr %#x.\n", hr);
3528 ok(count == 6, "Got unexpected segment count %u.\n", count);
3529 ID2D1GeometrySink_Release(sink);
3531 ID2D1RenderTarget_BeginDraw(rt);
3532 ID2D1RenderTarget_Clear(rt, &color);
3533 ID2D1RenderTarget_FillGeometry(rt, (ID2D1Geometry *)geometry, (ID2D1Brush *)brush, NULL);
3534 hr = ID2D1RenderTarget_EndDraw(rt, NULL, NULL);
3535 ok(SUCCEEDED(hr), "Failed to end draw, hr %#x.\n", hr);
3536 match = compare_surface(surface, "a875e68e0cb9c055927b1b50b879f90b24e38470");
3537 ok(match, "Surface does not match.\n");
3538 ID2D1PathGeometry_Release(geometry);
3540 hr = ID2D1Factory_CreatePathGeometry(factory, &geometry);
3541 ok(SUCCEEDED(hr), "Failed to create path geometry, hr %#x.\n", hr);
3542 hr = ID2D1PathGeometry_Open(geometry, &sink);
3543 ok(SUCCEEDED(hr), "Failed to open geometry sink, hr %#x.\n", hr);
3544 set_point(&point, 40.0f, 20.0f);
3545 ID2D1GeometrySink_BeginFigure(sink, point, D2D1_FIGURE_BEGIN_HOLLOW);
3546 line_to(sink, 75.0f, 300.0f);
3547 line_to(sink, 5.0f, 300.0f);
3548 ID2D1GeometrySink_EndFigure(sink, D2D1_FIGURE_END_OPEN);
3549 hr = ID2D1GeometrySink_Close(sink);
3550 ok(SUCCEEDED(hr), "Failed to close geometry sink, hr %#x.\n", hr);
3551 ID2D1GeometrySink_Release(sink);
3552 hr = ID2D1PathGeometry_GetSegmentCount(geometry, &count);
3553 ok(SUCCEEDED(hr), "Failed to get segment count, hr %#x.\n", hr);
3554 ok(count == 2, "Got unexpected segment count %u.\n", count);
3556 geometry_sink_init(&simplify_sink);
3557 hr = ID2D1PathGeometry_Simplify(geometry, D2D1_GEOMETRY_SIMPLIFICATION_OPTION_LINES,
3558 NULL, 0.0f, &simplify_sink.ID2D1SimplifiedGeometrySink_iface);
3559 ok(SUCCEEDED(hr), "Failed to simplify geometry, hr %#x.\n", hr);
3560 geometry_sink_check(&simplify_sink, D2D1_FILL_MODE_ALTERNATE, 1, &expected_figures[28], 1);
3561 geometry_sink_cleanup(&simplify_sink);
3563 ID2D1PathGeometry_Release(geometry);
3565 ID2D1SolidColorBrush_Release(brush);
3566 ID2D1RenderTarget_Release(rt);
3567 refcount = ID2D1Factory_Release(factory);
3568 ok(!refcount, "Factory has %u references left.\n", refcount);
3569 IDXGISurface_Release(surface);
3570 IDXGISwapChain_Release(swapchain);
3571 ID3D10Device1_Release(device);
3572 DestroyWindow(window);
3575 static void test_rectangle_geometry(void)
3577 ID2D1TransformedGeometry *transformed_geometry;
3578 ID2D1RectangleGeometry *geometry;
3579 struct geometry_sink sink;
3580 D2D1_MATRIX_3X2_F matrix;
3581 D2D1_RECT_F rect, rect2;
3582 ID2D1Factory *factory;
3583 D2D1_POINT_2F point;
3584 BOOL contains;
3585 HRESULT hr;
3586 BOOL match;
3588 static const struct geometry_segment expected_segments[] =
3590 /* Figure 0. */
3591 {SEGMENT_LINE, {{{10.0f, 0.0f}}}},
3592 {SEGMENT_LINE, {{{10.0f, 20.0f}}}},
3593 {SEGMENT_LINE, {{{ 0.0f, 20.0f}}}},
3594 /* Figure 1. */
3595 {SEGMENT_LINE, {{{4.42705116e+01f, 1.82442951e+01f}}}},
3596 {SEGMENT_LINE, {{{7.95376282e+01f, 5.06049728e+01f}}}},
3597 {SEGMENT_LINE, {{{5.52671127e+01f, 6.23606796e+01f}}}},
3598 /* Figure 2. */
3599 {SEGMENT_LINE, {{{25.0f, 15.0f}}}},
3600 {SEGMENT_LINE, {{{25.0f, 55.0f}}}},
3601 {SEGMENT_LINE, {{{25.0f, 55.0f}}}},
3602 /* Figure 3. */
3603 {SEGMENT_LINE, {{{35.0f, 45.0f}}}},
3604 {SEGMENT_LINE, {{{35.0f, 45.0f}}}},
3605 {SEGMENT_LINE, {{{30.0f, 45.0f}}}},
3606 /* Figure 4. */
3607 {SEGMENT_LINE, {{{ 1.07179585e+01f, 2.23205078e+02f}}}},
3608 {SEGMENT_LINE, {{{-5.85640755e+01f, 2.73205078e+02f}}}},
3609 {SEGMENT_LINE, {{{-7.85640717e+01f, 2.29903809e+02f}}}},
3610 /* Figure 5. */
3611 {SEGMENT_LINE, {{{40.0f, 20.0f}}}},
3612 {SEGMENT_LINE, {{{40.0f, 40.0f}}}},
3613 {SEGMENT_LINE, {{{30.0f, 40.0f}}}},
3614 /* Figure 6. */
3615 {SEGMENT_LINE, {{{ 2.14359169e+01f, 0.0f}}}},
3616 {SEGMENT_LINE, {{{-1.17128151e+02f, 0.0f}}}},
3617 {SEGMENT_LINE, {{{-1.57128143e+02f, 0.0f}}}},
3618 /* Figure 7. */
3619 {SEGMENT_LINE, {{{0.0f, 1.11602539e+02f}}}},
3620 {SEGMENT_LINE, {{{0.0f, 1.36602539e+02f}}}},
3621 {SEGMENT_LINE, {{{0.0f, 1.14951904e+02f}}}},
3623 static const struct expected_geometry_figure expected_figures[] =
3625 {D2D1_FIGURE_BEGIN_FILLED, D2D1_FIGURE_END_CLOSED, { 0.0f, 0.0f}, 3, &expected_segments[0]},
3626 {D2D1_FIGURE_BEGIN_FILLED, D2D1_FIGURE_END_CLOSED, {20.0f, 30.0f}, 3, &expected_segments[3]},
3627 {D2D1_FIGURE_BEGIN_FILLED, D2D1_FIGURE_END_CLOSED, {25.0f, 15.0f}, 3, &expected_segments[6]},
3628 {D2D1_FIGURE_BEGIN_FILLED, D2D1_FIGURE_END_CLOSED, {30.0f, 45.0f}, 3, &expected_segments[9]},
3629 {D2D1_FIGURE_BEGIN_FILLED, D2D1_FIGURE_END_CLOSED, {-9.28203964e+00f, 1.79903809e+02f},
3630 3, &expected_segments[12]},
3631 {D2D1_FIGURE_BEGIN_FILLED, D2D1_FIGURE_END_CLOSED, {30.0f, 20.0f}, 3, &expected_segments[15]},
3632 {D2D1_FIGURE_BEGIN_FILLED, D2D1_FIGURE_END_CLOSED, {-1.85640793e+01f, 0.0f}, 3, &expected_segments[18]},
3633 {D2D1_FIGURE_BEGIN_FILLED, D2D1_FIGURE_END_CLOSED, {0.0f, 8.99519043e+01f}, 3, &expected_segments[21]},
3636 hr = D2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED, &IID_ID2D1Factory, NULL, (void **)&factory);
3637 ok(SUCCEEDED(hr), "Failed to create factory, hr %#x.\n", hr);
3639 set_rect(&rect, 0.0f, 0.0f, 0.0f, 0.0f);
3640 hr = ID2D1Factory_CreateRectangleGeometry(factory, &rect, &geometry);
3641 ok(SUCCEEDED(hr), "Failed to create geometry, hr %#x.\n", hr);
3642 ID2D1RectangleGeometry_GetRect(geometry, &rect2);
3643 match = compare_rect(&rect2, 0.0f, 0.0f, 0.0f, 0.0f, 0);
3644 ok(match, "Got unexpected rectangle {%.8e, %.8e, %.8e, %.8e}.\n",
3645 rect2.left, rect2.top, rect2.right, rect2.bottom);
3646 ID2D1RectangleGeometry_Release(geometry);
3648 set_rect(&rect, 50.0f, 0.0f, 40.0f, 100.0f);
3649 hr = ID2D1Factory_CreateRectangleGeometry(factory, &rect, &geometry);
3650 ok(SUCCEEDED(hr), "Failed to create geometry, hr %#x.\n", hr);
3651 ID2D1RectangleGeometry_GetRect(geometry, &rect2);
3652 match = compare_rect(&rect2, 50.0f, 0.0f, 40.0f, 100.0f, 0);
3653 ok(match, "Got unexpected rectangle {%.8e, %.8e, %.8e, %.8e}.\n",
3654 rect2.left, rect2.top, rect2.right, rect2.bottom);
3655 ID2D1RectangleGeometry_Release(geometry);
3657 set_rect(&rect, 0.0f, 100.0f, 40.0f, 50.0f);
3658 hr = ID2D1Factory_CreateRectangleGeometry(factory, &rect, &geometry);
3659 ok(SUCCEEDED(hr), "Failed to create geometry, hr %#x.\n", hr);
3660 ID2D1RectangleGeometry_GetRect(geometry, &rect2);
3661 match = compare_rect(&rect2, 0.0f, 100.0f, 40.0f, 50.0f, 0);
3662 ok(match, "Got unexpected rectangle {%.8e, %.8e, %.8e, %.8e}.\n",
3663 rect2.left, rect2.top, rect2.right, rect2.bottom);
3664 ID2D1RectangleGeometry_Release(geometry);
3666 set_rect(&rect, 50.0f, 100.0f, 40.0f, 50.0f);
3667 hr = ID2D1Factory_CreateRectangleGeometry(factory, &rect, &geometry);
3668 ok(SUCCEEDED(hr), "Failed to create geometry, hr %#x.\n", hr);
3669 ID2D1RectangleGeometry_GetRect(geometry, &rect2);
3670 match = compare_rect(&rect2, 50.0f, 100.0f, 40.0f, 50.0f, 0);
3671 ok(match, "Got unexpected rectangle {%.8e, %.8e, %.8e, %.8e}.\n",
3672 rect2.left, rect2.top, rect2.right, rect2.bottom);
3673 ID2D1RectangleGeometry_Release(geometry);
3675 set_rect(&rect, 0.0f, 0.0f, 10.0f, 20.0f);
3676 hr = ID2D1Factory_CreateRectangleGeometry(factory, &rect, &geometry);
3677 ok(SUCCEEDED(hr), "Failed to create geometry, hr %#x.\n", hr);
3679 /* Edge. */
3680 contains = FALSE;
3681 set_point(&point, 0.0f, 0.0f);
3682 hr = ID2D1RectangleGeometry_FillContainsPoint(geometry, point, NULL, 0.0f, &contains);
3683 ok(SUCCEEDED(hr), "FillContainsPoint() failed, hr %#x.\n", hr);
3684 ok(!!contains, "Got wrong hit test result %d.\n", contains);
3686 /* Within tolerance limit around corner. */
3687 contains = TRUE;
3688 set_point(&point, -D2D1_DEFAULT_FLATTENING_TOLERANCE, 0.0f);
3689 hr = ID2D1RectangleGeometry_FillContainsPoint(geometry, point, NULL, 0.0f, &contains);
3690 ok(SUCCEEDED(hr), "FillContainsPoint() failed, hr %#x.\n", hr);
3691 ok(!contains, "Got wrong hit test result %d.\n", contains);
3693 contains = FALSE;
3694 set_point(&point, -D2D1_DEFAULT_FLATTENING_TOLERANCE + 0.01f, 0.0f);
3695 hr = ID2D1RectangleGeometry_FillContainsPoint(geometry, point, NULL, 0.0f, &contains);
3696 ok(SUCCEEDED(hr), "FillContainsPoint() failed, hr %#x.\n", hr);
3697 ok(!!contains, "Got wrong hit test result %d.\n", contains);
3699 contains = TRUE;
3700 set_point(&point, -D2D1_DEFAULT_FLATTENING_TOLERANCE - 0.01f, 0.0f);
3701 hr = ID2D1RectangleGeometry_FillContainsPoint(geometry, point, NULL, 0.0f, &contains);
3702 ok(SUCCEEDED(hr), "FillContainsPoint() failed, hr %#x.\n", hr);
3703 ok(!contains, "Got wrong hit test result %d.\n", contains);
3705 contains = TRUE;
3706 set_point(&point, -D2D1_DEFAULT_FLATTENING_TOLERANCE, -D2D1_DEFAULT_FLATTENING_TOLERANCE);
3707 hr = ID2D1RectangleGeometry_FillContainsPoint(geometry, point, NULL, 0.0f, &contains);
3708 ok(SUCCEEDED(hr), "FillContainsPoint() failed, hr %#x.\n", hr);
3709 ok(!contains, "Got wrong hit test result %d.\n", contains);
3711 /* Inside. */
3712 contains = FALSE;
3713 set_point(&point, 5.0f, 5.0f);
3714 hr = ID2D1RectangleGeometry_FillContainsPoint(geometry, point, NULL, 0.0f, &contains);
3715 ok(SUCCEEDED(hr), "FillContainsPoint() failed, hr %#x.\n", hr);
3716 ok(!!contains, "Got wrong hit test result %d.\n", contains);
3718 /* Test GetBounds() and Simplify(). */
3719 hr = ID2D1RectangleGeometry_GetBounds(geometry, NULL, &rect);
3720 ok(SUCCEEDED(hr), "Failed to get bounds.\n");
3721 match = compare_rect(&rect, 0.0f, 0.0f, 10.0f, 20.0f, 0);
3722 ok(match, "Got unexpected bounds {%.8e, %.8e, %.8e, %.8e}.\n",
3723 rect.left, rect.top, rect.right, rect.bottom);
3724 geometry_sink_init(&sink);
3725 hr = ID2D1RectangleGeometry_Simplify(geometry, D2D1_GEOMETRY_SIMPLIFICATION_OPTION_CUBICS_AND_LINES,
3726 NULL, 0.0f, &sink.ID2D1SimplifiedGeometrySink_iface);
3727 ok(SUCCEEDED(hr), "Failed to simplify geometry, hr %#x.\n", hr);
3728 geometry_sink_check(&sink, D2D1_FILL_MODE_ALTERNATE, 1, &expected_figures[0], 0);
3729 geometry_sink_cleanup(&sink);
3730 geometry_sink_init(&sink);
3731 hr = ID2D1RectangleGeometry_Simplify(geometry, D2D1_GEOMETRY_SIMPLIFICATION_OPTION_LINES,
3732 NULL, 0.0f, &sink.ID2D1SimplifiedGeometrySink_iface);
3733 ok(SUCCEEDED(hr), "Failed to simplify geometry, hr %#x.\n", hr);
3734 geometry_sink_check(&sink, D2D1_FILL_MODE_ALTERNATE, 1, &expected_figures[0], 0);
3735 geometry_sink_cleanup(&sink);
3737 set_matrix_identity(&matrix);
3738 translate_matrix(&matrix, 20.0f, 30.0f);
3739 scale_matrix(&matrix, 3.0f, 2.0f);
3740 rotate_matrix(&matrix, M_PI / -5.0f);
3741 hr = ID2D1RectangleGeometry_GetBounds(geometry, &matrix, &rect);
3742 ok(SUCCEEDED(hr), "Failed to get bounds.\n");
3743 match = compare_rect(&rect, 2.00000000e+01f, 1.82442951e+01f, 7.95376282e+01f, 6.23606796e+01f, 0);
3744 ok(match, "Got unexpected bounds {%.8e, %.8e, %.8e, %.8e}.\n",
3745 rect.left, rect.top, rect.right, rect.bottom);
3746 geometry_sink_init(&sink);
3747 hr = ID2D1RectangleGeometry_Simplify(geometry, D2D1_GEOMETRY_SIMPLIFICATION_OPTION_CUBICS_AND_LINES,
3748 &matrix, 0.0f, &sink.ID2D1SimplifiedGeometrySink_iface);
3749 ok(SUCCEEDED(hr), "Failed to simplify geometry, hr %#x.\n", hr);
3750 geometry_sink_check(&sink, D2D1_FILL_MODE_ALTERNATE, 1, &expected_figures[1], 1);
3751 geometry_sink_cleanup(&sink);
3753 set_matrix_identity(&matrix);
3754 translate_matrix(&matrix, 25.0f, 15.0f);
3755 scale_matrix(&matrix, 0.0f, 2.0f);
3756 hr = ID2D1RectangleGeometry_GetBounds(geometry, &matrix, &rect);
3757 ok(SUCCEEDED(hr), "Failed to get bounds.\n");
3758 match = compare_rect(&rect, 25.0f, 15.0f, 25.0f, 55.0f, 0);
3759 ok(match, "Got unexpected bounds {%.8e, %.8e, %.8e, %.8e}.\n",
3760 rect.left, rect.top, rect.right, rect.bottom);
3761 geometry_sink_init(&sink);
3762 hr = ID2D1RectangleGeometry_Simplify(geometry, D2D1_GEOMETRY_SIMPLIFICATION_OPTION_LINES,
3763 &matrix, 0.0f, &sink.ID2D1SimplifiedGeometrySink_iface);
3764 ok(SUCCEEDED(hr), "Failed to simplify geometry, hr %#x.\n", hr);
3765 geometry_sink_check(&sink, D2D1_FILL_MODE_ALTERNATE, 1, &expected_figures[2], 0);
3766 geometry_sink_cleanup(&sink);
3768 set_matrix_identity(&matrix);
3769 translate_matrix(&matrix, 30.0f, 45.0f);
3770 scale_matrix(&matrix, 0.5f, 0.0f);
3771 hr = ID2D1RectangleGeometry_GetBounds(geometry, &matrix, &rect);
3772 ok(SUCCEEDED(hr), "Failed to get bounds.\n");
3773 match = compare_rect(&rect, 30.0f, 45.0f, 35.0f, 45.0f, 0);
3774 ok(match, "Got unexpected bounds {%.8e, %.8e, %.8e, %.8e}.\n",
3775 rect.left, rect.top, rect.right, rect.bottom);
3776 geometry_sink_init(&sink);
3777 hr = ID2D1RectangleGeometry_Simplify(geometry, D2D1_GEOMETRY_SIMPLIFICATION_OPTION_LINES,
3778 &matrix, 0.0f, &sink.ID2D1SimplifiedGeometrySink_iface);
3779 ok(SUCCEEDED(hr), "Failed to simplify geometry, hr %#x.\n", hr);
3780 geometry_sink_check(&sink, D2D1_FILL_MODE_ALTERNATE, 1, &expected_figures[3], 0);
3781 geometry_sink_cleanup(&sink);
3783 set_matrix_identity(&matrix);
3784 scale_matrix(&matrix, 4.0f, 5.0f);
3785 rotate_matrix(&matrix, M_PI / 3.0f);
3786 translate_matrix(&matrix, 30.0f, 20.0f);
3787 hr = ID2D1Factory_CreateTransformedGeometry(factory, (ID2D1Geometry *)geometry, &matrix, &transformed_geometry);
3788 ok(SUCCEEDED(hr), "Failed to create transformed geometry, hr %#x.\n", hr);
3790 ID2D1TransformedGeometry_GetBounds(transformed_geometry, NULL, &rect);
3791 ok(SUCCEEDED(hr), "Failed to get bounds.\n");
3792 match = compare_rect(&rect, -7.85640717e+01f, 1.79903809e+02f, 1.07179594e+01f, 2.73205078e+02f, 1);
3793 ok(match, "Got unexpected bounds {%.8e, %.8e, %.8e, %.8e}.\n",
3794 rect.left, rect.top, rect.right, rect.bottom);
3795 geometry_sink_init(&sink);
3796 hr = ID2D1TransformedGeometry_Simplify(transformed_geometry, D2D1_GEOMETRY_SIMPLIFICATION_OPTION_CUBICS_AND_LINES,
3797 NULL, 0.0f, &sink.ID2D1SimplifiedGeometrySink_iface);
3798 ok(SUCCEEDED(hr), "Failed to simplify geometry, hr %#x.\n", hr);
3799 geometry_sink_check(&sink, D2D1_FILL_MODE_ALTERNATE, 1, &expected_figures[4], 1);
3800 geometry_sink_cleanup(&sink);
3801 geometry_sink_init(&sink);
3802 hr = ID2D1TransformedGeometry_Simplify(transformed_geometry, D2D1_GEOMETRY_SIMPLIFICATION_OPTION_LINES,
3803 NULL, 0.0f, &sink.ID2D1SimplifiedGeometrySink_iface);
3804 ok(SUCCEEDED(hr), "Failed to simplify geometry, hr %#x.\n", hr);
3805 geometry_sink_check(&sink, D2D1_FILL_MODE_ALTERNATE, 1, &expected_figures[4], 1);
3806 geometry_sink_cleanup(&sink);
3808 set_matrix_identity(&matrix);
3809 rotate_matrix(&matrix, M_PI / -3.0f);
3810 scale_matrix(&matrix, 0.25f, 0.2f);
3811 ID2D1TransformedGeometry_GetBounds(transformed_geometry, &matrix, &rect);
3812 ok(SUCCEEDED(hr), "Failed to get bounds.\n");
3813 match = compare_rect(&rect, 30.0f, 20.0f, 40.0f, 40.0f, 2);
3814 ok(match, "Got unexpected bounds {%.8e, %.8e, %.8e, %.8e}.\n",
3815 rect.left, rect.top, rect.right, rect.bottom);
3816 geometry_sink_init(&sink);
3817 hr = ID2D1TransformedGeometry_Simplify(transformed_geometry, D2D1_GEOMETRY_SIMPLIFICATION_OPTION_LINES,
3818 &matrix, 0.0f, &sink.ID2D1SimplifiedGeometrySink_iface);
3819 ok(SUCCEEDED(hr), "Failed to simplify geometry, hr %#x.\n", hr);
3820 geometry_sink_check(&sink, D2D1_FILL_MODE_ALTERNATE, 1, &expected_figures[5], 4);
3821 geometry_sink_cleanup(&sink);
3823 set_matrix_identity(&matrix);
3824 scale_matrix(&matrix, 2.0f, 0.0f);
3825 ID2D1TransformedGeometry_GetBounds(transformed_geometry, &matrix, &rect);
3826 ok(SUCCEEDED(hr), "Failed to get bounds.\n");
3827 match = compare_rect(&rect, -1.57128143e+02f, 0.00000000e+00f, 2.14359188e+01f, 0.00000000e+00f, 1);
3828 ok(match, "Got unexpected bounds {%.8e, %.8e, %.8e, %.8e}.\n",
3829 rect.left, rect.top, rect.right, rect.bottom);
3830 geometry_sink_init(&sink);
3831 hr = ID2D1TransformedGeometry_Simplify(transformed_geometry, D2D1_GEOMETRY_SIMPLIFICATION_OPTION_CUBICS_AND_LINES,
3832 &matrix, 0.0f, &sink.ID2D1SimplifiedGeometrySink_iface);
3833 ok(SUCCEEDED(hr), "Failed to simplify geometry, hr %#x.\n", hr);
3834 geometry_sink_check(&sink, D2D1_FILL_MODE_ALTERNATE, 1, &expected_figures[6], 1);
3835 geometry_sink_cleanup(&sink);
3837 set_matrix_identity(&matrix);
3838 scale_matrix(&matrix, 0.0f, 0.5f);
3839 ID2D1TransformedGeometry_GetBounds(transformed_geometry, &matrix, &rect);
3840 ok(SUCCEEDED(hr), "Failed to get bounds.\n");
3841 match = compare_rect(&rect, 0.00000000e+00f, 8.99519043e+01f, 0.00000000e+00, 1.36602539e+02f, 1);
3842 ok(match, "Got unexpected bounds {%.8e, %.8e, %.8e, %.8e}.\n",
3843 rect.left, rect.top, rect.right, rect.bottom);
3844 geometry_sink_init(&sink);
3845 hr = ID2D1TransformedGeometry_Simplify(transformed_geometry, D2D1_GEOMETRY_SIMPLIFICATION_OPTION_CUBICS_AND_LINES,
3846 &matrix, 0.0f, &sink.ID2D1SimplifiedGeometrySink_iface);
3847 ok(SUCCEEDED(hr), "Failed to simplify geometry, hr %#x.\n", hr);
3848 geometry_sink_check(&sink, D2D1_FILL_MODE_ALTERNATE, 1, &expected_figures[7], 1);
3849 geometry_sink_cleanup(&sink);
3851 ID2D1TransformedGeometry_Release(transformed_geometry);
3852 ID2D1RectangleGeometry_Release(geometry);
3853 ID2D1Factory_Release(factory);
3856 static void test_rounded_rectangle_geometry(void)
3858 ID2D1RoundedRectangleGeometry *geometry;
3859 D2D1_ROUNDED_RECT rect, rect2;
3860 ID2D1Factory *factory;
3861 HRESULT hr;
3863 hr = D2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED, &IID_ID2D1Factory, NULL, (void **)&factory);
3864 ok(SUCCEEDED(hr), "Failed to create factory, hr %#x.\n", hr);
3866 set_rounded_rect(&rect, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f);
3867 hr = ID2D1Factory_CreateRoundedRectangleGeometry(factory, &rect, &geometry);
3868 ok(SUCCEEDED(hr), "Failed to create geometry, hr %#x.\n", hr);
3870 ID2D1RoundedRectangleGeometry_GetRoundedRect(geometry, &rect2);
3871 ok(!memcmp(&rect, &rect2, sizeof(rect)), "Got unexpected rectangle {%.8e, %.8e, %.8e, %.8e, %.8e, %.8e}.\n",
3872 rect2.rect.left, rect2.rect.top, rect2.rect.right, rect2.rect.bottom, rect2.radiusX, rect2.radiusY);
3873 ID2D1RoundedRectangleGeometry_Release(geometry);
3875 /* X radius larger than half width. */
3876 set_rounded_rect(&rect, 0.0f, 0.0f, 50.0f, 40.0f, 30.0f, 5.0f);
3877 hr = ID2D1Factory_CreateRoundedRectangleGeometry(factory, &rect, &geometry);
3878 ID2D1RoundedRectangleGeometry_GetRoundedRect(geometry, &rect2);
3879 ok(!memcmp(&rect, &rect2, sizeof(rect)), "Got unexpected rectangle {%.8e, %.8e, %.8e, %.8e, %.8e, %.8e}.\n",
3880 rect2.rect.left, rect2.rect.top, rect2.rect.right, rect2.rect.bottom, rect2.radiusX, rect2.radiusY);
3881 ID2D1RoundedRectangleGeometry_Release(geometry);
3883 /* Y radius larger than half height. */
3884 set_rounded_rect(&rect, 0.0f, 0.0f, 50.0f, 40.0f, 5.0f, 30.0f);
3885 hr = ID2D1Factory_CreateRoundedRectangleGeometry(factory, &rect, &geometry);
3886 ID2D1RoundedRectangleGeometry_GetRoundedRect(geometry, &rect2);
3887 ok(!memcmp(&rect, &rect2, sizeof(rect)), "Got unexpected rectangle {%.8e, %.8e, %.8e, %.8e, %.8e, %.8e}.\n",
3888 rect2.rect.left, rect2.rect.top, rect2.rect.right, rect2.rect.bottom, rect2.radiusX, rect2.radiusY);
3889 ID2D1RoundedRectangleGeometry_Release(geometry);
3891 /* Both exceed rectangle size. */
3892 set_rounded_rect(&rect, 0.0f, 0.0f, 50.0f, 40.0f, 30.0f, 25.0f);
3893 hr = ID2D1Factory_CreateRoundedRectangleGeometry(factory, &rect, &geometry);
3894 ID2D1RoundedRectangleGeometry_GetRoundedRect(geometry, &rect2);
3895 ok(!memcmp(&rect, &rect2, sizeof(rect)), "Got unexpected rectangle {%.8e, %.8e, %.8e, %.8e, %.8e, %.8e}.\n",
3896 rect2.rect.left, rect2.rect.top, rect2.rect.right, rect2.rect.bottom, rect2.radiusX, rect2.radiusY);
3897 ID2D1RoundedRectangleGeometry_Release(geometry);
3899 ID2D1Factory_Release(factory);
3902 static void test_bitmap_formats(void)
3904 D2D1_BITMAP_PROPERTIES bitmap_desc;
3905 IDXGISwapChain *swapchain;
3906 D2D1_SIZE_U size = {4, 4};
3907 ID2D1RenderTarget *rt;
3908 ID3D10Device1 *device;
3909 IDXGISurface *surface;
3910 ID2D1Bitmap *bitmap;
3911 unsigned int i, j;
3912 HWND window;
3913 HRESULT hr;
3915 static const struct
3917 DXGI_FORMAT format;
3918 DWORD mask;
3920 bitmap_formats[] =
3922 {DXGI_FORMAT_R32G32B32A32_FLOAT, 0x8a},
3923 {DXGI_FORMAT_R16G16B16A16_FLOAT, 0x8a},
3924 {DXGI_FORMAT_R16G16B16A16_UNORM, 0x8a},
3925 {DXGI_FORMAT_R8G8B8A8_TYPELESS, 0x00},
3926 {DXGI_FORMAT_R8G8B8A8_UNORM, 0x0a},
3927 {DXGI_FORMAT_R8G8B8A8_UNORM_SRGB, 0x8a},
3928 {DXGI_FORMAT_R8G8B8A8_UINT, 0x00},
3929 {DXGI_FORMAT_R8G8B8A8_SNORM, 0x00},
3930 {DXGI_FORMAT_R8G8B8A8_SINT, 0x00},
3931 {DXGI_FORMAT_A8_UNORM, 0x06},
3932 {DXGI_FORMAT_B8G8R8A8_UNORM, 0x0a},
3933 {DXGI_FORMAT_B8G8R8X8_UNORM, 0x88},
3934 {DXGI_FORMAT_B8G8R8A8_TYPELESS, 0x00},
3935 {DXGI_FORMAT_B8G8R8A8_UNORM_SRGB, 0x8a},
3938 if (!(device = create_device()))
3940 skip("Failed to create device, skipping tests.\n");
3941 return;
3943 window = create_window();
3944 swapchain = create_swapchain(device, window, TRUE);
3945 hr = IDXGISwapChain_GetBuffer(swapchain, 0, &IID_IDXGISurface, (void **)&surface);
3946 ok(SUCCEEDED(hr), "Failed to get buffer, hr %#x.\n", hr);
3947 rt = create_render_target(surface);
3948 ok(!!rt, "Failed to create render target.\n");
3950 bitmap_desc.dpiX = 96.0f;
3951 bitmap_desc.dpiY = 96.0f;
3952 for (i = 0; i < ARRAY_SIZE(bitmap_formats); ++i)
3954 for (j = 0; j < 4; ++j)
3956 if ((bitmap_formats[i].mask & (0x80 | (1u << j))) == (0x80 | (1u << j)))
3957 continue;
3959 bitmap_desc.pixelFormat.format = bitmap_formats[i].format;
3960 bitmap_desc.pixelFormat.alphaMode = j;
3961 hr = ID2D1RenderTarget_CreateBitmap(rt, size, NULL, 0, &bitmap_desc, &bitmap);
3962 if (bitmap_formats[i].mask & (1u << j))
3963 ok(hr == S_OK, "Got unexpected hr %#x, for format %#x/%#x.\n",
3964 hr, bitmap_formats[i].format, j);
3965 else
3966 ok(hr == D2DERR_UNSUPPORTED_PIXEL_FORMAT, "Got unexpected hr %#x, for format %#x/%#x.\n",
3967 hr, bitmap_formats[i].format, j);
3968 if (SUCCEEDED(hr))
3969 ID2D1Bitmap_Release(bitmap);
3973 ID2D1RenderTarget_Release(rt);
3974 IDXGISurface_Release(surface);
3975 IDXGISwapChain_Release(swapchain);
3976 ID3D10Device1_Release(device);
3977 DestroyWindow(window);
3980 static void test_alpha_mode(void)
3982 D2D1_RENDER_TARGET_PROPERTIES rt_desc;
3983 D2D1_BITMAP_PROPERTIES bitmap_desc;
3984 ID2D1SolidColorBrush *color_brush;
3985 ID2D1BitmapBrush *bitmap_brush;
3986 IDXGISwapChain *swapchain;
3987 ID2D1RenderTarget *rt;
3988 ID3D10Device1 *device;
3989 IDXGISurface *surface;
3990 ID2D1Bitmap *bitmap;
3991 D2D1_COLOR_F color;
3992 D2D1_RECT_F rect;
3993 D2D1_SIZE_U size;
3994 ULONG refcount;
3995 HWND window;
3996 HRESULT hr;
3997 BOOL match;
3999 static const DWORD bitmap_data[] =
4001 0x7f7f0000, 0x7f7f7f00, 0x7f007f00, 0x7f007f7f,
4002 0x7f00007f, 0x7f7f007f, 0x7f000000, 0x7f404040,
4003 0x7f7f7f7f, 0x7f7f7f7f, 0x7f7f7f7f, 0x7f000000,
4004 0x7f7f7f7f, 0x7f000000, 0x7f000000, 0x7f000000,
4007 if (!(device = create_device()))
4009 skip("Failed to create device, skipping tests.\n");
4010 return;
4012 window = create_window();
4013 swapchain = create_swapchain(device, window, TRUE);
4014 hr = IDXGISwapChain_GetBuffer(swapchain, 0, &IID_IDXGISurface, (void **)&surface);
4015 ok(SUCCEEDED(hr), "Failed to get buffer, hr %#x.\n", hr);
4016 rt = create_render_target(surface);
4017 ok(!!rt, "Failed to create render target.\n");
4019 ID2D1RenderTarget_SetAntialiasMode(rt, D2D1_ANTIALIAS_MODE_ALIASED);
4021 set_size_u(&size, 4, 4);
4022 bitmap_desc.pixelFormat.format = DXGI_FORMAT_B8G8R8A8_UNORM;
4023 bitmap_desc.pixelFormat.alphaMode = D2D1_ALPHA_MODE_IGNORE;
4024 bitmap_desc.dpiX = 96.0f / 40.0f;
4025 bitmap_desc.dpiY = 96.0f / 30.0f;
4026 hr = ID2D1RenderTarget_CreateBitmap(rt, size, bitmap_data, 4 * sizeof(*bitmap_data), &bitmap_desc, &bitmap);
4027 ok(SUCCEEDED(hr), "Failed to create bitmap, hr %#x.\n", hr);
4029 hr = ID2D1RenderTarget_CreateBitmapBrush(rt, bitmap, NULL, NULL, &bitmap_brush);
4030 ok(SUCCEEDED(hr), "Failed to create brush, hr %#x.\n", hr);
4031 ID2D1BitmapBrush_SetInterpolationMode(bitmap_brush, D2D1_BITMAP_INTERPOLATION_MODE_NEAREST_NEIGHBOR);
4032 ID2D1BitmapBrush_SetExtendModeX(bitmap_brush, D2D1_EXTEND_MODE_WRAP);
4033 ID2D1BitmapBrush_SetExtendModeY(bitmap_brush, D2D1_EXTEND_MODE_WRAP);
4035 set_color(&color, 0.0f, 1.0f, 0.0f, 0.75f);
4036 hr = ID2D1RenderTarget_CreateSolidColorBrush(rt, &color, NULL, &color_brush);
4037 ok(SUCCEEDED(hr), "Failed to create brush, hr %#x.\n", hr);
4039 ID2D1RenderTarget_BeginDraw(rt);
4040 ID2D1RenderTarget_Clear(rt, NULL);
4041 hr = ID2D1RenderTarget_EndDraw(rt, NULL, NULL);
4042 ok(SUCCEEDED(hr), "Failed to end draw, hr %#x.\n", hr);
4043 match = compare_surface(surface, "48c41aff3a130a17ee210866b2ab7d36763934d5");
4044 ok(match, "Surface does not match.\n");
4046 ID2D1RenderTarget_BeginDraw(rt);
4047 set_color(&color, 1.0f, 0.0f, 0.0f, 0.25f);
4048 ID2D1RenderTarget_Clear(rt, &color);
4049 hr = ID2D1RenderTarget_EndDraw(rt, NULL, NULL);
4050 ok(SUCCEEDED(hr), "Failed to end draw, hr %#x.\n", hr);
4051 match = compare_surface(surface, "6487e683730fb5a77c1911388d00b04664c5c4e4");
4052 ok(match, "Surface does not match.\n");
4054 ID2D1RenderTarget_BeginDraw(rt);
4055 set_color(&color, 0.0f, 0.0f, 1.0f, 0.75f);
4056 ID2D1RenderTarget_Clear(rt, &color);
4057 hr = ID2D1RenderTarget_EndDraw(rt, NULL, NULL);
4058 ok(SUCCEEDED(hr), "Failed to end draw, hr %#x.\n", hr);
4059 match = compare_surface(surface, "7a35ba09e43cbaf591388ff1ef8de56157630c98");
4060 ok(match, "Surface does not match.\n");
4062 ID2D1RenderTarget_BeginDraw(rt);
4064 set_rect(&rect, 0.0f, 0.0f, 160.0f, 120.0f);
4065 ID2D1RenderTarget_FillRectangle(rt, &rect, (ID2D1Brush *)bitmap_brush);
4066 set_rect(&rect, 160.0f, 0.0f, 320.0f, 120.0f);
4067 ID2D1BitmapBrush_SetOpacity(bitmap_brush, 0.75f);
4068 ID2D1RenderTarget_FillRectangle(rt, &rect, (ID2D1Brush *)bitmap_brush);
4069 set_rect(&rect, 320.0f, 0.0f, 480.0f, 120.0f);
4070 ID2D1BitmapBrush_SetOpacity(bitmap_brush, 0.25f);
4071 ID2D1RenderTarget_FillRectangle(rt, &rect, (ID2D1Brush *)bitmap_brush);
4073 ID2D1Bitmap_Release(bitmap);
4074 bitmap_desc.pixelFormat.alphaMode = D2D1_ALPHA_MODE_PREMULTIPLIED;
4075 hr = ID2D1RenderTarget_CreateBitmap(rt, size, bitmap_data, 4 * sizeof(*bitmap_data), &bitmap_desc, &bitmap);
4076 ok(SUCCEEDED(hr), "Failed to create bitmap, hr %#x.\n", hr);
4077 ID2D1BitmapBrush_SetBitmap(bitmap_brush, bitmap);
4079 set_rect(&rect, 0.0f, 120.0f, 160.0f, 240.0f);
4080 ID2D1BitmapBrush_SetOpacity(bitmap_brush, 1.0f);
4081 ID2D1RenderTarget_FillRectangle(rt, &rect, (ID2D1Brush *)bitmap_brush);
4082 set_rect(&rect, 160.0f, 120.0f, 320.0f, 240.0f);
4083 ID2D1BitmapBrush_SetOpacity(bitmap_brush, 0.75f);
4084 ID2D1RenderTarget_FillRectangle(rt, &rect, (ID2D1Brush *)bitmap_brush);
4085 set_rect(&rect, 320.0f, 120.0f, 480.0f, 240.0f);
4086 ID2D1BitmapBrush_SetOpacity(bitmap_brush, 0.25f);
4087 ID2D1RenderTarget_FillRectangle(rt, &rect, (ID2D1Brush *)bitmap_brush);
4089 set_rect(&rect, 0.0f, 240.0f, 160.0f, 360.0f);
4090 ID2D1RenderTarget_FillRectangle(rt, &rect, (ID2D1Brush *)color_brush);
4091 set_rect(&rect, 160.0f, 240.0f, 320.0f, 360.0f);
4092 ID2D1SolidColorBrush_SetOpacity(color_brush, 0.75f);
4093 ID2D1RenderTarget_FillRectangle(rt, &rect, (ID2D1Brush *)color_brush);
4094 set_rect(&rect, 320.0f, 240.0f, 480.0f, 360.0f);
4095 ID2D1SolidColorBrush_SetOpacity(color_brush, 0.25f);
4096 ID2D1RenderTarget_FillRectangle(rt, &rect, (ID2D1Brush *)color_brush);
4098 hr = ID2D1RenderTarget_EndDraw(rt, NULL, NULL);
4099 ok(SUCCEEDED(hr), "Failed to end draw, hr %#x.\n", hr);
4100 match = compare_surface(surface, "14f8ac64b70966c7c3c6281c59aaecdb17c3b16a");
4101 ok(match, "Surface does not match.\n");
4103 ID2D1RenderTarget_Release(rt);
4104 rt_desc.type = D2D1_RENDER_TARGET_TYPE_DEFAULT;
4105 rt_desc.pixelFormat.format = DXGI_FORMAT_UNKNOWN;
4106 rt_desc.pixelFormat.alphaMode = D2D1_ALPHA_MODE_IGNORE;
4107 rt_desc.dpiX = 0.0f;
4108 rt_desc.dpiY = 0.0f;
4109 rt_desc.usage = D2D1_RENDER_TARGET_USAGE_NONE;
4110 rt_desc.minLevel = D2D1_FEATURE_LEVEL_DEFAULT;
4111 rt = create_render_target_desc(surface, &rt_desc);
4112 ok(!!rt, "Failed to create render target.\n");
4114 ID2D1RenderTarget_SetAntialiasMode(rt, D2D1_ANTIALIAS_MODE_ALIASED);
4116 ID2D1Bitmap_Release(bitmap);
4117 bitmap_desc.pixelFormat.alphaMode = D2D1_ALPHA_MODE_IGNORE;
4118 hr = ID2D1RenderTarget_CreateBitmap(rt, size, bitmap_data, 4 * sizeof(*bitmap_data), &bitmap_desc, &bitmap);
4119 ok(SUCCEEDED(hr), "Failed to create bitmap, hr %#x.\n", hr);
4120 ID2D1BitmapBrush_SetBitmap(bitmap_brush, bitmap);
4122 ID2D1BitmapBrush_Release(bitmap_brush);
4123 hr = ID2D1RenderTarget_CreateBitmapBrush(rt, bitmap, NULL, NULL, &bitmap_brush);
4124 ok(SUCCEEDED(hr), "Failed to create brush, hr %#x.\n", hr);
4125 ID2D1BitmapBrush_SetInterpolationMode(bitmap_brush, D2D1_BITMAP_INTERPOLATION_MODE_NEAREST_NEIGHBOR);
4126 ID2D1BitmapBrush_SetExtendModeX(bitmap_brush, D2D1_EXTEND_MODE_WRAP);
4127 ID2D1BitmapBrush_SetExtendModeY(bitmap_brush, D2D1_EXTEND_MODE_WRAP);
4129 ID2D1SolidColorBrush_Release(color_brush);
4130 set_color(&color, 0.0f, 1.0f, 0.0f, 0.75f);
4131 hr = ID2D1RenderTarget_CreateSolidColorBrush(rt, &color, NULL, &color_brush);
4132 ok(SUCCEEDED(hr), "Failed to create brush, hr %#x.\n", hr);
4134 ID2D1RenderTarget_BeginDraw(rt);
4135 ID2D1RenderTarget_Clear(rt, NULL);
4136 hr = ID2D1RenderTarget_EndDraw(rt, NULL, NULL);
4137 ok(SUCCEEDED(hr), "Failed to end draw, hr %#x.\n", hr);
4138 match = compare_surface(surface, "b44510bf2d2e61a8d7c0ad862de49a471f1fd13f");
4139 ok(match, "Surface does not match.\n");
4141 ID2D1RenderTarget_BeginDraw(rt);
4142 set_color(&color, 1.0f, 0.0f, 0.0f, 0.25f);
4143 ID2D1RenderTarget_Clear(rt, &color);
4144 hr = ID2D1RenderTarget_EndDraw(rt, NULL, NULL);
4145 ok(SUCCEEDED(hr), "Failed to end draw, hr %#x.\n", hr);
4146 match = compare_surface(surface, "2184f4a9198fc1de09ac85301b7a03eebadd9b81");
4147 ok(match, "Surface does not match.\n");
4149 ID2D1RenderTarget_BeginDraw(rt);
4150 set_color(&color, 0.0f, 0.0f, 1.0f, 0.75f);
4151 ID2D1RenderTarget_Clear(rt, &color);
4152 hr = ID2D1RenderTarget_EndDraw(rt, NULL, NULL);
4153 ok(SUCCEEDED(hr), "Failed to end draw, hr %#x.\n", hr);
4154 match = compare_surface(surface, "6527ec83b4039c895b50f9b3e144fe0cf90d1889");
4155 ok(match, "Surface does not match.\n");
4157 ID2D1RenderTarget_BeginDraw(rt);
4159 set_rect(&rect, 0.0f, 0.0f, 160.0f, 120.0f);
4160 ID2D1RenderTarget_FillRectangle(rt, &rect, (ID2D1Brush *)bitmap_brush);
4161 set_rect(&rect, 160.0f, 0.0f, 320.0f, 120.0f);
4162 ID2D1BitmapBrush_SetOpacity(bitmap_brush, 0.75f);
4163 ID2D1RenderTarget_FillRectangle(rt, &rect, (ID2D1Brush *)bitmap_brush);
4164 set_rect(&rect, 320.0f, 0.0f, 480.0f, 120.0f);
4165 ID2D1BitmapBrush_SetOpacity(bitmap_brush, 0.25f);
4166 ID2D1RenderTarget_FillRectangle(rt, &rect, (ID2D1Brush *)bitmap_brush);
4168 ID2D1Bitmap_Release(bitmap);
4169 bitmap_desc.pixelFormat.alphaMode = D2D1_ALPHA_MODE_PREMULTIPLIED;
4170 hr = ID2D1RenderTarget_CreateBitmap(rt, size, bitmap_data, 4 * sizeof(*bitmap_data), &bitmap_desc, &bitmap);
4171 ok(SUCCEEDED(hr), "Failed to create bitmap, hr %#x.\n", hr);
4172 ID2D1BitmapBrush_SetBitmap(bitmap_brush, bitmap);
4174 set_rect(&rect, 0.0f, 120.0f, 160.0f, 240.0f);
4175 ID2D1BitmapBrush_SetOpacity(bitmap_brush, 1.0f);
4176 ID2D1RenderTarget_FillRectangle(rt, &rect, (ID2D1Brush *)bitmap_brush);
4177 set_rect(&rect, 160.0f, 120.0f, 320.0f, 240.0f);
4178 ID2D1BitmapBrush_SetOpacity(bitmap_brush, 0.75f);
4179 ID2D1RenderTarget_FillRectangle(rt, &rect, (ID2D1Brush *)bitmap_brush);
4180 set_rect(&rect, 320.0f, 120.0f, 480.0f, 240.0f);
4181 ID2D1BitmapBrush_SetOpacity(bitmap_brush, 0.25f);
4182 ID2D1RenderTarget_FillRectangle(rt, &rect, (ID2D1Brush *)bitmap_brush);
4184 set_rect(&rect, 0.0f, 240.0f, 160.0f, 360.0f);
4185 ID2D1RenderTarget_FillRectangle(rt, &rect, (ID2D1Brush *)color_brush);
4186 set_rect(&rect, 160.0f, 240.0f, 320.0f, 360.0f);
4187 ID2D1SolidColorBrush_SetOpacity(color_brush, 0.75f);
4188 ID2D1RenderTarget_FillRectangle(rt, &rect, (ID2D1Brush *)color_brush);
4189 set_rect(&rect, 320.0f, 240.0f, 480.0f, 360.0f);
4190 ID2D1SolidColorBrush_SetOpacity(color_brush, 0.25f);
4191 ID2D1RenderTarget_FillRectangle(rt, &rect, (ID2D1Brush *)color_brush);
4193 hr = ID2D1RenderTarget_EndDraw(rt, NULL, NULL);
4194 ok(SUCCEEDED(hr), "Failed to end draw, hr %#x.\n", hr);
4195 match = compare_surface(surface, "465f5a3190d7bde408b3206b4be939fb22f8a3d6");
4196 ok(match, "Surface does not match.\n");
4198 refcount = ID2D1Bitmap_Release(bitmap);
4199 ok(refcount == 1, "Bitmap has %u references left.\n", refcount);
4200 ID2D1SolidColorBrush_Release(color_brush);
4201 ID2D1BitmapBrush_Release(bitmap_brush);
4202 ID2D1RenderTarget_Release(rt);
4203 IDXGISurface_Release(surface);
4204 IDXGISwapChain_Release(swapchain);
4205 ID3D10Device1_Release(device);
4206 DestroyWindow(window);
4209 static void test_shared_bitmap(void)
4211 IDXGISwapChain *swapchain1, *swapchain2;
4212 IWICBitmap *wic_bitmap1, *wic_bitmap2;
4213 ID2D1GdiInteropRenderTarget *interop;
4214 D2D1_RENDER_TARGET_PROPERTIES desc;
4215 D2D1_BITMAP_PROPERTIES bitmap_desc;
4216 ID2D1RenderTarget *rt1, *rt2, *rt3;
4217 IDXGISurface *surface1, *surface2;
4218 ID2D1Factory *factory1, *factory2;
4219 ID3D10Device1 *device1, *device2;
4220 IWICImagingFactory *wic_factory;
4221 ID2D1Bitmap *bitmap1, *bitmap2;
4222 DXGI_SURFACE_DESC surface_desc;
4223 D2D1_PIXEL_FORMAT pixel_format;
4224 D2D1_SIZE_U size = {4, 4};
4225 IDXGISurface1 *surface3;
4226 HWND window1, window2;
4227 HRESULT hr;
4229 if (!(device1 = create_device()))
4231 skip("Failed to create device, skipping tests.\n");
4232 return;
4235 window1 = create_window();
4236 window2 = create_window();
4237 swapchain1 = create_swapchain(device1, window1, TRUE);
4238 swapchain2 = create_swapchain(device1, window2, TRUE);
4239 hr = IDXGISwapChain_GetBuffer(swapchain1, 0, &IID_IDXGISurface, (void **)&surface1);
4240 ok(SUCCEEDED(hr), "Failed to get buffer, hr %#x.\n", hr);
4241 hr = IDXGISwapChain_GetBuffer(swapchain2, 0, &IID_IDXGISurface, (void **)&surface2);
4242 ok(SUCCEEDED(hr), "Failed to get buffer, hr %#x.\n", hr);
4244 CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
4245 hr = CoCreateInstance(&CLSID_WICImagingFactory, NULL, CLSCTX_INPROC_SERVER,
4246 &IID_IWICImagingFactory, (void **)&wic_factory);
4247 ok(SUCCEEDED(hr), "Failed to create WIC imaging factory, hr %#x.\n", hr);
4248 hr = IWICImagingFactory_CreateBitmap(wic_factory, 640, 480,
4249 &GUID_WICPixelFormat32bppPBGRA, WICBitmapCacheOnDemand, &wic_bitmap1);
4250 ok(SUCCEEDED(hr), "Failed to create bitmap, hr %#x.\n", hr);
4251 hr = IWICImagingFactory_CreateBitmap(wic_factory, 640, 480,
4252 &GUID_WICPixelFormat32bppPBGRA, WICBitmapCacheOnDemand, &wic_bitmap2);
4253 ok(SUCCEEDED(hr), "Failed to create bitmap, hr %#x.\n", hr);
4254 IWICImagingFactory_Release(wic_factory);
4256 desc.type = D2D1_RENDER_TARGET_TYPE_DEFAULT;
4257 desc.pixelFormat.format = DXGI_FORMAT_UNKNOWN;
4258 desc.pixelFormat.alphaMode = D2D1_ALPHA_MODE_PREMULTIPLIED;
4259 desc.dpiX = 0.0f;
4260 desc.dpiY = 0.0f;
4261 desc.usage = D2D1_RENDER_TARGET_USAGE_NONE;
4262 desc.minLevel = D2D1_FEATURE_LEVEL_DEFAULT;
4264 bitmap_desc.pixelFormat.format = DXGI_FORMAT_B8G8R8A8_UNORM;
4265 bitmap_desc.pixelFormat.alphaMode = D2D1_ALPHA_MODE_PREMULTIPLIED;
4266 bitmap_desc.dpiX = 96.0f;
4267 bitmap_desc.dpiY = 96.0f;
4269 hr = D2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED, &IID_ID2D1Factory, NULL, (void **)&factory1);
4270 ok(SUCCEEDED(hr), "Failed to create factory, hr %#x.\n", hr);
4271 hr = D2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED, &IID_ID2D1Factory, NULL, (void **)&factory2);
4272 ok(SUCCEEDED(hr), "Failed to create factory, hr %#x.\n", hr);
4274 /* DXGI surface render targets with the same device and factory. */
4275 hr = ID2D1Factory_CreateDxgiSurfaceRenderTarget(factory1, surface1, &desc, &rt1);
4276 ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr);
4277 hr = ID2D1RenderTarget_CreateBitmap(rt1, size, NULL, 0, &bitmap_desc, &bitmap1);
4278 check_bitmap_surface(bitmap1, TRUE, 0);
4279 ok(SUCCEEDED(hr), "Failed to create bitmap, hr %#x.\n", hr);
4281 hr = ID2D1Factory_CreateDxgiSurfaceRenderTarget(factory1, surface2, &desc, &rt2);
4282 ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr);
4283 hr = ID2D1RenderTarget_CreateSharedBitmap(rt2, &IID_ID2D1Bitmap, bitmap1, NULL, &bitmap2);
4284 ok(SUCCEEDED(hr), "Failed to create bitmap, hr %#x.\n", hr);
4285 check_bitmap_surface(bitmap2, TRUE, 0);
4286 ID2D1Bitmap_Release(bitmap2);
4287 hr = ID2D1RenderTarget_CreateSharedBitmap(rt2, &IID_IUnknown, bitmap1, NULL, &bitmap2);
4288 ok(hr == E_INVALIDARG, "Got unexpected hr %#x.\n", hr);
4289 ID2D1RenderTarget_Release(rt2);
4291 /* DXGI surface render targets with the same device but different factories. */
4292 hr = ID2D1Factory_CreateDxgiSurfaceRenderTarget(factory2, surface2, &desc, &rt2);
4293 ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr);
4294 hr = ID2D1RenderTarget_CreateSharedBitmap(rt2, &IID_ID2D1Bitmap, bitmap1, NULL, &bitmap2);
4295 ok(hr == D2DERR_WRONG_FACTORY, "Got unexpected hr %#x.\n", hr);
4296 ID2D1RenderTarget_Release(rt2);
4298 /* DXGI surface render targets with different devices but the same factory. */
4299 IDXGISurface_Release(surface2);
4300 IDXGISwapChain_Release(swapchain2);
4301 device2 = create_device();
4302 ok(!!device2, "Failed to create device.\n");
4303 swapchain2 = create_swapchain(device2, window2, TRUE);
4304 hr = IDXGISwapChain_GetBuffer(swapchain2, 0, &IID_IDXGISurface, (void **)&surface2);
4305 ok(SUCCEEDED(hr), "Failed to get buffer, hr %#x.\n", hr);
4307 hr = ID2D1Factory_CreateDxgiSurfaceRenderTarget(factory1, surface2, &desc, &rt2);
4308 ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr);
4309 hr = ID2D1RenderTarget_CreateSharedBitmap(rt2, &IID_ID2D1Bitmap, bitmap1, NULL, &bitmap2);
4310 ok(hr == D2DERR_UNSUPPORTED_OPERATION, "Got unexpected hr %#x.\n", hr);
4311 ID2D1RenderTarget_Release(rt2);
4313 /* DXGI surface render targets with different devices and different factories. */
4314 hr = ID2D1Factory_CreateDxgiSurfaceRenderTarget(factory2, surface2, &desc, &rt2);
4315 ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr);
4316 hr = ID2D1RenderTarget_CreateSharedBitmap(rt2, &IID_ID2D1Bitmap, bitmap1, NULL, &bitmap2);
4317 ok(hr == D2DERR_WRONG_FACTORY, "Got unexpected hr %#x.\n", hr);
4318 ID2D1RenderTarget_Release(rt2);
4320 /* DXGI surface render target and WIC bitmap render target, same factory. */
4321 hr = ID2D1Factory_CreateWicBitmapRenderTarget(factory1, wic_bitmap2, &desc, &rt2);
4322 ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr);
4323 hr = ID2D1RenderTarget_CreateSharedBitmap(rt2, &IID_ID2D1Bitmap, bitmap1, NULL, &bitmap2);
4324 ok(hr == D2DERR_UNSUPPORTED_OPERATION, "Got unexpected hr %#x.\n", hr);
4325 ID2D1RenderTarget_Release(rt2);
4327 /* WIC bitmap render targets on different D2D factories. */
4328 ID2D1Bitmap_Release(bitmap1);
4329 ID2D1RenderTarget_Release(rt1);
4330 hr = ID2D1Factory_CreateWicBitmapRenderTarget(factory1, wic_bitmap1, &desc, &rt1);
4331 ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr);
4332 hr = ID2D1RenderTarget_CreateBitmap(rt1, size, NULL, 0, &bitmap_desc, &bitmap1);
4333 ok(SUCCEEDED(hr), "Failed to create bitmap, hr %#x.\n", hr);
4335 hr = ID2D1RenderTarget_QueryInterface(rt1, &IID_ID2D1GdiInteropRenderTarget, (void **)&interop);
4336 ok(SUCCEEDED(hr), "Failed to get interop target, hr %#x.\n", hr);
4337 hr = ID2D1GdiInteropRenderTarget_QueryInterface(interop, &IID_ID2D1RenderTarget, (void **)&rt3);
4338 ok(SUCCEEDED(hr), "Failed to get render target back, %#x.\n", hr);
4339 ok(rt3 == rt1, "Unexpected render target\n");
4340 ID2D1RenderTarget_Release(rt3);
4341 ID2D1GdiInteropRenderTarget_Release(interop);
4343 hr = ID2D1Factory_CreateWicBitmapRenderTarget(factory2, wic_bitmap2, &desc, &rt2);
4344 ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr);
4345 hr = ID2D1RenderTarget_CreateSharedBitmap(rt2, &IID_ID2D1Bitmap, bitmap1, NULL, &bitmap2);
4346 ok(hr == D2DERR_WRONG_FACTORY, "Got unexpected hr %#x.\n", hr);
4347 ID2D1RenderTarget_Release(rt2);
4349 /* WIC bitmap render targets on the same D2D factory. */
4350 hr = ID2D1Factory_CreateWicBitmapRenderTarget(factory1, wic_bitmap2, &desc, &rt2);
4351 ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr);
4352 hr = ID2D1RenderTarget_CreateSharedBitmap(rt2, &IID_ID2D1Bitmap, bitmap1, NULL, &bitmap2);
4353 ok(SUCCEEDED(hr), "Failed to create bitmap, hr %#x.\n", hr);
4354 check_bitmap_surface(bitmap2, FALSE, 0);
4355 ID2D1Bitmap_Release(bitmap2);
4356 ID2D1RenderTarget_Release(rt2);
4358 /* Shared DXGI surface. */
4359 desc.type = D2D1_RENDER_TARGET_TYPE_DEFAULT;
4360 desc.pixelFormat.format = DXGI_FORMAT_B8G8R8A8_UNORM;
4361 desc.pixelFormat.alphaMode = D2D1_ALPHA_MODE_PREMULTIPLIED;
4362 desc.dpiX = 0.0f;
4363 desc.dpiY = 0.0f;
4364 desc.usage = D2D1_RENDER_TARGET_USAGE_NONE;
4365 desc.minLevel = D2D1_FEATURE_LEVEL_DEFAULT;
4367 hr = ID2D1Factory_CreateDxgiSurfaceRenderTarget(factory1, surface2, &desc, &rt2);
4368 ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr);
4370 bitmap_desc.pixelFormat.format = DXGI_FORMAT_B8G8R8A8_UNORM;
4371 bitmap_desc.pixelFormat.alphaMode = D2D1_ALPHA_MODE_PREMULTIPLIED;
4372 bitmap_desc.dpiX = 0.0f;
4373 bitmap_desc.dpiY = 0.0f;
4375 hr = ID2D1RenderTarget_CreateSharedBitmap(rt2, &IID_IDXGISurface, surface2, &bitmap_desc, &bitmap2);
4376 ok(SUCCEEDED(hr) || broken(hr == E_INVALIDARG) /* vista */, "Failed to create bitmap, hr %#x.\n", hr);
4378 if (SUCCEEDED(hr))
4380 static const struct bitmap_format_test
4382 D2D1_PIXEL_FORMAT original;
4383 D2D1_PIXEL_FORMAT result;
4384 HRESULT hr;
4386 bitmap_format_tests[] =
4388 { { DXGI_FORMAT_UNKNOWN, D2D1_ALPHA_MODE_PREMULTIPLIED },
4389 { DXGI_FORMAT_B8G8R8A8_UNORM, D2D1_ALPHA_MODE_PREMULTIPLIED } },
4391 { { DXGI_FORMAT_UNKNOWN, D2D1_ALPHA_MODE_IGNORE },
4392 { DXGI_FORMAT_B8G8R8A8_UNORM, D2D1_ALPHA_MODE_IGNORE } },
4394 { { DXGI_FORMAT_UNKNOWN, D2D1_ALPHA_MODE_UNKNOWN }, { 0 }, WINCODEC_ERR_UNSUPPORTEDPIXELFORMAT },
4396 { { DXGI_FORMAT_B8G8R8A8_UNORM, D2D1_ALPHA_MODE_UNKNOWN }, { 0 }, WINCODEC_ERR_UNSUPPORTEDPIXELFORMAT },
4398 { { DXGI_FORMAT_B8G8R8A8_UNORM, D2D1_ALPHA_MODE_IGNORE },
4399 { DXGI_FORMAT_B8G8R8A8_UNORM, D2D1_ALPHA_MODE_IGNORE } },
4401 { { DXGI_FORMAT_UNKNOWN, D2D1_ALPHA_MODE_STRAIGHT }, { 0 }, WINCODEC_ERR_UNSUPPORTEDPIXELFORMAT },
4402 { { DXGI_FORMAT_B8G8R8A8_UNORM, D2D1_ALPHA_MODE_STRAIGHT }, { 0 }, WINCODEC_ERR_UNSUPPORTEDPIXELFORMAT },
4404 unsigned int i;
4406 size = ID2D1Bitmap_GetPixelSize(bitmap2);
4407 hr = IDXGISurface_GetDesc(surface2, &surface_desc);
4408 ok(SUCCEEDED(hr), "Failed to get surface description, hr %#x.\n", hr);
4409 ok(size.width == surface_desc.Width && size.height == surface_desc.Height, "Got wrong bitmap size.\n");
4411 check_bitmap_surface(bitmap2, TRUE, D2D1_BITMAP_OPTIONS_TARGET | D2D1_BITMAP_OPTIONS_CANNOT_DRAW);
4413 ID2D1Bitmap_Release(bitmap2);
4415 /* IDXGISurface1 is supported too. */
4416 if (IDXGISurface_QueryInterface(surface2, &IID_IDXGISurface1, (void **)&surface3) == S_OK)
4418 hr = ID2D1RenderTarget_CreateSharedBitmap(rt2, &IID_IDXGISurface1, surface3, &bitmap_desc, &bitmap2);
4419 ok(SUCCEEDED(hr), "Failed to create bitmap, hr %#x.\n", hr);
4421 ID2D1Bitmap_Release(bitmap2);
4422 IDXGISurface1_Release(surface3);
4425 for (i = 0; i < ARRAY_SIZE(bitmap_format_tests); ++i)
4427 bitmap_desc.pixelFormat = bitmap_format_tests[i].original;
4429 hr = ID2D1RenderTarget_CreateSharedBitmap(rt2, &IID_IDXGISurface, surface2, &bitmap_desc, &bitmap2);
4430 todo_wine_if(i == 2 || i == 3 || i == 5 || i == 6)
4431 ok(hr == bitmap_format_tests[i].hr, "%u: unexpected hr %#x.\n", i, hr);
4433 if (SUCCEEDED(bitmap_format_tests[i].hr))
4435 pixel_format = ID2D1Bitmap_GetPixelFormat(bitmap2);
4436 ok(pixel_format.format == bitmap_format_tests[i].result.format, "%u: unexpected pixel format %#x.\n",
4437 i, pixel_format.format);
4438 ok(pixel_format.alphaMode == bitmap_format_tests[i].result.alphaMode, "%u: unexpected alpha mode %d.\n",
4439 i, pixel_format.alphaMode);
4441 ID2D1Bitmap_Release(bitmap2);
4446 ID2D1RenderTarget_Release(rt2);
4448 ID2D1Bitmap_Release(bitmap1);
4449 ID2D1RenderTarget_Release(rt1);
4450 ID2D1Factory_Release(factory2);
4451 ID2D1Factory_Release(factory1);
4452 IWICBitmap_Release(wic_bitmap2);
4453 IWICBitmap_Release(wic_bitmap1);
4454 IDXGISurface_Release(surface2);
4455 IDXGISurface_Release(surface1);
4456 IDXGISwapChain_Release(swapchain2);
4457 IDXGISwapChain_Release(swapchain1);
4458 ID3D10Device1_Release(device2);
4459 ID3D10Device1_Release(device1);
4460 DestroyWindow(window2);
4461 DestroyWindow(window1);
4462 CoUninitialize();
4465 static void test_bitmap_updates(void)
4467 D2D1_BITMAP_PROPERTIES bitmap_desc;
4468 IDXGISwapChain *swapchain;
4469 ID2D1RenderTarget *rt;
4470 ID3D10Device1 *device;
4471 IDXGISurface *surface;
4472 D2D1_RECT_U dst_rect;
4473 ID2D1Bitmap *bitmap;
4474 D2D1_COLOR_F color;
4475 D2D1_RECT_F rect;
4476 D2D1_SIZE_U size;
4477 HWND window;
4478 HRESULT hr;
4479 BOOL match;
4481 static const DWORD bitmap_data[] =
4483 0xffff0000, 0xffffff00, 0xff00ff00, 0xff00ffff,
4484 0xff0000ff, 0xffff00ff, 0xff000000, 0xff7f7f7f,
4485 0xffffffff, 0xffffffff, 0xffffffff, 0xff000000,
4486 0xffffffff, 0xff000000, 0xff000000, 0xff000000,
4489 if (!(device = create_device()))
4491 skip("Failed to create device, skipping tests.\n");
4492 return;
4494 window = create_window();
4495 swapchain = create_swapchain(device, window, TRUE);
4496 hr = IDXGISwapChain_GetBuffer(swapchain, 0, &IID_IDXGISurface, (void **)&surface);
4497 ok(SUCCEEDED(hr), "Failed to get buffer, hr %#x.\n", hr);
4498 rt = create_render_target(surface);
4499 ok(!!rt, "Failed to create render target.\n");
4501 ID2D1RenderTarget_SetAntialiasMode(rt, D2D1_ANTIALIAS_MODE_ALIASED);
4503 ID2D1RenderTarget_BeginDraw(rt);
4504 set_color(&color, 0.0f, 0.0f, 1.0f, 1.0f);
4505 ID2D1RenderTarget_Clear(rt, &color);
4507 set_size_u(&size, 4, 4);
4508 bitmap_desc.pixelFormat.format = DXGI_FORMAT_B8G8R8A8_UNORM;
4509 bitmap_desc.pixelFormat.alphaMode = D2D1_ALPHA_MODE_PREMULTIPLIED;
4510 bitmap_desc.dpiX = 96.0f;
4511 bitmap_desc.dpiY = 96.0f;
4512 hr = ID2D1RenderTarget_CreateBitmap(rt, size, NULL, 0, &bitmap_desc, &bitmap);
4513 ok(SUCCEEDED(hr), "Failed to create bitmap, hr %#x.\n", hr);
4515 set_rect(&rect, 0.0f, 0.0f, 320.0f, 240.0f);
4516 ID2D1RenderTarget_DrawBitmap(rt, bitmap, &rect, 1.0f,
4517 D2D1_BITMAP_INTERPOLATION_MODE_NEAREST_NEIGHBOR, NULL);
4519 ID2D1Bitmap_Release(bitmap);
4521 bitmap_desc.pixelFormat.alphaMode = D2D1_ALPHA_MODE_IGNORE;
4522 hr = ID2D1RenderTarget_CreateBitmap(rt, size, NULL, 0, &bitmap_desc, &bitmap);
4523 ok(SUCCEEDED(hr), "Failed to create bitmap, hr %#x.\n", hr);
4525 set_rect(&rect, 0.0f, 240.0f, 320.0f, 480.0f);
4526 ID2D1RenderTarget_DrawBitmap(rt, bitmap, &rect, 1.0f,
4527 D2D1_BITMAP_INTERPOLATION_MODE_NEAREST_NEIGHBOR, NULL);
4529 set_rect_u(&dst_rect, 1, 1, 3, 3);
4530 hr = ID2D1Bitmap_CopyFromMemory(bitmap, &dst_rect, bitmap_data, 4 * sizeof(*bitmap_data));
4531 ok(SUCCEEDED(hr), "Failed to update bitmap, hr %#x.\n", hr);
4532 set_rect_u(&dst_rect, 0, 3, 3, 4);
4533 hr = ID2D1Bitmap_CopyFromMemory(bitmap, &dst_rect, &bitmap_data[6], 4 * sizeof(*bitmap_data));
4534 ok(SUCCEEDED(hr), "Failed to update bitmap, hr %#x.\n", hr);
4535 set_rect_u(&dst_rect, 0, 0, 4, 1);
4536 hr = ID2D1Bitmap_CopyFromMemory(bitmap, &dst_rect, &bitmap_data[10], 4 * sizeof(*bitmap_data));
4537 ok(SUCCEEDED(hr), "Failed to update bitmap, hr %#x.\n", hr);
4538 set_rect_u(&dst_rect, 0, 1, 1, 3);
4539 hr = ID2D1Bitmap_CopyFromMemory(bitmap, &dst_rect, &bitmap_data[2], sizeof(*bitmap_data));
4540 ok(SUCCEEDED(hr), "Failed to update bitmap, hr %#x.\n", hr);
4541 set_rect_u(&dst_rect, 4, 4, 3, 1);
4542 hr = ID2D1Bitmap_CopyFromMemory(bitmap, &dst_rect, bitmap_data, sizeof(*bitmap_data));
4543 ok(SUCCEEDED(hr), "Failed to update bitmap, hr %#x.\n", hr);
4544 set_rect(&rect, 320.0f, 240.0f, 640.0f, 480.0f);
4545 ID2D1RenderTarget_DrawBitmap(rt, bitmap, &rect, 1.0f,
4546 D2D1_BITMAP_INTERPOLATION_MODE_NEAREST_NEIGHBOR, NULL);
4548 hr = ID2D1Bitmap_CopyFromMemory(bitmap, NULL, bitmap_data, 4 * sizeof(*bitmap_data));
4549 ok(SUCCEEDED(hr), "Failed to update bitmap, hr %#x.\n", hr);
4550 set_rect(&rect, 320.0f, 0.0f, 640.0f, 240.0f);
4551 ID2D1RenderTarget_DrawBitmap(rt, bitmap, &rect, 1.0f,
4552 D2D1_BITMAP_INTERPOLATION_MODE_NEAREST_NEIGHBOR, NULL);
4554 hr = ID2D1RenderTarget_EndDraw(rt, NULL, NULL);
4555 ok(SUCCEEDED(hr), "Failed to end draw, hr %#x.\n", hr);
4557 match = compare_surface(surface, "cb8136c91fbbdc76bb83b8c09edc1907b0a5d0a6");
4558 ok(match, "Surface does not match.\n");
4560 ID2D1Bitmap_Release(bitmap);
4561 ID2D1RenderTarget_Release(rt);
4562 IDXGISurface_Release(surface);
4563 IDXGISwapChain_Release(swapchain);
4564 ID3D10Device1_Release(device);
4565 DestroyWindow(window);
4568 static void test_opacity_brush(void)
4570 ID2D1BitmapBrush *bitmap_brush, *opacity_brush;
4571 D2D1_BITMAP_PROPERTIES bitmap_desc;
4572 ID2D1RectangleGeometry *geometry;
4573 ID2D1SolidColorBrush *color_brush;
4574 IDXGISwapChain *swapchain;
4575 D2D1_MATRIX_3X2_F matrix;
4576 ID2D1RenderTarget *rt;
4577 ID3D10Device1 *device;
4578 IDXGISurface *surface;
4579 ID2D1Factory *factory;
4580 ID2D1Bitmap *bitmap;
4581 D2D1_COLOR_F color;
4582 D2D1_RECT_F rect;
4583 D2D1_SIZE_U size;
4584 ULONG refcount;
4585 HWND window;
4586 HRESULT hr;
4587 BOOL match;
4589 static const DWORD bitmap_data[] =
4591 0xffff0000, 0x40ffff00, 0x4000ff00, 0xff00ffff,
4592 0x7f0000ff, 0x00ff00ff, 0x00000000, 0x7f7f7f7f,
4593 0x7fffffff, 0x00ffffff, 0x00ffffff, 0x7f000000,
4594 0xffffffff, 0x40000000, 0x40000000, 0xff000000,
4597 if (!(device = create_device()))
4599 skip("Failed to create device, skipping tests.\n");
4600 return;
4602 window = create_window();
4603 swapchain = create_swapchain(device, window, TRUE);
4604 hr = IDXGISwapChain_GetBuffer(swapchain, 0, &IID_IDXGISurface, (void **)&surface);
4605 ok(SUCCEEDED(hr), "Failed to get buffer, hr %#x.\n", hr);
4606 rt = create_render_target(surface);
4607 ok(!!rt, "Failed to create render target.\n");
4608 ID2D1RenderTarget_GetFactory(rt, &factory);
4610 ID2D1RenderTarget_SetDpi(rt, 192.0f, 48.0f);
4611 ID2D1RenderTarget_SetAntialiasMode(rt, D2D1_ANTIALIAS_MODE_ALIASED);
4613 set_color(&color, 0.0f, 1.0f, 0.0f, 0.8f);
4614 hr = ID2D1RenderTarget_CreateSolidColorBrush(rt, &color, NULL, &color_brush);
4615 ok(SUCCEEDED(hr), "Failed to create color brush, hr %#x.\n", hr);
4617 set_size_u(&size, 4, 4);
4618 bitmap_desc.pixelFormat.format = DXGI_FORMAT_B8G8R8A8_UNORM;
4619 bitmap_desc.pixelFormat.alphaMode = D2D1_ALPHA_MODE_PREMULTIPLIED;
4620 bitmap_desc.dpiX = 96.0f;
4621 bitmap_desc.dpiY = 96.0f;
4622 hr = ID2D1RenderTarget_CreateBitmap(rt, size, bitmap_data, 4 * sizeof(*bitmap_data), &bitmap_desc, &bitmap);
4623 ok(SUCCEEDED(hr), "Failed to create bitmap, hr %#x.\n", hr);
4624 hr = ID2D1RenderTarget_CreateBitmapBrush(rt, bitmap, NULL, NULL, &opacity_brush);
4625 ok(SUCCEEDED(hr), "Failed to create bitmap brush, hr %#x.\n", hr);
4626 ID2D1BitmapBrush_SetInterpolationMode(opacity_brush, D2D1_BITMAP_INTERPOLATION_MODE_NEAREST_NEIGHBOR);
4627 refcount = ID2D1Bitmap_Release(bitmap);
4628 ok(refcount == 1, "Got unexpected refcount %u.\n", refcount);
4630 set_size_u(&size, 1, 1);
4631 bitmap_desc.pixelFormat.format = DXGI_FORMAT_B8G8R8A8_UNORM;
4632 bitmap_desc.pixelFormat.alphaMode = D2D1_ALPHA_MODE_IGNORE;
4633 bitmap_desc.dpiX = 96.0f;
4634 bitmap_desc.dpiY = 96.0f;
4635 hr = ID2D1RenderTarget_CreateBitmap(rt, size, &bitmap_data[2], sizeof(*bitmap_data), &bitmap_desc, &bitmap);
4636 ok(SUCCEEDED(hr), "Failed to create bitmap, hr %#x.\n", hr);
4637 hr = ID2D1RenderTarget_CreateBitmapBrush(rt, bitmap, NULL, NULL, &bitmap_brush);
4638 ok(SUCCEEDED(hr), "Failed to create bitmap brush, hr %#x.\n", hr);
4639 ID2D1BitmapBrush_SetInterpolationMode(bitmap_brush, D2D1_BITMAP_INTERPOLATION_MODE_NEAREST_NEIGHBOR);
4640 refcount = ID2D1Bitmap_Release(bitmap);
4641 ok(refcount == 1, "Got unexpected refcount %u.\n", refcount);
4643 ID2D1RenderTarget_BeginDraw(rt);
4645 set_color(&color, 0.0f, 0.0f, 1.0f, 1.0f);
4646 ID2D1RenderTarget_Clear(rt, &color);
4648 set_rect(&rect, 40.0f, 120.0f, 120.0f, 360.0f);
4649 ID2D1RenderTarget_FillRectangle(rt, &rect, (ID2D1Brush *)color_brush);
4651 set_matrix_identity(&matrix);
4652 translate_matrix(&matrix, 120.0f, 120.0f);
4653 scale_matrix(&matrix, 20.0f, 60.0f);
4654 ID2D1BitmapBrush_SetTransform(opacity_brush, &matrix);
4655 set_rect(&rect, 120.0f, 120.0f, 200.0f, 360.0f);
4656 ID2D1RenderTarget_FillRectangle(rt, &rect, (ID2D1Brush *)opacity_brush);
4658 set_rect(&rect, 200.0f, 120.0f, 280.0f, 360.0f);
4659 ID2D1RenderTarget_FillRectangle(rt, &rect, (ID2D1Brush *)bitmap_brush);
4661 set_matrix_identity(&matrix);
4662 translate_matrix(&matrix, 40.0f, 360.0f);
4663 scale_matrix(&matrix, 20.0f, 60.0f);
4664 ID2D1BitmapBrush_SetTransform(opacity_brush, &matrix);
4665 set_rect(&rect, 40.0f, 360.0f, 120.0f, 600.0f);
4666 ID2D1Factory_CreateRectangleGeometry(factory, &rect, &geometry);
4667 ID2D1RenderTarget_FillGeometry(rt, (ID2D1Geometry *)geometry,
4668 (ID2D1Brush *)opacity_brush, (ID2D1Brush *)color_brush);
4669 ID2D1RectangleGeometry_Release(geometry);
4671 set_matrix_identity(&matrix);
4672 translate_matrix(&matrix, 120.0f, 360.0f);
4673 scale_matrix(&matrix, 20.0f, 60.0f);
4674 ID2D1BitmapBrush_SetTransform(opacity_brush, &matrix);
4675 set_rect(&rect, 120.0f, 360.0f, 200.0f, 600.0f);
4676 ID2D1Factory_CreateRectangleGeometry(factory, &rect, &geometry);
4677 ID2D1RenderTarget_FillGeometry(rt, (ID2D1Geometry *)geometry,
4678 (ID2D1Brush *)color_brush, (ID2D1Brush *)opacity_brush);
4679 ID2D1RectangleGeometry_Release(geometry);
4681 set_matrix_identity(&matrix);
4682 translate_matrix(&matrix, 200.0f, 360.0f);
4683 scale_matrix(&matrix, 20.0f, 60.0f);
4684 ID2D1BitmapBrush_SetTransform(opacity_brush, &matrix);
4685 set_rect(&rect, 200.0f, 360.0f, 280.0f, 600.0f);
4686 ID2D1Factory_CreateRectangleGeometry(factory, &rect, &geometry);
4687 ID2D1RenderTarget_FillGeometry(rt, (ID2D1Geometry *)geometry,
4688 (ID2D1Brush *)bitmap_brush, (ID2D1Brush *)opacity_brush);
4690 hr = ID2D1RenderTarget_EndDraw(rt, NULL, NULL);
4691 ok(hr == D2DERR_INCOMPATIBLE_BRUSH_TYPES, "Got unexpected hr %#x.\n", hr);
4692 match = compare_surface(surface, "7141c6c7b3decb91196428efb1856bcbf9872935");
4693 ok(match, "Surface does not match.\n");
4694 ID2D1RenderTarget_BeginDraw(rt);
4696 ID2D1RenderTarget_FillGeometry(rt, (ID2D1Geometry *)geometry,
4697 (ID2D1Brush *)bitmap_brush, (ID2D1Brush *)opacity_brush);
4698 ID2D1RectangleGeometry_Release(geometry);
4700 ID2D1SolidColorBrush_SetOpacity(color_brush, 0.5f);
4701 set_matrix_identity(&matrix);
4702 translate_matrix(&matrix, 40.0f, 600.0f);
4703 scale_matrix(&matrix, 20.0f, 60.0f);
4704 ID2D1BitmapBrush_SetTransform(opacity_brush, &matrix);
4705 set_rect(&rect, 40.0f, 600.0f, 120.0f, 840.0f);
4706 ID2D1Factory_CreateRectangleGeometry(factory, &rect, &geometry);
4707 ID2D1RenderTarget_FillGeometry(rt, (ID2D1Geometry *)geometry,
4708 (ID2D1Brush *)opacity_brush, (ID2D1Brush *)color_brush);
4709 ID2D1RectangleGeometry_Release(geometry);
4711 ID2D1BitmapBrush_SetOpacity(opacity_brush, 0.8f);
4712 set_matrix_identity(&matrix);
4713 translate_matrix(&matrix, 120.0f, 600.0f);
4714 scale_matrix(&matrix, 20.0f, 60.0f);
4715 ID2D1BitmapBrush_SetTransform(opacity_brush, &matrix);
4716 set_rect(&rect, 120.0f, 600.0f, 200.0f, 840.0f);
4717 ID2D1Factory_CreateRectangleGeometry(factory, &rect, &geometry);
4718 ID2D1RenderTarget_FillGeometry(rt, (ID2D1Geometry *)geometry,
4719 (ID2D1Brush *)opacity_brush, (ID2D1Brush *)bitmap_brush);
4720 ID2D1RectangleGeometry_Release(geometry);
4722 set_matrix_identity(&matrix);
4723 translate_matrix(&matrix, 200.0f, 600.0f);
4724 scale_matrix(&matrix, 20.0f, 60.0f);
4725 ID2D1BitmapBrush_SetTransform(opacity_brush, &matrix);
4726 set_rect(&rect, 200.0f, 600.0f, 280.0f, 840.0f);
4727 ID2D1Factory_CreateRectangleGeometry(factory, &rect, &geometry);
4728 ID2D1RenderTarget_FillGeometry(rt, (ID2D1Geometry *)geometry,
4729 (ID2D1Brush *)bitmap_brush, (ID2D1Brush *)opacity_brush);
4730 ID2D1RectangleGeometry_Release(geometry);
4732 hr = ID2D1RenderTarget_EndDraw(rt, NULL, NULL);
4733 ok(SUCCEEDED(hr), "Failed to end draw, hr %#x.\n", hr);
4734 match = compare_surface(surface, "c3a5802d1750efa3e9122c1a92f6064df3872732");
4735 ok(match, "Surface does not match.\n");
4737 ID2D1BitmapBrush_Release(bitmap_brush);
4738 ID2D1BitmapBrush_Release(opacity_brush);
4739 ID2D1SolidColorBrush_Release(color_brush);
4740 ID2D1RenderTarget_Release(rt);
4741 refcount = ID2D1Factory_Release(factory);
4742 ok(!refcount, "Factory has %u references left.\n", refcount);
4743 IDXGISurface_Release(surface);
4744 IDXGISwapChain_Release(swapchain);
4745 ID3D10Device1_Release(device);
4746 DestroyWindow(window);
4749 static void test_create_target(void)
4751 IDXGISwapChain *swapchain;
4752 ID2D1Factory *factory;
4753 ID2D1RenderTarget *rt;
4754 ID3D10Device1 *device;
4755 IDXGISurface *surface;
4756 HWND window;
4757 HRESULT hr;
4758 static const struct
4760 float dpi_x, dpi_y;
4761 float rt_dpi_x, rt_dpi_y;
4762 HRESULT hr;
4764 create_dpi_tests[] =
4766 { 0.0f, 0.0f, 96.0f, 96.0f, S_OK },
4767 { 192.0f, 0.0f, 96.0f, 96.0f, E_INVALIDARG },
4768 { 0.0f, 192.0f, 96.0f, 96.0f, E_INVALIDARG },
4769 { 192.0f, -10.0f, 96.0f, 96.0f, E_INVALIDARG },
4770 { -10.0f, 192.0f, 96.0f, 96.0f, E_INVALIDARG },
4771 { 48.0f, 96.0f, 48.0f, 96.0f, S_OK },
4773 unsigned int i;
4775 if (!(device = create_device()))
4777 skip("Failed to create device, skipping tests.\n");
4778 return;
4780 window = create_window();
4781 swapchain = create_swapchain(device, window, TRUE);
4782 hr = IDXGISwapChain_GetBuffer(swapchain, 0, &IID_IDXGISurface, (void **)&surface);
4783 ok(SUCCEEDED(hr), "Failed to get buffer, hr %#x.\n", hr);
4785 hr = D2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED, &IID_ID2D1Factory, NULL, (void **)&factory);
4786 ok(SUCCEEDED(hr), "Failed to create factory, hr %#x.\n", hr);
4788 for (i = 0; i < ARRAY_SIZE(create_dpi_tests); ++i)
4790 ID2D1GdiInteropRenderTarget *interop;
4791 D2D1_RENDER_TARGET_PROPERTIES desc;
4792 ID2D1RenderTarget *rt2;
4793 float dpi_x, dpi_y;
4794 IUnknown *unk;
4796 desc.type = D2D1_RENDER_TARGET_TYPE_DEFAULT;
4797 desc.pixelFormat.format = DXGI_FORMAT_UNKNOWN;
4798 desc.pixelFormat.alphaMode = D2D1_ALPHA_MODE_PREMULTIPLIED;
4799 desc.dpiX = create_dpi_tests[i].dpi_x;
4800 desc.dpiY = create_dpi_tests[i].dpi_y;
4801 desc.usage = D2D1_RENDER_TARGET_USAGE_NONE;
4802 desc.minLevel = D2D1_FEATURE_LEVEL_DEFAULT;
4804 hr = ID2D1Factory_CreateDxgiSurfaceRenderTarget(factory, surface, &desc, &rt);
4805 ok(hr == create_dpi_tests[i].hr, "Wrong return code, hr %#x, expected %#x, test %u.\n", hr,
4806 create_dpi_tests[i].hr, i);
4808 if (FAILED(hr))
4809 continue;
4811 hr = ID2D1RenderTarget_QueryInterface(rt, &IID_IUnknown, (void **)&unk);
4812 ok(SUCCEEDED(hr), "Failed to get IUnknown, hr %#x.\n", hr);
4813 ok(unk == (IUnknown *)rt, "Expected same interface pointer.\n");
4814 IUnknown_Release(unk);
4816 hr = ID2D1RenderTarget_QueryInterface(rt, &IID_ID2D1GdiInteropRenderTarget, (void **)&interop);
4817 ok(SUCCEEDED(hr), "Failed to get interop target, hr %#x.\n", hr);
4818 hr = ID2D1GdiInteropRenderTarget_QueryInterface(interop, &IID_ID2D1RenderTarget, (void **)&rt2);
4819 ok(SUCCEEDED(hr), "Failed to get render target back, %#x.\n", hr);
4820 ok(rt2 == rt, "Unexpected render target\n");
4821 ID2D1RenderTarget_Release(rt2);
4822 ID2D1GdiInteropRenderTarget_Release(interop);
4824 ID2D1RenderTarget_GetDpi(rt, &dpi_x, &dpi_y);
4825 ok(dpi_x == create_dpi_tests[i].rt_dpi_x, "Wrong dpi_x %.8e, expected %.8e, test %u\n",
4826 dpi_x, create_dpi_tests[i].rt_dpi_x, i);
4827 ok(dpi_y == create_dpi_tests[i].rt_dpi_y, "Wrong dpi_y %.8e, expected %.8e, test %u\n",
4828 dpi_y, create_dpi_tests[i].rt_dpi_y, i);
4830 ID2D1RenderTarget_Release(rt);
4833 ID2D1Factory_Release(factory);
4834 IDXGISurface_Release(surface);
4835 IDXGISwapChain_Release(swapchain);
4836 ID3D10Device1_Release(device);
4837 DestroyWindow(window);
4840 static void test_draw_text_layout(void)
4842 static const struct
4844 D2D1_TEXT_ANTIALIAS_MODE aa_mode;
4845 DWRITE_RENDERING_MODE rendering_mode;
4846 HRESULT hr;
4848 antialias_mode_tests[] =
4850 { D2D1_TEXT_ANTIALIAS_MODE_DEFAULT, DWRITE_RENDERING_MODE_ALIASED },
4851 { D2D1_TEXT_ANTIALIAS_MODE_ALIASED, DWRITE_RENDERING_MODE_ALIASED },
4852 { D2D1_TEXT_ANTIALIAS_MODE_ALIASED, DWRITE_RENDERING_MODE_DEFAULT },
4853 { D2D1_TEXT_ANTIALIAS_MODE_ALIASED, DWRITE_RENDERING_MODE_OUTLINE },
4854 { D2D1_TEXT_ANTIALIAS_MODE_GRAYSCALE, DWRITE_RENDERING_MODE_DEFAULT },
4855 { D2D1_TEXT_ANTIALIAS_MODE_GRAYSCALE, DWRITE_RENDERING_MODE_OUTLINE },
4856 { D2D1_TEXT_ANTIALIAS_MODE_GRAYSCALE, DWRITE_RENDERING_MODE_CLEARTYPE_NATURAL },
4857 { D2D1_TEXT_ANTIALIAS_MODE_GRAYSCALE, DWRITE_RENDERING_MODE_CLEARTYPE_NATURAL_SYMMETRIC },
4858 { D2D1_TEXT_ANTIALIAS_MODE_GRAYSCALE, DWRITE_RENDERING_MODE_CLEARTYPE_GDI_NATURAL },
4859 { D2D1_TEXT_ANTIALIAS_MODE_GRAYSCALE, DWRITE_RENDERING_MODE_CLEARTYPE_GDI_CLASSIC },
4860 { D2D1_TEXT_ANTIALIAS_MODE_CLEARTYPE, DWRITE_RENDERING_MODE_DEFAULT },
4861 { D2D1_TEXT_ANTIALIAS_MODE_CLEARTYPE, DWRITE_RENDERING_MODE_CLEARTYPE_NATURAL },
4862 { D2D1_TEXT_ANTIALIAS_MODE_CLEARTYPE, DWRITE_RENDERING_MODE_CLEARTYPE_NATURAL_SYMMETRIC },
4863 { D2D1_TEXT_ANTIALIAS_MODE_CLEARTYPE, DWRITE_RENDERING_MODE_CLEARTYPE_GDI_NATURAL },
4864 { D2D1_TEXT_ANTIALIAS_MODE_CLEARTYPE, DWRITE_RENDERING_MODE_CLEARTYPE_GDI_CLASSIC },
4865 { D2D1_TEXT_ANTIALIAS_MODE_CLEARTYPE, DWRITE_RENDERING_MODE_OUTLINE, E_INVALIDARG },
4866 { D2D1_TEXT_ANTIALIAS_MODE_GRAYSCALE, DWRITE_RENDERING_MODE_ALIASED, E_INVALIDARG },
4867 { D2D1_TEXT_ANTIALIAS_MODE_CLEARTYPE, DWRITE_RENDERING_MODE_ALIASED, E_INVALIDARG },
4868 { D2D1_TEXT_ANTIALIAS_MODE_ALIASED, DWRITE_RENDERING_MODE_CLEARTYPE_NATURAL, E_INVALIDARG },
4869 { D2D1_TEXT_ANTIALIAS_MODE_ALIASED, DWRITE_RENDERING_MODE_CLEARTYPE_NATURAL_SYMMETRIC, E_INVALIDARG },
4870 { D2D1_TEXT_ANTIALIAS_MODE_ALIASED, DWRITE_RENDERING_MODE_CLEARTYPE_GDI_NATURAL, E_INVALIDARG },
4871 { D2D1_TEXT_ANTIALIAS_MODE_ALIASED, DWRITE_RENDERING_MODE_CLEARTYPE_GDI_CLASSIC, E_INVALIDARG },
4873 D2D1_RENDER_TARGET_PROPERTIES desc;
4874 IDXGISwapChain *swapchain;
4875 ID2D1Factory *factory, *factory2;
4876 ID2D1RenderTarget *rt, *rt2;
4877 ID3D10Device1 *device;
4878 IDXGISurface *surface;
4879 HWND window;
4880 HRESULT hr;
4881 IDWriteFactory *dwrite_factory;
4882 IDWriteTextFormat *text_format;
4883 IDWriteTextLayout *text_layout;
4884 D2D1_POINT_2F origin;
4885 DWRITE_TEXT_RANGE range;
4886 D2D1_COLOR_F color;
4887 ID2D1SolidColorBrush *brush, *brush2;
4888 ID2D1RectangleGeometry *geometry;
4889 D2D1_RECT_F rect;
4890 unsigned int i;
4892 if (!(device = create_device()))
4894 skip("Failed to create device, skipping tests.\n");
4895 return;
4897 window = create_window();
4898 swapchain = create_swapchain(device, window, TRUE);
4899 hr = IDXGISwapChain_GetBuffer(swapchain, 0, &IID_IDXGISurface, (void **)&surface);
4900 ok(SUCCEEDED(hr), "Failed to get buffer, hr %#x.\n", hr);
4902 hr = D2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED, &IID_ID2D1Factory, NULL, (void **)&factory);
4903 ok(SUCCEEDED(hr), "Failed to create factory, hr %#x.\n", hr);
4905 hr = D2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED, &IID_ID2D1Factory, NULL, (void **)&factory2);
4906 ok(SUCCEEDED(hr), "Failed to create factory, hr %#x.\n", hr);
4907 ok(factory != factory2, "got same factory\n");
4909 desc.type = D2D1_RENDER_TARGET_TYPE_DEFAULT;
4910 desc.pixelFormat.format = DXGI_FORMAT_UNKNOWN;
4911 desc.pixelFormat.alphaMode = D2D1_ALPHA_MODE_PREMULTIPLIED;
4912 desc.dpiX = 0.0f;
4913 desc.dpiY = 0.0f;
4914 desc.usage = D2D1_RENDER_TARGET_USAGE_NONE;
4915 desc.minLevel = D2D1_FEATURE_LEVEL_DEFAULT;
4917 hr = ID2D1Factory_CreateDxgiSurfaceRenderTarget(factory, surface, &desc, &rt);
4918 ok(SUCCEEDED(hr), "Failed to create a target, hr %#x.\n", hr);
4920 hr = ID2D1Factory_CreateDxgiSurfaceRenderTarget(factory2, surface, &desc, &rt2);
4921 ok(SUCCEEDED(hr), "Failed to create a target, hr %#x.\n", hr);
4923 hr = DWriteCreateFactory(DWRITE_FACTORY_TYPE_SHARED, &IID_IDWriteFactory, (IUnknown **)&dwrite_factory);
4924 ok(SUCCEEDED(hr), "Failed to create factory, hr %#x.\n", hr);
4926 hr = IDWriteFactory_CreateTextFormat(dwrite_factory, L"Tahoma", NULL, DWRITE_FONT_WEIGHT_NORMAL,
4927 DWRITE_FONT_STYLE_NORMAL, DWRITE_FONT_STRETCH_NORMAL, 10.0f, L"", &text_format);
4928 ok(SUCCEEDED(hr), "Failed to create text format, hr %#x.\n", hr);
4930 hr = IDWriteFactory_CreateTextLayout(dwrite_factory, L"text", 4, text_format, 100.0f, 100.0f, &text_layout);
4931 ok(SUCCEEDED(hr), "Failed to create text layout, hr %#x.\n", hr);
4933 set_color(&color, 0.0f, 0.0f, 0.0f, 0.0f);
4934 hr = ID2D1RenderTarget_CreateSolidColorBrush(rt, &color, NULL, &brush);
4935 ok(SUCCEEDED(hr), "Failed to create brush, hr %#x.\n", hr);
4937 hr = ID2D1RenderTarget_CreateSolidColorBrush(rt2, &color, NULL, &brush2);
4938 ok(SUCCEEDED(hr), "Failed to create brush, hr %#x.\n", hr);
4940 /* effect brush is created from different factory */
4941 range.startPosition = 0;
4942 range.length = 4;
4943 hr = IDWriteTextLayout_SetDrawingEffect(text_layout, (IUnknown*)brush2, range);
4944 ok(SUCCEEDED(hr), "Failed to set drawing effect, hr %#x.\n", hr);
4946 ID2D1RenderTarget_BeginDraw(rt);
4948 origin.x = origin.y = 0.0f;
4949 ID2D1RenderTarget_DrawTextLayout(rt, origin, text_layout, (ID2D1Brush*)brush, D2D1_DRAW_TEXT_OPTIONS_NONE);
4951 hr = ID2D1RenderTarget_EndDraw(rt, NULL, NULL);
4952 todo_wine
4953 ok(hr == D2DERR_WRONG_FACTORY, "Unexpected hr %#x.\n", hr);
4955 /* Effect is d2d resource, but not a brush. */
4956 set_rect(&rect, 0.0f, 0.0f, 10.0f, 10.0f);
4957 hr = ID2D1Factory_CreateRectangleGeometry(factory, &rect, &geometry);
4958 ok(SUCCEEDED(hr), "Failed to geometry, hr %#x.\n", hr);
4960 range.startPosition = 0;
4961 range.length = 4;
4962 hr = IDWriteTextLayout_SetDrawingEffect(text_layout, (IUnknown*)geometry, range);
4963 ok(SUCCEEDED(hr), "Failed to set drawing effect, hr %#x.\n", hr);
4964 ID2D1RectangleGeometry_Release(geometry);
4966 ID2D1RenderTarget_BeginDraw(rt);
4968 origin.x = origin.y = 0.0f;
4969 ID2D1RenderTarget_DrawTextLayout(rt, origin, text_layout, (ID2D1Brush*)brush, D2D1_DRAW_TEXT_OPTIONS_NONE);
4971 hr = ID2D1RenderTarget_EndDraw(rt, NULL, NULL);
4972 ok(SUCCEEDED(hr), "EndDraw() failed, hr %#x.\n", hr);
4974 for (i = 0; i < ARRAY_SIZE(antialias_mode_tests); ++i)
4976 IDWriteRenderingParams *rendering_params;
4978 ID2D1RenderTarget_SetTextAntialiasMode(rt, antialias_mode_tests[i].aa_mode);
4980 hr = IDWriteFactory_CreateCustomRenderingParams(dwrite_factory, 2.0f, 1.0f, 0.0f, DWRITE_PIXEL_GEOMETRY_FLAT,
4981 antialias_mode_tests[i].rendering_mode, &rendering_params);
4982 ok(SUCCEEDED(hr), "Failed to create custom rendering params, hr %#x.\n", hr);
4984 ID2D1RenderTarget_SetTextRenderingParams(rt, rendering_params);
4986 ID2D1RenderTarget_BeginDraw(rt);
4988 ID2D1RenderTarget_DrawTextLayout(rt, origin, text_layout, (ID2D1Brush *)brush, D2D1_DRAW_TEXT_OPTIONS_NONE);
4990 hr = ID2D1RenderTarget_EndDraw(rt, NULL, NULL);
4991 ok(hr == antialias_mode_tests[i].hr, "%u: unexpected hr %#x.\n", i, hr);
4993 IDWriteRenderingParams_Release(rendering_params);
4996 IDWriteTextFormat_Release(text_format);
4997 IDWriteTextLayout_Release(text_layout);
4998 IDWriteFactory_Release(dwrite_factory);
4999 ID2D1RenderTarget_Release(rt);
5000 ID2D1RenderTarget_Release(rt2);
5002 ID2D1Factory_Release(factory);
5003 ID2D1Factory_Release(factory2);
5004 IDXGISurface_Release(surface);
5005 IDXGISwapChain_Release(swapchain);
5006 ID3D10Device1_Release(device);
5007 DestroyWindow(window);
5010 static void create_target_dibsection(HDC hdc, UINT32 width, UINT32 height)
5012 char bmibuf[FIELD_OFFSET(BITMAPINFO, bmiColors[256])];
5013 BITMAPINFO *bmi = (BITMAPINFO*)bmibuf;
5014 HBITMAP hbm;
5016 memset(bmi, 0, sizeof(bmibuf));
5017 bmi->bmiHeader.biSize = sizeof(bmi->bmiHeader);
5018 bmi->bmiHeader.biHeight = -height;
5019 bmi->bmiHeader.biWidth = width;
5020 bmi->bmiHeader.biBitCount = 32;
5021 bmi->bmiHeader.biPlanes = 1;
5022 bmi->bmiHeader.biCompression = BI_RGB;
5024 hbm = CreateDIBSection(hdc, bmi, DIB_RGB_COLORS, NULL, NULL, 0);
5025 ok(hbm != NULL, "Failed to create a dib section.\n");
5027 DeleteObject(SelectObject(hdc, hbm));
5030 static void test_dc_target(void)
5032 static const D2D1_PIXEL_FORMAT invalid_formats[] =
5034 { DXGI_FORMAT_UNKNOWN, D2D1_ALPHA_MODE_PREMULTIPLIED },
5035 { DXGI_FORMAT_B8G8R8A8_UNORM, D2D1_ALPHA_MODE_UNKNOWN },
5036 { DXGI_FORMAT_R8G8B8A8_UNORM, D2D1_ALPHA_MODE_PREMULTIPLIED },
5038 D2D1_TEXT_ANTIALIAS_MODE text_aa_mode;
5039 ID2D1GdiInteropRenderTarget *interop;
5040 D2D1_RENDER_TARGET_PROPERTIES desc;
5041 D2D1_MATRIX_3X2_F matrix, matrix2;
5042 ID2D1DCRenderTarget *rt, *rt2;
5043 D2D1_ANTIALIAS_MODE aa_mode;
5044 ID2D1SolidColorBrush *brush;
5045 ID2D1RenderTarget *rt3;
5046 ID2D1Factory *factory;
5047 ID3D10Device1 *device;
5048 FLOAT dpi_x, dpi_y;
5049 D2D1_COLOR_F color;
5050 D2D1_SIZE_U sizeu;
5051 D2D1_SIZE_F size;
5052 D2D1_TAG t1, t2;
5053 unsigned int i;
5054 HDC hdc, hdc2;
5055 D2D_RECT_F r;
5056 COLORREF clr;
5057 HRESULT hr;
5058 RECT rect;
5060 if (!(device = create_device()))
5062 skip("Failed to create device, skipping tests.\n");
5063 return;
5065 ID3D10Device1_Release(device);
5067 hr = D2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED, &IID_ID2D1Factory, NULL, (void **)&factory);
5068 ok(SUCCEEDED(hr), "Failed to create factory, hr %#x.\n", hr);
5070 for (i = 0; i < ARRAY_SIZE(invalid_formats); ++i)
5072 desc.type = D2D1_RENDER_TARGET_TYPE_DEFAULT;
5073 desc.pixelFormat = invalid_formats[i];
5074 desc.dpiX = 96.0f;
5075 desc.dpiY = 96.0f;
5076 desc.usage = D2D1_RENDER_TARGET_USAGE_NONE;
5077 desc.minLevel = D2D1_FEATURE_LEVEL_DEFAULT;
5079 hr = ID2D1Factory_CreateDCRenderTarget(factory, &desc, &rt);
5080 ok(hr == D2DERR_UNSUPPORTED_PIXEL_FORMAT, "Got unexpected hr %#x.\n", hr);
5083 desc.type = D2D1_RENDER_TARGET_TYPE_DEFAULT;
5084 desc.pixelFormat.format = DXGI_FORMAT_B8G8R8A8_UNORM;
5085 desc.pixelFormat.alphaMode = D2D1_ALPHA_MODE_PREMULTIPLIED;
5086 desc.dpiX = 96.0f;
5087 desc.dpiY = 96.0f;
5088 desc.usage = D2D1_RENDER_TARGET_USAGE_NONE;
5089 desc.minLevel = D2D1_FEATURE_LEVEL_DEFAULT;
5090 hr = ID2D1Factory_CreateDCRenderTarget(factory, &desc, &rt);
5091 ok(SUCCEEDED(hr), "Failed to create target, hr %#x.\n", hr);
5093 hr = ID2D1DCRenderTarget_QueryInterface(rt, &IID_ID2D1GdiInteropRenderTarget, (void **)&interop);
5094 ok(SUCCEEDED(hr), "Failed to get interop target, hr %#x.\n", hr);
5095 hr = ID2D1GdiInteropRenderTarget_QueryInterface(interop, &IID_ID2D1RenderTarget, (void **)&rt3);
5096 ok(SUCCEEDED(hr), "Failed to get render target back, %#x.\n", hr);
5097 ok(rt3 == (ID2D1RenderTarget *)rt, "Unexpected render target\n");
5098 ID2D1RenderTarget_Release(rt3);
5099 hr = ID2D1GdiInteropRenderTarget_QueryInterface(interop, &IID_ID2D1DCRenderTarget, (void **)&rt2);
5100 ok(SUCCEEDED(hr), "Failed to get render target back, %#x.\n", hr);
5101 ok(rt2 == rt, "Unexpected render target\n");
5102 ID2D1DCRenderTarget_Release(rt2);
5103 ID2D1GdiInteropRenderTarget_Release(interop);
5105 size = ID2D1DCRenderTarget_GetSize(rt);
5106 ok(size.width == 0.0f, "got width %.08e.\n", size.width);
5107 ok(size.height == 0.0f, "got height %.08e.\n", size.height);
5109 sizeu = ID2D1DCRenderTarget_GetPixelSize(rt);
5110 ok(sizeu.width == 0, "got width %u.\n", sizeu.width);
5111 ok(sizeu.height == 0, "got height %u.\n", sizeu.height);
5113 /* object creation methods work without BindDC() */
5114 set_color(&color, 0.0f, 0.0f, 0.0f, 0.0f);
5115 hr = ID2D1DCRenderTarget_CreateSolidColorBrush(rt, &color, NULL, &brush);
5116 ok(SUCCEEDED(hr), "Failed to create a brush, hr %#x.\n", hr);
5117 ID2D1SolidColorBrush_Release(brush);
5119 ID2D1DCRenderTarget_BeginDraw(rt);
5120 hr = ID2D1DCRenderTarget_EndDraw(rt, NULL, NULL);
5121 ok(hr == D2DERR_WRONG_STATE, "Got unexpected hr %#x.\n", hr);
5123 ID2D1DCRenderTarget_Release(rt);
5125 /* BindDC() */
5126 hr = ID2D1Factory_CreateDCRenderTarget(factory, &desc, &rt);
5127 ok(SUCCEEDED(hr), "Failed to create target, hr %#x.\n", hr);
5129 aa_mode = ID2D1DCRenderTarget_GetAntialiasMode(rt);
5130 ok(aa_mode == D2D1_ANTIALIAS_MODE_PER_PRIMITIVE, "Got wrong default aa mode %d.\n", aa_mode);
5131 text_aa_mode = ID2D1DCRenderTarget_GetTextAntialiasMode(rt);
5132 ok(text_aa_mode == D2D1_TEXT_ANTIALIAS_MODE_DEFAULT, "Got wrong default text aa mode %d.\n", text_aa_mode);
5134 ID2D1DCRenderTarget_GetDpi(rt, &dpi_x, &dpi_y);
5135 ok(dpi_x == 96.0f && dpi_y == 96.0f, "Got dpi_x %f, dpi_y %f.\n", dpi_x, dpi_y);
5137 hdc = CreateCompatibleDC(NULL);
5138 ok(hdc != NULL, "Failed to create an HDC.\n");
5140 create_target_dibsection(hdc, 16, 16);
5142 SetRect(&rect, 0, 0, 32, 32);
5143 hr = ID2D1DCRenderTarget_BindDC(rt, NULL, &rect);
5144 ok(hr == E_INVALIDARG, "BindDC() returned %#x.\n", hr);
5146 /* Target properties are retained during BindDC() */
5147 ID2D1DCRenderTarget_SetTags(rt, 1, 2);
5148 ID2D1DCRenderTarget_SetAntialiasMode(rt, D2D1_ANTIALIAS_MODE_ALIASED);
5149 ID2D1DCRenderTarget_SetTextAntialiasMode(rt, D2D1_TEXT_ANTIALIAS_MODE_CLEARTYPE);
5151 set_matrix_identity(&matrix);
5152 translate_matrix(&matrix, 200.0f, 600.0f);
5153 ID2D1DCRenderTarget_SetTransform(rt, &matrix);
5155 hr = ID2D1DCRenderTarget_BindDC(rt, hdc, &rect);
5156 ok(hr == S_OK, "BindDC() returned %#x.\n", hr);
5158 ID2D1DCRenderTarget_GetTags(rt, &t1, &t2);
5159 ok(t1 == 1 && t2 == 2, "Got wrong tags.\n");
5161 aa_mode = ID2D1DCRenderTarget_GetAntialiasMode(rt);
5162 ok(aa_mode == D2D1_ANTIALIAS_MODE_ALIASED, "Got wrong aa mode %d.\n", aa_mode);
5164 text_aa_mode = ID2D1DCRenderTarget_GetTextAntialiasMode(rt);
5165 ok(text_aa_mode == D2D1_TEXT_ANTIALIAS_MODE_CLEARTYPE, "Got wrong text aa mode %d.\n", text_aa_mode);
5167 ID2D1DCRenderTarget_GetTransform(rt, &matrix2);
5168 ok(!memcmp(&matrix, &matrix2, sizeof(matrix)), "Got wrong target transform.\n");
5170 set_matrix_identity(&matrix);
5171 ID2D1DCRenderTarget_SetTransform(rt, &matrix);
5173 /* target size comes from specified dimensions, not from selected bitmap size */
5174 size = ID2D1DCRenderTarget_GetSize(rt);
5175 ok(size.width == 32.0f, "got width %.08e.\n", size.width);
5176 ok(size.height == 32.0f, "got height %.08e.\n", size.height);
5178 /* clear one HDC to red, switch to another one, partially fill it and test contents */
5179 ID2D1DCRenderTarget_BeginDraw(rt);
5181 set_color(&color, 1.0f, 0.0f, 0.0f, 1.0f);
5182 ID2D1DCRenderTarget_Clear(rt, &color);
5184 hr = ID2D1DCRenderTarget_EndDraw(rt, NULL, NULL);
5185 ok(SUCCEEDED(hr), "EndDraw() failed, hr %#x.\n", hr);
5187 clr = GetPixel(hdc, 0, 0);
5188 ok(clr == RGB(255, 0, 0), "Unexpected color 0x%08x.\n", clr);
5190 hdc2 = CreateCompatibleDC(NULL);
5191 ok(hdc2 != NULL, "Failed to create an HDC.\n");
5193 create_target_dibsection(hdc2, 16, 16);
5195 hr = ID2D1DCRenderTarget_BindDC(rt, hdc2, &rect);
5196 ok(hr == S_OK, "BindDC() returned %#x.\n", hr);
5198 clr = GetPixel(hdc2, 0, 0);
5199 ok(clr == 0, "Unexpected color 0x%08x.\n", clr);
5201 set_color(&color, 0.0f, 1.0f, 0.0f, 1.0f);
5202 hr = ID2D1DCRenderTarget_CreateSolidColorBrush(rt, &color, NULL, &brush);
5203 ok(SUCCEEDED(hr), "Failed to create brush, hr %#x.\n", hr);
5205 ID2D1DCRenderTarget_BeginDraw(rt);
5207 r.left = r.top = 0.0f;
5208 r.bottom = 16.0f;
5209 r.right = 8.0f;
5210 ID2D1DCRenderTarget_FillRectangle(rt, &r, (ID2D1Brush*)brush);
5212 hr = ID2D1DCRenderTarget_EndDraw(rt, NULL, NULL);
5213 ok(SUCCEEDED(hr), "EndDraw() failed, hr %#x.\n", hr);
5215 ID2D1SolidColorBrush_Release(brush);
5217 clr = GetPixel(hdc2, 0, 0);
5218 ok(clr == RGB(0, 255, 0), "Unexpected color 0x%08x.\n", clr);
5220 clr = GetPixel(hdc2, 10, 0);
5221 ok(clr == 0, "Unexpected color 0x%08x.\n", clr);
5223 /* Invalid DC. */
5224 hr = ID2D1DCRenderTarget_BindDC(rt, (HDC)0xdeadbeef, &rect);
5225 todo_wine
5226 ok(hr == E_INVALIDARG, "BindDC() returned %#x.\n", hr);
5228 ID2D1DCRenderTarget_BeginDraw(rt);
5230 set_color(&color, 1.0f, 0.0f, 0.0f, 1.0f);
5231 ID2D1DCRenderTarget_Clear(rt, &color);
5233 hr = ID2D1DCRenderTarget_EndDraw(rt, NULL, NULL);
5234 ok(SUCCEEDED(hr), "EndDraw() failed, hr %#x.\n", hr);
5236 clr = GetPixel(hdc2, 0, 0);
5237 todo_wine
5238 ok(clr == RGB(255, 0, 0), "Unexpected color 0x%08x.\n", clr);
5240 hr = ID2D1DCRenderTarget_BindDC(rt, NULL, &rect);
5241 ok(hr == E_INVALIDARG, "BindDC() returned %#x.\n", hr);
5243 ID2D1DCRenderTarget_BeginDraw(rt);
5245 set_color(&color, 0.0f, 0.0f, 1.0f, 1.0f);
5246 ID2D1DCRenderTarget_Clear(rt, &color);
5248 hr = ID2D1DCRenderTarget_EndDraw(rt, NULL, NULL);
5249 ok(SUCCEEDED(hr), "EndDraw() failed, hr %#x.\n", hr);
5251 clr = GetPixel(hdc2, 0, 0);
5252 todo_wine
5253 ok(clr == RGB(0, 0, 255), "Unexpected color 0x%08x.\n", clr);
5255 DeleteDC(hdc);
5256 DeleteDC(hdc2);
5257 ID2D1DCRenderTarget_Release(rt);
5258 ID2D1Factory_Release(factory);
5261 static void test_hwnd_target(void)
5263 D2D1_HWND_RENDER_TARGET_PROPERTIES hwnd_rt_desc;
5264 ID2D1GdiInteropRenderTarget *interop;
5265 D2D1_RENDER_TARGET_PROPERTIES desc;
5266 ID2D1HwndRenderTarget *rt, *rt2;
5267 ID2D1RenderTarget *rt3;
5268 ID2D1Factory *factory;
5269 ID3D10Device1 *device;
5270 D2D1_SIZE_U size;
5271 HRESULT hr;
5273 if (!(device = create_device()))
5275 skip("Failed to create device, skipping tests.\n");
5276 return;
5278 ID3D10Device1_Release(device);
5280 hr = D2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED, &IID_ID2D1Factory, NULL, (void **)&factory);
5281 ok(SUCCEEDED(hr), "Failed to create factory, hr %#x.\n", hr);
5283 desc.type = D2D1_RENDER_TARGET_TYPE_DEFAULT;
5284 desc.pixelFormat.format = DXGI_FORMAT_B8G8R8A8_UNORM;
5285 desc.pixelFormat.alphaMode = D2D1_ALPHA_MODE_PREMULTIPLIED;
5286 desc.dpiX = 0.0f;
5287 desc.dpiY = 0.0f;
5288 desc.usage = D2D1_RENDER_TARGET_USAGE_NONE;
5289 desc.minLevel = D2D1_FEATURE_LEVEL_DEFAULT;
5291 hwnd_rt_desc.hwnd = NULL;
5292 hwnd_rt_desc.pixelSize.width = 64;
5293 hwnd_rt_desc.pixelSize.height = 64;
5294 hwnd_rt_desc.presentOptions = D2D1_PRESENT_OPTIONS_NONE;
5296 hr = ID2D1Factory_CreateHwndRenderTarget(factory, &desc, &hwnd_rt_desc, &rt);
5297 ok(FAILED(hr), "Target creation should fail, hr %#x.\n", hr);
5299 hwnd_rt_desc.hwnd = (HWND)0xdeadbeef;
5300 hr = ID2D1Factory_CreateHwndRenderTarget(factory, &desc, &hwnd_rt_desc, &rt);
5301 ok(FAILED(hr), "Target creation should fail, hr %#x.\n", hr);
5303 hwnd_rt_desc.hwnd = CreateWindowA("static", "d2d_test", 0, 0, 0, 0, 0, 0, 0, 0, 0);
5304 ok(!!hwnd_rt_desc.hwnd, "Failed to create target window.\n");
5305 hr = ID2D1Factory_CreateHwndRenderTarget(factory, &desc, &hwnd_rt_desc, &rt);
5306 ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr);
5308 hr = ID2D1HwndRenderTarget_QueryInterface(rt, &IID_ID2D1GdiInteropRenderTarget, (void **)&interop);
5309 ok(SUCCEEDED(hr), "Failed to get interop target, hr %#x.\n", hr);
5310 hr = ID2D1GdiInteropRenderTarget_QueryInterface(interop, &IID_ID2D1RenderTarget, (void **)&rt3);
5311 ok(SUCCEEDED(hr), "Failed to get render target back, %#x.\n", hr);
5312 ok(rt3 == (ID2D1RenderTarget *)rt, "Unexpected render target\n");
5313 ID2D1RenderTarget_Release(rt3);
5314 hr = ID2D1GdiInteropRenderTarget_QueryInterface(interop, &IID_ID2D1HwndRenderTarget, (void **)&rt2);
5315 ok(SUCCEEDED(hr), "Failed to get render target back, %#x.\n", hr);
5316 ok(rt2 == rt, "Unexpected render target\n");
5317 ID2D1HwndRenderTarget_Release(rt2);
5318 ID2D1GdiInteropRenderTarget_Release(interop);
5320 size.width = 128;
5321 size.height = 64;
5322 hr = ID2D1HwndRenderTarget_Resize(rt, &size);
5323 ok(SUCCEEDED(hr), "Failed to resize render target, hr %#x.\n", hr);
5325 ID2D1HwndRenderTarget_Release(rt);
5327 DestroyWindow(hwnd_rt_desc.hwnd);
5328 ID2D1Factory_Release(factory);
5331 #define test_compatible_target_size(r) test_compatible_target_size_(__LINE__, r)
5332 static void test_compatible_target_size_(unsigned int line, ID2D1RenderTarget *rt)
5334 static const D2D1_SIZE_F size_1_0 = { 1.0f, 0.0f };
5335 static const D2D1_SIZE_F size_1_1 = { 1.0f, 1.0f };
5336 static const D2D1_SIZE_U px_size_1_1 = { 1, 1 };
5337 static const D2D1_SIZE_U zero_px_size;
5338 static const D2D1_SIZE_F zero_size;
5339 static const struct size_test
5341 const D2D1_SIZE_U *pixel_size;
5342 const D2D1_SIZE_F *size;
5344 size_tests[] =
5346 { &zero_px_size, NULL },
5347 { &zero_px_size, &zero_size },
5348 { NULL, &zero_size },
5349 { NULL, &size_1_0 },
5350 { &px_size_1_1, &size_1_1 },
5352 float dpi_x, dpi_y, rt_dpi_x, rt_dpi_y;
5353 D2D1_SIZE_U pixel_size, expected_size;
5354 ID2D1BitmapRenderTarget *bitmap_rt;
5355 ID2D1DeviceContext *context;
5356 unsigned int i;
5357 HRESULT hr;
5359 ID2D1RenderTarget_GetDpi(rt, &rt_dpi_x, &rt_dpi_y);
5361 for (i = 0; i < ARRAY_SIZE(size_tests); ++i)
5363 hr = ID2D1RenderTarget_CreateCompatibleRenderTarget(rt, size_tests[i].size, size_tests[i].pixel_size,
5364 NULL, D2D1_COMPATIBLE_RENDER_TARGET_OPTIONS_NONE, &bitmap_rt);
5365 ok_(__FILE__, line)(SUCCEEDED(hr), "%u: Failed to create render target, hr %#x.\n", i, hr);
5367 if (size_tests[i].pixel_size)
5369 expected_size = *size_tests[i].pixel_size;
5371 else if (size_tests[i].size)
5373 expected_size.width = ceilf((size_tests[i].size->width * rt_dpi_x) / 96.0f);
5374 expected_size.height = ceilf((size_tests[i].size->height * rt_dpi_y) / 96.0f);
5376 else
5378 expected_size = ID2D1RenderTarget_GetPixelSize(rt);
5381 pixel_size = ID2D1BitmapRenderTarget_GetPixelSize(bitmap_rt);
5382 ok_(__FILE__, line)(!memcmp(&pixel_size, &expected_size, sizeof(pixel_size)),
5383 "%u: unexpected target size %ux%u.\n", i, pixel_size.width, pixel_size.height);
5385 ID2D1BitmapRenderTarget_GetDpi(bitmap_rt, &dpi_x, &dpi_y);
5386 if (size_tests[i].pixel_size && size_tests[i].size && size_tests[i].size->width != 0.0f
5387 && size_tests[i].size->height != 0.0f)
5389 ok_(__FILE__, line)(dpi_x == pixel_size.width * 96.0f / size_tests[i].size->width
5390 && dpi_y == pixel_size.height * 96.0f / size_tests[i].size->height,
5391 "%u: unexpected target dpi %.8ex%.8e.\n", i, dpi_x, dpi_y);
5393 else
5394 ok_(__FILE__, line)(dpi_x == rt_dpi_x && dpi_y == rt_dpi_y,
5395 "%u: unexpected target dpi %.8ex%.8e.\n", i, dpi_x, dpi_y);
5396 ID2D1BitmapRenderTarget_Release(bitmap_rt);
5399 pixel_size.height = pixel_size.width = 0;
5400 hr = ID2D1RenderTarget_CreateCompatibleRenderTarget(rt, NULL, &pixel_size, NULL,
5401 D2D1_COMPATIBLE_RENDER_TARGET_OPTIONS_NONE, &bitmap_rt);
5402 ok_(__FILE__, line)(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr);
5404 if (SUCCEEDED(ID2D1BitmapRenderTarget_QueryInterface(bitmap_rt, &IID_ID2D1DeviceContext, (void **)&context)))
5406 ID2D1Bitmap *bitmap;
5408 pixel_size = ID2D1DeviceContext_GetPixelSize(context);
5409 ok_(__FILE__, line)(!pixel_size.width && !pixel_size.height, "Unexpected target size %ux%u.\n",
5410 pixel_size.width, pixel_size.height);
5412 ID2D1DeviceContext_GetTarget(context, (ID2D1Image **)&bitmap);
5413 pixel_size = ID2D1Bitmap_GetPixelSize(bitmap);
5414 ok_(__FILE__, line)(!pixel_size.width && !pixel_size.height, "Unexpected target size %ux%u.\n",
5415 pixel_size.width, pixel_size.height);
5416 ID2D1Bitmap_Release(bitmap);
5418 ID2D1DeviceContext_Release(context);
5421 ID2D1BitmapRenderTarget_Release(bitmap_rt);
5424 static void test_bitmap_target(void)
5426 D2D1_HWND_RENDER_TARGET_PROPERTIES hwnd_rt_desc;
5427 ID2D1GdiInteropRenderTarget *interop;
5428 D2D1_SIZE_U pixel_size, pixel_size2;
5429 D2D1_RENDER_TARGET_PROPERTIES desc;
5430 ID2D1BitmapRenderTarget *rt, *rt2;
5431 ID2D1HwndRenderTarget *hwnd_rt;
5432 ID2D1Bitmap *bitmap, *bitmap2;
5433 ID2D1DCRenderTarget *dc_rt;
5434 D2D1_SIZE_F size, size2;
5435 ID2D1RenderTarget *rt3;
5436 ID2D1Factory *factory;
5437 ID3D10Device1 *device;
5438 float dpi[2], dpi2[2];
5439 D2D1_COLOR_F color;
5440 ULONG refcount;
5441 HRESULT hr;
5443 if (!(device = create_device()))
5445 skip("Failed to create device, skipping tests.\n");
5446 return;
5448 ID3D10Device1_Release(device);
5450 hr = D2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED, &IID_ID2D1Factory, NULL, (void **)&factory);
5451 ok(SUCCEEDED(hr), "Failed to create factory, hr %#x.\n", hr);
5453 desc.type = D2D1_RENDER_TARGET_TYPE_DEFAULT;
5454 desc.pixelFormat.format = DXGI_FORMAT_B8G8R8A8_UNORM;
5455 desc.pixelFormat.alphaMode = D2D1_ALPHA_MODE_PREMULTIPLIED;
5456 desc.dpiX = 96.0f;
5457 desc.dpiY = 192.0f;
5458 desc.usage = D2D1_RENDER_TARGET_USAGE_NONE;
5459 desc.minLevel = D2D1_FEATURE_LEVEL_DEFAULT;
5461 hwnd_rt_desc.hwnd = CreateWindowA("static", "d2d_test", 0, 0, 0, 0, 0, 0, 0, 0, 0);
5462 ok(!!hwnd_rt_desc.hwnd, "Failed to create target window.\n");
5463 hwnd_rt_desc.pixelSize.width = 64;
5464 hwnd_rt_desc.pixelSize.height = 64;
5465 hwnd_rt_desc.presentOptions = D2D1_PRESENT_OPTIONS_NONE;
5467 hr = ID2D1Factory_CreateHwndRenderTarget(factory, &desc, &hwnd_rt_desc, &hwnd_rt);
5468 ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr);
5470 test_compatible_target_size((ID2D1RenderTarget *)hwnd_rt);
5472 hr = ID2D1HwndRenderTarget_CreateCompatibleRenderTarget(hwnd_rt, NULL, NULL, NULL,
5473 D2D1_COMPATIBLE_RENDER_TARGET_OPTIONS_NONE, &rt);
5474 ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr);
5476 hr = ID2D1BitmapRenderTarget_QueryInterface(rt, &IID_ID2D1GdiInteropRenderTarget, (void **)&interop);
5477 ok(SUCCEEDED(hr), "Failed to get interop target, hr %#x.\n", hr);
5478 hr = ID2D1GdiInteropRenderTarget_QueryInterface(interop, &IID_ID2D1RenderTarget, (void **)&rt3);
5479 ok(SUCCEEDED(hr), "Failed to get render target back, %#x.\n", hr);
5480 ok(rt3 == (ID2D1RenderTarget *)rt, "Unexpected render target\n");
5481 ID2D1RenderTarget_Release(rt3);
5482 hr = ID2D1GdiInteropRenderTarget_QueryInterface(interop, &IID_ID2D1BitmapRenderTarget, (void **)&rt2);
5483 ok(SUCCEEDED(hr), "Failed to get render target back, %#x.\n", hr);
5484 ok(rt2 == rt, "Unexpected render target\n");
5485 ID2D1BitmapRenderTarget_Release(rt2);
5486 ID2D1GdiInteropRenderTarget_Release(interop);
5488 /* See if parent target is referenced. */
5489 ID2D1HwndRenderTarget_AddRef(hwnd_rt);
5490 refcount = ID2D1HwndRenderTarget_Release(hwnd_rt);
5491 ok(refcount == 1, "Target should not have been referenced, got %u.\n", refcount);
5493 /* Size was not specified, should match parent. */
5494 pixel_size = ID2D1HwndRenderTarget_GetPixelSize(hwnd_rt);
5495 pixel_size2 = ID2D1BitmapRenderTarget_GetPixelSize(rt);
5496 ok(!memcmp(&pixel_size, &pixel_size2, sizeof(pixel_size)), "Got target pixel size mismatch.\n");
5498 size = ID2D1HwndRenderTarget_GetSize(hwnd_rt);
5499 size2 = ID2D1BitmapRenderTarget_GetSize(rt);
5500 ok(!memcmp(&size, &size2, sizeof(size)), "Got target DIP size mismatch.\n");
5502 ID2D1HwndRenderTarget_GetDpi(hwnd_rt, dpi, dpi + 1);
5503 ID2D1BitmapRenderTarget_GetDpi(rt, dpi2, dpi2 + 1);
5504 ok(!memcmp(dpi, dpi2, sizeof(dpi)), "Got dpi mismatch.\n");
5506 ID2D1BitmapRenderTarget_Release(rt);
5508 /* Pixel size specified. */
5509 set_size_u(&pixel_size, 32, 32);
5510 hr = ID2D1HwndRenderTarget_CreateCompatibleRenderTarget(hwnd_rt, NULL, &pixel_size, NULL,
5511 D2D1_COMPATIBLE_RENDER_TARGET_OPTIONS_NONE, &rt);
5512 ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr);
5514 pixel_size2 = ID2D1BitmapRenderTarget_GetPixelSize(rt);
5515 ok(!memcmp(&pixel_size, &pixel_size2, sizeof(pixel_size)), "Got target pixel size mismatch.\n");
5517 ID2D1BitmapRenderTarget_GetDpi(rt, dpi2, dpi2 + 1);
5518 ok(!memcmp(dpi, dpi2, sizeof(dpi)), "Got dpi mismatch.\n");
5520 ID2D1BitmapRenderTarget_Release(rt);
5522 /* Both pixel size and DIP size are specified. */
5523 set_size_u(&pixel_size, 128, 128);
5524 hr = ID2D1HwndRenderTarget_CreateCompatibleRenderTarget(hwnd_rt, &size, &pixel_size, NULL,
5525 D2D1_COMPATIBLE_RENDER_TARGET_OPTIONS_NONE, &rt);
5526 ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr);
5528 /* Doubled pixel size dimensions with the same DIP size give doubled dpi. */
5529 ID2D1BitmapRenderTarget_GetDpi(rt, dpi2, dpi2 + 1);
5530 ok(dpi[0] == dpi2[0] / 2.0f && dpi[1] == dpi2[1] / 2.0f, "Got dpi mismatch.\n");
5532 ID2D1BitmapRenderTarget_Release(rt);
5534 /* DIP size is specified, fractional. */
5535 set_size_f(&size, 70.1f, 70.4f);
5536 hr = ID2D1HwndRenderTarget_CreateCompatibleRenderTarget(hwnd_rt, &size, NULL, NULL,
5537 D2D1_COMPATIBLE_RENDER_TARGET_OPTIONS_NONE, &rt);
5538 ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr);
5540 ID2D1BitmapRenderTarget_GetDpi(rt, dpi2, dpi2 + 1);
5542 pixel_size = ID2D1BitmapRenderTarget_GetPixelSize(rt);
5543 ok(pixel_size.width == ceilf(size.width * dpi[0] / 96.0f)
5544 && pixel_size.height == ceilf(size.height * dpi[1] / 96.0f), "Wrong pixel size %ux%u\n",
5545 pixel_size.width, pixel_size.height);
5547 dpi[0] *= (pixel_size.width / size.width) * (96.0f / dpi[0]);
5548 dpi[1] *= (pixel_size.height / size.height) * (96.0f / dpi[1]);
5550 ok(compare_float(dpi[0], dpi2[0], 1) && compare_float(dpi[1], dpi2[1], 1), "Got dpi mismatch.\n");
5552 ID2D1HwndRenderTarget_Release(hwnd_rt);
5554 /* Check if GetBitmap() returns same instance. */
5555 hr = ID2D1BitmapRenderTarget_GetBitmap(rt, &bitmap);
5556 ok(SUCCEEDED(hr), "GetBitmap() failed, hr %#x.\n", hr);
5557 hr = ID2D1BitmapRenderTarget_GetBitmap(rt, &bitmap2);
5558 ok(SUCCEEDED(hr), "GetBitmap() failed, hr %#x.\n", hr);
5559 ok(bitmap == bitmap2, "Got different bitmap instances.\n");
5561 /* Draw something, see if bitmap instance is retained. */
5562 ID2D1BitmapRenderTarget_BeginDraw(rt);
5563 set_color(&color, 1.0f, 1.0f, 0.0f, 1.0f);
5564 ID2D1BitmapRenderTarget_Clear(rt, &color);
5565 hr = ID2D1BitmapRenderTarget_EndDraw(rt, NULL, NULL);
5566 ok(SUCCEEDED(hr), "EndDraw() failed, hr %#x.\n", hr);
5568 ID2D1Bitmap_Release(bitmap2);
5569 hr = ID2D1BitmapRenderTarget_GetBitmap(rt, &bitmap2);
5570 ok(SUCCEEDED(hr), "GetBitmap() failed, hr %#x.\n", hr);
5571 ok(bitmap == bitmap2, "Got different bitmap instances.\n");
5573 ID2D1Bitmap_Release(bitmap);
5574 ID2D1Bitmap_Release(bitmap2);
5576 refcount = ID2D1BitmapRenderTarget_Release(rt);
5577 ok(!refcount, "Target should be released, got %u.\n", refcount);
5579 DestroyWindow(hwnd_rt_desc.hwnd);
5581 /* Compatible target created from a DC target without associated HDC */
5582 desc.type = D2D1_RENDER_TARGET_TYPE_DEFAULT;
5583 desc.pixelFormat.format = DXGI_FORMAT_B8G8R8A8_UNORM;
5584 desc.pixelFormat.alphaMode = D2D1_ALPHA_MODE_PREMULTIPLIED;
5585 desc.dpiX = 192.0f;
5586 desc.dpiY = 96.0f;
5587 desc.usage = D2D1_RENDER_TARGET_USAGE_NONE;
5588 desc.minLevel = D2D1_FEATURE_LEVEL_DEFAULT;
5589 hr = ID2D1Factory_CreateDCRenderTarget(factory, &desc, &dc_rt);
5590 ok(SUCCEEDED(hr), "Failed to create target, hr %#x.\n", hr);
5592 test_compatible_target_size((ID2D1RenderTarget *)dc_rt);
5594 hr = ID2D1DCRenderTarget_CreateCompatibleRenderTarget(dc_rt, NULL, NULL, NULL,
5595 D2D1_COMPATIBLE_RENDER_TARGET_OPTIONS_NONE, &rt);
5596 ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr);
5598 pixel_size = ID2D1BitmapRenderTarget_GetPixelSize(rt);
5599 ok(pixel_size.width == 0 && pixel_size.height == 0, "Got wrong size\n");
5601 hr = ID2D1BitmapRenderTarget_GetBitmap(rt, &bitmap);
5602 ok(SUCCEEDED(hr), "GetBitmap() failed, hr %#x.\n", hr);
5603 pixel_size = ID2D1Bitmap_GetPixelSize(bitmap);
5604 ok(pixel_size.width == 0 && pixel_size.height == 0, "Got wrong size\n");
5605 ID2D1Bitmap_Release(bitmap);
5607 ID2D1BitmapRenderTarget_Release(rt);
5608 ID2D1DCRenderTarget_Release(dc_rt);
5610 ID2D1Factory_Release(factory);
5613 static void test_desktop_dpi(void)
5615 ID2D1Factory *factory;
5616 float dpi_x, dpi_y;
5617 HRESULT hr;
5619 hr = D2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED, &IID_ID2D1Factory, NULL, (void **)&factory);
5620 ok(SUCCEEDED(hr), "Failed to create factory, hr %#x.\n", hr);
5622 dpi_x = dpi_y = 0.0f;
5623 ID2D1Factory_GetDesktopDpi(factory, &dpi_x, &dpi_y);
5624 ok(dpi_x > 0.0f && dpi_y > 0.0f, "Got wrong dpi %f x %f.\n", dpi_x, dpi_y);
5626 ID2D1Factory_Release(factory);
5629 static void test_stroke_style(void)
5631 static const struct
5633 D2D1_DASH_STYLE dash_style;
5634 UINT32 dash_count;
5635 float dashes[6];
5637 dash_style_tests[] =
5639 {D2D1_DASH_STYLE_SOLID, 0},
5640 {D2D1_DASH_STYLE_DASH, 2, {2.0f, 2.0f}},
5641 {D2D1_DASH_STYLE_DOT, 2, {0.0f, 2.0f}},
5642 {D2D1_DASH_STYLE_DASH_DOT, 4, {2.0f, 2.0f, 0.0f, 2.0f}},
5643 {D2D1_DASH_STYLE_DASH_DOT_DOT, 6, {2.0f, 2.0f, 0.0f, 2.0f, 0.0f, 2.0f}},
5645 D2D1_STROKE_STYLE_PROPERTIES desc;
5646 ID2D1StrokeStyle *style;
5647 ID2D1Factory *factory;
5648 UINT32 count;
5649 HRESULT hr;
5650 D2D1_CAP_STYLE cap_style;
5651 D2D1_LINE_JOIN line_join;
5652 float miter_limit, dash_offset;
5653 D2D1_DASH_STYLE dash_style;
5654 unsigned int i;
5655 float dashes[2];
5657 hr = D2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED, &IID_ID2D1Factory, NULL, (void **)&factory);
5658 ok(SUCCEEDED(hr), "Failed to create factory, hr %#x.\n", hr);
5660 desc.startCap = D2D1_CAP_STYLE_SQUARE;
5661 desc.endCap = D2D1_CAP_STYLE_ROUND;
5662 desc.dashCap = D2D1_CAP_STYLE_TRIANGLE;
5663 desc.lineJoin = D2D1_LINE_JOIN_BEVEL;
5664 desc.miterLimit = 1.5f;
5665 desc.dashStyle = D2D1_DASH_STYLE_DOT;
5666 desc.dashOffset = -1.0f;
5668 hr = ID2D1Factory_CreateStrokeStyle(factory, &desc, NULL, 0, &style);
5669 ok(SUCCEEDED(hr), "Failed to create stroke style, %#x.\n", hr);
5671 cap_style = ID2D1StrokeStyle_GetStartCap(style);
5672 ok(cap_style == D2D1_CAP_STYLE_SQUARE, "Unexpected cap style %d.\n", cap_style);
5673 cap_style = ID2D1StrokeStyle_GetEndCap(style);
5674 ok(cap_style == D2D1_CAP_STYLE_ROUND, "Unexpected cap style %d.\n", cap_style);
5675 cap_style = ID2D1StrokeStyle_GetDashCap(style);
5676 ok(cap_style == D2D1_CAP_STYLE_TRIANGLE, "Unexpected cap style %d.\n", cap_style);
5677 line_join = ID2D1StrokeStyle_GetLineJoin(style);
5678 ok(line_join == D2D1_LINE_JOIN_BEVEL, "Unexpected line joind %d.\n", line_join);
5679 miter_limit = ID2D1StrokeStyle_GetMiterLimit(style);
5680 ok(miter_limit == 1.5f, "Unexpected miter limit %f.\n", miter_limit);
5681 dash_style = ID2D1StrokeStyle_GetDashStyle(style);
5682 ok(dash_style == D2D1_DASH_STYLE_DOT, "Unexpected dash style %d.\n", dash_style);
5683 dash_offset = ID2D1StrokeStyle_GetDashOffset(style);
5684 ok(dash_offset == -1.0f, "Unexpected dash offset %f.\n", dash_offset);
5686 /* Custom dash pattern, no dashes data specified. */
5687 desc.startCap = D2D1_CAP_STYLE_SQUARE;
5688 desc.endCap = D2D1_CAP_STYLE_ROUND;
5689 desc.dashCap = D2D1_CAP_STYLE_TRIANGLE;
5690 desc.lineJoin = D2D1_LINE_JOIN_BEVEL;
5691 desc.miterLimit = 1.5f;
5692 desc.dashStyle = D2D1_DASH_STYLE_CUSTOM;
5693 desc.dashOffset = 0.0f;
5695 ID2D1StrokeStyle_Release(style);
5697 hr = ID2D1Factory_CreateStrokeStyle(factory, &desc, NULL, 0, &style);
5698 ok(hr == E_INVALIDARG, "Unexpected return value, %#x.\n", hr);
5700 hr = ID2D1Factory_CreateStrokeStyle(factory, &desc, dashes, 0, &style);
5701 ok(hr == E_INVALIDARG, "Unexpected return value, %#x.\n", hr);
5703 hr = ID2D1Factory_CreateStrokeStyle(factory, &desc, dashes, 1, &style);
5704 ok(hr == S_OK, "Unexpected return value, %#x.\n", hr);
5705 ID2D1StrokeStyle_Release(style);
5707 /* Builtin style, dashes are specified. */
5708 desc.dashStyle = D2D1_DASH_STYLE_DOT;
5709 hr = ID2D1Factory_CreateStrokeStyle(factory, &desc, dashes, 1, &style);
5710 ok(hr == E_INVALIDARG, "Unexpected return value, %#x.\n", hr);
5712 /* Invalid style. */
5713 desc.dashStyle = 100;
5714 hr = ID2D1Factory_CreateStrokeStyle(factory, &desc, NULL, 0, &style);
5715 ok(hr == E_INVALIDARG, "Unexpected return value, %#x.\n", hr);
5717 /* Test returned dash pattern for builtin styles. */
5718 desc.startCap = D2D1_CAP_STYLE_SQUARE;
5719 desc.endCap = D2D1_CAP_STYLE_ROUND;
5720 desc.dashCap = D2D1_CAP_STYLE_TRIANGLE;
5721 desc.lineJoin = D2D1_LINE_JOIN_BEVEL;
5722 desc.miterLimit = 1.5f;
5723 desc.dashOffset = 0.0f;
5725 for (i = 0; i < ARRAY_SIZE(dash_style_tests); ++i)
5727 float dashes[10];
5728 UINT dash_count;
5730 desc.dashStyle = dash_style_tests[i].dash_style;
5732 hr = ID2D1Factory_CreateStrokeStyle(factory, &desc, NULL, 0, &style);
5733 ok(SUCCEEDED(hr), "Failed to create stroke style, %#x.\n", hr);
5735 dash_count = ID2D1StrokeStyle_GetDashesCount(style);
5736 ok(dash_count == dash_style_tests[i].dash_count, "%u: unexpected dash count %u, expected %u.\n",
5737 i, dash_count, dash_style_tests[i].dash_count);
5738 ok(dash_count < ARRAY_SIZE(dashes), "%u: unexpectedly large dash count %u.\n", i, dash_count);
5739 if (dash_count == dash_style_tests[i].dash_count)
5741 unsigned int j;
5743 ID2D1StrokeStyle_GetDashes(style, dashes, dash_count);
5744 ok(!memcmp(dashes, dash_style_tests[i].dashes, sizeof(*dashes) * dash_count),
5745 "%u: unexpected dash array.\n", i);
5747 /* Ask for more dashes than style actually has. */
5748 memset(dashes, 0xcc, sizeof(dashes));
5749 ID2D1StrokeStyle_GetDashes(style, dashes, ARRAY_SIZE(dashes));
5750 ok(!memcmp(dashes, dash_style_tests[i].dashes, sizeof(*dashes) * dash_count),
5751 "%u: unexpected dash array.\n", i);
5753 for (j = dash_count; j < ARRAY_SIZE(dashes); ++j)
5754 ok(dashes[j] == 0.0f, "%u: unexpected dash value at %u.\n", i, j);
5757 ID2D1StrokeStyle_Release(style);
5760 /* NULL dashes array, non-zero length. */
5761 memset(&desc, 0, sizeof(desc));
5762 hr = ID2D1Factory_CreateStrokeStyle(factory, &desc, NULL, 1, &style);
5763 ok(SUCCEEDED(hr), "Failed to create stroke style, %#x.\n", hr);
5765 count = ID2D1StrokeStyle_GetDashesCount(style);
5766 ok(count == 0, "Unexpected dashes count %u.\n", count);
5768 ID2D1StrokeStyle_Release(style);
5770 ID2D1Factory_Release(factory);
5773 static void test_gradient(void)
5775 ID2D1GradientStopCollection *gradient;
5776 D2D1_GRADIENT_STOP stops[3], stops2[3];
5777 IDXGISwapChain *swapchain;
5778 ID2D1RenderTarget *rt;
5779 ID3D10Device1 *device;
5780 IDXGISurface *surface;
5781 D2D1_COLOR_F color;
5782 unsigned int i;
5783 UINT32 count;
5784 HWND window;
5785 HRESULT hr;
5787 if (!(device = create_device()))
5789 skip("Failed to create device, skipping tests.\n");
5790 return;
5792 window = create_window();
5793 swapchain = create_swapchain(device, window, TRUE);
5794 hr = IDXGISwapChain_GetBuffer(swapchain, 0, &IID_IDXGISurface, (void **)&surface);
5795 ok(SUCCEEDED(hr), "Failed to get buffer, hr %#x.\n", hr);
5796 rt = create_render_target(surface);
5797 ok(!!rt, "Failed to create render target.\n");
5799 stops2[0].position = 0.5f;
5800 set_color(&stops2[0].color, 1.0f, 1.0f, 0.0f, 1.0f);
5801 stops2[1] = stops2[0];
5802 hr = ID2D1RenderTarget_CreateGradientStopCollection(rt, stops2, 2, D2D1_GAMMA_2_2,
5803 D2D1_EXTEND_MODE_CLAMP, &gradient);
5804 ok(SUCCEEDED(hr), "Failed to create stop collection, hr %#x.\n", hr);
5806 count = ID2D1GradientStopCollection_GetGradientStopCount(gradient);
5807 ok(count == 2, "Unexpected stop count %u.\n", count);
5809 /* Request more stops than collection has. */
5810 stops[0].position = 123.4f;
5811 set_color(&stops[0].color, 1.0f, 0.5f, 0.4f, 1.0f);
5812 color = stops[0].color;
5813 stops[2] = stops[1] = stops[0];
5814 ID2D1GradientStopCollection_GetGradientStops(gradient, stops, ARRAY_SIZE(stops));
5815 ok(!memcmp(stops, stops2, sizeof(*stops) * count), "Unexpected gradient stops array.\n");
5816 for (i = count; i < ARRAY_SIZE(stops); ++i)
5818 ok(stops[i].position == 123.4f, "%u: unexpected stop position %f.\n", i, stops[i].position);
5819 ok(!memcmp(&stops[i].color, &color, sizeof(color)), "%u: unexpected stop color.\n", i);
5822 ID2D1GradientStopCollection_Release(gradient);
5823 ID2D1RenderTarget_Release(rt);
5825 IDXGISurface_Release(surface);
5826 IDXGISwapChain_Release(swapchain);
5827 ID3D10Device1_Release(device);
5828 DestroyWindow(window);
5831 static void test_draw_geometry(void)
5833 ID2D1TransformedGeometry *transformed_geometry[4];
5834 ID2D1RectangleGeometry *rect_geometry[2];
5835 D2D1_POINT_2F point = {0.0f, 0.0f};
5836 D2D1_ROUNDED_RECT rounded_rect;
5837 ID2D1SolidColorBrush *brush;
5838 ID2D1PathGeometry *geometry;
5839 IDXGISwapChain *swapchain;
5840 D2D1_MATRIX_3X2_F matrix;
5841 ID2D1GeometrySink *sink;
5842 ID2D1RenderTarget *rt;
5843 ID3D10Device1 *device;
5844 IDXGISurface *surface;
5845 ID2D1Factory *factory;
5846 D2D1_POINT_2F p0, p1;
5847 D2D1_ELLIPSE ellipse;
5848 D2D1_COLOR_F color;
5849 D2D1_RECT_F rect;
5850 ULONG refcount;
5851 HWND window;
5852 HRESULT hr;
5853 BOOL match;
5855 if (!(device = create_device()))
5857 skip("Failed to create device, skipping tests.\n");
5858 return;
5860 window = create_window();
5861 swapchain = create_swapchain(device, window, TRUE);
5862 hr = IDXGISwapChain_GetBuffer(swapchain, 0, &IID_IDXGISurface, (void **)&surface);
5863 ok(SUCCEEDED(hr), "Failed to get buffer, hr %#x.\n", hr);
5864 rt = create_render_target(surface);
5865 ok(!!rt, "Failed to create render target.\n");
5866 ID2D1RenderTarget_GetFactory(rt, &factory);
5868 ID2D1RenderTarget_SetDpi(rt, 192.0f, 48.0f);
5869 ID2D1RenderTarget_SetAntialiasMode(rt, D2D1_ANTIALIAS_MODE_ALIASED);
5870 set_color(&color, 0.890f, 0.851f, 0.600f, 1.0f);
5871 hr = ID2D1RenderTarget_CreateSolidColorBrush(rt, &color, NULL, &brush);
5872 ok(SUCCEEDED(hr), "Failed to create brush, hr %#x.\n", hr);
5874 ID2D1RenderTarget_BeginDraw(rt);
5875 set_color(&color, 0.396f, 0.180f, 0.537f, 1.0f);
5876 ID2D1RenderTarget_Clear(rt, &color);
5878 set_point(&p0, 40.0f, 160.0f);
5879 ID2D1RenderTarget_DrawLine(rt, p0, p0, (ID2D1Brush *)brush, 10.0f, NULL);
5880 set_point(&p0, 100.0f, 160.0f);
5881 set_point(&p1, 140.0f, 160.0f);
5882 ID2D1RenderTarget_DrawLine(rt, p0, p1, (ID2D1Brush *)brush, 10.0f, NULL);
5883 set_point(&p0, 200.0f, 80.0f);
5884 set_point(&p1, 200.0f, 240.0f);
5885 ID2D1RenderTarget_DrawLine(rt, p0, p1, (ID2D1Brush *)brush, 10.0f, NULL);
5886 set_point(&p0, 260.0f, 240.0f);
5887 set_point(&p1, 300.0f, 80.0f);
5888 ID2D1RenderTarget_DrawLine(rt, p0, p1, (ID2D1Brush *)brush, 10.0f, NULL);
5890 set_rect(&rect, 40.0f, 480.0f, 40.0f, 480.0f);
5891 ID2D1RenderTarget_DrawRectangle(rt, &rect, (ID2D1Brush *)brush, 10.0f, NULL);
5892 set_rect(&rect, 100.0f, 480.0f, 140.0f, 480.0f);
5893 ID2D1RenderTarget_DrawRectangle(rt, &rect, (ID2D1Brush *)brush, 10.0f, NULL);
5894 set_rect(&rect, 200.0f, 400.0f, 200.0f, 560.0f);
5895 ID2D1RenderTarget_DrawRectangle(rt, &rect, (ID2D1Brush *)brush, 10.0f, NULL);
5896 set_rect(&rect, 260.0f, 560.0f, 300.0f, 400.0f);
5897 ID2D1RenderTarget_DrawRectangle(rt, &rect, (ID2D1Brush *)brush, 10.0f, NULL);
5899 set_ellipse(&ellipse, 40.0f, 800.0f, 0.0f, 0.0f);
5900 ID2D1RenderTarget_DrawEllipse(rt, &ellipse, (ID2D1Brush *)brush, 10.0f, NULL);
5901 set_ellipse(&ellipse, 120.0f, 800.0f, 20.0f, 0.0f);
5902 ID2D1RenderTarget_DrawEllipse(rt, &ellipse, (ID2D1Brush *)brush, 10.0f, NULL);
5903 set_ellipse(&ellipse, 200.0f, 800.0f, 0.0f, 80.0f);
5904 ID2D1RenderTarget_DrawEllipse(rt, &ellipse, (ID2D1Brush *)brush, 10.0f, NULL);
5905 set_ellipse(&ellipse, 280.0f, 800.0f, 20.0f, 80.0f);
5906 ID2D1RenderTarget_DrawEllipse(rt, &ellipse, (ID2D1Brush *)brush, 10.0f, NULL);
5908 hr = ID2D1RenderTarget_EndDraw(rt, NULL, NULL);
5909 ok(SUCCEEDED(hr), "Failed to end draw, hr %#x.\n", hr);
5911 match = compare_figure(surface, 0, 0, 160, 160, 0xff652e89, 0, "");
5912 ok(match, "Figure does not match.\n");
5913 match = compare_figure(surface, 160, 0, 160, 160, 0xff652e89, 0, "yGBQUFBQUFBQUFDoYQAA");
5914 ok(match, "Figure does not match.\n");
5915 match = compare_figure(surface, 320, 0, 160, 160, 0xff652e89, 0,
5916 "xjIUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEU"
5917 "jAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEU"
5918 "jAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEU"
5919 "jAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEU"
5920 "jAEUjAEUjAEUjAEUxjIA");
5921 ok(match, "Figure does not match.\n");
5922 match = compare_figure(surface, 480, 0, 160, 160, 0xff652e89, 2,
5923 "zjECnQETjAEVigEVigEVigEVigEVigEVigEVigEVigEVigEVigEVigEVigEVigEVigEVigEVigEV"
5924 "igEVigEVigEVigEVigEVigEVigEVigEVigEVigEVigEVigEVigEVigEVigEVigEVigEVigEVigEV"
5925 "igEVigEVigEVigEVigEVigEVigEVigEVigEVigEVigEVigEVigEVigEVigEVigEVigEVigEVigEV"
5926 "igEVigEVigEVigEVigEVigEVigEVigEVigEVigEVigEVigEVigEVigEVigEVigEVigEVigEVigEV"
5927 "igEVigEVigEVigEVjAETnQECzjEA");
5928 ok(match, "Figure does not match.\n");
5930 match = compare_figure(surface, 0, 160, 160, 160, 0xff652e89, 0, "5mAUjAEUjAEUjAEUjAEUhmIA");
5931 ok(match, "Figure does not match.\n");
5932 match = compare_figure(surface, 160, 160, 160, 160, 0xff652e89, 0, "vmBkPGQ8ZDxkPGTeYQAA");
5933 ok(match, "Figure does not match.\n");
5934 match = compare_figure(surface, 320, 160, 160, 160, 0xff652e89, 0,
5935 "5i4UjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEU"
5936 "jAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEU"
5937 "jAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEU"
5938 "jAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEU"
5939 "jAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUhjAA");
5940 ok(match, "Figure does not match.\n");
5941 match = compare_figure(surface, 480, 160, 160, 160, 0xff652e89, 0,
5942 "vi5kPGQ8ZDxkPGQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwU"
5943 "PBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8"
5944 "FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwU"
5945 "PBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8"
5946 "FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwU"
5947 "PBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8ZDxkPGQ8ZDxk3i8A");
5948 ok(match, "Figure does not match.\n");
5950 match = compare_figure(surface, 0, 320, 160, 160, 0xff652e89, 0, "iGIQjgEUjAEUjgEQiGIA");
5951 todo_wine ok(match, "Figure does not match.\n");
5952 match = compare_figure(surface, 160, 320, 160, 160, 0xff652e89, 0, "yGBQSGA+ZDxkPmDgYQAA");
5953 todo_wine ok(match, "Figure does not match.\n");
5954 match = compare_figure(surface, 320, 320, 160, 160, 0xff652e89, 0,
5955 "iDAQjgEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEU"
5956 "jAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEU"
5957 "jAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEU"
5958 "jAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEU"
5959 "jAEUjAEUjAEUjAEUjAEUjAEUjAEUjgEQiDAA");
5960 todo_wine ok(match, "Figure does not match.\n");
5961 match = compare_figure(surface, 480, 320, 160, 160, 0xff652e89, 10,
5962 "hDAYgwEieyh1LnAybBcIF2gWDhZkFhIWYRUWFV4VGhVbFRwVWRUeFVcVIBVVFCQUUxQmFFEUKBRP"
5963 "FSgVTRUqFUwULBRLFC4USRQwFEgUMBRHFDIURhQyFEUUNBREFDQUQxQ2FEIUNhRBFDgUQBQ4FEAU"
5964 "OBQ/FDoUPhQ6FD4UOhQ+FDoUPhQ6FD0UPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8"
5965 "FDwUPBQ8FDwUPBQ8FD0UOhQ+FDoUPhQ6FD4UOhQ+FDoUPxQ4FEAUOBRAFDgUQRQ2FEIUNhRDFDQU"
5966 "RBQ0FEUUMhRGFDIURxQwFEgUMBRJFC4USxQsFEwVKhVNFSgVTxQoFFEUJhRTFCQUVRUgFVcVHhVZ"
5967 "FRwVWxUaFV4VFhVhFhIWZBYOFmgXCBdsMnAudSh7IoMBGIQw");
5968 todo_wine ok(match, "Figure does not match.\n");
5970 ID2D1RenderTarget_BeginDraw(rt);
5971 set_color(&color, 0.396f, 0.180f, 0.537f, 1.0f);
5972 ID2D1RenderTarget_Clear(rt, &color);
5974 set_rounded_rect(&rounded_rect, 40.0f, 160.0f, 40.0f, 160.0f, 10.0f, 10.0f);
5975 ID2D1RenderTarget_DrawRoundedRectangle(rt, &rounded_rect, (ID2D1Brush *)brush, 10.0f, NULL);
5976 set_rounded_rect(&rounded_rect, 100.0f, 160.0f, 140.0f, 160.0f, 10.0f, 10.0f);
5977 ID2D1RenderTarget_DrawRoundedRectangle(rt, &rounded_rect, (ID2D1Brush *)brush, 10.0f, NULL);
5978 set_rounded_rect(&rounded_rect, 200.0f, 80.0f, 200.0f, 240.0f, 10.0f, 10.0f);
5979 ID2D1RenderTarget_DrawRoundedRectangle(rt, &rounded_rect, (ID2D1Brush *)brush, 10.0f, NULL);
5980 set_rounded_rect(&rounded_rect, 260.0f, 240.0f, 300.0f, 80.0f, 10.0f, 10.0f);
5981 ID2D1RenderTarget_DrawRoundedRectangle(rt, &rounded_rect, (ID2D1Brush *)brush, 10.0f, NULL);
5983 set_rounded_rect(&rounded_rect, 40.0f, 480.0f, 40.0f, 480.0f, 10.0f, 20.0f);
5984 ID2D1RenderTarget_DrawRoundedRectangle(rt, &rounded_rect, (ID2D1Brush *)brush, 10.0f, NULL);
5985 set_rounded_rect(&rounded_rect, 100.0f, 480.0f, 140.0f, 480.0f, 10.0f, 20.0f);
5986 ID2D1RenderTarget_DrawRoundedRectangle(rt, &rounded_rect, (ID2D1Brush *)brush, 10.0f, NULL);
5987 set_rounded_rect(&rounded_rect, 200.0f, 400.0f, 200.0f, 560.0f, 10.0f, 20.0f);
5988 ID2D1RenderTarget_DrawRoundedRectangle(rt, &rounded_rect, (ID2D1Brush *)brush, 10.0f, NULL);
5989 set_rounded_rect(&rounded_rect, 260.0f, 560.0f, 300.0f, 400.0f, 10.0f, 20.0f);
5990 ID2D1RenderTarget_DrawRoundedRectangle(rt, &rounded_rect, (ID2D1Brush *)brush, 10.0f, NULL);
5992 set_rounded_rect(&rounded_rect, 40.0f, 800.0f, 40.0f, 800.0f, 10.0f, 5.0f);
5993 ID2D1RenderTarget_DrawRoundedRectangle(rt, &rounded_rect, (ID2D1Brush *)brush, 10.0f, NULL);
5994 set_rounded_rect(&rounded_rect, 100.0f, 800.0f, 140.0f, 800.0f, 10.0f, 5.0f);
5995 ID2D1RenderTarget_DrawRoundedRectangle(rt, &rounded_rect, (ID2D1Brush *)brush, 10.0f, NULL);
5996 set_rounded_rect(&rounded_rect, 200.0f, 720.0f, 200.0f, 880.0f, 10.0f, 5.0f);
5997 ID2D1RenderTarget_DrawRoundedRectangle(rt, &rounded_rect, (ID2D1Brush *)brush, 10.0f, NULL);
5998 set_rounded_rect(&rounded_rect, 260.0f, 880.0f, 300.0f, 720.0f, 10.0f, 5.0f);
5999 ID2D1RenderTarget_DrawRoundedRectangle(rt, &rounded_rect, (ID2D1Brush *)brush, 10.0f, NULL);
6001 hr = ID2D1RenderTarget_EndDraw(rt, NULL, NULL);
6002 ok(SUCCEEDED(hr), "Failed to end draw, hr %#x.\n", hr);
6004 match = compare_figure(surface, 0, 0, 160, 160, 0xff652e89, 0, "iGIQjgEUjAEUjgEQiGIA");
6005 todo_wine ok(match, "Figure does not match.\n");
6006 match = compare_figure(surface, 160, 0, 160, 160, 0xff652e89, 0, "yGBQSGA+ZDxkPmDgYQAA");
6007 todo_wine ok(match, "Figure does not match.\n");
6008 match = compare_figure(surface, 320, 0, 160, 160, 0xff652e89, 0,
6009 "iDAQjgEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEU"
6010 "jAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEU"
6011 "jAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEU"
6012 "jAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEU"
6013 "jAEUjAEUjAEUjAEUjAEUjAEUjAEUjgEQiDAA");
6014 todo_wine ok(match, "Figure does not match.\n");
6015 match = compare_figure(surface, 480, 0, 160, 160, 0xff652e89, 0,
6016 "3C4oaUZVUExYRlxCHCgcPxU4FT0UPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwU"
6017 "PBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8"
6018 "FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwU"
6019 "PBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8"
6020 "FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwU"
6021 "PBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FD0VOBU/YEJcRlhMUFVG7S8A");
6022 todo_wine ok(match, "Figure does not match.\n");
6024 match = compare_figure(surface, 0, 160, 160, 160, 0xff652e89, 0, "iGIQjgEUjAEUjgEQiGIA");
6025 todo_wine ok(match, "Figure does not match.\n");
6026 match = compare_figure(surface, 160, 160, 160, 160, 0xff652e89, 0, "yGBQSGA+ZDxkPmDgYQAA");
6027 todo_wine ok(match, "Figure does not match.\n");
6028 match = compare_figure(surface, 320, 160, 160, 160, 0xff652e89, 0,
6029 "iDAQjgEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEU"
6030 "jAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEU"
6031 "jAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEU"
6032 "jAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEU"
6033 "jAEUjAEUjAEUjAEUjAEUjAEUjAEUjgEQiDAA");
6034 todo_wine ok(match, "Figure does not match.\n");
6035 match = compare_figure(surface, 480, 160, 160, 160, 0xff652e89, 8,
6036 "3C4obT5dSFRQTlRKGCgYRhYwFkMVNBVBFTYVPxU5FD4UOhQ9FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwU"
6037 "PBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8"
6038 "FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwU"
6039 "PBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8"
6040 "FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwU"
6041 "PBQ8FDwUPRQ6FD4UOhQ/FTYVQRU0FUMWMBZGWEpVTVBTSltA8C8A");
6042 todo_wine ok(match, "Figure does not match.\n");
6044 match = compare_figure(surface, 0, 320, 160, 160, 0xff652e89, 0, "iGIQjgEUjAEUjgEQiGIA");
6045 todo_wine ok(match, "Figure does not match.\n");
6046 match = compare_figure(surface, 160, 320, 160, 160, 0xff652e89, 0, "yGBQSGA+ZDxkPmDgYQAA");
6047 todo_wine ok(match, "Figure does not match.\n");
6048 match = compare_figure(surface, 320, 320, 160, 160, 0xff652e89, 0,
6049 "iDAQjgEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEU"
6050 "jAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEU"
6051 "jAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEU"
6052 "jAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEU"
6053 "jAEUjAEUjAEUjAEUjAEUjAEUjAEUjgEQiDAA");
6054 todo_wine ok(match, "Figure does not match.\n");
6055 match = compare_figure(surface, 480, 320, 160, 160, 0xff652e89, 0,
6056 "3C4oZU5NWERgP2I9HigePBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwU"
6057 "PBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8"
6058 "FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwU"
6059 "PBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8"
6060 "FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwU"
6061 "PBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8ZD1iP2BEWE1O6S8A");
6062 todo_wine ok(match, "Figure does not match.\n");
6064 ID2D1RenderTarget_BeginDraw(rt);
6065 set_color(&color, 0.396f, 0.180f, 0.537f, 1.0f);
6066 ID2D1RenderTarget_Clear(rt, &color);
6068 set_rounded_rect(&rounded_rect, 40.0f, 160.0f, 40.0f, 160.0f, 1000.0f, 1000.0f);
6069 ID2D1RenderTarget_DrawRoundedRectangle(rt, &rounded_rect, (ID2D1Brush *)brush, 10.0f, NULL);
6070 set_rounded_rect(&rounded_rect, 100.0f, 160.0f, 140.0f, 160.0f, 1000.0f, 1000.0f);
6071 ID2D1RenderTarget_DrawRoundedRectangle(rt, &rounded_rect, (ID2D1Brush *)brush, 10.0f, NULL);
6072 set_rounded_rect(&rounded_rect, 200.0f, 80.0f, 200.0f, 240.0f, 1000.0f, 1000.0f);
6073 ID2D1RenderTarget_DrawRoundedRectangle(rt, &rounded_rect, (ID2D1Brush *)brush, 10.0f, NULL);
6074 set_rounded_rect(&rounded_rect, 260.0f, 240.0f, 300.0f, 80.0f, 1000.0f, 1000.0f);
6075 ID2D1RenderTarget_DrawRoundedRectangle(rt, &rounded_rect, (ID2D1Brush *)brush, 10.0f, NULL);
6077 set_rounded_rect(&rounded_rect, 40.0f, 480.0f, 40.0f, 480.0f, 10.0f, 1000.0f);
6078 ID2D1RenderTarget_DrawRoundedRectangle(rt, &rounded_rect, (ID2D1Brush *)brush, 10.0f, NULL);
6079 set_rounded_rect(&rounded_rect, 100.0f, 480.0f, 140.0f, 480.0f, 10.0f, 1000.0f);
6080 ID2D1RenderTarget_DrawRoundedRectangle(rt, &rounded_rect, (ID2D1Brush *)brush, 10.0f, NULL);
6081 set_rounded_rect(&rounded_rect, 200.0f, 400.0f, 200.0f, 560.0f, 10.0f, 1000.0f);
6082 ID2D1RenderTarget_DrawRoundedRectangle(rt, &rounded_rect, (ID2D1Brush *)brush, 10.0f, NULL);
6083 set_rounded_rect(&rounded_rect, 260.0f, 560.0f, 300.0f, 400.0f, 10.0f, 1000.0f);
6084 ID2D1RenderTarget_DrawRoundedRectangle(rt, &rounded_rect, (ID2D1Brush *)brush, 10.0f, NULL);
6086 set_rounded_rect(&rounded_rect, 40.0f, 800.0f, 40.0f, 800.0f, 1000.0f, 10.0f);
6087 ID2D1RenderTarget_DrawRoundedRectangle(rt, &rounded_rect, (ID2D1Brush *)brush, 10.0f, NULL);
6088 set_rounded_rect(&rounded_rect, 100.0f, 800.0f, 140.0f, 800.0f, 1000.0f, 10.0f);
6089 ID2D1RenderTarget_DrawRoundedRectangle(rt, &rounded_rect, (ID2D1Brush *)brush, 10.0f, NULL);
6090 set_rounded_rect(&rounded_rect, 200.0f, 720.0f, 200.0f, 880.0f, 1000.0f, 10.0f);
6091 ID2D1RenderTarget_DrawRoundedRectangle(rt, &rounded_rect, (ID2D1Brush *)brush, 10.0f, NULL);
6092 set_rounded_rect(&rounded_rect, 260.0f, 880.0f, 300.0f, 720.0f, 1000.0f, 10.0f);
6093 ID2D1RenderTarget_DrawRoundedRectangle(rt, &rounded_rect, (ID2D1Brush *)brush, 10.0f, NULL);
6095 hr = ID2D1RenderTarget_EndDraw(rt, NULL, NULL);
6096 ok(SUCCEEDED(hr), "Failed to end draw, hr %#x.\n", hr);
6098 match = compare_figure(surface, 0, 0, 160, 160, 0xff652e89, 0, "iGIQjgEUjAEUjgEQiGIA");
6099 todo_wine ok(match, "Figure does not match.\n");
6100 match = compare_figure(surface, 160, 0, 160, 160, 0xff652e89, 0, "yGBQSGA+ZDxkPmDgYQAA");
6101 todo_wine ok(match, "Figure does not match.\n");
6102 match = compare_figure(surface, 320, 0, 160, 160, 0xff652e89, 0,
6103 "iDAQjgEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEU"
6104 "jAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEU"
6105 "jAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEU"
6106 "jAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEUjAEU"
6107 "jAEUjAEUjAEUjAEUjAEUjAEUjAEUjgEQiDAA");
6108 todo_wine ok(match, "Figure does not match.\n");
6109 match = compare_figure(surface, 480, 0, 160, 160, 0xff652e89, 16,
6110 "hDAYgwEieyh1LnAybBcIF2gWDhZkFhIWYRUWFV4WGRVbFRwVWRUeFVcVIBVVFSMUUxQmFFEVJxRP"
6111 "FSgVTRUqFUwULBRLFC4USRUvFEgUMBRHFDIURhQyFEUUNBREFDQUQxQ2FEIUNhRBFDgUQBQ4FEAU"
6112 "OBQ/FTkUPhQ6FD4UOhQ+FDoUPhQ6FD0UPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8"
6113 "FDwUPBQ8FDwUPBQ8FD0UOhQ+FDoUPhQ6FD4UOhQ+FDoUPxQ4FEAUOBRAFDgUQRQ2FEIUNhRDFDQU"
6114 "RBQ0FEUUMhRGFDIURxQwFEgUMBRJFC4USxQsFEwVKhVNFSgVTxQoFFEUJhRTFCQUVRUgFVcVHhVZ"
6115 "FRwVWxUaFV4VFhVhFhIWZBYOFmgWChZsMnAudCp6IoMBGIQw");
6116 todo_wine ok(match, "Figure does not match.\n");
6118 match = compare_figure(surface, 0, 160, 160, 160, 0xff652e89, 0, "iGIQjgEUjAEUjgEQiGIA");
6119 todo_wine ok(match, "Figure does not match.\n");
6120 match = compare_figure(surface, 160, 160, 160, 160, 0xff652e89, 0, "yGBQSGA+ZDxkPmDgYQAA");
6121 todo_wine ok(match, "Figure does not match.\n");
6122 match = compare_figure(surface, 320, 160, 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(surface, 480, 160, 160, 160, 0xff652e89, 16,
6130 "3C4obzpjQF5EWkhXFSAVVRQkFFMUJhRRFCgUTxQqFE0VKhVMFCwUSxQuFEoULhVIFDAUSBQwFUYU"
6131 "MhRGFDIURRQ0FEQUNBRDFTQVQhQ2FEIUNhRCFDYUQRQ4FEAUOBRAFDgUQBQ4FD8UOhQ+FDoUPhQ6"
6132 "FD4UOhQ+FDoUPhQ6FD0VOxQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwU"
6133 "PBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBU7FD0UOhQ+FDoUPhQ6FD4UOhQ+FDoUPhQ6FD8UOBRA"
6134 "FDgUQBQ4FEAUOBRBFDYUQhQ2FEIUNhRCFTQVQxQ0FEQUNBRFFDIURhQyFEYVMBVHFDAUSBUuFUkU"
6135 "LhRLFCwUTBUrFE0UKhRPFCgUURQmFFMUJBRVSldIWUZdQWI78i8A");
6136 todo_wine ok(match, "Figure does not match.\n");
6138 match = compare_figure(surface, 0, 320, 160, 160, 0xff652e89, 0, "iGIQjgEUjAEUjgEQiGIA");
6139 todo_wine ok(match, "Figure does not match.\n");
6140 match = compare_figure(surface, 160, 320, 160, 160, 0xff652e89, 0, "yGBQSGA+ZDxkPmDgYQAA");
6141 todo_wine ok(match, "Figure does not match.\n");
6142 match = compare_figure(surface, 320, 320, 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(surface, 480, 320, 160, 160, 0xff652e89, 8,
6150 "9i80ZERWUExYRV5AHCocPRY4FjwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwU"
6151 "PBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8"
6152 "FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwU"
6153 "PBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8"
6154 "FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwU"
6155 "PBQ8FDwUPBQ8FDwUPBQ8FToVPRssG0BeRFpLUFVGYzT2LwAA");
6156 todo_wine ok(match, "Figure does not match.\n");
6158 hr = ID2D1Factory_CreatePathGeometry(factory, &geometry);
6159 ok(SUCCEEDED(hr), "Failed to create path geometry, hr %#x.\n", hr);
6160 hr = ID2D1PathGeometry_Open(geometry, &sink);
6161 ok(SUCCEEDED(hr), "Failed to open geometry sink, hr %#x.\n", hr);
6163 set_point(&point, 40.0f, 160.0f);
6164 ID2D1GeometrySink_BeginFigure(sink, point, D2D1_FIGURE_BEGIN_FILLED);
6165 ID2D1GeometrySink_EndFigure(sink, D2D1_FIGURE_END_OPEN);
6167 set_point(&point, 120.0f, 160.0f);
6168 ID2D1GeometrySink_BeginFigure(sink, point, D2D1_FIGURE_BEGIN_FILLED);
6169 line_to(sink, 120.0f, 160.0f);
6170 ID2D1GeometrySink_EndFigure(sink, D2D1_FIGURE_END_OPEN);
6172 set_point(&point, 200.0f, 160.0f);
6173 ID2D1GeometrySink_BeginFigure(sink, point, D2D1_FIGURE_BEGIN_FILLED);
6174 ID2D1GeometrySink_EndFigure(sink, D2D1_FIGURE_END_CLOSED);
6176 set_point(&point, 280.0f, 160.0f);
6177 ID2D1GeometrySink_BeginFigure(sink, point, D2D1_FIGURE_BEGIN_FILLED);
6178 line_to(sink, 280.0f, 160.0f);
6179 ID2D1GeometrySink_EndFigure(sink, D2D1_FIGURE_END_CLOSED);
6181 set_point(&point, 20.0f, 480.0f);
6182 ID2D1GeometrySink_BeginFigure(sink, point, D2D1_FIGURE_BEGIN_FILLED);
6183 line_to(sink, 60.0f, 480.0f);
6184 ID2D1GeometrySink_EndFigure(sink, D2D1_FIGURE_END_OPEN);
6186 set_point(&point, 120.0f, 400.0f);
6187 ID2D1GeometrySink_BeginFigure(sink, point, D2D1_FIGURE_BEGIN_FILLED);
6188 line_to(sink, 120.0f, 560.0f);
6189 line_to(sink, 120.0f, 400.0f);
6190 line_to(sink, 120.0f, 560.0f);
6191 ID2D1GeometrySink_EndFigure(sink, D2D1_FIGURE_END_OPEN);
6193 set_point(&point, 180.0f, 480.0f);
6194 ID2D1GeometrySink_BeginFigure(sink, point, D2D1_FIGURE_BEGIN_FILLED);
6195 line_to(sink, 220.0f, 480.0f);
6196 ID2D1GeometrySink_EndFigure(sink, D2D1_FIGURE_END_CLOSED);
6198 set_point(&point, 280.0f, 400.0f);
6199 ID2D1GeometrySink_BeginFigure(sink, point, D2D1_FIGURE_BEGIN_FILLED);
6200 line_to(sink, 280.0f, 560.0f);
6201 line_to(sink, 280.0f, 400.0f);
6202 line_to(sink, 280.0f, 560.0f);
6203 ID2D1GeometrySink_EndFigure(sink, D2D1_FIGURE_END_CLOSED);
6205 set_point(&point, 20.0f, 880.0f);
6206 ID2D1GeometrySink_BeginFigure(sink, point, D2D1_FIGURE_BEGIN_FILLED);
6207 line_to(sink, 40.0f, 720.0f);
6208 line_to(sink, 60.0f, 880.0f);
6209 ID2D1GeometrySink_EndFigure(sink, D2D1_FIGURE_END_OPEN);
6211 set_point(&point, 100.0f, 720.0f);
6212 ID2D1GeometrySink_BeginFigure(sink, point, D2D1_FIGURE_BEGIN_FILLED);
6213 line_to(sink, 120.0f, 880.0f);
6214 line_to(sink, 140.0f, 720.0f);
6215 ID2D1GeometrySink_EndFigure(sink, D2D1_FIGURE_END_OPEN);
6217 set_point(&point, 180.0f, 880.0f);
6218 ID2D1GeometrySink_BeginFigure(sink, point, D2D1_FIGURE_BEGIN_FILLED);
6219 line_to(sink, 200.0f, 720.0f);
6220 line_to(sink, 220.0f, 880.0f);
6221 ID2D1GeometrySink_EndFigure(sink, D2D1_FIGURE_END_CLOSED);
6223 set_point(&point, 260.0f, 720.0f);
6224 ID2D1GeometrySink_BeginFigure(sink, point, D2D1_FIGURE_BEGIN_FILLED);
6225 line_to(sink, 280.0f, 880.0f);
6226 line_to(sink, 300.0f, 720.0f);
6227 ID2D1GeometrySink_EndFigure(sink, D2D1_FIGURE_END_CLOSED);
6229 ID2D1GeometrySink_SetFillMode(sink, D2D1_FILL_MODE_ALTERNATE);
6230 hr = ID2D1GeometrySink_Close(sink);
6231 ok(SUCCEEDED(hr), "Failed to close geometry sink, hr %#x.\n", hr);
6232 ID2D1GeometrySink_Release(sink);
6234 ID2D1RenderTarget_BeginDraw(rt);
6235 ID2D1RenderTarget_Clear(rt, &color);
6236 ID2D1RenderTarget_DrawGeometry(rt, (ID2D1Geometry *)geometry, (ID2D1Brush *)brush, 5.0f, NULL);
6237 hr = ID2D1RenderTarget_EndDraw(rt, NULL, NULL);
6238 ok(SUCCEEDED(hr), "Failed to end draw, hr %#x.\n", hr);
6239 ID2D1PathGeometry_Release(geometry);
6241 match = compare_figure(surface, 0, 0, 160, 160, 0xff652e89, 0, "");
6242 ok(match, "Figure does not match.\n");
6243 match = compare_figure(surface, 160, 0, 160, 160, 0xff652e89, 0, "");
6244 ok(match, "Figure does not match.\n");
6245 match = compare_figure(surface, 320, 0, 160, 160, 0xff652e89, 0, "");
6246 ok(match, "Figure does not match.\n");
6247 match = compare_figure(surface, 480, 0, 160, 160, 0xff652e89, 0, "q2MKlgEKq2MA");
6248 todo_wine ok(match, "Figure does not match.\n");
6250 match = compare_figure(surface, 0, 160, 160, 160, 0xff652e89, 0, "iGNQUFCIYwAA");
6251 ok(match, "Figure does not match.\n");
6252 match = compare_figure(surface, 160, 160, 160, 160, 0xff652e89, 0,
6253 "qyIKlgEKlgEKlgEKlgEKlgEKlgEKlgEKlgEKlgEKlgEKlgEKlgEKlgEKlgEKlgEKlgEKlgEKlgEK"
6254 "lgEKlgEKlgEKlgEKlgEKlgEKlgEKlgEKlgEKlgEKlgEKlgEKlgEKlgEKlgEKlgEKlgEKlgEKlgEK"
6255 "lgEKlgEKlgEKlgEKlgEKlgEKlgEKlgEKlgEKlgEKlgEKlgEKlgEKlgEKlgEKQQpLCkEKSwqWAQqW"
6256 "AQqWAQqWAQqWAQqWAQqWAQqWAQqWAQqWAQqWAQqWAQqWAQqWAQqWAQqWAQqWAQqWAQqWAQqWAQqW"
6257 "AQqWAQqWAQqWAQqWAQqWAQqWAQqWAQqWAQqWAQqWAQqWAQqWAQqWAQqWAQqWAQqWAQqWAQqWAQqW"
6258 "AQqWAQqWAQqWAQqWAQqWAQqWAQqWAQqWAQqWAQqWAQrLIwAA");
6259 ok(match, "Figure does not match.\n");
6260 match = compare_figure(surface, 320, 160, 160, 160, 0xff652e89, 0, "4GLAAuBi");
6261 ok(match, "Figure does not match.\n");
6262 match = compare_figure(surface, 480, 160, 160, 160, 0xff652e89, 0,
6263 "qyIKlgEKlgEKlgEKlgEKlgEKlgEKlgEKlgEKlgEKlgEKlgEKlgEKlgEKlgEKlgEKlgEKlgEKlgEK"
6264 "lgEKlgEKlgEKlgEKlgEKlgEKlgEKlgEKlgEKlgEKlgEKlgEKlgEKlgEKlgEKlgEKlgEKlgEKlgEK"
6265 "lgEKlgEKlgEKlgEKlgEKlgEKlgEKlgEKlgEKlgEKlgEKlgEKlgEKlgEKSwpBCksKQQqWAQqWAQqW"
6266 "AQqWAQqWAQqWAQqWAQqWAQqWAQqWAQqWAQqWAQqWAQqWAQqWAQqWAQqWAQqWAQqWAQqWAQqWAQqW"
6267 "AQqWAQqWAQqWAQqWAQqWAQqWAQqWAQqWAQqWAQqWAQqWAQqWAQqWAQqWAQqWAQqWAQqWAQqWAQqW"
6268 "AQqWAQqWAQqWAQqWAQqWAQqWAQqWAQqWAQqWAQqWAQrLIwAA");
6269 ok(match, "Figure does not match.\n");
6271 match = compare_figure(surface, 0, 320, 160, 160, 0xff652e89, 0,
6272 "rycCngECnQEEnAEEmwEGmgEGmQEImAEIlwEKlgEKlQEMlAEMkwEOkgEOkQEQkAEQjwESjgESjQEU"
6273 "jAEUiwEKAgqKAQoCCokBCgQKiAEKBAqHAQoGCoYBCgYKhQEKCAqEAQoICoMBCgoKggEKCgqBAQoM"
6274 "CoABCgwKfwoOCn4KDgp9ChAKfAoQCnsKEgp6ChIKeQoUCngKFAp3ChYKdgoWCnUKGAp0ChgKcwoa"
6275 "CnIKGgpxChwKcAocCm8KHgpuCh4KbQogCmwKIAprCiIKagoiCmkKJApoCiQKZwomCmYKJgplCigK"
6276 "ZAooCmMKKgpiCioKYQosCmAKLApfCi4KXgouCl0KMApcCjAKWwoyCloKMgpZCjQKWAo0ClcKNgpW"
6277 "CjYKVQo4ClQKOApTCjoKUgo6ClEKPApQCjwKTwo+Ck4KPgpNCkAKTApACksKQgpKCkIKSQpECkgK"
6278 "RApHCkYKozIA");
6279 ok(match, "Figure does not match.\n");
6280 match = compare_figure(surface, 160, 320, 160, 160, 0xff652e89, 0,
6281 "ozIKRgpHCkQKSApECkkKQgpKCkIKSwpACkwKQApNCj4KTgo+Ck8KPApQCjwKUQo6ClIKOgpTCjgK"
6282 "VAo4ClUKNgpWCjYKVwo0ClgKNApZCjIKWgoyClsKMApcCjAKXQouCl4KLgpfCiwKYAosCmEKKgpi"
6283 "CioKYwooCmQKKAplCiYKZgomCmcKJApoCiQKaQoiCmoKIgprCiAKbAogCm0KHgpuCh4KbwocCnAK"
6284 "HApxChoKcgoaCnMKGAp0ChgKdQoWCnYKFgp3ChQKeAoUCnkKEgp6ChIKewoQCnwKEAp9Cg4KfgoO"
6285 "Cn8KDAqAAQoMCoEBCgoKggEKCgqDAQoICoQBCggKhQEKBgqGAQoGCocBCgQKiAEKBAqJAQoCCooB"
6286 "CgIKiwEUjAEUjQESjgESjwEQkAEQkQEOkgEOkwEMlAEMlQEKlgEKlwEImAEImQEGmgEGmwEEnAEE"
6287 "nQECngECrycA");
6288 ok(match, "Figure does not match.\n");
6289 match = compare_figure(surface, 320, 320, 160, 160, 0xff652e89, 0,
6290 "rycCngECnQEEnAEEmwEGmgEGmQEImAEIlwEKlgEKlQEMlAEMkwEOkgEOkQEQkAEQjwESjgESjQEU"
6291 "jAEUiwEKAgqKAQoCCokBCgQKiAEKBAqHAQoGCoYBCgYKhQEKCAqEAQoICoMBCgoKggEKCgqBAQoM"
6292 "CoABCgwKfwoOCn4KDgp9ChAKfAoQCnsKEgp6ChIKeQoUCngKFAp3ChYKdgoWCnUKGAp0ChgKcwoa"
6293 "CnIKGgpxChwKcAocCm8KHgpuCh4KbQogCmwKIAprCiIKagoiCmkKJApoCiQKZwomCmYKJgplCigK"
6294 "ZAooCmMKKgpiCioKYQosCmAKLApfCi4KXgouCl0KMApcCjAKWwoyCloKMgpZCjQKWAo0ClcKNgpW"
6295 "CjYKVQo4ClQKOApTCjoKUgo6ClEKPApQCjwKTwo+Ck4KPgpNCkAKTApACksKQgpKCkIKSQpECkgK"
6296 "RApHWkZagzEA");
6297 ok(match, "Figure does not match.\n");
6298 match = compare_figure(surface, 480, 320, 160, 160, 0xff652e89, 0,
6299 "gzFaRlpHCkQKSApECkkKQgpKCkIKSwpACkwKQApNCj4KTgo+Ck8KPApQCjwKUQo6ClIKOgpTCjgK"
6300 "VAo4ClUKNgpWCjYKVwo0ClgKNApZCjIKWgoyClsKMApcCjAKXQouCl4KLgpfCiwKYAosCmEKKgpi"
6301 "CioKYwooCmQKKAplCiYKZgomCmcKJApoCiQKaQoiCmoKIgprCiAKbAogCm0KHgpuCh4KbwocCnAK"
6302 "HApxChoKcgoaCnMKGAp0ChgKdQoWCnYKFgp3ChQKeAoUCnkKEgp6ChIKewoQCnwKEAp9Cg4KfgoO"
6303 "Cn8KDAqAAQoMCoEBCgoKggEKCgqDAQoICoQBCggKhQEKBgqGAQoGCocBCgQKiAEKBAqJAQoCCooB"
6304 "CgIKiwEUjAEUjQESjgESjwEQkAEQkQEOkgEOkwEMlAEMlQEKlgEKlwEImAEImQEGmgEGmwEEnAEE"
6305 "nQECngECrycA");
6306 ok(match, "Figure does not match.\n");
6308 set_rect(&rect, 20.0f, 80.0f, 60.0f, 240.0f);
6309 hr = ID2D1Factory_CreateRectangleGeometry(factory, &rect, &rect_geometry[0]);
6310 ok(SUCCEEDED(hr), "Failed to create geometry, hr %#x.\n", hr);
6312 set_rect(&rect, -1.0f, -1.0f, 1.0f, 1.0f);
6313 hr = ID2D1Factory_CreateRectangleGeometry(factory, &rect, &rect_geometry[1]);
6314 ok(SUCCEEDED(hr), "Failed to create geometry, hr %#x.\n", hr);
6316 set_matrix_identity(&matrix);
6317 translate_matrix(&matrix, 160.0f, 640.0f);
6318 scale_matrix(&matrix, 40.0f, 160.0f);
6319 rotate_matrix(&matrix, M_PI / -5.0f);
6320 hr = ID2D1Factory_CreateTransformedGeometry(factory,
6321 (ID2D1Geometry *)rect_geometry[1], &matrix, &transformed_geometry[0]);
6322 ok(SUCCEEDED(hr), "Failed to create geometry, hr %#x.\n", hr);
6324 set_matrix_identity(&matrix);
6325 scale_matrix(&matrix, 0.5f, 1.0f);
6326 translate_matrix(&matrix, -80.0f, 0.0f);
6327 hr = ID2D1Factory_CreateTransformedGeometry(factory,
6328 (ID2D1Geometry *)transformed_geometry[0], &matrix, &transformed_geometry[1]);
6329 ok(SUCCEEDED(hr), "Failed to create geometry, hr %#x.\n", hr);
6331 set_matrix_identity(&matrix);
6332 rotate_matrix(&matrix, M_PI / 2.0f);
6333 translate_matrix(&matrix, 80.0f, -320.0f);
6334 scale_matrix(&matrix, 2.0f, 0.25f);
6335 hr = ID2D1Factory_CreateTransformedGeometry(factory,
6336 (ID2D1Geometry *)transformed_geometry[1], &matrix, &transformed_geometry[2]);
6337 ok(SUCCEEDED(hr), "Failed to create geometry, hr %#x.\n", hr);
6339 ID2D1RenderTarget_BeginDraw(rt);
6340 ID2D1RenderTarget_Clear(rt, &color);
6341 ID2D1RenderTarget_DrawGeometry(rt, (ID2D1Geometry *)rect_geometry[0], (ID2D1Brush *)brush, 10.0f, NULL);
6342 ID2D1RenderTarget_DrawGeometry(rt, (ID2D1Geometry *)transformed_geometry[0], (ID2D1Brush *)brush, 10.0f, NULL);
6343 ID2D1RenderTarget_DrawGeometry(rt, (ID2D1Geometry *)transformed_geometry[1], (ID2D1Brush *)brush, 5.0f, NULL);
6344 ID2D1RenderTarget_DrawGeometry(rt, (ID2D1Geometry *)transformed_geometry[2], (ID2D1Brush *)brush, 15.0f, NULL);
6345 hr = ID2D1RenderTarget_EndDraw(rt, NULL, NULL);
6346 ok(SUCCEEDED(hr), "Failed to end draw, hr %#x.\n", hr);
6347 ID2D1TransformedGeometry_Release(transformed_geometry[2]);
6348 ID2D1TransformedGeometry_Release(transformed_geometry[1]);
6349 ID2D1TransformedGeometry_Release(transformed_geometry[0]);
6350 ID2D1RectangleGeometry_Release(rect_geometry[1]);
6351 ID2D1RectangleGeometry_Release(rect_geometry[0]);
6353 match = compare_figure(surface, 0, 0, 160, 160, 0xff652e89, 0,
6354 "vi5kPGQ8ZDxkPGQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwU"
6355 "PBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8"
6356 "FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwU"
6357 "PBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8"
6358 "FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwU"
6359 "PBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8ZDxkPGQ8ZDxk3i8A");
6360 ok(match, "Figure does not match.\n");
6361 match = compare_figure(surface, 160, 0, 320, 160, 0xff652e89, 32,
6362 "8XYGtQIOrAIXpAIfmwIokwIwigI4gwJA+gFJ8gFR6QEzAiXhATMKJdgBMxMl0AEzGyXHATMkJb8B"
6363 "MysmtgEzNCWvATM8JaYBM0UlngEzTSWVATNWJY0BM14lhAEzZyV8M28lczN4JWszgAElYjOIASZa"
6364 "M5ABJVgtmQElWCWhASVYJaEBJVgloQElWCWhASVYJaEBJVgloQElWCWhASVYJaEBJVglmQEtWCWQ"
6365 "ATNaJogBM2IlgAEzayV4M3MlbzN8JWczhAElXjONASVWM5UBJU0zngElRTOmASU8M68BJTQztgEm"
6366 "KzO/ASUkM8cBJRsz0AElEzPYASUKM+EBJQIz6QFR8gFJ+gFAgwI4igIwkwIomwIfpAIXrAIOtQIG"
6367 "8XYA");
6368 ok(match, "Figure does not match.\n");
6369 match = compare_figure(surface, 0, 160, 160, 320, 0xff652e89, 32,
6370 "ujEBngECnQEDnQEEmwEFmgEHmQEHmAEIlwEKlgEKlQELlAENkwENkgEOkQEQjwERjwESjQETjAEU"
6371 "jAEKAQqKAQoCCokBCgMKiQEKBAqHAQoFCoYBCgYKhgEKBwqEAQoICoMBCgkKgwEKCgqBAQoLCoAB"
6372 "Cg0KfgsNCn4KDgp9ChAKewsQCnsKEQp6ChMKeAoUCngKFAp3ChYKdQoXCnUKGApzChkKcgoaCnIK"
6373 "GwpwChwKbwodCm4LHgptCh8KbAogCmsLIQpqCiIKaQokCmcKJQpnCiUKZgonCmQKKApkCigKYwoq"
6374 "CmEKKwphCisKYAotCl4KLgpdCy8KXAowClsKMQpaCzIKWQozClgKNApXCjYKVgo2ClUKNwpUCjkK"
6375 "Uwo5ClIKOwpQCjwKTws8Ck8KPgpNCj8KTAs/CkwKQQpKCkIKSQtCCkkKRApHCkUKRgpHCkUKRwpE"
6376 "CkgKQwpKCkIKSgpBCksKQApNCj4LTQo+Ck4KPQpQCjsLUAo7ClIKOQpTCjgLUwo4ClUKNgpWCjUK"
6377 "Vwo1ClgKMwpZCjQKWAo0ClkKMwpZCjQKWQozClkKMwpZCjQKWQozClkKMwpZCjQKWQozClkKNApY"
6378 "CjQKWQozClkKNApZCjMKWQozClkKNApZCjMKWQozClkKNApZCjMKWQo0ClgKNApZCjMKWQo0ClkK"
6379 "MwpZCjMKWQo0ClkKMwpZCjMKWQo0ClkKMwpZCjQKWAo0ClkKMwpYCjUKVwo1ClYKNgpVCjgKUws4"
6380 "ClMKOQpSCjsKUAs7ClAKPQpOCj4KTQs+Ck0KQApLCkEKSgpCCkoKQwpICkQKRwpFCkcKRgpFCkcK"
6381 "RApJCkILSQpCCkoKQQpMCj8LTAo/Ck0KPgpPCjwLTwo8ClAKOwpSCjkKUwo5ClQKNwpVCjYKVgo2"
6382 "ClcKNApYCjMKWQoyC1oKMQpbCjAKXAovC10KLgpeCi0KYAorCmEKKwphCioKYwooCmQKKApkCicK"
6383 "ZgolCmcKJQpnCiQKaQoiCmoKIQtrCiAKbAofCm0KHgtuCh0KbwocCnAKGwpyChoKcgoZCnMKGAp1"
6384 "ChcKdQoWCncKFAp4ChQKeAoTCnoKEQp7ChALewoQCn0KDgp+Cg0LfgoNCoABCgsKgQEKCgqDAQoJ"
6385 "CoMBCggKhAEKBwqGAQoGCoYBCgUKhwEKBAqJAQoDCokBCgIKigEKAQqMARSMARONARKPARGPARCR"
6386 "AQ6SAQ2TAQ2UAQuVAQqWAQqXAQiYAQeZAQeaAQWbAQSdAQOdAQKeAQG6MQAA");
6387 ok(match, "Figure does not match.\n");
6388 match = compare_figure(surface, 160, 160, 320, 320, 0xff652e89, 64,
6389 "82ICvQIEugIHuAIJtgIKtAINsgIPsAIRrQITrAIVqQIYpwIZpgIbowIeoQIgnwIhnQIkmwImmAIp"
6390 "lgIVARSVAhUDFJICFQUVkAIVBxSPAhUJFIwCFQwUigIVDRWHAhYPFIYCFRIUhAIVFBSBAhUWFf8B"
6391 "FRgU/gEVGhT7ARUcFfkBFR4U9wEWIBT1ARUjFPMBFSQV8AEVJxTvARUpFOwBFisU6gEVLRXoARUv"
6392 "FOYBFjEU5AEVMxXiARU1FOABFTgU3gEVOhTbARY7FdkBFT4U2AEVQBTVARZCFNMBFUQV0QEVRhTP"
6393 "ARVJFM0BFUoVygEWTBTJARVPFMcBFVEUxAEVUxXCARVVFMEBFVcUvgEVWRW8ARVbFbkBFl0UuAEV"
6394 "YBS2ARVhFbMBFWQUsgEVZhSwARVoFK0BFWoVqwEVbBSpARZuFKcBFXAVpQEVchWiARV1FKEBFXcU"
6395 "nwEVeBWcARV7FJsBFX0UmAEWfxSWARWBARWUARWDARSSARWGARSQARWHARWOARWJARWLARWMARSK"
6396 "ARWOARSHARaPARWFARWSARSEARWUARSBARWXARR/FZgBFX0VmgEUexWdARR5FZ4BFXYWoAEVdBWj"
6397 "ARRzFaUBFHAVpwEVbhWpARRtFasBFGoVrgEUaBWvARVmFbEBFGcUsgEUZxSxARVmFbEBFWYUsgEU"
6398 "ZxSyARRnFLEBFWYVsQEUZxSyARRnFLIBFGcUsQEVZhWxARRnFLIBFGcUsQEVZhWxARVmFLIBFGcU"
6399 "sgEUZxSxARVmFbEBFGcUsgEUZxSyARRmFbEBFWYVsQEUZxSyARRnFLEBFWYVsQEUZxSyARRnFLIB"
6400 "FGcUsQEVZhWxARRnFLIBFGcUsgEUZhWxARVmFbEBFGcUsgEUZxSxARVmFa8BFWgUrgEVahSrARVt"
6401 "FKkBFW4VpwEVcBSlARVzFKMBFXQVoAEWdhWeARV5FJ0BFXsUmgEVfRWYARV/FJcBFYEBFJQBFYQB"
6402 "FJIBFYUBFY8BFocBFI4BFYoBFIwBFYsBFYkBFY4BFYcBFZABFIYBFZIBFIMBFZQBFYEBFZYBFH8W"
6403 "mAEUfRWbARR7FZwBFXgVnwEUdxWhARR1FaIBFXIVpQEVcBWnARRuFqkBFGwVqwEVahWtARRoFbAB"
6404 "FGYVsgEUZBWzARVhFbYBFGAVuAEUXRa5ARVbFbwBFVkVvgEUVxXBARRVFcIBFVMVxAEUURXHARRP"
6405 "FckBFEwWygEVShXNARRJFc8BFEYV0QEVRBXTARRCFtUBFEAV2AEUPhXZARU7FtsBFDoV3gEUOBXg"
6406 "ARQ1FeIBFTMV5AEUMRbmARQvFegBFS0V6gEUKxbsARQpFe8BFCcV8AEVJBXzARQjFfUBFCAW9wEU"
6407 "HhX5ARUcFfsBFBoV/gEUGBX/ARUWFYECFBQVhAIUEhWGAhQPFocCFQ0VigIUDBWMAhQJFY8CFAcV"
6408 "kAIVBRWSAhQDFZUCFAEVlgIpmAImmwIknQIhnwIgoQIeowIbpgIZpwIYqQIVrAITrQIRsAIPsgIN"
6409 "tAIKtgIJuAIHugIEvQIC82IA");
6410 ok(match, "Figure does not match.\n");
6412 hr = ID2D1Factory_CreatePathGeometry(factory, &geometry);
6413 ok(SUCCEEDED(hr), "Failed to create path geometry, hr %#x.\n", hr);
6414 hr = ID2D1PathGeometry_Open(geometry, &sink);
6415 ok(SUCCEEDED(hr), "Failed to open geometry sink, hr %#x.\n", hr);
6417 set_point(&point, 20.0f, 80.0f);
6418 ID2D1GeometrySink_BeginFigure(sink, point, D2D1_FIGURE_BEGIN_HOLLOW);
6419 quadratic_to(sink, 40.0f, 80.0f, 60.0f, 80.0f);
6420 quadratic_to(sink, 60.0f, 160.0f, 60.0f, 240.0f);
6421 quadratic_to(sink, 40.0f, 240.0f, 20.0f, 240.0f);
6422 quadratic_to(sink, 20.0f, 160.0f, 20.0f, 80.0f);
6423 ID2D1GeometrySink_EndFigure(sink, D2D1_FIGURE_END_CLOSED);
6425 set_point(&point, 100.0f, 80.0f);
6426 ID2D1GeometrySink_BeginFigure(sink, point, D2D1_FIGURE_BEGIN_HOLLOW);
6427 quadratic_to(sink, 105.0f, 80.0f, 140.0f, 80.0f);
6428 quadratic_to(sink, 140.0f, 100.0f, 140.0f, 240.0f);
6429 quadratic_to(sink, 135.0f, 240.0f, 100.0f, 240.0f);
6430 quadratic_to(sink, 100.0f, 220.0f, 100.0f, 80.0f);
6431 ID2D1GeometrySink_EndFigure(sink, D2D1_FIGURE_END_CLOSED);
6433 set_point(&point, 180.0f, 80.0f);
6434 ID2D1GeometrySink_BeginFigure(sink, point, D2D1_FIGURE_BEGIN_HOLLOW);
6435 quadratic_to(sink, 215.0f, 80.0f, 220.0f, 80.0f);
6436 quadratic_to(sink, 220.0f, 220.0f, 220.0f, 240.0f);
6437 quadratic_to(sink, 185.0f, 240.0f, 180.0f, 240.0f);
6438 quadratic_to(sink, 180.0f, 100.0f, 180.0f, 80.0f);
6439 ID2D1GeometrySink_EndFigure(sink, D2D1_FIGURE_END_CLOSED);
6441 set_point(&point, 260.0f, 80.0f);
6442 ID2D1GeometrySink_BeginFigure(sink, point, D2D1_FIGURE_BEGIN_HOLLOW);
6443 quadratic_to(sink, 280.0f, 80.0f, 300.0f, 80.0f);
6444 quadratic_to(sink, 300.0f, 160.0f, 300.0f, 240.0f);
6445 quadratic_to(sink, 280.0f, 240.0f, 260.0f, 240.0f);
6446 quadratic_to(sink, 260.0f, 160.0f, 260.0f, 80.0f);
6447 ID2D1GeometrySink_EndFigure(sink, D2D1_FIGURE_END_OPEN);
6449 set_point(&point, 20.0f, 400.0f);
6450 ID2D1GeometrySink_BeginFigure(sink, point, D2D1_FIGURE_BEGIN_HOLLOW);
6451 quadratic_to(sink, 40.0f, 420.0f, 60.0f, 400.0f);
6452 quadratic_to(sink, 55.0f, 480.0f, 60.0f, 560.0f);
6453 quadratic_to(sink, 40.0f, 540.0f, 20.0f, 560.0f);
6454 quadratic_to(sink, 25.0f, 480.0f, 20.0f, 400.0f);
6455 ID2D1GeometrySink_EndFigure(sink, D2D1_FIGURE_END_CLOSED);
6457 set_point(&point, 100.0f, 400.0f);
6458 ID2D1GeometrySink_BeginFigure(sink, point, D2D1_FIGURE_BEGIN_HOLLOW);
6459 quadratic_to(sink, 105.0f, 420.0f, 140.0f, 400.0f);
6460 quadratic_to(sink, 135.0f, 420.0f, 140.0f, 560.0f);
6461 quadratic_to(sink, 135.0f, 540.0f, 100.0f, 560.0f);
6462 quadratic_to(sink, 105.0f, 540.0f, 100.0f, 400.0f);
6463 ID2D1GeometrySink_EndFigure(sink, D2D1_FIGURE_END_CLOSED);
6465 set_point(&point, 180.0f, 400.0f);
6466 ID2D1GeometrySink_BeginFigure(sink, point, D2D1_FIGURE_BEGIN_HOLLOW);
6467 quadratic_to(sink, 215.0f, 420.0f, 220.0f, 400.0f);
6468 quadratic_to(sink, 215.0f, 540.0f, 220.0f, 560.0f);
6469 quadratic_to(sink, 185.0f, 540.0f, 180.0f, 560.0f);
6470 quadratic_to(sink, 185.0f, 420.0f, 180.0f, 400.0f);
6471 ID2D1GeometrySink_EndFigure(sink, D2D1_FIGURE_END_CLOSED);
6473 set_point(&point, 260.0f, 400.0f);
6474 ID2D1GeometrySink_BeginFigure(sink, point, D2D1_FIGURE_BEGIN_HOLLOW);
6475 quadratic_to(sink, 280.0f, 420.0f, 300.0f, 400.0f);
6476 quadratic_to(sink, 295.0f, 480.0f, 300.0f, 560.0f);
6477 quadratic_to(sink, 280.0f, 540.0f, 260.0f, 560.0f);
6478 quadratic_to(sink, 265.0f, 480.0f, 260.0f, 400.0f);
6479 ID2D1GeometrySink_EndFigure(sink, D2D1_FIGURE_END_OPEN);
6481 set_point(&point, 20.0f, 720.0f);
6482 ID2D1GeometrySink_BeginFigure(sink, point, D2D1_FIGURE_BEGIN_HOLLOW);
6483 quadratic_to(sink, 40.0f, 700.0f, 60.0f, 720.0f);
6484 quadratic_to(sink, 65.0f, 800.0f, 60.0f, 880.0f);
6485 quadratic_to(sink, 40.0f, 900.0f, 20.0f, 880.0f);
6486 quadratic_to(sink, 15.0f, 800.0f, 20.0f, 720.0f);
6487 ID2D1GeometrySink_EndFigure(sink, D2D1_FIGURE_END_CLOSED);
6489 set_point(&point, 100.0f, 720.0f);
6490 ID2D1GeometrySink_BeginFigure(sink, point, D2D1_FIGURE_BEGIN_HOLLOW);
6491 quadratic_to(sink, 105.0f, 700.0f, 140.0f, 720.0f);
6492 quadratic_to(sink, 145.0f, 740.0f, 140.0f, 880.0f);
6493 quadratic_to(sink, 135.0f, 900.0f, 100.0f, 880.0f);
6494 quadratic_to(sink, 95.0f, 860.0f, 100.0f, 720.0f);
6495 ID2D1GeometrySink_EndFigure(sink, D2D1_FIGURE_END_CLOSED);
6497 set_point(&point, 180.0f, 720.0f);
6498 ID2D1GeometrySink_BeginFigure(sink, point, D2D1_FIGURE_BEGIN_HOLLOW);
6499 quadratic_to(sink, 215.0f, 700.0f, 220.0f, 720.0f);
6500 quadratic_to(sink, 225.0f, 860.0f, 220.0f, 880.0f);
6501 quadratic_to(sink, 185.0f, 900.0f, 180.0f, 880.0f);
6502 quadratic_to(sink, 175.0f, 740.0f, 180.0f, 720.0f);
6503 ID2D1GeometrySink_EndFigure(sink, D2D1_FIGURE_END_CLOSED);
6505 set_point(&point, 260.0f, 720.0f);
6506 ID2D1GeometrySink_BeginFigure(sink, point, D2D1_FIGURE_BEGIN_HOLLOW);
6507 quadratic_to(sink, 280.0f, 700.0f, 300.0f, 720.0f);
6508 quadratic_to(sink, 305.0f, 800.0f, 300.0f, 880.0f);
6509 quadratic_to(sink, 280.0f, 900.0f, 260.0f, 880.0f);
6510 quadratic_to(sink, 255.0f, 800.0f, 260.0f, 720.0f);
6511 ID2D1GeometrySink_EndFigure(sink, D2D1_FIGURE_END_OPEN);
6513 hr = ID2D1GeometrySink_Close(sink);
6514 ok(SUCCEEDED(hr), "Failed to close geometry sink, hr %#x.\n", hr);
6515 ID2D1GeometrySink_Release(sink);
6517 ID2D1RenderTarget_BeginDraw(rt);
6518 ID2D1RenderTarget_Clear(rt, &color);
6519 ID2D1RenderTarget_DrawGeometry(rt, (ID2D1Geometry *)geometry, (ID2D1Brush *)brush, 10.0f, NULL);
6520 hr = ID2D1RenderTarget_EndDraw(rt, NULL, NULL);
6521 ok(SUCCEEDED(hr), "Failed to end draw, hr %#x.\n", hr);
6522 ID2D1PathGeometry_Release(geometry);
6524 match = compare_figure(surface, 0, 0, 160, 160, 0xff652e89, 0,
6525 "vi5kPGQ8ZDxkPGQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwU"
6526 "PBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8"
6527 "FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwU"
6528 "PBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8"
6529 "FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwU"
6530 "PBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8ZDxkPGQ8ZDxk3i8A");
6531 ok(match, "Figure does not match.\n");
6532 match = compare_figure(surface, 160, 0, 160, 160, 0xff652e89, 0,
6533 "vi5kPGQ8ZDxkPGQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwU"
6534 "PBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8"
6535 "FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwU"
6536 "PBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8"
6537 "FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwU"
6538 "PBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8ZDxkPGQ8ZDxk3i8A");
6539 ok(match, "Figure does not match.\n");
6540 match = compare_figure(surface, 320, 0, 160, 160, 0xff652e89, 0,
6541 "vi5kPGQ8ZDxkPGQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwU"
6542 "PBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8"
6543 "FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwU"
6544 "PBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8"
6545 "FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwU"
6546 "PBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8ZDxkPGQ8ZDxk3i8A");
6547 ok(match, "Figure does not match.\n");
6548 match = compare_figure(surface, 480, 0, 160, 160, 0xff652e89, 0,
6549 "yC5aRlpGWjxkPGQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwU"
6550 "PBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8"
6551 "FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwU"
6552 "PBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8"
6553 "FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwU"
6554 "PBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8FDwUPBQ8ZDxkPGQ8ZDxk3i8A");
6555 ok(match, "Figure does not match.\n");
6557 match = compare_figure(surface, 0, 160, 160, 160, 0xff652e89, 64,
6558 "3SoDYAM6B1gHOgtQCzoPSA87EkASPBc2FzwcLBw8IiAiPWI+Yj5iPhQBOAEUPhQKJgoUPxQ4FEAU"
6559 "OBRAFDgUQBQ4FEAUOBRBFDYUQhQ2FEIUNhRCFDYUQhQ2FEIUNhRDFDQURBQ0FEQUNBREFDQURBQ0"
6560 "FEQUNBREFDQURBQ0FEQUNBREFDQURRQyFEYUMhRGFDIURhQyFEYUMhRGFDIURhQyFEYUMhRGFDIU"
6561 "RhQyFEYUMhRGFDIURhQyFEYUMhRGFDIURhQyFEYUMhRGFDIURhQyFEYUMhRGFDIURhQyFEYUMhRG"
6562 "FDIURRQ0FEQUNBREFDQURBQ0FEQUNBREFDQURBQ0FEQUNBREFDQURBQ0FEMUNhRCFDYUQhQ2FEIU"
6563 "NhRCFDYUQhQ2FEEUOBRAFDgUQBQ4FEAUOBRAFDgUPxQKJgoUPhQBOAEUPmI+Yj5iPSIgIjwcLBw8"
6564 "FzYXPBJAEjsPSA86C1ALOgdYBzoDYAPdKgAA");
6565 ok(match, "Figure does not match.\n");
6566 match = compare_figure(surface, 160, 160, 160, 160, 0xff652e89, 1024,
6567 "uxUBnwECngEDnQEEnAEFmwEGmwEGmgEHmQEImAEJlwEKlgELlQEMlQEMlAENkwEOkgEPkQEQkAER"
6568 "VQQ2Ek0KOBJFEDkTPRY6FDUcOxUrJDwYHi09Yj5iP2BAQwkUQDgUFEAUOBRAFDcUQRQ3FEEUNxRC"
6569 "FDYUQhQ2FEIUNhRCFDUUQxQ1FEMUNRRDFDUUQxQ1FEQUNBREFDQURBQ0FEQUNBREFDQURBQ0FEQU"
6570 "NBREFDQURBQ0FEQUNBRFFDMURRQzFEUUMxRFFDMURRQzFEUUMxRFFDMURRQzFEUUMxRFFDMURRQ0"
6571 "FEQUNBRFFDMURRQzFEUUMxRFFDMURRQzFEUUMxRFFDMURRQzFEUUMxRFFDMURRQ0FEQUNBREFDQU"
6572 "RBQ0FEQUNBREFDQURBQ0FEQUNBREFDQURBQ0FEQUNRRDFDUUQxQ1FEMUNRRDFDUUQhQ2FEIUNhRC"
6573 "FDYUQhQ3FEEUNxRBFDcUQBQ4FEAUFDhAFAlDQGA/Yj5iPS0eGDwkKxU7HDUUOhY9EzkQRRI4Ck0S"
6574 "NgRVEZABEJEBD5IBDpMBDZQBDJUBDJUBC5YBCpcBCZgBCJkBB5oBBpsBBpsBBZwBBJ0BA54BAp8B"
6575 "AbsV");
6576 ok(match, "Figure does not match.\n");
6577 match = compare_figure(surface, 320, 160, 160, 160, 0xff652e89, 1024,
6578 "pBYBngECnQEDnAEEmwEFmgEGmQEGmQEHmAEIlwEJlgEKlQELlAEMkwEMkwENkgEOkQEPkAEQNgRV"
6579 "ETcKTRI4EEUSOhY9EzscNRQ8JCsVPS0eGD5iPmI/YEAUCUNAFBQ4QBQ4FEEUNxRBFDcUQRQ3FEEU"
6580 "NhRCFDYUQhQ2FEMUNRRDFDUUQxQ1FEMUNRRDFDUUQxQ0FEQUNBREFDQURBQ0FEQUNBREFDQURBQ0"
6581 "FEQUNBREFDQURBQ0FEQUMxRFFDMURRQzFEUUMxRFFDMURRQzFEUUMxRFFDMURRQzFEUUMxREFDQU"
6582 "RBQ0FEQUMxRFFDMURRQzFEUUMxRFFDMURRQzFEUUMxRFFDMURRQzFEUUMxREFDQURBQ0FEQUNBRE"
6583 "FDQURBQ0FEQUNBREFDQURBQ0FEQUNBREFDQUQxQ1FEMUNRRDFDUUQxQ1FEMUNRRDFDYUQhQ2FEIU"
6584 "NhRBFDcUQRQ3FEEUNxRBFDgUQDgUFEBDCRRAYD9iPmI+GB4tPRUrJDwUNRw7Ez0WOhJFEDgSTQo3"
6585 "EVUENhCQAQ+RAQ6SAQ2TAQyTAQyUAQuVAQqWAQmXAQiYAQeZAQaZAQaaAQWbAQScAQOdAQKeAQGk"
6586 "FgAA");
6587 ok(match, "Figure does not match.\n");
6588 match = compare_figure(surface, 480, 160, 160, 160, 0xff652e89, 64,
6589 "wCsDmQEHlQELkQEPSwJAEkgLNhc8HCwcPCIgIj1iPmI+Yj4UATgBFD4UCiYKFD8UOBRAFDgUQBQ4"
6590 "FEAUOBRAFDgUQRQ2FEIUNhRCFDYUQhQ2FEIUNhRCFDYUQxQ0FEQUNBREFDQURBQ0FEQUNBREFDQU"
6591 "RBQ0FEQUNBREFDQURBQ0FEUUMhRGFDIURhQyFEYUMhRGFDIURhQyFEYUMhRGFDIURhQyFEYUMhRG"
6592 "FDIURhQyFEYUMhRGFDIURhQyFEYUMhRGFDIURhQyFEYUMhRGFDIURhQyFEYUMhRGFDIURhQyFEUU"
6593 "NBREFDQURBQ0FEQUNBREFDQURBQ0FEQUNBREFDQURBQ0FEQUNBRDFDYUQhQ2FEIUNhRCFDYUQhQ2"
6594 "FEIUNhRBFDgUQBQ4FEAUOBRAFDgUQBQ4FD8UCiYKFD4UATgBFD5iPmI+Yj0iICI8HCwcPBc2FzwS"
6595 "QBI7D0gPOgtQCzoHWAc6A2AD3SoA");
6596 ok(match, "Figure does not match.\n");
6598 match = compare_figure(surface, 0, 320, 160, 160, 0xff652e89, 64,
6599 "3SkmcThiRFdOTVhEICAgPhwsHDwXNhc8FDwUOxQ+FDoUPhQ6FD4UOhQ+FDoUPhQ5FEAUOBRAFDgU"
6600 "QBQ4FEAUOBRAFDcUQhQ2FEIUNhRCFDYUQhQ2FEIUNhRCFDUURBQ0FEQUNBREFDQURBQ0FEQUNBRE"
6601 "FDQURBQ0FEQUNBREFDQURBQzFEYUMhRGFDIURhQyFEYUMhRGFDIURhQyFEYUMhRGFDIURhQyFEYU"
6602 "MhRGFDIURhQyFEYUMhRGFDIURhQyFEYUMhRGFDIURhQyFEYUMhRGFDIURhQyFEYUMhRGFDIURhQz"
6603 "FEQUNBREFDQURBQ0FEQUNBREFDQURBQ0FEQUNBREFDQURBQ0FEQUNRRCFDYUQhQ2FEIUNhRCFDYU"
6604 "QhQ2FEIUNxRAFDgUQBQ4FEAUOBRAFDgUQBQ5FD4UOhQ+FDoUPhQ6FD4UOhQ+FDsUPBQ8FzYXPBws"
6605 "HD4gICBEWE1OV0RiOHEm3SkA");
6606 ok(match, "Figure does not match.\n");
6607 match = compare_figure(surface, 160, 320, 160, 160, 0xff652e89, 1024,
6608 "zykoczhkRVhQTlpEFx4tPRUrJDwUNRw7FDwVOxQ+FDoUPhQ5FEAUOBRAFDgUQBQ4FEAUOBRBFDcU"
6609 "QRQ3FEEUNhRCFDYUQhQ2FEIUNhRDFDUUQxQ1FEMUNRRDFDUUQxQ0FEQUNBREFDQURBQ0FEQUNBRE"
6610 "FDQURBQ0FEQUNBREFDQURBQ0FEQUMxRFFDMURRQzFEUUMxRFFDMURRQzFEUUMxRFFDMURRQzFEUU"
6611 "MxRFFDMURBQ0FEQUMxRFFDMURRQzFEUUMxRFFDMURRQzFEUUMxRFFDMURRQzFEUUMxRFFDMURBQ0"
6612 "FEQUNBREFDQURBQ0FEQUNBREFDQURBQ0FEQUNBREFDQURBQ0FEMUNRRDFDUUQxQ1FEMUNRRDFDYU"
6613 "QhQ2FEIUNhRCFDYUQRQ3FEEUNxRBFDgUQBQ4FEAUOBRAFDgUQBQ5FD4UOhQ+FDsVPBQ7HDUUPCQr"
6614 "FT0tHhdEWk5QWEVkOHMozykA");
6615 ok(match, "Figure does not match.\n");
6616 match = compare_figure(surface, 320, 320, 160, 160, 0xff652e89, 1024,
6617 "6SkobThfRVNQSFpALR4XPSQrFTscNRQ7FTwUOhQ+FDoUPhQ5FEAUOBRAFDgUQBQ4FEAUNxRBFDcU"
6618 "QRQ3FEEUNxRCFDYUQhQ2FEIUNRRDFDUUQxQ1FEMUNRRDFDUUQxQ1FEQUNBREFDQURBQ0FEQUNBRE"
6619 "FDQURBQ0FEQUNBREFDQURBQ0FEQUNBRFFDMURRQzFEUUMxRFFDMURRQzFEUUMxRFFDMURRQzFEUU"
6620 "MxRFFDQURBQ0FEQUNBRFFDMURRQzFEUUMxRFFDMURRQzFEUUMxRFFDMURRQzFEUUMxRFFDQURBQ0"
6621 "FEQUNBREFDQURBQ0FEQUNBREFDQURBQ0FEQUNBREFDQURBQ1FEMUNRRDFDUUQxQ1FEMUNRRDFDUU"
6622 "QhQ2FEIUNhRCFDcUQRQ3FEEUNxRBFDcUQBQ4FEAUOBRAFDgUQBQ5FD4UOhQ+FDoUPBU7FDUcOxUr"
6623 "JD0XHi1AWkhQU0VfOG0o6SkA");
6624 ok(match, "Figure does not match.\n");
6625 match = compare_figure(surface, 480, 320, 160, 160, 0xff652e89, 64,
6626 "3SkmcThiRFdOTVhGHiAgRhQsHDwXNhc8FDwUOxQ+FDoUPhQ6FD4UOhQ+FDoUPhQ5FEAUOBRAFDgU"
6627 "QBQ4FEAUOBRAFDcUQhQ2FEIUNhRCFDYUQhQ2FEIUNhRCFDUURBQ0FEQUNBREFDQURBQ0FEQUNBRE"
6628 "FDQURBQ0FEQUNBREFDQURBQzFEYUMhRGFDIURhQyFEYUMhRGFDIURhQyFEYUMhRGFDIURhQyFEYU"
6629 "MhRGFDIURhQyFEYUMhRGFDIURhQyFEYUMhRGFDIURhQyFEYUMhRGFDIURhQyFEYUMhRGFDIURhQz"
6630 "FEQUNBREFDQURBQ0FEQUNBREFDQURBQ0FEQUNBREFDQURBQ0FEQUNRRCFDYUQhQ2FEIUNhRCFDYU"
6631 "QhQ2FEIUNxRAFDgUQBQ4FEAUOBRAFDgUQBQ5FD4UOhQ+FDoUPhQ6FD4UOhQ+FDsUPBQ8FzYXPBws"
6632 "HD4gICBEWE1OV0RiOHEm3SkA");
6633 ok(match, "Figure does not match.\n");
6635 hr = ID2D1Factory_CreatePathGeometry(factory, &geometry);
6636 ok(SUCCEEDED(hr), "Failed to create path geometry, hr %#x.\n", hr);
6637 hr = ID2D1PathGeometry_Open(geometry, &sink);
6638 ok(SUCCEEDED(hr), "Failed to open geometry sink, hr %#x.\n", hr);
6640 set_point(&point, -0.402914f, 0.915514f);
6641 ID2D1GeometrySink_BeginFigure(sink, point, D2D1_FIGURE_BEGIN_HOLLOW);
6642 quadratic_to(sink, -0.310379f, 0.882571f, -0.116057f, 0.824000f);
6643 quadratic_to(sink, 0.008350f, 0.693614f, -0.052343f, 0.448886f);
6644 quadratic_to(sink, -0.154236f, 0.246072f, -0.279229f, 0.025343f);
6645 quadratic_to(sink, -0.370064f, -0.588586f, -0.383029f, -0.924114f);
6646 quadratic_to(sink, -0.295479f, -0.958764f, -0.017086f, -0.988400f);
6647 quadratic_to(sink, 0.208836f, -0.954157f, 0.272200f, -0.924114f);
6648 quadratic_to(sink, 0.295614f, -0.569071f, 0.230143f, 0.022886f);
6649 quadratic_to(sink, 0.101664f, 0.220643f, 0.012057f, 0.451571f);
6650 quadratic_to(sink, -0.028764f, 0.709014f, 0.104029f, 0.833943f);
6651 quadratic_to(sink, 0.319414f, 0.913057f, 0.403229f, 0.942628f);
6652 quadratic_to(sink, 0.317721f, 1.023450f, -0.017086f, 1.021771f);
6653 quadratic_to(sink, -0.310843f, 1.007472f, -0.402914f, 0.915514f);
6654 ID2D1GeometrySink_EndFigure(sink, D2D1_FIGURE_END_CLOSED);
6656 hr = ID2D1GeometrySink_Close(sink);
6657 ok(SUCCEEDED(hr), "Failed to close geometry sink, hr %#x.\n", hr);
6658 ID2D1GeometrySink_Release(sink);
6660 set_matrix_identity(&matrix);
6661 translate_matrix(&matrix, 40.0f, 160.0f);
6662 scale_matrix(&matrix, 20.0f, 80.0f);
6663 hr = ID2D1Factory_CreateTransformedGeometry(factory,
6664 (ID2D1Geometry *)geometry, &matrix, &transformed_geometry[0]);
6665 ok(SUCCEEDED(hr), "Failed to create geometry, hr %#x.\n", hr);
6667 set_matrix_identity(&matrix);
6668 translate_matrix(&matrix, 160.0f, 640.0f);
6669 scale_matrix(&matrix, 40.0f, 160.0f);
6670 rotate_matrix(&matrix, M_PI / -5.0f);
6671 hr = ID2D1Factory_CreateTransformedGeometry(factory,
6672 (ID2D1Geometry *)geometry, &matrix, &transformed_geometry[1]);
6673 ok(SUCCEEDED(hr), "Failed to create geometry, hr %#x.\n", hr);
6674 ID2D1PathGeometry_Release(geometry);
6676 set_matrix_identity(&matrix);
6677 scale_matrix(&matrix, 0.5f, 1.0f);
6678 translate_matrix(&matrix, -80.0f, 0.0f);
6679 hr = ID2D1Factory_CreateTransformedGeometry(factory,
6680 (ID2D1Geometry *)transformed_geometry[1], &matrix, &transformed_geometry[2]);
6681 ok(SUCCEEDED(hr), "Failed to create geometry, hr %#x.\n", hr);
6683 set_matrix_identity(&matrix);
6684 rotate_matrix(&matrix, M_PI / 2.0f);
6685 translate_matrix(&matrix, 80.0f, -320.0f);
6686 scale_matrix(&matrix, 2.0f, 0.25f);
6687 hr = ID2D1Factory_CreateTransformedGeometry(factory,
6688 (ID2D1Geometry *)transformed_geometry[2], &matrix, &transformed_geometry[3]);
6689 ok(SUCCEEDED(hr), "Failed to create geometry, hr %#x.\n", hr);
6691 ID2D1RenderTarget_BeginDraw(rt);
6692 ID2D1RenderTarget_Clear(rt, &color);
6693 ID2D1RenderTarget_DrawGeometry(rt, (ID2D1Geometry *)transformed_geometry[0], (ID2D1Brush *)brush, 2.0f, NULL);
6694 ID2D1RenderTarget_DrawGeometry(rt, (ID2D1Geometry *)transformed_geometry[1], (ID2D1Brush *)brush, 10.0f, NULL);
6695 ID2D1RenderTarget_DrawGeometry(rt, (ID2D1Geometry *)transformed_geometry[2], (ID2D1Brush *)brush, 5.0f, NULL);
6696 ID2D1RenderTarget_DrawGeometry(rt, (ID2D1Geometry *)transformed_geometry[3], (ID2D1Brush *)brush, 15.0f, NULL);
6697 hr = ID2D1RenderTarget_EndDraw(rt, NULL, NULL);
6698 ok(SUCCEEDED(hr), "Failed to end draw, hr %#x.\n", hr);
6699 ID2D1TransformedGeometry_Release(transformed_geometry[3]);
6700 ID2D1TransformedGeometry_Release(transformed_geometry[2]);
6701 ID2D1TransformedGeometry_Release(transformed_geometry[1]);
6702 ID2D1TransformedGeometry_Release(transformed_geometry[0]);
6704 match = compare_figure(surface, 0, 0, 160, 160, 0xff652e89, 128,
6705 "yjIJkQEHBwaIAQUSBYMBBBYEggEEFgSCAQQWBIIBBBYEggEEFgSCAQQWBIIBBBYEggEEFgSCAQQW"
6706 "BIIBBBYEggEEFgSDAQQVBIMBBBUEgwEEFQSDAQQVBIMBBBUEgwEEFQSDAQQVBIMBBBUEgwEEFQSD"
6707 "AQQVBIQBBBQEhAEEFASEAQQTBIUBBBMEhQEEEwSFAQQTBIUBBBMEhQEEEwSGAQQSBIYBBBIEhgEE"
6708 "EgSGAQQSBIYBBBIEhgEEEgSGAQQRBIgBBBAEiAEEEASIAQQQBIkBBA4EigEEDgSLAQQMBIwBBAwE"
6709 "jQEECgSOAQQJBJABBAgEkAEFBgSSAQQGBJMBBAQElAEEBASVAQQDBJUBBAIElwEEAQSXAQiZAQeZ"
6710 "AQaaAQaaAQaaAQabAQWbAQWbAQWbAQWaAQeZAQeZAQeZAQiXAQQBBJYBBAMElQEEAwWRAQUGBY0B"
6711 "BQwFhwEFEgSCAQUXBYABBBoFfgUYBIIBBhEFiAEUpTEA");
6712 ok(match, "Figure does not match.\n");
6713 match = compare_figure(surface, 160, 0, 320, 160, 0xff652e89, 512,
6714 "yJIBArkCDa4CGKMCIZoCK5ECM4gCO4ECQ/gBS/EBUesBLAYl5QEsDiPeASwWIdkBLBwh0wEsISHO"
6715 "ASsgKMsBKR4vyAEnHDPIASUaNMsBIxg1mQEFMCIUN54BCygiDzijAREhIgY9qAEYGWGuAR4RXbMB"
6716 "JAhbuQGAAcABesYBc84Ba9YBTvQBP4MCOIoCNI4CM5ACMZICL5QCLZYCK5kCKJsCJ54CI6MCHq8C"
6717 "EraSAQAA");
6718 ok(match, "Figure does not match.\n");
6719 match = compare_figure(surface, 0, 160, 160, 320, 0xff652e89, 512,
6720 "xWkCmwEFmAEJlQELlAENkgEOkQEPjwESjQETjAEVigELAQqJAQsCCogBCwQKhwEKBQqGAQoGCoYB"
6721 "CgcKhAEKCAqEAQoIC4IBCgoKggEKCgqBAQoMCoABCgwKfwoNCn8KDgp9Cg8KfQoPCnwKEQp7ChEK"
6722 "egoSCnoKEwp4ChQKeAoUCncLFQp2ChYKdgoWCnYKFwp2ChYKdgoWCncKFgp2ChYKdgoWCncKFQt2"
6723 "ChYKdwoVCncKFQp4ChUKdwoVCncKFQp4ChUKdwoVCngKFAp4ChUKeAoUCngKFAp4CxMKeQoUCngK"
6724 "FAp5ChMKeQoUCnkKEwp5ChMKegoSC3kKEwp6ChIKegoSCnoLEgp6ChIKegoSCnsKEQp7ChEKfAoQ"
6725 "CnwKEAp9Cg8KfQoPCn4KDgp+Cg4KfwoOCn4KDgp/Cg0KfwoNCoABCgwKgAEKDAqBAQoLCoEBCgsK"
6726 "gQELCgqCAQoKCoIBCwkKgwEKCQqDAQoJCoQBCggKhAEKCQqEAQsHCoUBCwYKhgELBQqHAQsECogB"
6727 "CwMKiQELAgqLAQoBCowBFI0BE44BE44BEo8BEZABEJEBD5IBDpMBDpMBDZMBDZQBDJQBDZQBDJQB"
6728 "DBUCfgwSBH4MEQV/DA4GgAEMDAiAAQ0KCYEBDAgLgQENBQ2BAQ0EDoIBDQEPgwEdgwEdgwEdgwEc"
6729 "hAEKAgQCCoUBCgYKhgEKBgqGAQoFC4YBCgUKhwEKBAqIAQoECogBCgMKiQEKAwqIAQoDCokBCgMK"
6730 "iQEKAgqJAQoCCooBCgIKiQEKAgqKAQoBCosBCgEKigEKAQqLARSMARSLARSMAROMARONARKOARGO"
6731 "ARGPARCQAQ6RAQ2YAQTEZAAA");
6732 ok(match, "Figure does not match.\n");
6733 match = compare_figure(surface, 160, 160, 320, 320, 0xff652e89, 1024,
6734 "ytABA7gCCbICD60CFKkCF6cCGqMCHqACIZ0CJJoCJpgCKZUCFgIUkgIWBBWPAhYHFI4CFQoUjAIV"
6735 "DBSKAhUNFYgCFQ8UhwIVERSFAhUTFIMCFRQVgQIUFxSAAhQZFP4BFBoV/AEUHBT7ARQeFPkBFB8V"
6736 "9wEUIRT2ARQjFPQBFSMV8gEVJRTxARUnFPABFCgV7gEUKhTtARQsFOwBFCwV7AEULBTsARUsFOwB"
6737 "FSsV7AEULBTtARQsFO0BFCsU7QEVKxTtARUqFe0BFSoU7gEUKxTuARQqFe4BFCoU7wEUKhTuARUp"
6738 "FO8BFSkU7wEVKBXvARUoFPABFCkU8AEUKBTxARQoFPEBFCcV8QEUJxTxARUnFPEBFSYU8gEVJhTy"
6739 "ARUlFfIBFSUU8wEUJRXzARQlFPQBFCUU9AEUJBT1ARQkFPUBFCMU9gEUIhT2ARUhFPcBFSAU+AEV"
6740 "HxT5ARUeFPoBFR4U+gEVHRT7ARUcFPwBFRsU/QEVGhT+ARUZFP8BFBkUgAIUGBSBAhQXFIICFBcU"
6741 "ggIUFhSDAhQVFIQCFBQUhQIUExSGAhQSFIcCFBIUhwIUERSIAhUPFIkCFg0UigIXCxSNAhYJFI8C"
6742 "FggUkAIXBRSSAhcDFJQCFwEUlgIrlwIpmgImnAIkngIjnwIhoQIfowIepAIcpgIbpgIaqAIZqAIZ"
6743 "qAIYKwP7ARgnBf0BGCMI/QEZHgz+ARgbD/8BGBcSgAIYEhaAAhoNGIICGggcgwIaBB+DAjyEAjyF"
6744 "AjqGAjmIAjiIAiECFIkCFAIIBBSKAhQNFIsCFAwUjAIUCxSNAhQKFI4CFAkUjwIUBxWQAhQGFZEC"
6745 "FAUVkQIUBRWRAhQFFZECFQMVkwIUAxWTAhQDFZMCFAIVlAIVARWVAiqVAimWAimWAiiYAiaZAiaZ"
6746 "AiWaAiScAiKdAiGeAh+hAhyjAhmuAg3GxgEA");
6747 ok(match, "Figure does not match.\n");
6749 ID2D1SolidColorBrush_Release(brush);
6750 ID2D1RenderTarget_Release(rt);
6751 refcount = ID2D1Factory_Release(factory);
6752 ok(!refcount, "Factory has %u references left.\n", refcount);
6753 IDXGISurface_Release(surface);
6754 IDXGISwapChain_Release(swapchain);
6755 ID3D10Device1_Release(device);
6756 DestroyWindow(window);
6759 static void test_fill_geometry(void)
6761 ID2D1TransformedGeometry *transformed_geometry[4];
6762 ID2D1RectangleGeometry *rect_geometry[2];
6763 D2D1_POINT_2F point = {0.0f, 0.0f};
6764 D2D1_ROUNDED_RECT rounded_rect;
6765 ID2D1SolidColorBrush *brush;
6766 ID2D1PathGeometry *geometry;
6767 IDXGISwapChain *swapchain;
6768 D2D1_MATRIX_3X2_F matrix;
6769 ID2D1GeometrySink *sink;
6770 ID2D1RenderTarget *rt;
6771 ID3D10Device1 *device;
6772 IDXGISurface *surface;
6773 ID2D1Factory *factory;
6774 D2D1_ELLIPSE ellipse;
6775 D2D1_COLOR_F color;
6776 D2D1_RECT_F rect;
6777 ULONG refcount;
6778 HWND window;
6779 HRESULT hr;
6780 BOOL match;
6782 if (!(device = create_device()))
6784 skip("Failed to create device, skipping tests.\n");
6785 return;
6787 window = create_window();
6788 swapchain = create_swapchain(device, window, TRUE);
6789 hr = IDXGISwapChain_GetBuffer(swapchain, 0, &IID_IDXGISurface, (void **)&surface);
6790 ok(SUCCEEDED(hr), "Failed to get buffer, hr %#x.\n", hr);
6791 rt = create_render_target(surface);
6792 ok(!!rt, "Failed to create render target.\n");
6793 ID2D1RenderTarget_GetFactory(rt, &factory);
6795 ID2D1RenderTarget_SetDpi(rt, 192.0f, 48.0f);
6796 ID2D1RenderTarget_SetAntialiasMode(rt, D2D1_ANTIALIAS_MODE_ALIASED);
6797 set_color(&color, 0.890f, 0.851f, 0.600f, 1.0f);
6798 hr = ID2D1RenderTarget_CreateSolidColorBrush(rt, &color, NULL, &brush);
6799 ok(SUCCEEDED(hr), "Failed to create brush, hr %#x.\n", hr);
6801 ID2D1RenderTarget_BeginDraw(rt);
6802 set_color(&color, 0.396f, 0.180f, 0.537f, 1.0f);
6803 ID2D1RenderTarget_Clear(rt, &color);
6805 set_rect(&rect, 40.0f, 480.0f, 40.0f, 480.0f);
6806 ID2D1RenderTarget_FillRectangle(rt, &rect, (ID2D1Brush *)brush);
6807 set_rect(&rect, 100.0f, 480.0f, 140.0f, 480.0f);
6808 ID2D1RenderTarget_FillRectangle(rt, &rect, (ID2D1Brush *)brush);
6809 set_rect(&rect, 200.0f, 400.0f, 200.0f, 560.0f);
6810 ID2D1RenderTarget_FillRectangle(rt, &rect, (ID2D1Brush *)brush);
6811 set_rect(&rect, 260.0f, 560.0f, 300.0f, 400.0f);
6812 ID2D1RenderTarget_FillRectangle(rt, &rect, (ID2D1Brush *)brush);
6814 set_ellipse(&ellipse, 40.0f, 800.0f, 0.0f, 0.0f);
6815 ID2D1RenderTarget_FillEllipse(rt, &ellipse, (ID2D1Brush *)brush);
6816 set_ellipse(&ellipse, 120.0f, 800.0f, 20.0f, 0.0f);
6817 ID2D1RenderTarget_FillEllipse(rt, &ellipse, (ID2D1Brush *)brush);
6818 set_ellipse(&ellipse, 200.0f, 800.0f, 0.0f, 80.0f);
6819 ID2D1RenderTarget_FillEllipse(rt, &ellipse, (ID2D1Brush *)brush);
6820 set_ellipse(&ellipse, 280.0f, 800.0f, 20.0f, 80.0f);
6821 ID2D1RenderTarget_FillEllipse(rt, &ellipse, (ID2D1Brush *)brush);
6823 hr = ID2D1RenderTarget_EndDraw(rt, NULL, NULL);
6824 ok(SUCCEEDED(hr), "Failed to end draw, hr %#x.\n", hr);
6826 match = compare_figure(surface, 0, 160, 160, 160, 0xff652e89, 0, "gMgB");
6827 ok(match, "Figure does not match.\n");
6828 match = compare_figure(surface, 160, 160, 160, 160, 0xff652e89, 0, "gMgB");
6829 ok(match, "Figure does not match.\n");
6830 match = compare_figure(surface, 320, 160, 160, 160, 0xff652e89, 0, "gMgB");
6831 ok(match, "Figure does not match.\n");
6832 match = compare_figure(surface, 480, 160, 160, 160, 0xff652e89, 0,
6833 "qDJQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQ"
6834 "UFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQ"
6835 "UFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFCoMgAA");
6836 ok(match, "Figure does not match.\n");
6838 match = compare_figure(surface, 0, 320, 160, 160, 0xff652e89, 0, "gMgB");
6839 ok(match, "Figure does not match.\n");
6840 match = compare_figure(surface, 160, 320, 160, 160, 0xff652e89, 0, "gMgB");
6841 ok(match, "Figure does not match.\n");
6842 match = compare_figure(surface, 320, 320, 160, 160, 0xff652e89, 0, "gMgB");
6843 ok(match, "Figure does not match.\n");
6844 match = compare_figure(surface, 480, 320, 160, 160, 0xff652e89, 8,
6845 "yjIMjwEWhwEcggEgfiR6KHYscy5xMG40azZpOGc6ZTxjPmI+YUBfQl1EXERbRlpGWUhYSFdKVkpV"
6846 "TFRMVExTTlJOUk5STlJOUVBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUU5STlJOUk5STlNMVExUTFVK"
6847 "VkpXSFhIWUZaRltEXERdQl9AYT5iPmM8ZTpnOGk2azRuMHEucyx2KHokfiCCARyHARaPAQzKMgAA");
6848 ok(match, "Figure does not match.\n");
6850 ID2D1RenderTarget_BeginDraw(rt);
6851 set_color(&color, 0.396f, 0.180f, 0.537f, 1.0f);
6852 ID2D1RenderTarget_Clear(rt, &color);
6854 set_rounded_rect(&rounded_rect, 40.0f, 160.0f, 40.0f, 160.0f, 10.0f, 10.0f);
6855 ID2D1RenderTarget_FillRoundedRectangle(rt, &rounded_rect, (ID2D1Brush *)brush);
6856 set_rounded_rect(&rounded_rect, 100.0f, 160.0f, 140.0f, 160.0f, 10.0f, 10.0f);
6857 ID2D1RenderTarget_FillRoundedRectangle(rt, &rounded_rect, (ID2D1Brush *)brush);
6858 set_rounded_rect(&rounded_rect, 200.0f, 80.0f, 200.0f, 240.0f, 10.0f, 10.0f);
6859 ID2D1RenderTarget_FillRoundedRectangle(rt, &rounded_rect, (ID2D1Brush *)brush);
6860 set_rounded_rect(&rounded_rect, 260.0f, 240.0f, 300.0f, 80.0f, 10.0f, 10.0f);
6861 ID2D1RenderTarget_FillRoundedRectangle(rt, &rounded_rect, (ID2D1Brush *)brush);
6863 set_rounded_rect(&rounded_rect, 40.0f, 480.0f, 40.0f, 480.0f, 10.0f, 20.0f);
6864 ID2D1RenderTarget_FillRoundedRectangle(rt, &rounded_rect, (ID2D1Brush *)brush);
6865 set_rounded_rect(&rounded_rect, 100.0f, 480.0f, 140.0f, 480.0f, 10.0f, 20.0f);
6866 ID2D1RenderTarget_FillRoundedRectangle(rt, &rounded_rect, (ID2D1Brush *)brush);
6867 set_rounded_rect(&rounded_rect, 200.0f, 400.0f, 200.0f, 560.0f, 10.0f, 20.0f);
6868 ID2D1RenderTarget_FillRoundedRectangle(rt, &rounded_rect, (ID2D1Brush *)brush);
6869 set_rounded_rect(&rounded_rect, 260.0f, 560.0f, 300.0f, 400.0f, 10.0f, 20.0f);
6870 ID2D1RenderTarget_FillRoundedRectangle(rt, &rounded_rect, (ID2D1Brush *)brush);
6872 set_rounded_rect(&rounded_rect, 40.0f, 800.0f, 40.0f, 800.0f, 10.0f, 5.0f);
6873 ID2D1RenderTarget_FillRoundedRectangle(rt, &rounded_rect, (ID2D1Brush *)brush);
6874 set_rounded_rect(&rounded_rect, 100.0f, 800.0f, 140.0f, 800.0f, 10.0f, 5.0f);
6875 ID2D1RenderTarget_FillRoundedRectangle(rt, &rounded_rect, (ID2D1Brush *)brush);
6876 set_rounded_rect(&rounded_rect, 200.0f, 720.0f, 200.0f, 880.0f, 10.0f, 5.0f);
6877 ID2D1RenderTarget_FillRoundedRectangle(rt, &rounded_rect, (ID2D1Brush *)brush);
6878 set_rounded_rect(&rounded_rect, 260.0f, 880.0f, 300.0f, 720.0f, 10.0f, 5.0f);
6879 ID2D1RenderTarget_FillRoundedRectangle(rt, &rounded_rect, (ID2D1Brush *)brush);
6881 hr = ID2D1RenderTarget_EndDraw(rt, NULL, NULL);
6882 ok(SUCCEEDED(hr), "Failed to end draw, hr %#x.\n", hr);
6884 match = compare_figure(surface, 0, 0, 160, 160, 0xff652e89, 0, "gMgB");
6885 ok(match, "Figure does not match.\n");
6886 match = compare_figure(surface, 160, 0, 160, 160, 0xff652e89, 0, "gMgB");
6887 ok(match, "Figure does not match.\n");
6888 match = compare_figure(surface, 320, 0, 160, 160, 0xff652e89, 0, "gMgB");
6889 ok(match, "Figure does not match.\n");
6890 match = compare_figure(surface, 480, 0, 160, 160, 0xff652e89, 0,
6891 "szI6YURZSlROUVBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQ"
6892 "UFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQ"
6893 "UFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUU5USllEYTqzMgAA");
6894 ok(match, "Figure does not match.\n");
6896 match = compare_figure(surface, 0, 160, 160, 160, 0xff652e89, 0, "gMgB");
6897 ok(match, "Figure does not match.\n");
6898 match = compare_figure(surface, 160, 160, 160, 160, 0xff652e89, 0, "gMgB");
6899 ok(match, "Figure does not match.\n");
6900 match = compare_figure(surface, 320, 160, 160, 160, 0xff652e89, 0, "gMgB");
6901 ok(match, "Figure does not match.\n");
6902 match = compare_figure(surface, 480, 160, 160, 160, 0xff652e89, 2,
6903 "tjI0aDxhQlxGWEpVTFNOUk5RUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQ"
6904 "UFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQ"
6905 "UFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFFOUk5TTFVKWEZcQmA+ZzS2MgAA");
6906 ok(match, "Figure does not match.\n");
6908 match = compare_figure(surface, 0, 320, 160, 160, 0xff652e89, 0, "gMgB");
6909 ok(match, "Figure does not match.\n");
6910 match = compare_figure(surface, 160, 320, 160, 160, 0xff652e89, 0, "gMgB");
6911 ok(match, "Figure does not match.\n");
6912 match = compare_figure(surface, 320, 320, 160, 160, 0xff652e89, 0, "gMgB");
6913 ok(match, "Figure does not match.\n");
6914 match = compare_figure(surface, 480, 320, 160, 160, 0xff652e89, 0,
6915 "sDJAWkxSUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQ"
6916 "UFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQ"
6917 "UFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFJMWkCwMgAA");
6918 ok(match, "Figure does not match.\n");
6920 ID2D1RenderTarget_BeginDraw(rt);
6921 set_color(&color, 0.396f, 0.180f, 0.537f, 1.0f);
6922 ID2D1RenderTarget_Clear(rt, &color);
6924 set_rounded_rect(&rounded_rect, 40.0f, 160.0f, 40.0f, 160.0f, 1000.0f, 1000.0f);
6925 ID2D1RenderTarget_FillRoundedRectangle(rt, &rounded_rect, (ID2D1Brush *)brush);
6926 set_rounded_rect(&rounded_rect, 100.0f, 160.0f, 140.0f, 160.0f, 1000.0f, 1000.0f);
6927 ID2D1RenderTarget_FillRoundedRectangle(rt, &rounded_rect, (ID2D1Brush *)brush);
6928 set_rounded_rect(&rounded_rect, 200.0f, 80.0f, 200.0f, 240.0f, 1000.0f, 1000.0f);
6929 ID2D1RenderTarget_FillRoundedRectangle(rt, &rounded_rect, (ID2D1Brush *)brush);
6930 set_rounded_rect(&rounded_rect, 260.0f, 240.0f, 300.0f, 80.0f, 1000.0f, 1000.0f);
6931 ID2D1RenderTarget_FillRoundedRectangle(rt, &rounded_rect, (ID2D1Brush *)brush);
6933 set_rounded_rect(&rounded_rect, 40.0f, 480.0f, 40.0f, 480.0f, 10.0f, 1000.0f);
6934 ID2D1RenderTarget_FillRoundedRectangle(rt, &rounded_rect, (ID2D1Brush *)brush);
6935 set_rounded_rect(&rounded_rect, 100.0f, 480.0f, 140.0f, 480.0f, 10.0f, 1000.0f);
6936 ID2D1RenderTarget_FillRoundedRectangle(rt, &rounded_rect, (ID2D1Brush *)brush);
6937 set_rounded_rect(&rounded_rect, 200.0f, 400.0f, 200.0f, 560.0f, 10.0f, 1000.0f);
6938 ID2D1RenderTarget_FillRoundedRectangle(rt, &rounded_rect, (ID2D1Brush *)brush);
6939 set_rounded_rect(&rounded_rect, 260.0f, 560.0f, 300.0f, 400.0f, 10.0f, 1000.0f);
6940 ID2D1RenderTarget_FillRoundedRectangle(rt, &rounded_rect, (ID2D1Brush *)brush);
6942 set_rounded_rect(&rounded_rect, 40.0f, 800.0f, 40.0f, 800.0f, 1000.0f, 10.0f);
6943 ID2D1RenderTarget_FillRoundedRectangle(rt, &rounded_rect, (ID2D1Brush *)brush);
6944 set_rounded_rect(&rounded_rect, 100.0f, 800.0f, 140.0f, 800.0f, 1000.0f, 10.0f);
6945 ID2D1RenderTarget_FillRoundedRectangle(rt, &rounded_rect, (ID2D1Brush *)brush);
6946 set_rounded_rect(&rounded_rect, 200.0f, 720.0f, 200.0f, 880.0f, 1000.0f, 10.0f);
6947 ID2D1RenderTarget_FillRoundedRectangle(rt, &rounded_rect, (ID2D1Brush *)brush);
6948 set_rounded_rect(&rounded_rect, 260.0f, 880.0f, 300.0f, 720.0f, 1000.0f, 10.0f);
6949 ID2D1RenderTarget_FillRoundedRectangle(rt, &rounded_rect, (ID2D1Brush *)brush);
6951 hr = ID2D1RenderTarget_EndDraw(rt, NULL, NULL);
6952 ok(SUCCEEDED(hr), "Failed to end draw, hr %#x.\n", hr);
6954 match = compare_figure(surface, 0, 0, 160, 160, 0xff652e89, 0, "gMgB");
6955 ok(match, "Figure does not match.\n");
6956 match = compare_figure(surface, 160, 0, 160, 160, 0xff652e89, 0, "gMgB");
6957 ok(match, "Figure does not match.\n");
6958 match = compare_figure(surface, 320, 0, 160, 160, 0xff652e89, 0, "gMgB");
6959 ok(match, "Figure does not match.\n");
6960 match = compare_figure(surface, 480, 0, 160, 160, 0xff652e89, 10,
6961 "yjIMjwEWhwEcggEgfiR6KHYscy5xMG40azZpOGc6ZTxjPmI+YUBfQl1EXERbRlpGWUhYSFdKVkpV"
6962 "TFRMVExTTlJOUk5STlJOUVBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUU5STlJOUk5STlNMVExUTFVK"
6963 "VkpXSFhIWUZaRltEXERdQl9AYT5iPmM8ZTpnOGk2azRuMHEucyx2KHokfiCCARyHARaPAQzKMgAA");
6964 ok(match, "Figure does not match.\n");
6966 match = compare_figure(surface, 0, 160, 160, 160, 0xff652e89, 0, "gMgB");
6967 ok(match, "Figure does not match.\n");
6968 match = compare_figure(surface, 160, 160, 160, 160, 0xff652e89, 0, "gMgB");
6969 ok(match, "Figure does not match.\n");
6970 match = compare_figure(surface, 320, 160, 160, 160, 0xff652e89, 0, "gMgB");
6971 ok(match, "Figure does not match.\n");
6972 match = compare_figure(surface, 480, 160, 160, 160, 0xff652e89, 10,
6973 "uTIucDJsNmk4ZzplPGM+YUBgQF9CXkJdRFxEW0ZaRllIWEhXSlZKVkpWSlVMVExUTFRMU05STlJO"
6974 "Uk5STlJOUk9QUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFFPUU5STlJOUk5STlJOU0xU"
6975 "TFRMVExVSlZKVkpWSldIWEhZRlpGW0RcRF1CXkJfQGBAYT5jPGU6ZzhpNmwycC65MgAA");
6976 ok(match, "Figure does not match.\n");
6978 match = compare_figure(surface, 0, 320, 160, 160, 0xff652e89, 0, "gMgB");
6979 ok(match, "Figure does not match.\n");
6980 match = compare_figure(surface, 160, 320, 160, 160, 0xff652e89, 0, "gMgB");
6981 ok(match, "Figure does not match.\n");
6982 match = compare_figure(surface, 320, 320, 160, 160, 0xff652e89, 0, "gMgB");
6983 ok(match, "Figure does not match.\n");
6984 match = compare_figure(surface, 480, 320, 160, 160, 0xff652e89, 10,
6985 "vzIiczhhRldMUlBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQ"
6986 "UFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQ"
6987 "UFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUkxXRmA6cSS+MgAA");
6988 ok(match, "Figure does not match.\n");
6990 hr = ID2D1Factory_CreatePathGeometry(factory, &geometry);
6991 ok(SUCCEEDED(hr), "Failed to create path geometry, hr %#x.\n", hr);
6992 hr = ID2D1PathGeometry_Open(geometry, &sink);
6993 ok(SUCCEEDED(hr), "Failed to open geometry sink, hr %#x.\n", hr);
6995 set_point(&point, 40.0f, 160.0f);
6996 ID2D1GeometrySink_BeginFigure(sink, point, D2D1_FIGURE_BEGIN_FILLED);
6997 ID2D1GeometrySink_EndFigure(sink, D2D1_FIGURE_END_OPEN);
6999 set_point(&point, 120.0f, 160.0f);
7000 ID2D1GeometrySink_BeginFigure(sink, point, D2D1_FIGURE_BEGIN_FILLED);
7001 line_to(sink, 120.0f, 160.0f);
7002 ID2D1GeometrySink_EndFigure(sink, D2D1_FIGURE_END_OPEN);
7004 set_point(&point, 200.0f, 160.0f);
7005 ID2D1GeometrySink_BeginFigure(sink, point, D2D1_FIGURE_BEGIN_FILLED);
7006 ID2D1GeometrySink_EndFigure(sink, D2D1_FIGURE_END_CLOSED);
7008 set_point(&point, 280.0f, 160.0f);
7009 ID2D1GeometrySink_BeginFigure(sink, point, D2D1_FIGURE_BEGIN_FILLED);
7010 line_to(sink, 280.0f, 160.0f);
7011 ID2D1GeometrySink_EndFigure(sink, D2D1_FIGURE_END_CLOSED);
7013 set_point(&point, 20.0f, 480.0f);
7014 ID2D1GeometrySink_BeginFigure(sink, point, D2D1_FIGURE_BEGIN_FILLED);
7015 line_to(sink, 60.0f, 480.0f);
7016 ID2D1GeometrySink_EndFigure(sink, D2D1_FIGURE_END_OPEN);
7018 set_point(&point, 120.0f, 400.0f);
7019 ID2D1GeometrySink_BeginFigure(sink, point, D2D1_FIGURE_BEGIN_FILLED);
7020 line_to(sink, 120.0f, 560.0f);
7021 line_to(sink, 120.0f, 400.0f);
7022 line_to(sink, 120.0f, 560.0f);
7023 ID2D1GeometrySink_EndFigure(sink, D2D1_FIGURE_END_OPEN);
7025 set_point(&point, 180.0f, 480.0f);
7026 ID2D1GeometrySink_BeginFigure(sink, point, D2D1_FIGURE_BEGIN_FILLED);
7027 line_to(sink, 220.0f, 480.0f);
7028 ID2D1GeometrySink_EndFigure(sink, D2D1_FIGURE_END_CLOSED);
7030 set_point(&point, 280.0f, 400.0f);
7031 ID2D1GeometrySink_BeginFigure(sink, point, D2D1_FIGURE_BEGIN_FILLED);
7032 line_to(sink, 280.0f, 560.0f);
7033 line_to(sink, 280.0f, 400.0f);
7034 line_to(sink, 280.0f, 560.0f);
7035 ID2D1GeometrySink_EndFigure(sink, D2D1_FIGURE_END_CLOSED);
7037 set_point(&point, 20.0f, 880.0f);
7038 ID2D1GeometrySink_BeginFigure(sink, point, D2D1_FIGURE_BEGIN_FILLED);
7039 line_to(sink, 40.0f, 720.0f);
7040 line_to(sink, 60.0f, 880.0f);
7041 ID2D1GeometrySink_EndFigure(sink, D2D1_FIGURE_END_OPEN);
7043 set_point(&point, 100.0f, 720.0f);
7044 ID2D1GeometrySink_BeginFigure(sink, point, D2D1_FIGURE_BEGIN_FILLED);
7045 line_to(sink, 120.0f, 880.0f);
7046 line_to(sink, 140.0f, 720.0f);
7047 ID2D1GeometrySink_EndFigure(sink, D2D1_FIGURE_END_OPEN);
7049 set_point(&point, 180.0f, 880.0f);
7050 ID2D1GeometrySink_BeginFigure(sink, point, D2D1_FIGURE_BEGIN_FILLED);
7051 line_to(sink, 200.0f, 720.0f);
7052 line_to(sink, 220.0f, 880.0f);
7053 ID2D1GeometrySink_EndFigure(sink, D2D1_FIGURE_END_CLOSED);
7055 set_point(&point, 260.0f, 720.0f);
7056 ID2D1GeometrySink_BeginFigure(sink, point, D2D1_FIGURE_BEGIN_FILLED);
7057 line_to(sink, 280.0f, 880.0f);
7058 line_to(sink, 300.0f, 720.0f);
7059 ID2D1GeometrySink_EndFigure(sink, D2D1_FIGURE_END_CLOSED);
7061 ID2D1GeometrySink_SetFillMode(sink, D2D1_FILL_MODE_ALTERNATE);
7062 hr = ID2D1GeometrySink_Close(sink);
7063 ok(SUCCEEDED(hr), "Failed to close geometry sink, hr %#x.\n", hr);
7064 ID2D1GeometrySink_Release(sink);
7066 ID2D1RenderTarget_BeginDraw(rt);
7067 ID2D1RenderTarget_Clear(rt, &color);
7068 ID2D1RenderTarget_FillGeometry(rt, (ID2D1Geometry *)geometry, (ID2D1Brush *)brush, NULL);
7069 hr = ID2D1RenderTarget_EndDraw(rt, NULL, NULL);
7070 ok(SUCCEEDED(hr), "Failed to end draw, hr %#x.\n", hr);
7071 ID2D1PathGeometry_Release(geometry);
7073 match = compare_figure(surface, 0, 0, 160, 160, 0xff652e89, 0, "gMgB");
7074 ok(match, "Figure does not match.\n");
7075 match = compare_figure(surface, 160, 0, 160, 160, 0xff652e89, 0, "gMgB");
7076 ok(match, "Figure does not match.\n");
7077 match = compare_figure(surface, 320, 0, 160, 160, 0xff652e89, 0, "gMgB");
7078 ok(match, "Figure does not match.\n");
7079 match = compare_figure(surface, 480, 0, 160, 160, 0xff652e89, 0, "gMgB");
7080 ok(match, "Figure does not match.\n");
7082 match = compare_figure(surface, 0, 160, 160, 160, 0xff652e89, 0, "gMgB");
7083 ok(match, "Figure does not match.\n");
7084 match = compare_figure(surface, 160, 160, 160, 160, 0xff652e89, 0, "gMgB");
7085 ok(match, "Figure does not match.\n");
7086 match = compare_figure(surface, 320, 160, 160, 160, 0xff652e89, 0, "gMgB");
7087 ok(match, "Figure does not match.\n");
7088 match = compare_figure(surface, 480, 160, 160, 160, 0xff652e89, 0, "gMgB");
7089 ok(match, "Figure does not match.\n");
7091 match = compare_figure(surface, 0, 320, 160, 160, 0xff652e89, 0,
7092 "7zMCngECnQEEnAEEmwEGmgEGmQEImAEIlwEKlgEKlQEMlAEMkwEOkgEOkQEQkAEQjwESjgESjQEU"
7093 "jAEUiwEWigEWiQEYiAEYhwEahgEahQEchAEcgwEeggEegQEggAEgfyJ+In0kfCR7JnomeSh4KHcq"
7094 "dip1LHQscy5yLnEwcDBvMm4ybTRsNGs2ajZpOGg4ZzpmOmU8ZDxjPmI+YUBgQF9CXkJdRFxEW0Za"
7095 "RllIWEhXSlZKVUxUTFNOUk5RUKgy");
7096 ok(match, "Figure does not match.\n");
7097 match = compare_figure(surface, 160, 320, 160, 160, 0xff652e89, 0,
7098 "qDJQUU5STlNMVExVSlZKV0hYSFlGWkZbRFxEXUJeQl9AYEBhPmI+YzxkPGU6ZjpnOGg4aTZqNms0"
7099 "bDRtMm4ybzBwMHEuci5zLHQsdSp2KncoeCh5JnomeyR8JH0ifiJ/IIABIIEBHoIBHoMBHIQBHIUB"
7100 "GoYBGocBGIgBGIkBFooBFosBFIwBFI0BEo4BEo8BEJABEJEBDpIBDpMBDJQBDJUBCpYBCpcBCJgB"
7101 "CJkBBpoBBpsBBJwBBJ0BAp4BAu8z");
7102 ok(match, "Figure does not match.\n");
7103 match = compare_figure(surface, 320, 320, 160, 160, 0xff652e89, 0,
7104 "7zMCngECnQEEnAEEmwEGmgEGmQEImAEIlwEKlgEKlQEMlAEMkwEOkgEOkQEQkAEQjwESjgESjQEU"
7105 "jAEUiwEWigEWiQEYiAEYhwEahgEahQEchAEcgwEeggEegQEggAEgfyJ+In0kfCR7JnomeSh4KHcq"
7106 "dip1LHQscy5yLnEwcDBvMm4ybTRsNGs2ajZpOGg4ZzpmOmU8ZDxjPmI+YUBgQF9CXkJdRFxEW0Za"
7107 "RllIWEhXSlZKVUxUTFNOUk5RUKgy");
7108 ok(match, "Figure does not match.\n");
7109 match = compare_figure(surface, 480, 320, 160, 160, 0xff652e89, 0,
7110 "qDJQUU5STlNMVExVSlZKV0hYSFlGWkZbRFxEXUJeQl9AYEBhPmI+YzxkPGU6ZjpnOGg4aTZqNms0"
7111 "bDRtMm4ybzBwMHEuci5zLHQsdSp2KncoeCh5JnomeyR8JH0ifiJ/IIABIIEBHoIBHoMBHIQBHIUB"
7112 "GoYBGocBGIgBGIkBFooBFosBFIwBFI0BEo4BEo8BEJABEJEBDpIBDpMBDJQBDJUBCpYBCpcBCJgB"
7113 "CJkBBpoBBpsBBJwBBJ0BAp4BAu8z");
7114 ok(match, "Figure does not match.\n");
7116 set_rect(&rect, 20.0f, 80.0f, 60.0f, 240.0f);
7117 hr = ID2D1Factory_CreateRectangleGeometry(factory, &rect, &rect_geometry[0]);
7118 ok(SUCCEEDED(hr), "Failed to create geometry, hr %#x.\n", hr);
7120 set_rect(&rect, -1.0f, -1.0f, 1.0f, 1.0f);
7121 hr = ID2D1Factory_CreateRectangleGeometry(factory, &rect, &rect_geometry[1]);
7122 ok(SUCCEEDED(hr), "Failed to create geometry, hr %#x.\n", hr);
7124 set_matrix_identity(&matrix);
7125 translate_matrix(&matrix, 160.0f, 640.0f);
7126 scale_matrix(&matrix, 40.0f, 160.0f);
7127 rotate_matrix(&matrix, M_PI / -5.0f);
7128 hr = ID2D1Factory_CreateTransformedGeometry(factory,
7129 (ID2D1Geometry *)rect_geometry[1], &matrix, &transformed_geometry[0]);
7130 ok(SUCCEEDED(hr), "Failed to create geometry, hr %#x.\n", hr);
7132 set_matrix_identity(&matrix);
7133 scale_matrix(&matrix, 0.5f, 1.0f);
7134 translate_matrix(&matrix, -80.0f, 0.0f);
7135 hr = ID2D1Factory_CreateTransformedGeometry(factory,
7136 (ID2D1Geometry *)transformed_geometry[0], &matrix, &transformed_geometry[1]);
7137 ok(SUCCEEDED(hr), "Failed to create geometry, hr %#x.\n", hr);
7139 set_matrix_identity(&matrix);
7140 rotate_matrix(&matrix, M_PI / 2.0f);
7141 translate_matrix(&matrix, 80.0f, -320.0f);
7142 scale_matrix(&matrix, 2.0f, 0.25f);
7143 hr = ID2D1Factory_CreateTransformedGeometry(factory,
7144 (ID2D1Geometry *)transformed_geometry[1], &matrix, &transformed_geometry[2]);
7145 ok(SUCCEEDED(hr), "Failed to create geometry, hr %#x.\n", hr);
7147 ID2D1RenderTarget_BeginDraw(rt);
7148 ID2D1RenderTarget_Clear(rt, &color);
7149 ID2D1RenderTarget_FillGeometry(rt, (ID2D1Geometry *)rect_geometry[0], (ID2D1Brush *)brush, NULL);
7150 ID2D1RenderTarget_FillGeometry(rt, (ID2D1Geometry *)transformed_geometry[0], (ID2D1Brush *)brush, NULL);
7151 ID2D1RenderTarget_FillGeometry(rt, (ID2D1Geometry *)transformed_geometry[1], (ID2D1Brush *)brush, NULL);
7152 ID2D1RenderTarget_FillGeometry(rt, (ID2D1Geometry *)transformed_geometry[2], (ID2D1Brush *)brush, NULL);
7153 hr = ID2D1RenderTarget_EndDraw(rt, NULL, NULL);
7154 ok(SUCCEEDED(hr), "Failed to end draw, hr %#x.\n", hr);
7155 ID2D1TransformedGeometry_Release(transformed_geometry[2]);
7156 ID2D1TransformedGeometry_Release(transformed_geometry[1]);
7157 ID2D1TransformedGeometry_Release(transformed_geometry[0]);
7158 ID2D1RectangleGeometry_Release(rect_geometry[1]);
7159 ID2D1RectangleGeometry_Release(rect_geometry[0]);
7161 match = compare_figure(surface, 0, 0, 160, 160, 0xff652e89, 0,
7162 "qDJQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQ"
7163 "UFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQ"
7164 "UFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFCoMgAA");
7165 ok(match, "Figure does not match.\n");
7166 match = compare_figure(surface, 160, 0, 320, 160, 0xff652e89, 32,
7167 "sIMBA7cCDK8CFKYCHZ4CJJYCLY4CNYUCPv0BRvQBT+wBV+MBYNsBaNIBccoBecEBgQG6AYkBsQGS"
7168 "AakBmgGgAaMBmAGrAY8BtAGHAbwBfsUBfcYBfcYBfcUBfsUBfcYBfcYBfcYBfcYBfcUBfr0BhgG0"
7169 "AY8BrAGXAaMBoAGbAagBkgGwAYsBuAGCAcEBeskBcdIBadoBYOMBWOsBT/QBR/wBPoUCNowCLpUC"
7170 "Jp0CHaYCFa4CDLcCBK+DAQAA");
7171 ok(match, "Figure does not match.\n");
7172 match = compare_figure(surface, 0, 160, 160, 320, 0xff652e89, 32,
7173 "+D0BngEDnQEDnAEEmwEGmgEGmQEHmAEJlwEJlgELlAEMkwENkwEOkQEPkAEQkAERjgESjQETjQEU"
7174 "iwEVigEXiQEXiAEYhwEahgEahQEbhAEdggEeggEegQEgfyF/In0jfCR8JXomeSd5KHcpdip2K3Qs"
7175 "cy5xL3EvcDFuMm4ybTRrNWs1ajdoOGg5ZjplO2U8Yz1iPmFAYEBfQV5DXUNcRVpGWkZZSFdJV0lW"
7176 "S1RMVExTTlFPUFFPUU5STVRMVEtVSldJV0hYR1pGWkVcQ11CXkJfQGA/YT9iPWM+Yj5jPWM+Yz1j"
7177 "PWM+Yz1jPmI+Yz1jPmI+Yz1jPmM9Yz1jPmM9Yz5iPmM9Yz5iPmM9Yz5jPWM9Yz5jPWM+Yj5jPWM+"
7178 "Yj5jPWI/YT9gQF9CXkJdRFtFW0VaR1hIV0lXSlVLVExUTVJOUVBQUE9RTlNNU0xUS1ZKVklXSFlG"
7179 "WkZaRVxDXUNeQV9AYEBhPmI9Yz1kO2U6ZjpnOGg3ajVrNWs0bTJuMm4xcC9xL3Eucyx0LHUqdil3"
7180 "KXgneSZ6JXwkfCN9In8hfyCBAR6CAR6CAR2EARuFARuFARqHARiIAReJAReKARWLARSNARONARKO"
7181 "ARGQARCQAQ+RAQ6TAQ2TAQyUAQuWAQqWAQmYAQeZAQaaAQabAQScAQOdAQOeAQH4PQAA");
7182 ok(match, "Figure does not match.\n");
7183 match = compare_figure(surface, 160, 160, 320, 320, 0xff652e89, 32,
7184 "sXkBvgIDvAIEugIHuAIJtgILswINsgIPrwISrQITrAIVqQIYpwIapQIbowIeoQIgngIjnAIkmwIm"
7185 "mAIplgIqlQIskgIvkAIxjQIzjAI1igI3hwI5hgI7hAI9gQJA/wFB/QFE+wFG+QFI9gFK9QFM8wFO"
7186 "8AFQ7wFS7AFV6gFX6AFY5gFb5AFd4gFf3wFh3gFj2wFm2QFn2AFp1QFs0wFu0QFvzwFyzQF0ygF3"
7187 "yAF4xwF6xAF9wgF+wAGBAb4BgwG8AYUBuQGHAbgBiQG2AYsBswGOAbEBjwGvAZIBrQGUAasBlQGp"
7188 "AZgBpwGaAaUBnAGiAZ4BoQGgAZ4BowGcAaUBmgGmAZgBqQGWAasBlAGsAZIBrwGQAbEBjQG0AYsB"
7189 "tQGKAbcBhwG6AYUBvAGDAb0BgQHAAX/CAXzEAXvGAXvGAXvGAXvFAXvGAXvGAXvGAXvFAXvGAXvG"
7190 "AXvFAXvGAXvGAXvGAXvFAXvGAXvGAXvFAXzFAXvGAXvGAXvFAXvGAXvGAXvGAXvFAXvGAXvGAXvF"
7191 "AXzFAXvGAXvGAXvFAXvGAXvGAXvGAXvEAXzCAX/AAYEBvgGCAbwBhQG6AYcBtwGKAbUBiwG0AY0B"
7192 "sQGQAa8BkgGtAZMBqwGWAakBmAGmAZoBpQGcAaMBngGgAaEBngGiAZ0BpAGaAacBmAGpAZUBqwGU"
7193 "Aa0BkgGvAY8BsQGOAbMBjAG1AYkBuAGHAbkBhQG8AYMBvgGBAcABfsIBfcQBe8YBeMgBd8oBdM0B"
7194 "cs8BcNABbtMBbNUBatcBZ9kBZtsBY94BYd8BYOEBXeQBW+YBWOgBV+oBVewBUu8BUPABT/IBTPUB"
7195 "SvYBSPkBRvsBRP0BQf8BQIECPoMCO4YCOYcCN4oCNYwCM40CMZACL5ICLZQCKpYCKZgCJpsCJJ0C"
7196 "Ip4CIKECHqMCHKQCGqcCGKkCFawCE60CEq8CD7ICDbMCDLUCCbgCB7oCBLwCA74CAbF5");
7197 ok(match, "Figure does not match.\n");
7199 hr = ID2D1Factory_CreatePathGeometry(factory, &geometry);
7200 ok(SUCCEEDED(hr), "Failed to create path geometry, hr %#x.\n", hr);
7201 hr = ID2D1PathGeometry_Open(geometry, &sink);
7202 ok(SUCCEEDED(hr), "Failed to open geometry sink, hr %#x.\n", hr);
7204 set_point(&point, 20.0f, 80.0f);
7205 ID2D1GeometrySink_BeginFigure(sink, point, D2D1_FIGURE_BEGIN_FILLED);
7206 quadratic_to(sink, 40.0f, 80.0f, 60.0f, 80.0f);
7207 quadratic_to(sink, 60.0f, 160.0f, 60.0f, 240.0f);
7208 quadratic_to(sink, 40.0f, 240.0f, 20.0f, 240.0f);
7209 quadratic_to(sink, 20.0f, 160.0f, 20.0f, 80.0f);
7210 ID2D1GeometrySink_EndFigure(sink, D2D1_FIGURE_END_CLOSED);
7212 set_point(&point, 100.0f, 80.0f);
7213 ID2D1GeometrySink_BeginFigure(sink, point, D2D1_FIGURE_BEGIN_FILLED);
7214 quadratic_to(sink, 105.0f, 80.0f, 140.0f, 80.0f);
7215 quadratic_to(sink, 140.0f, 100.0f, 140.0f, 240.0f);
7216 quadratic_to(sink, 135.0f, 240.0f, 100.0f, 240.0f);
7217 quadratic_to(sink, 100.0f, 220.0f, 100.0f, 80.0f);
7218 ID2D1GeometrySink_EndFigure(sink, D2D1_FIGURE_END_CLOSED);
7220 set_point(&point, 180.0f, 80.0f);
7221 ID2D1GeometrySink_BeginFigure(sink, point, D2D1_FIGURE_BEGIN_FILLED);
7222 quadratic_to(sink, 215.0f, 80.0f, 220.0f, 80.0f);
7223 quadratic_to(sink, 220.0f, 220.0f, 220.0f, 240.0f);
7224 quadratic_to(sink, 185.0f, 240.0f, 180.0f, 240.0f);
7225 quadratic_to(sink, 180.0f, 100.0f, 180.0f, 80.0f);
7226 ID2D1GeometrySink_EndFigure(sink, D2D1_FIGURE_END_CLOSED);
7228 set_point(&point, 260.0f, 80.0f);
7229 ID2D1GeometrySink_BeginFigure(sink, point, D2D1_FIGURE_BEGIN_FILLED);
7230 quadratic_to(sink, 280.0f, 80.0f, 300.0f, 80.0f);
7231 quadratic_to(sink, 300.0f, 160.0f, 300.0f, 240.0f);
7232 quadratic_to(sink, 280.0f, 240.0f, 260.0f, 240.0f);
7233 quadratic_to(sink, 260.0f, 160.0f, 260.0f, 80.0f);
7234 ID2D1GeometrySink_EndFigure(sink, D2D1_FIGURE_END_OPEN);
7236 set_point(&point, 20.0f, 400.0f);
7237 ID2D1GeometrySink_BeginFigure(sink, point, D2D1_FIGURE_BEGIN_FILLED);
7238 quadratic_to(sink, 40.0f, 420.0f, 60.0f, 400.0f);
7239 quadratic_to(sink, 55.0f, 480.0f, 60.0f, 560.0f);
7240 quadratic_to(sink, 40.0f, 540.0f, 20.0f, 560.0f);
7241 quadratic_to(sink, 25.0f, 480.0f, 20.0f, 400.0f);
7242 ID2D1GeometrySink_EndFigure(sink, D2D1_FIGURE_END_CLOSED);
7244 set_point(&point, 100.0f, 400.0f);
7245 ID2D1GeometrySink_BeginFigure(sink, point, D2D1_FIGURE_BEGIN_FILLED);
7246 quadratic_to(sink, 105.0f, 420.0f, 140.0f, 400.0f);
7247 quadratic_to(sink, 135.0f, 420.0f, 140.0f, 560.0f);
7248 quadratic_to(sink, 135.0f, 540.0f, 100.0f, 560.0f);
7249 quadratic_to(sink, 105.0f, 540.0f, 100.0f, 400.0f);
7250 ID2D1GeometrySink_EndFigure(sink, D2D1_FIGURE_END_CLOSED);
7252 set_point(&point, 180.0f, 400.0f);
7253 ID2D1GeometrySink_BeginFigure(sink, point, D2D1_FIGURE_BEGIN_FILLED);
7254 quadratic_to(sink, 215.0f, 420.0f, 220.0f, 400.0f);
7255 quadratic_to(sink, 215.0f, 540.0f, 220.0f, 560.0f);
7256 quadratic_to(sink, 185.0f, 540.0f, 180.0f, 560.0f);
7257 quadratic_to(sink, 185.0f, 420.0f, 180.0f, 400.0f);
7258 ID2D1GeometrySink_EndFigure(sink, D2D1_FIGURE_END_CLOSED);
7260 set_point(&point, 260.0f, 400.0f);
7261 ID2D1GeometrySink_BeginFigure(sink, point, D2D1_FIGURE_BEGIN_FILLED);
7262 quadratic_to(sink, 280.0f, 420.0f, 300.0f, 400.0f);
7263 quadratic_to(sink, 295.0f, 480.0f, 300.0f, 560.0f);
7264 quadratic_to(sink, 280.0f, 540.0f, 260.0f, 560.0f);
7265 quadratic_to(sink, 265.0f, 480.0f, 260.0f, 400.0f);
7266 ID2D1GeometrySink_EndFigure(sink, D2D1_FIGURE_END_OPEN);
7268 set_point(&point, 20.0f, 720.0f);
7269 ID2D1GeometrySink_BeginFigure(sink, point, D2D1_FIGURE_BEGIN_FILLED);
7270 quadratic_to(sink, 40.0f, 700.0f, 60.0f, 720.0f);
7271 quadratic_to(sink, 65.0f, 800.0f, 60.0f, 880.0f);
7272 quadratic_to(sink, 40.0f, 900.0f, 20.0f, 880.0f);
7273 quadratic_to(sink, 15.0f, 800.0f, 20.0f, 720.0f);
7274 ID2D1GeometrySink_EndFigure(sink, D2D1_FIGURE_END_CLOSED);
7276 set_point(&point, 100.0f, 720.0f);
7277 ID2D1GeometrySink_BeginFigure(sink, point, D2D1_FIGURE_BEGIN_FILLED);
7278 quadratic_to(sink, 105.0f, 700.0f, 140.0f, 720.0f);
7279 quadratic_to(sink, 145.0f, 740.0f, 140.0f, 880.0f);
7280 quadratic_to(sink, 135.0f, 900.0f, 100.0f, 880.0f);
7281 quadratic_to(sink, 95.0f, 860.0f, 100.0f, 720.0f);
7282 ID2D1GeometrySink_EndFigure(sink, D2D1_FIGURE_END_CLOSED);
7284 set_point(&point, 180.0f, 720.0f);
7285 ID2D1GeometrySink_BeginFigure(sink, point, D2D1_FIGURE_BEGIN_FILLED);
7286 quadratic_to(sink, 215.0f, 700.0f, 220.0f, 720.0f);
7287 quadratic_to(sink, 225.0f, 860.0f, 220.0f, 880.0f);
7288 quadratic_to(sink, 185.0f, 900.0f, 180.0f, 880.0f);
7289 quadratic_to(sink, 175.0f, 740.0f, 180.0f, 720.0f);
7290 ID2D1GeometrySink_EndFigure(sink, D2D1_FIGURE_END_CLOSED);
7292 set_point(&point, 260.0f, 720.0f);
7293 ID2D1GeometrySink_BeginFigure(sink, point, D2D1_FIGURE_BEGIN_FILLED);
7294 quadratic_to(sink, 280.0f, 700.0f, 300.0f, 720.0f);
7295 quadratic_to(sink, 305.0f, 800.0f, 300.0f, 880.0f);
7296 quadratic_to(sink, 280.0f, 900.0f, 260.0f, 880.0f);
7297 quadratic_to(sink, 255.0f, 800.0f, 260.0f, 720.0f);
7298 ID2D1GeometrySink_EndFigure(sink, D2D1_FIGURE_END_OPEN);
7300 hr = ID2D1GeometrySink_Close(sink);
7301 ok(SUCCEEDED(hr), "Failed to close geometry sink, hr %#x.\n", hr);
7302 ID2D1GeometrySink_Release(sink);
7304 ID2D1RenderTarget_BeginDraw(rt);
7305 ID2D1RenderTarget_Clear(rt, &color);
7306 ID2D1RenderTarget_FillGeometry(rt, (ID2D1Geometry *)geometry, (ID2D1Brush *)brush, NULL);
7307 hr = ID2D1RenderTarget_EndDraw(rt, NULL, NULL);
7308 ok(SUCCEEDED(hr), "Failed to end draw, hr %#x.\n", hr);
7309 ID2D1PathGeometry_Release(geometry);
7311 match = compare_figure(surface, 0, 0, 160, 160, 0xff652e89, 0,
7312 "qDJQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQ"
7313 "UFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQ"
7314 "UFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFCoMgAA");
7315 ok(match, "Figure does not match.\n");
7316 match = compare_figure(surface, 160, 0, 160, 160, 0xff652e89, 0,
7317 "qDJQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQ"
7318 "UFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQ"
7319 "UFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFCoMgAA");
7320 match = compare_figure(surface, 320, 0, 160, 160, 0xff652e89, 0,
7321 "qDJQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQ"
7322 "UFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQ"
7323 "UFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFCoMgAA");
7324 ok(match, "Figure does not match.\n");
7325 match = compare_figure(surface, 480, 0, 160, 160, 0xff652e89, 0,
7326 "qDJQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQ"
7327 "UFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQ"
7328 "UFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFCoMgAA");
7329 ok(match, "Figure does not match.\n");
7331 match = compare_figure(surface, 0, 160, 160, 160, 0xff652e89, 16,
7332 "qDICTAJQB0IHUQs4C1IRLBFSGxgbUk5STlNMVExUTFRMVExVSlZKVkpWSlZKVkpXSFhIWEhYSFhI"
7333 "WEhYSFhIWEhYSFlGWkZaRlpGWkZaRlpGWkZaRlpGWkZaRlpGWkZaRlpGWkZaRlpGWkZaRlpGWkZa"
7334 "RllIWEhYSFhIWEhYSFhIWEhYSFhIV0pWSlZKVkpWSlZKVUxUTFRMVExUTFNOUk5SGxgbUhEsEVIL"
7335 "OAtRB0IHUAJMAqgy");
7336 ok(match, "Figure does not match.\n");
7337 match = compare_figure(surface, 160, 160, 160, 160, 0xff652e89, 16,
7338 "qDIBSwRQAkMKUQQ5EVIIKxtTDRkmVExUTFRMVEtVS1VLVkpWSlZKVklXSVdJV0lXSVhIWEhYSFhI"
7339 "WEhYSFhIWEhYSFhIWUdZR1lHWUdZR1lHWUdZR1lHWUdZSFhIWUdZR1lHWUdZR1lHWUdZR1lHWUdZ"
7340 "SFhIWEhYSFhIWEhYSFhIWEhYSFhJV0lXSVdJV0lWSlZKVkpWS1VLVUtUTFRMVExUJhkNUxsrCFIR"
7341 "OQRRCkMCUARLAagy");
7342 ok(match, "Figure does not match.\n");
7343 match = compare_figure(surface, 320, 160, 160, 160, 0xff652e89, 16,
7344 "qDIESwFRCkMCUhE5BFIbKwhTJhkNVExUTFRMVUtVS1VLVUpWSlZKV0lXSVdJV0lXSVdIWEhYSFhI"
7345 "WEhYSFhIWEhYSFhIWEdZR1lHWUdZR1lHWUdZR1lHWUdYSFhIWEdZR1lHWUdZR1lHWUdZR1lHWUdY"
7346 "SFhIWEhYSFhIWEhYSFhIWEhYSFdJV0lXSVdJV0lXSlZKVkpVS1VLVUtVTFRMVExUDRkmUwgrG1IE"
7347 "ORFSAkMKUQFLBKgy");
7348 ok(match, "Figure does not match.\n");
7349 match = compare_figure(surface, 480, 160, 160, 160, 0xff652e89, 16,
7350 "qDICTAJQB0IHUQs4C1IRLBFSGxgbUk5STlNMVExUTFRMVExVSlZKVkpWSlZKVkpXSFhIWEhYSFhI"
7351 "WEhYSFhIWEhYSFlGWkZaRlpGWkZaRlpGWkZaRlpGWkZaRlpGWkZaRlpGWkZaRlpGWkZaRlpGWkZa"
7352 "RllIWEhYSFhIWEhYSFhIWEhYSFhIV0pWSlZKVkpWSlZKVUxUTFRMVExUTFNOUk5SGxgbUhEsEVIL"
7353 "OAtRB0IHUAJMAqgy");
7354 ok(match, "Figure does not match.\n");
7356 match = compare_figure(surface, 0, 320, 160, 160, 0xff652e89, 16,
7357 "pCwYfixuOGNCWUxSUFBQT1JOUk5STlJOUk1UTFRMVExUTFRLVkpWSlZKVkpWSlZJWEhYSFhIWEhY"
7358 "SFhIWEhYSFhIWEdaRlpGWkZaRlpGWkZaRlpGWkZaRlpGWkZaRlpGWkZaRlpGWkZaRlpGWkZaRlpG"
7359 "WkdYSFhIWEhYSFhIWEhYSFhIWEhYSVZKVkpWSlZKVkpWS1RMVExUTFRMVE1STlJOUk5STlJPUFBQ"
7360 "UkxZQmM4bix+GKQs");
7361 ok(match, "Figure does not match.\n");
7362 match = compare_figure(surface, 160, 320, 160, 160, 0xff652e89, 16,
7363 "liwZgQErcTllQ1xLVFBQUU9STlJNVExUTFRMVExVS1VLVUpWSlZKVkpXSVdJV0lXSVdIWEhYSFhI"
7364 "WEhYSFhIWEhYSFhIWEdZR1lHWUdZR1lHWUdZR1lHWUdZR1hIWEdZR1lHWUdZR1lHWUdZR1lHWUdZ"
7365 "R1hIWEhYSFhIWEhYSFhIWEhYSFhIV0lXSVdJV0lXSlZKVkpWSlVLVUtVTFRMVExUTFRNUk5ST1FQ"
7366 "UFRLXENlOXErgQEZliwA");
7367 ok(match, "Figure does not match.\n");
7368 match = compare_figure(surface, 320, 320, 160, 160, 0xff652e89, 16,
7369 "sSwZeytrOV9DVktRUE9RTlJOUk1UTFRMVExUS1VLVUtVS1ZKVkpWSVdJV0lXSVdJV0lYSFhIWEhY"
7370 "SFhIWEhYSFhIWEhYSFlHWUdZR1lHWUdZR1lHWUdZR1lIWEhYSFlHWUdZR1lHWUdZR1lHWUdZR1lI"
7371 "WEhYSFhIWEhYSFhIWEhYSFhIWElXSVdJV0lXSVdJVkpWSlZLVUtVS1VLVExUTFRMVE1STlJOUU9Q"
7372 "UUtWQ185ayt7GbEs");
7373 ok(match, "Figure does not match.\n");
7374 match = compare_figure(surface, 480, 320, 160, 160, 0xff652e89, 16,
7375 "pCwYfixuOGNCWUxSUFBQT1JOUk5STlJOUk1UTFRMVExUTFRLVkpWSlZKVkpWSlZJWEhYSFhIWEhY"
7376 "SFhIWEhYSFhIWEdaRlpGWkZaRlpGWkZaRlpGWkZaRlpGWkZaRlpGWkZaRlpGWkZaRlpGWkZaRlpG"
7377 "WkdYSFhIWEhYSFhIWEhYSFhIWEhYSVZKVkpWSlZKVkpWS1RMVExUTFRMVE1STlJOUk5STlJPUFBQ"
7378 "UkxZQmM4bix+GKQs");
7379 ok(match, "Figure does not match.\n");
7381 hr = ID2D1Factory_CreatePathGeometry(factory, &geometry);
7382 ok(SUCCEEDED(hr), "Failed to create path geometry, hr %#x.\n", hr);
7383 hr = ID2D1PathGeometry_Open(geometry, &sink);
7384 ok(SUCCEEDED(hr), "Failed to open geometry sink, hr %#x.\n", hr);
7386 set_point(&point, -0.402914f, 0.915514f);
7387 ID2D1GeometrySink_BeginFigure(sink, point, D2D1_FIGURE_BEGIN_FILLED);
7388 quadratic_to(sink, -0.310379f, 0.882571f, -0.116057f, 0.824000f);
7389 quadratic_to(sink, 0.008350f, 0.693614f, -0.052343f, 0.448886f);
7390 quadratic_to(sink, -0.154236f, 0.246072f, -0.279229f, 0.025343f);
7391 quadratic_to(sink, -0.370064f, -0.588586f, -0.383029f, -0.924114f);
7392 quadratic_to(sink, -0.295479f, -0.958764f, -0.017086f, -0.988400f);
7393 quadratic_to(sink, 0.208836f, -0.954157f, 0.272200f, -0.924114f);
7394 quadratic_to(sink, 0.295614f, -0.569071f, 0.230143f, 0.022886f);
7395 quadratic_to(sink, 0.101664f, 0.220643f, 0.012057f, 0.451571f);
7396 quadratic_to(sink, -0.028764f, 0.709014f, 0.104029f, 0.833943f);
7397 quadratic_to(sink, 0.319414f, 0.913057f, 0.403229f, 0.942628f);
7398 quadratic_to(sink, 0.317721f, 1.023450f, -0.017086f, 1.021771f);
7399 quadratic_to(sink, -0.310843f, 1.007472f, -0.402914f, 0.915514f);
7400 ID2D1GeometrySink_EndFigure(sink, D2D1_FIGURE_END_CLOSED);
7402 hr = ID2D1GeometrySink_Close(sink);
7403 ok(SUCCEEDED(hr), "Failed to close geometry sink, hr %#x.\n", hr);
7404 ID2D1GeometrySink_Release(sink);
7406 set_matrix_identity(&matrix);
7407 translate_matrix(&matrix, 40.0f, 160.0f);
7408 scale_matrix(&matrix, 20.0f, 80.0f);
7409 hr = ID2D1Factory_CreateTransformedGeometry(factory,
7410 (ID2D1Geometry *)geometry, &matrix, &transformed_geometry[0]);
7411 ok(SUCCEEDED(hr), "Failed to create geometry, hr %#x.\n", hr);
7413 set_matrix_identity(&matrix);
7414 translate_matrix(&matrix, 160.0f, 640.0f);
7415 scale_matrix(&matrix, 40.0f, 160.0f);
7416 rotate_matrix(&matrix, M_PI / -5.0f);
7417 hr = ID2D1Factory_CreateTransformedGeometry(factory,
7418 (ID2D1Geometry *)geometry, &matrix, &transformed_geometry[1]);
7419 ok(SUCCEEDED(hr), "Failed to create geometry, hr %#x.\n", hr);
7420 ID2D1PathGeometry_Release(geometry);
7422 set_matrix_identity(&matrix);
7423 scale_matrix(&matrix, 0.5f, 1.0f);
7424 translate_matrix(&matrix, -80.0f, 0.0f);
7425 hr = ID2D1Factory_CreateTransformedGeometry(factory,
7426 (ID2D1Geometry *)transformed_geometry[1], &matrix, &transformed_geometry[2]);
7427 ok(SUCCEEDED(hr), "Failed to create geometry, hr %#x.\n", hr);
7429 set_matrix_identity(&matrix);
7430 rotate_matrix(&matrix, M_PI / 2.0f);
7431 translate_matrix(&matrix, 80.0f, -320.0f);
7432 scale_matrix(&matrix, 2.0f, 0.25f);
7433 hr = ID2D1Factory_CreateTransformedGeometry(factory,
7434 (ID2D1Geometry *)transformed_geometry[2], &matrix, &transformed_geometry[3]);
7435 ok(SUCCEEDED(hr), "Failed to create geometry, hr %#x.\n", hr);
7437 ID2D1RenderTarget_BeginDraw(rt);
7438 ID2D1RenderTarget_Clear(rt, &color);
7439 ID2D1RenderTarget_FillGeometry(rt, (ID2D1Geometry *)transformed_geometry[0], (ID2D1Brush *)brush, NULL);
7440 ID2D1RenderTarget_FillGeometry(rt, (ID2D1Geometry *)transformed_geometry[1], (ID2D1Brush *)brush, NULL);
7441 ID2D1RenderTarget_FillGeometry(rt, (ID2D1Geometry *)transformed_geometry[2], (ID2D1Brush *)brush, NULL);
7442 ID2D1RenderTarget_FillGeometry(rt, (ID2D1Geometry *)transformed_geometry[3], (ID2D1Brush *)brush, NULL);
7443 hr = ID2D1RenderTarget_EndDraw(rt, NULL, NULL);
7444 ok(SUCCEEDED(hr), "Failed to end draw, hr %#x.\n", hr);
7445 ID2D1TransformedGeometry_Release(transformed_geometry[3]);
7446 ID2D1TransformedGeometry_Release(transformed_geometry[2]);
7447 ID2D1TransformedGeometry_Release(transformed_geometry[1]);
7448 ID2D1TransformedGeometry_Release(transformed_geometry[0]);
7450 match = compare_figure(surface, 0, 0, 160, 160, 0xff652e89, 32,
7451 "6DMNjgEWiAEahgEahgEahgEahgEahgEahgEahgEahgEahgEahgEahwEZhwEZhwEZhwEZhwEZhwEZ"
7452 "hwEZhwEZhwEZiAEYiAEYiAEYiAEYiAEXiQEXiQEXiQEXigEWigEWigEWigEWigEWigEWigEWiwEU"
7453 "jAEUjAEUjAEUjQESjgESjwEQkAEQkQEOkgENlAEMlQEKlgEKlwEImAEImQEHmQEGmwEFmwEEnQED"
7454 "nQECngECngECnwEBnwEBnwEBnwEBnwEBnwECnQEDnQEDnQEEmwEFmgEHmQEHlwELkQERjAEXhgEd"
7455 "hAEfgwEchgEXjwEMqTEA");
7456 ok(match, "Figure does not match.\n");
7457 match = compare_figure(surface, 160, 0, 320, 160, 0xff652e89, 32,
7458 "h58BBrYCDq0CF6QCIJwCKJMCMIwCNoUCPf8BQ/kBSPQBTu4BTe8BTPEBSfUBRvgBQf0BPYECOYUC"
7459 "NIoCMI4CK+UBAS0W/AEHIwiPAgsaBZcCEAwIngIepAIaqAIWrAITsAIRsgIPtQIMtwILugIHwAIB"
7460 "ypwB");
7461 ok(match, "Figure does not match.\n");
7462 match = compare_figure(surface, 0, 160, 160, 320, 0xff652e89, 32,
7463 "wW4DnAEEmwEFmgEHmAEIlwEKlQELlAEMkwEOkQEPkAEQkAERjgESjgETjAEUjAEUiwEWigEWiQEX"
7464 "iQEYhwEZhwEZhgEbhQEbhAEchAEdggEeggEeggEfgAEggAEggAEhgAEggAEggQEggAEggAEggQEg"
7465 "gAEggQEfgQEfggEfgQEfgQEfggEfgQEfggEeggEfggEeggEegwEdgwEeggEegwEdgwEegwEdgwEd"
7466 "hAEchAEdhAEchAEchAEdhAEchAEchQEbhQEbhgEahgEahwEZhwEZiAEYiAEYiQEYiAEYiQEXiQEX"
7467 "igEWigEWiwEViwEViwEVjAEUjAEUjQETjQETjgESjgETjgESjwERkAEQkQEPkwENlAEMlQELlgEK"
7468 "lwEKlwEJmAEImQEHmgEGmwEFnAEEnQEEnQEDnQEDngECngEDngECngECnwECngECnwECngECngED"
7469 "ngECEgGLAQMQAosBAw4EjAEDCwaMAQQJBo0BBQYIjQEHAgqNARKOARKPARCQARCQARCQAQ+RAQ6S"
7470 "AQ6SAQ2TAQ2SAQ2TAQ2TAQyTAQyUAQyUAQuUAQuVAQuUAQuVAQqWAQmWAQqWAQmXAQiXAQiYAQeY"
7471 "AQeZAQWbAQSDZwAA");
7472 ok(match, "Figure does not match.\n");
7473 match = compare_figure(surface, 160, 160, 320, 320, 0xff652e89, 32,
7474 "g90BBLkCCLYCC7ICDrACEa0CFKoCF6cCGqQCHKMCHqECIJ8CIpwCJJsCJpkCKJcCKZYCK5QCLZIC"
7475 "L5ACMI8CMo0CNIsCNYoCN4gCOYcCOYYCO4QCPYICPoECQIACQYACQIECQIACQIECQIECQIECP4IC"
7476 "P4ICP4ECP4ICP4ICPoMCPoMCPoMCPYQCPYMCPYQCPYQCPYQCPIUCPIUCPIUCO4YCO4YCOoYCO4YC"
7477 "OocCOocCOocCOYgCOYgCOIkCOIkCN4oCNosCNYwCNI0CM44CMo4CM44CMo8CMZACMJECL5ICLpMC"
7478 "LZQCLJUCK5YCK5YCKpcCKZgCKJkCJ5oCJpsCJpsCJZwCJJ4CIqACIKICH6MCHaUCG6cCGakCF6wC"
7479 "Fa0CE68CEbECD7MCDrQCDLYCCrgCCbkCB7sCBrsCBbwCBbwCBL0CBL0CBL0CBL0CA70CBL0CBL0C"
7480 "BLwCBSUBlgIFIQSXAgYbCJcCBxcKmQIIEQ6ZAgoMEJoCDQUTnAIknAIjnQIingIhnwIgoAIfoQIe"
7481 "ogIdowIcpAIbpQIapQIZpgIZpgIZpwIYpwIXqAIXqAIXqQIVqgIVqgIUqwITrQISrQIRrgIQsAIO"
7482 "sQIMswILtQIIhs4B");
7483 ok(match, "Figure does not match.\n");
7485 hr = ID2D1Factory_CreatePathGeometry(factory, &geometry);
7486 ok(SUCCEEDED(hr), "Failed to create path geometry, hr %#x.\n", hr);
7487 hr = ID2D1PathGeometry_Open(geometry, &sink);
7488 ok(SUCCEEDED(hr), "Failed to open geometry sink, hr %#x.\n", hr);
7490 set_point(&point, -0.402914f, 0.915514f);
7491 ID2D1GeometrySink_BeginFigure(sink, point, D2D1_FIGURE_BEGIN_HOLLOW);
7492 quadratic_to(sink, -0.310379f, 0.882571f, -0.116057f, 0.824000f);
7493 quadratic_to(sink, 0.008350f, 0.693614f, -0.052343f, 0.448886f);
7494 quadratic_to(sink, -0.154236f, 0.246072f, -0.279229f, 0.025343f);
7495 quadratic_to(sink, -0.370064f, -0.588586f, -0.383029f, -0.924114f);
7496 quadratic_to(sink, -0.295479f, -0.958764f, -0.017086f, -0.988400f);
7497 quadratic_to(sink, 0.208836f, -0.954157f, 0.272200f, -0.924114f);
7498 quadratic_to(sink, 0.295614f, -0.569071f, 0.230143f, 0.022886f);
7499 quadratic_to(sink, 0.101664f, 0.220643f, 0.012057f, 0.451571f);
7500 quadratic_to(sink, -0.028764f, 0.709014f, 0.104029f, 0.833943f);
7501 quadratic_to(sink, 0.319414f, 0.913057f, 0.403229f, 0.942628f);
7502 quadratic_to(sink, 0.317721f, 1.023450f, -0.017086f, 1.021771f);
7503 quadratic_to(sink, -0.310843f, 1.007472f, -0.402914f, 0.915514f);
7504 ID2D1GeometrySink_EndFigure(sink, D2D1_FIGURE_END_CLOSED);
7506 hr = ID2D1GeometrySink_Close(sink);
7507 ok(SUCCEEDED(hr), "Failed to close geometry sink, hr %#x.\n", hr);
7508 ID2D1GeometrySink_Release(sink);
7510 set_matrix_identity(&matrix);
7511 translate_matrix(&matrix, 40.0f, 160.0f);
7512 scale_matrix(&matrix, 20.0f, 80.0f);
7513 hr = ID2D1Factory_CreateTransformedGeometry(factory,
7514 (ID2D1Geometry *)geometry, &matrix, &transformed_geometry[0]);
7515 ok(SUCCEEDED(hr), "Failed to create geometry, hr %#x.\n", hr);
7517 set_matrix_identity(&matrix);
7518 translate_matrix(&matrix, 160.0f, 640.0f);
7519 scale_matrix(&matrix, 40.0f, 160.0f);
7520 rotate_matrix(&matrix, M_PI / -5.0f);
7521 hr = ID2D1Factory_CreateTransformedGeometry(factory,
7522 (ID2D1Geometry *)geometry, &matrix, &transformed_geometry[1]);
7523 ok(SUCCEEDED(hr), "Failed to create geometry, hr %#x.\n", hr);
7524 ID2D1PathGeometry_Release(geometry);
7526 set_matrix_identity(&matrix);
7527 scale_matrix(&matrix, 0.5f, 1.0f);
7528 translate_matrix(&matrix, -80.0f, 0.0f);
7529 hr = ID2D1Factory_CreateTransformedGeometry(factory,
7530 (ID2D1Geometry *)transformed_geometry[1], &matrix, &transformed_geometry[2]);
7531 ok(SUCCEEDED(hr), "Failed to create geometry, hr %#x.\n", hr);
7533 set_matrix_identity(&matrix);
7534 rotate_matrix(&matrix, M_PI / 2.0f);
7535 translate_matrix(&matrix, 80.0f, -320.0f);
7536 scale_matrix(&matrix, 2.0f, 0.25f);
7537 hr = ID2D1Factory_CreateTransformedGeometry(factory,
7538 (ID2D1Geometry *)transformed_geometry[2], &matrix, &transformed_geometry[3]);
7539 ok(SUCCEEDED(hr), "Failed to create geometry, hr %#x.\n", hr);
7541 ID2D1RenderTarget_BeginDraw(rt);
7542 ID2D1RenderTarget_Clear(rt, &color);
7543 ID2D1RenderTarget_FillGeometry(rt, (ID2D1Geometry *)transformed_geometry[0], (ID2D1Brush *)brush, NULL);
7544 ID2D1RenderTarget_FillGeometry(rt, (ID2D1Geometry *)transformed_geometry[1], (ID2D1Brush *)brush, NULL);
7545 ID2D1RenderTarget_FillGeometry(rt, (ID2D1Geometry *)transformed_geometry[2], (ID2D1Brush *)brush, NULL);
7546 ID2D1RenderTarget_FillGeometry(rt, (ID2D1Geometry *)transformed_geometry[3], (ID2D1Brush *)brush, NULL);
7547 hr = ID2D1RenderTarget_EndDraw(rt, NULL, NULL);
7548 ok(SUCCEEDED(hr), "Failed to end draw, hr %#x.\n", hr);
7549 ID2D1TransformedGeometry_Release(transformed_geometry[3]);
7550 ID2D1TransformedGeometry_Release(transformed_geometry[2]);
7551 ID2D1TransformedGeometry_Release(transformed_geometry[1]);
7552 ID2D1TransformedGeometry_Release(transformed_geometry[0]);
7554 match = compare_figure(surface, 0, 0, 160, 160, 0xff652e89, 0, "gMgB");
7555 ok(match, "Figure does not match.\n");
7556 match = compare_figure(surface, 160, 0, 320, 160, 0xff652e89, 0, "gJAD");
7557 ok(match, "Figure does not match.\n");
7558 match = compare_figure(surface, 0, 160, 160, 320, 0xff652e89, 0, "gJAD");
7559 ok(match, "Figure does not match.\n");
7560 match = compare_figure(surface, 160, 160, 320, 320, 0xff652e89, 0, "gKAG");
7561 ok(match, "Figure does not match.\n");
7563 ID2D1SolidColorBrush_Release(brush);
7564 ID2D1RenderTarget_Release(rt);
7565 refcount = ID2D1Factory_Release(factory);
7566 ok(!refcount, "Factory has %u references left.\n", refcount);
7567 IDXGISurface_Release(surface);
7568 IDXGISwapChain_Release(swapchain);
7569 ID3D10Device1_Release(device);
7570 DestroyWindow(window);
7573 static void test_gdi_interop(void)
7575 ID2D1GdiInteropRenderTarget *interop;
7576 D2D1_RENDER_TARGET_PROPERTIES desc;
7577 IWICImagingFactory *wic_factory;
7578 IWICBitmapLock *wic_lock;
7579 IWICBitmap *wic_bitmap;
7580 ID2D1RenderTarget *rt;
7581 ID2D1Factory *factory;
7582 ID3D10Device1 *device;
7583 D2D1_COLOR_F color;
7584 HRESULT hr;
7585 BOOL match;
7586 RECT rect;
7587 HDC dc;
7589 if (!(device = create_device()))
7591 skip("Failed to create device, skipping tests.\n");
7592 return;
7595 hr = D2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED, &IID_ID2D1Factory, NULL, (void **)&factory);
7596 ok(SUCCEEDED(hr), "Failed to create factory, hr %#x.\n", hr);
7598 CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
7599 hr = CoCreateInstance(&CLSID_WICImagingFactory, NULL, CLSCTX_INPROC_SERVER,
7600 &IID_IWICImagingFactory, (void **)&wic_factory);
7601 ok(SUCCEEDED(hr), "Failed to create WIC imaging factory, hr %#x.\n", hr);
7602 hr = IWICImagingFactory_CreateBitmap(wic_factory, 16, 16,
7603 &GUID_WICPixelFormat32bppPBGRA, WICBitmapCacheOnDemand, &wic_bitmap);
7604 ok(SUCCEEDED(hr), "Failed to create bitmap, hr %#x.\n", hr);
7605 IWICImagingFactory_Release(wic_factory);
7607 /* WIC target, default usage */
7608 desc.type = D2D1_RENDER_TARGET_TYPE_DEFAULT;
7609 desc.pixelFormat.format = DXGI_FORMAT_UNKNOWN;
7610 desc.pixelFormat.alphaMode = D2D1_ALPHA_MODE_PREMULTIPLIED;
7611 desc.dpiX = 0.0f;
7612 desc.dpiY = 0.0f;
7613 desc.usage = D2D1_RENDER_TARGET_USAGE_NONE;
7614 desc.minLevel = D2D1_FEATURE_LEVEL_DEFAULT;
7616 hr = ID2D1Factory_CreateWicBitmapRenderTarget(factory, wic_bitmap, &desc, &rt);
7617 ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr);
7619 hr = ID2D1RenderTarget_QueryInterface(rt, &IID_ID2D1GdiInteropRenderTarget, (void **)&interop);
7620 ok(SUCCEEDED(hr), "Failed to get gdi interop interface, hr %#x.\n", hr);
7622 ID2D1RenderTarget_BeginDraw(rt);
7623 dc = (void *)0xdeadbeef;
7624 hr = ID2D1GdiInteropRenderTarget_GetDC(interop, D2D1_DC_INITIALIZE_MODE_COPY, &dc);
7625 ok(FAILED(hr), "GetDC() was expected to fail, hr %#x.\n", hr);
7626 todo_wine
7627 ok(dc == NULL, "Expected NULL dc, got %p.\n", dc);
7628 ID2D1GdiInteropRenderTarget_Release(interop);
7629 ID2D1RenderTarget_EndDraw(rt, NULL, NULL);
7631 ID2D1RenderTarget_Release(rt);
7633 /* WIC target, gdi compatible */
7634 desc.usage = D2D1_RENDER_TARGET_USAGE_GDI_COMPATIBLE;
7636 hr = ID2D1Factory_CreateWicBitmapRenderTarget(factory, wic_bitmap, &desc, &rt);
7637 ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr);
7639 hr = ID2D1RenderTarget_QueryInterface(rt, &IID_ID2D1GdiInteropRenderTarget, (void **)&interop);
7640 ok(SUCCEEDED(hr), "Failed to get gdi interop interface, hr %#x.\n", hr);
7642 ID2D1RenderTarget_BeginDraw(rt);
7643 dc = NULL;
7644 hr = ID2D1GdiInteropRenderTarget_GetDC(interop, D2D1_DC_INITIALIZE_MODE_COPY, &dc);
7645 ok(SUCCEEDED(hr), "GetDC() was expected to succeed, hr %#x.\n", hr);
7646 ok(dc != NULL, "Expected NULL dc, got %p.\n", dc);
7647 ID2D1GdiInteropRenderTarget_ReleaseDC(interop, NULL);
7648 hr = ID2D1RenderTarget_EndDraw(rt, NULL, NULL);
7649 ok(SUCCEEDED(hr), "EndDraw() failed, hr %#x.\n", hr);
7651 ID2D1RenderTarget_BeginDraw(rt);
7652 set_color(&color, 1.0f, 0.0f, 0.0f, 1.0f);
7653 ID2D1RenderTarget_Clear(rt, &color);
7654 hr = ID2D1RenderTarget_EndDraw(rt, NULL, NULL);
7655 ok(SUCCEEDED(hr), "EndDraw() failed, hr %#x.\n", hr);
7657 match = compare_wic_bitmap(wic_bitmap, "54034063dbc1c1bb61cb60ec57e4498678dc2b13");
7658 ok(match, "Bitmap does not match.\n");
7660 /* Do solid fill using GDI */
7661 ID2D1RenderTarget_BeginDraw(rt);
7663 hr = ID2D1GdiInteropRenderTarget_GetDC(interop, D2D1_DC_INITIALIZE_MODE_COPY, &dc);
7664 ok(SUCCEEDED(hr), "GetDC() was expected to succeed, hr %#x.\n", hr);
7666 SetRect(&rect, 0, 0, 16, 16);
7667 FillRect(dc, &rect, GetStockObject(BLACK_BRUSH));
7668 ID2D1GdiInteropRenderTarget_ReleaseDC(interop, NULL);
7670 hr = ID2D1RenderTarget_EndDraw(rt, NULL, NULL);
7671 ok(SUCCEEDED(hr), "EndDraw() failed, hr %#x.\n", hr);
7673 match = compare_wic_bitmap(wic_bitmap, "60cacbf3d72e1e7834203da608037b1bf83b40e8");
7674 ok(match, "Bitmap does not match.\n");
7676 /* Bitmap is locked at BeginDraw(). */
7677 hr = IWICBitmap_Lock(wic_bitmap, NULL, WICBitmapLockRead, &wic_lock);
7678 ok(SUCCEEDED(hr), "Expected bitmap to be unlocked, hr %#x.\n", hr);
7679 IWICBitmapLock_Release(wic_lock);
7681 ID2D1RenderTarget_BeginDraw(rt);
7682 hr = IWICBitmap_Lock(wic_bitmap, NULL, WICBitmapLockRead, &wic_lock);
7683 todo_wine
7684 ok(hr == WINCODEC_ERR_ALREADYLOCKED, "Expected bitmap to be locked, hr %#x.\n", hr);
7685 if (SUCCEEDED(hr))
7686 IWICBitmapLock_Release(wic_lock);
7687 hr = ID2D1RenderTarget_EndDraw(rt, NULL, NULL);
7688 ok(SUCCEEDED(hr), "EndDraw() failed, hr %#x.\n", hr);
7690 /* Lock before BeginDraw(). */
7691 hr = IWICBitmap_Lock(wic_bitmap, NULL, WICBitmapLockRead, &wic_lock);
7692 ok(SUCCEEDED(hr), "Expected bitmap to be unlocked, hr %#x.\n", hr);
7693 ID2D1RenderTarget_BeginDraw(rt);
7694 hr = ID2D1RenderTarget_EndDraw(rt, NULL, NULL);
7695 todo_wine
7696 ok(hr == WINCODEC_ERR_ALREADYLOCKED, "Unexpected hr %#x.\n", hr);
7697 IWICBitmapLock_Release(wic_lock);
7699 ID2D1GdiInteropRenderTarget_Release(interop);
7700 ID2D1RenderTarget_Release(rt);
7702 IWICBitmap_Release(wic_bitmap);
7703 ID2D1Factory_Release(factory);
7706 static void test_layer(void)
7708 ID2D1Factory *factory, *layer_factory;
7709 IDXGISwapChain *swapchain;
7710 ID2D1RenderTarget *rt;
7711 ID3D10Device1 *device;
7712 IDXGISurface *surface;
7713 ID2D1Layer *layer;
7714 D2D1_SIZE_F size;
7715 ULONG refcount;
7716 HWND window;
7717 HRESULT hr;
7719 if (!(device = create_device()))
7721 skip("Failed to create device, skipping tests.\n");
7722 return;
7724 window = create_window();
7725 swapchain = create_swapchain(device, window, TRUE);
7726 hr = IDXGISwapChain_GetBuffer(swapchain, 0, &IID_IDXGISurface, (void **)&surface);
7727 ok(SUCCEEDED(hr), "Failed to get buffer, hr %#x.\n", hr);
7728 rt = create_render_target(surface);
7729 ok(!!rt, "Failed to create render target.\n");
7730 ID2D1RenderTarget_GetFactory(rt, &factory);
7732 ID2D1RenderTarget_SetDpi(rt, 192.0f, 48.0f);
7733 ID2D1RenderTarget_SetAntialiasMode(rt, D2D1_ANTIALIAS_MODE_ALIASED);
7735 hr = ID2D1RenderTarget_CreateLayer(rt, NULL, &layer);
7736 ok(SUCCEEDED(hr), "Failed to create layer, hr %#x.\n", hr);
7737 ID2D1Layer_GetFactory(layer, &layer_factory);
7738 ok(layer_factory == factory, "Got unexpected layer factory %p, expected %p.\n", layer_factory, factory);
7739 ID2D1Factory_Release(layer_factory);
7740 size = ID2D1Layer_GetSize(layer);
7741 ok(size.width == 0.0f, "Got unexpected width %.8e.\n", size.width);
7742 ok(size.height == 0.0f, "Got unexpected height %.8e.\n", size.height);
7743 ID2D1Layer_Release(layer);
7745 set_size_f(&size, 800.0f, 600.0f);
7746 hr = ID2D1RenderTarget_CreateLayer(rt, &size, &layer);
7747 ok(SUCCEEDED(hr), "Failed to create layer, hr %#x.\n", hr);
7748 size = ID2D1Layer_GetSize(layer);
7749 ok(size.width == 800.0f, "Got unexpected width %.8e.\n", size.width);
7750 ok(size.height == 600.0f, "Got unexpected height %.8e.\n", size.height);
7751 ID2D1Layer_Release(layer);
7753 ID2D1RenderTarget_Release(rt);
7754 refcount = ID2D1Factory_Release(factory);
7755 ok(!refcount, "Factory has %u references left.\n", refcount);
7756 IDXGISurface_Release(surface);
7757 IDXGISwapChain_Release(swapchain);
7758 ID3D10Device1_Release(device);
7759 DestroyWindow(window);
7762 static void test_bezier_intersect(void)
7764 D2D1_POINT_2F point = {0.0f, 0.0f};
7765 ID2D1SolidColorBrush *brush;
7766 ID2D1PathGeometry *geometry;
7767 IDXGISwapChain *swapchain;
7768 ID2D1GeometrySink *sink;
7769 ID2D1RenderTarget *rt;
7770 ID3D10Device1 *device;
7771 IDXGISurface *surface;
7772 ID2D1Factory *factory;
7773 D2D1_COLOR_F color;
7774 ULONG refcount;
7775 HWND window;
7776 HRESULT hr;
7777 BOOL match;
7779 if (!(device = create_device()))
7781 skip("Failed to create device, skipping tests.\n");
7782 return;
7784 window = create_window();
7785 swapchain = create_swapchain(device, window, TRUE);
7786 hr = IDXGISwapChain_GetBuffer(swapchain, 0, &IID_IDXGISurface, (void **)&surface);
7787 ok(SUCCEEDED(hr), "Failed to get buffer, hr %#x.\n", hr);
7788 rt = create_render_target(surface);
7789 ok(!!rt, "Failed to create render target.\n");
7790 ID2D1RenderTarget_GetFactory(rt, &factory);
7792 ID2D1RenderTarget_SetDpi(rt, 192.0f, 48.0f);
7793 ID2D1RenderTarget_SetAntialiasMode(rt, D2D1_ANTIALIAS_MODE_ALIASED);
7794 set_color(&color, 0.890f, 0.851f, 0.600f, 1.0f);
7795 hr = ID2D1RenderTarget_CreateSolidColorBrush(rt, &color, NULL, &brush);
7796 ok(SUCCEEDED(hr), "Failed to create brush, hr %#x.\n", hr);
7798 hr = ID2D1Factory_CreatePathGeometry(factory, &geometry);
7799 ok(SUCCEEDED(hr), "Failed to create path geometry, hr %#x.\n", hr);
7800 hr = ID2D1PathGeometry_Open(geometry, &sink);
7801 ok(SUCCEEDED(hr), "Failed to open geometry sink, hr %#x.\n", hr);
7803 set_point(&point, 160.0f, 720.0f);
7804 ID2D1GeometrySink_BeginFigure(sink, point, D2D1_FIGURE_BEGIN_FILLED);
7805 cubic_to(sink, 119.0f, 720.0f, 83.0f, 600.0f, 80.0f, 474.0f);
7806 cubic_to(sink, 78.0f, 349.0f, 108.0f, 245.0f, 135.0f, 240.0f);
7807 cubic_to(sink, 163.0f, 235.0f, 180.0f, 318.0f, 176.0f, 370.0f);
7808 cubic_to(sink, 171.0f, 422.0f, 149.0f, 422.0f, 144.0f, 370.0f);
7809 cubic_to(sink, 140.0f, 318.0f, 157.0f, 235.0f, 185.0f, 240.0f);
7810 cubic_to(sink, 212.0f, 245.0f, 242.0f, 349.0f, 240.0f, 474.0f);
7811 cubic_to(sink, 238.0f, 600.0f, 201.0f, 720.0f, 160.0f, 720.0f);
7812 ID2D1GeometrySink_EndFigure(sink, D2D1_FIGURE_END_CLOSED);
7814 set_point(&point, 160.0f, 240.0f);
7815 ID2D1GeometrySink_BeginFigure(sink, point, D2D1_FIGURE_BEGIN_FILLED);
7816 line_to(sink, 240.0f, 240.0f);
7817 line_to(sink, 240.0f, 720.0f);
7818 line_to(sink, 160.0f, 720.0f);
7819 ID2D1GeometrySink_EndFigure(sink, D2D1_FIGURE_END_CLOSED);
7821 hr = ID2D1GeometrySink_Close(sink);
7822 ok(SUCCEEDED(hr), "Failed to close geometry sink, hr %#x.\n", hr);
7823 ID2D1GeometrySink_Release(sink);
7825 ID2D1RenderTarget_BeginDraw(rt);
7826 set_color(&color, 0.396f, 0.180f, 0.537f, 1.0f);
7827 ID2D1RenderTarget_Clear(rt, &color);
7828 ID2D1RenderTarget_FillGeometry(rt, (ID2D1Geometry *)geometry, (ID2D1Brush *)brush, NULL);
7829 hr = ID2D1RenderTarget_EndDraw(rt, NULL, NULL);
7830 ok(SUCCEEDED(hr), "Failed to end draw, hr %#x.\n", hr);
7831 ID2D1PathGeometry_Release(geometry);
7833 match = compare_figure(surface, 160, 120, 320, 240, 0xff652e89, 2048,
7834 "aRQjIxRpYiIcHCJiXSwXFyxdWTQTEzRZVTsQEDtVUkIMDEJST0cKCkdPTUsICEtNSlEFBVFKSFUD"
7835 "A1VIRlkBAVlGRFsBAVtEQlwCAlxCQFwEBFxAPl0FBV0+PF0HB108Ol4ICF46OV0KCl05N14LC143"
7836 "Nl4MDF42NF8NDV80M14PD14zMV8QEF8xMF8REV8wL18SEl8vLWATE2AtLGAUFGAsK2EUFGErKWIV"
7837 "FWIpKGIWFmIoJ2IXF2InJmIYGGImJWMYGGMlJGMZGWMkI2MaGmMjImQaGmQiIWQbG2QhIGQcHGQg"
7838 "H2UcHGUfHmUdHWUeHWYdHWYdHGcdHWccG2ceHmcbGmgeHmgaGWgfH2gZGWgfH2gZGGkfH2kYF2kg"
7839 "IGkXFmogIGoWFmogIGoWFWsgIGsVFGshIWsUE2whIWwTE2whIWwTEm0hIW0SEW4hIW4REW4hIW4R"
7840 "EG8hIW8QD3AhIXAPD3AhIXAPDnEhIXEODnEhIXEODXIhIXINDHQgIHQMDHQgIHQMC3UgIHULC3Yf"
7841 "H3YLCncfH3cKCngeHngKCXkeHnkJCXodHXoJCXscHHsJCHwcHHwICH0bG30IB38aGn8HB4ABGRmA"
7842 "AQcHgQEYGIEBBwaEARYWhAEGBoUBFRWFAQYFiAETE4gBBQWKARERigEFBYwBDw+MAQUEkAEMDJAB"
7843 "BASTAQkJkwEEBJwBnAEEA50BnQEDA50BnQEDA50BnQEDA50BnQEDAp4BngECAp4BngECAp4BngEC"
7844 "Ap4BngECAp4BngECAZ8BnwEBAZ8BnwEBAZ8BnwEBAZ8BnwEBAZ8BnwEBAZ8BnwEBAZ8BnwGhAaAB"
7845 "oAGgAaABoAGgAaABoAGgAaABoAGgAaABoAGgAaABoAGgAaABoAGgAaABoAGgAaABoAGgAaABoAGg"
7846 "AaABoAGgAaABoAGgAaABoAGhAZ8BoQGfAZ8BAQGfAZ8BAQGfAZ8BAQGfAZ8BAQGfAZ8BAQKeAZ8B"
7847 "AQKeAZ4BAgKeAZ4BAgKeAZ4BAgOdAZ4BAgOdAZ4BAgOdAZ0BAwScAZ0BAwScAZ0BAwScAZ0BAwSc"
7848 "AZwBBAWbAZwBBAWbAZwBBAWbAZsBBQaaAZsBBQaaAZoBBgeZAZoBBgeZAZoBBgeZAZkBBwiYAZkB"
7849 "BwiYAZgBCAmXAZgBCAmXAZgBCAmXAZcBCQqWAZcBCQqWAZYBCguVAZYBCguVAZUBCwyUAZUBCw2T"
7850 "AZQBDA2TAZQBDA6SAZMBDQ6SAZMBDQ+RAZIBDg+RAZIBDhCQAZEBDxCQAZABEBGPAZABEBKOAY8B"
7851 "ERONAY4BEhONAY4BEhSMAY0BExWLAYwBFBWLAYwBFBaKAYsBFReJAYoBFheJAYoBFhiIAYkBFxmH"
7852 "AYgBGBqGAYcBGRuFAYYBGhuFAYUBGxyEAYUBGx2DAYQBHB6CAYMBHR+BAYIBHiCAAYEBHyF/gAEg"
7853 "In5/ISJ+fiIjfX0jJHx8JCV7eyUmenomJ3l5Jyh4eCgpd3cpK3V2Kix0dSstc3QsLnJzLS9xci4w"
7854 "cHAwMm5vMTNtbjI0bG0zNWtrNTdpajY4aGk3OmZnOTtlZjo8ZGQ8PmJjPT9hYj5BX2BAQl5eQkRc"
7855 "XUNGWltFR1lZR0lXWEhLVVZKTVNUTE9RUk5RT1BQUk5OUlRMTFRWSkpWWUdIWFtFRVteQkNdYEBA"
7856 "YGI+PmJlOztlaDg4aGs1NWtuMjJuci4vcXUrK3V6JiZ6fiIifoMBHR2DAYsBFRWLAZUBCwuVAQAA");
7857 ok(match, "Figure does not match.\n");
7859 hr = ID2D1Factory_CreatePathGeometry(factory, &geometry);
7860 ok(SUCCEEDED(hr), "Failed to create path geometry, hr %#x.\n", hr);
7861 hr = ID2D1PathGeometry_Open(geometry, &sink);
7862 ok(SUCCEEDED(hr), "Failed to open geometry sink, hr %#x.\n", hr);
7864 set_point(&point, 240.0f, 720.0f);
7865 ID2D1GeometrySink_BeginFigure(sink, point, D2D1_FIGURE_BEGIN_FILLED);
7866 cubic_to(sink, 152.0f, 720.0f, 80.0f, 613.0f, 80.0f, 480.0f);
7867 cubic_to(sink, 80.0f, 347.0f, 152.0f, 240.0f, 240.0f, 240.0f);
7868 cubic_to(sink, 152.0f, 339.0f, 134.0f, 528.0f, 200.0f, 660.0f);
7869 cubic_to(sink, 212.0f, 683.0f, 225.0f, 703.0f, 240.0f, 720.0f);
7870 ID2D1GeometrySink_EndFigure(sink, D2D1_FIGURE_END_CLOSED);
7872 hr = ID2D1GeometrySink_Close(sink);
7873 ok(SUCCEEDED(hr), "Failed to close geometry sink, hr %#x.\n", hr);
7874 ID2D1GeometrySink_Release(sink);
7876 ID2D1RenderTarget_BeginDraw(rt);
7877 ID2D1RenderTarget_Clear(rt, &color);
7878 ID2D1RenderTarget_FillGeometry(rt, (ID2D1Geometry *)geometry, (ID2D1Brush *)brush, NULL);
7879 hr = ID2D1RenderTarget_EndDraw(rt, NULL, NULL);
7880 ok(SUCCEEDED(hr), "Failed to end draw, hr %#x.\n", hr);
7881 ID2D1PathGeometry_Release(geometry);
7883 match = compare_figure(surface, 160, 120, 320, 240, 0xff652e89, 2048,
7884 "pQIZkgIrhAI5/QE/9gFH7wFO6wFS5wFW4gFb3gFf2wFi2AFl1gFn1AFp0gFszwFuzQFxywFyyQF1"
7885 "xwF2xgF4xAF5xAF6wgF8wAF+vwF+vwF/vQGBAbwBggG7AYMBugGEAbkBhQG4AYYBtwGHAbcBiAG1"
7886 "AYkBtAGKAbQBigGzAYsBswGMAbEBjQGxAY0BsQGOAa8BjwGvAZABrgGQAa4BkQGtAZEBrQGSAawB"
7887 "kgGsAZMBqwGTAasBlAGrAZQBqgGVAakBlQGqAZUBqQGWAagBlwGoAZYBqAGXAagBlwGnAZgBpwGY"
7888 "AaYBmQGmAZkBpgGZAaUBmgGlAZoBpQGaAaUBmgGkAZsBpAGbAaQBmwGkAZsBpAGcAaMBnAGjAZwB"
7889 "owGcAaMBnAGjAZ0BogGdAaIBnQGiAZ4BoQGeAaEBngGiAZ4BoQGeAaEBnwGgAZ8BoQGeAaEBnwGh"
7890 "AZ4BoQGfAaABnwGhAZ8BoAGgAaABnwGgAaABoAGfAaABoAGgAaABnwGgAaABoAGgAaABnwGgAaAB"
7891 "oAGgAaABnwGhAZ8BoQGfAaABoAGgAaABoAGfAaEBnwGhAZ8BoQGfAaEBnwGhAZ8BoQGfAaABoAGg"
7892 "AaABoAGgAaEBnwGhAZ8BoQGfAaEBnwGhAaABoAGgAaABoAGgAaABoAGgAaEBoAGgAaABoAGgAaAB"
7893 "oQGgAaABoAGgAaABoQGfAaEBoAGhAZ8BoQGfAaIBnwGhAZ8BogGfAaEBnwGiAZ8BogGeAaIBnwGi"
7894 "AZ4BogGfAaIBngGjAZ4BowGdAaMBngGjAZ4BowGdAaQBnQGkAZ0BpAGcAaUBnAGlAZwBpQGcAaUB"
7895 "mwGmAZsBpgGbAaYBmwGmAZsBpgGbAacBmgGnAZkBqAGZAagBmQGpAZgBqQGZAagBmQGpAZgBqQGY"
7896 "AaoBlwGqAZcBqwGWAasBlgGsAZUBrQGVAawBlQGtAZQBrgGUAa0BlAGuAZMBrwGTAa8BkgGwAZEB"
7897 "sQGRAbEBkAGyAZABsgGPAbMBjwG0AY4BtAGNAbUBjQG2AYwBtgGLAbgBigG4AYoBuQGJAboBhwG7"
7898 "AYcBvAGGAb0BhQG+AYQBvwGDAcABggHBAYIBwgGAAcMBf8QBfsYBfMgBe8gBesoBeMwBd80BddAB"
7899 "c9EBcdQBb9YBbNkBatsBaN0BZeEBYuQBX+gBW+0BVvEBUvUBTvwBR4QCQIoCOZgCK6oCGQIA");
7900 ok(match, "Figure does not match.\n");
7902 ID2D1SolidColorBrush_Release(brush);
7903 ID2D1RenderTarget_Release(rt);
7904 refcount = ID2D1Factory_Release(factory);
7905 ok(!refcount, "Factory has %u references left.\n", refcount);
7906 IDXGISurface_Release(surface);
7907 IDXGISwapChain_Release(swapchain);
7908 ID3D10Device1_Release(device);
7909 DestroyWindow(window);
7912 static void test_create_device(void)
7914 D2D1_CREATION_PROPERTIES properties = {0};
7915 ID3D10Device1 *d3d_device;
7916 IDXGIDevice *dxgi_device;
7917 ID2D1Factory1 *factory;
7918 ID2D1Factory *factory2;
7919 ID2D1Device *device;
7920 ULONG refcount;
7921 HRESULT hr;
7923 if (!(d3d_device = create_device()))
7925 skip("Failed to create device, skipping tests.\n");
7926 return;
7929 if (FAILED(D2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED, &IID_ID2D1Factory1, NULL, (void **)&factory)))
7931 win_skip("ID2D1Factory1 is not supported.\n");
7932 ID3D10Device1_Release(d3d_device);
7933 return;
7936 hr = ID3D10Device1_QueryInterface(d3d_device, &IID_IDXGIDevice, (void **)&dxgi_device);
7937 ok(SUCCEEDED(hr), "Failed to get IDXGIDevice interface, hr %#x.\n", hr);
7939 hr = ID2D1Factory1_CreateDevice(factory, dxgi_device, &device);
7940 ok(SUCCEEDED(hr), "Failed to get ID2D1Device, hr %#x.\n", hr);
7942 ID2D1Device_GetFactory(device, &factory2);
7943 ok(factory2 == (ID2D1Factory *)factory, "Got unexpected factory %p, expected %p.\n", factory2, factory);
7944 ID2D1Factory_Release(factory2);
7945 ID2D1Device_Release(device);
7947 if (pD2D1CreateDevice)
7949 hr = pD2D1CreateDevice(dxgi_device, NULL, &device);
7950 ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
7951 ID2D1Device_Release(device);
7953 hr = pD2D1CreateDevice(dxgi_device, &properties, &device);
7954 ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
7955 ID2D1Device_Release(device);
7957 else
7958 win_skip("D2D1CreateDevice() is unavailable.\n");
7960 IDXGIDevice_Release(dxgi_device);
7961 ID3D10Device1_Release(d3d_device);
7963 refcount = ID2D1Factory1_Release(factory);
7964 ok(!refcount, "Factory has %u references left.\n", refcount);
7967 #define check_rt_bitmap_surface(r, s, o) check_rt_bitmap_surface_(__LINE__, r, s, o)
7968 static void check_rt_bitmap_surface_(unsigned int line, ID2D1RenderTarget *rt, BOOL has_surface, DWORD options)
7970 ID2D1BitmapRenderTarget *compatible_rt;
7971 D2D1_BITMAP_PROPERTIES bitmap_desc;
7972 IWICImagingFactory *wic_factory;
7973 ID2D1Bitmap *bitmap, *bitmap2;
7974 ID2D1DeviceContext *context;
7975 ID2D1DCRenderTarget *dc_rt;
7976 IWICBitmap *wic_bitmap;
7977 ID2D1Image *target;
7978 D2D1_SIZE_U size;
7979 HRESULT hr;
7981 static const DWORD bitmap_data[] =
7983 0x7f7f0000,
7986 /* Raw data bitmap. */
7987 set_size_u(&size, 1, 1);
7988 bitmap_desc.pixelFormat.format = DXGI_FORMAT_B8G8R8A8_UNORM;
7989 bitmap_desc.pixelFormat.alphaMode = D2D1_ALPHA_MODE_IGNORE;
7990 bitmap_desc.dpiX = 96.0f;
7991 bitmap_desc.dpiY = 96.0f;
7992 hr = ID2D1RenderTarget_CreateBitmap(rt, size, bitmap_data, sizeof(*bitmap_data), &bitmap_desc, &bitmap);
7993 ok_(__FILE__, line)(SUCCEEDED(hr), "Failed to create bitmap, hr %#x.\n", hr);
7995 check_bitmap_surface_(line, bitmap, has_surface, options);
7997 ID2D1Bitmap_Release(bitmap);
7999 /* Zero sized bitmaps. */
8000 set_size_u(&size, 0, 0);
8001 hr = ID2D1RenderTarget_CreateBitmap(rt, size, NULL, 0, &bitmap_desc, &bitmap);
8002 ok_(__FILE__, line)(SUCCEEDED(hr), "Failed to create bitmap, hr %#x.\n", hr);
8003 check_bitmap_surface_(line, bitmap, has_surface, options);
8004 ID2D1Bitmap_Release(bitmap);
8006 set_size_u(&size, 2, 0);
8007 hr = ID2D1RenderTarget_CreateBitmap(rt, size, NULL, 0, &bitmap_desc, &bitmap);
8008 ok_(__FILE__, line)(SUCCEEDED(hr), "Failed to create bitmap, hr %#x.\n", hr);
8009 check_bitmap_surface_(line, bitmap, has_surface, options);
8010 ID2D1Bitmap_Release(bitmap);
8012 set_size_u(&size, 0, 2);
8013 hr = ID2D1RenderTarget_CreateBitmap(rt, size, NULL, 0, &bitmap_desc, &bitmap);
8014 ok_(__FILE__, line)(SUCCEEDED(hr), "Failed to create bitmap, hr %#x.\n", hr);
8015 check_bitmap_surface_(line, bitmap, has_surface, options);
8016 ID2D1Bitmap_Release(bitmap);
8018 /* WIC bitmap. */
8019 CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
8021 hr = CoCreateInstance(&CLSID_WICImagingFactory, NULL, CLSCTX_INPROC_SERVER,
8022 &IID_IWICImagingFactory, (void **)&wic_factory);
8023 ok_(__FILE__, line)(SUCCEEDED(hr), "Failed to create WIC imaging factory, hr %#x.\n", hr);
8025 hr = IWICImagingFactory_CreateBitmap(wic_factory, 16, 16,
8026 &GUID_WICPixelFormat32bppPBGRA, WICBitmapCacheOnDemand, &wic_bitmap);
8027 ok_(__FILE__, line)(SUCCEEDED(hr), "Failed to create WIC bitmap, hr %#x.\n", hr);
8028 IWICImagingFactory_Release(wic_factory);
8030 hr = ID2D1RenderTarget_CreateBitmapFromWicBitmap(rt, (IWICBitmapSource *)wic_bitmap, NULL, &bitmap);
8031 ok_(__FILE__, line)(SUCCEEDED(hr), "Failed to create bitmap from WIC source, hr %#x.\n", hr);
8033 check_bitmap_surface_(line, bitmap, has_surface, options);
8035 ID2D1Bitmap_Release(bitmap);
8037 CoUninitialize();
8039 /* Compatible target follows its parent. */
8040 hr = ID2D1RenderTarget_QueryInterface(rt, &IID_ID2D1DeviceContext, (void **)&context);
8041 ok_(__FILE__, line)(SUCCEEDED(hr), "Failed to get device context, hr %#x.\n", hr);
8043 dc_rt = NULL;
8044 ID2D1RenderTarget_QueryInterface(rt, &IID_ID2D1DCRenderTarget, (void **)&dc_rt);
8046 bitmap = NULL;
8047 target = NULL;
8048 ID2D1DeviceContext_GetTarget(context, &target);
8049 if (target && FAILED(ID2D1Image_QueryInterface(target, &IID_ID2D1Bitmap, (void **)&bitmap)))
8051 ID2D1Image_Release(target);
8052 target = NULL;
8054 if (bitmap)
8056 D2D1_PIXEL_FORMAT rt_format, bitmap_format;
8058 rt_format = ID2D1RenderTarget_GetPixelFormat(rt);
8059 bitmap_format = ID2D1Bitmap_GetPixelFormat(bitmap);
8060 ok_(__FILE__, line)(!memcmp(&rt_format, &bitmap_format, sizeof(rt_format)), "Unexpected bitmap format.\n");
8062 ID2D1Bitmap_Release(bitmap);
8065 /* Pixel format is not defined until target is set, for DC target it's specified on creation. */
8066 if (target || dc_rt)
8068 ID2D1Device *device, *device2;
8069 ID2D1DeviceContext *context2;
8071 ID2D1DeviceContext_GetDevice(context, &device);
8073 hr = ID2D1RenderTarget_CreateCompatibleRenderTarget(rt, NULL, NULL, NULL,
8074 D2D1_COMPATIBLE_RENDER_TARGET_OPTIONS_NONE, &compatible_rt);
8075 ok_(__FILE__, line)(SUCCEEDED(hr), "Failed to create compatible render target, hr %#x.\n", hr);
8077 hr = ID2D1BitmapRenderTarget_QueryInterface(compatible_rt, &IID_ID2D1DeviceContext, (void **)&context2);
8078 ok_(__FILE__, line)(SUCCEEDED(hr), "Failed to get device context, hr %#x.\n", hr);
8080 ID2D1DeviceContext_GetDevice(context2, &device2);
8081 ok_(__FILE__, line)(device == device2, "Unexpected device.\n");
8083 ID2D1Device_Release(device);
8084 ID2D1Device_Release(device2);
8086 hr = ID2D1BitmapRenderTarget_CreateBitmap(compatible_rt, size,
8087 bitmap_data, sizeof(*bitmap_data), &bitmap_desc, &bitmap);
8088 ok_(__FILE__, line)(SUCCEEDED(hr), "Failed to create bitmap, hr %#x.\n", hr);
8089 check_bitmap_surface_(line, bitmap, has_surface, options);
8090 ID2D1Bitmap_Release(bitmap);
8092 hr = ID2D1BitmapRenderTarget_GetBitmap(compatible_rt, &bitmap);
8093 ok_(__FILE__, line)(SUCCEEDED(hr), "Failed to get compatible target bitmap, hr %#x.\n", hr);
8095 bitmap2 = NULL;
8096 ID2D1DeviceContext_GetTarget(context2, (ID2D1Image **)&bitmap2);
8097 ok_(__FILE__, line)(bitmap2 == bitmap, "Unexpected bitmap.\n");
8099 check_bitmap_surface_(line, bitmap, has_surface, D2D1_BITMAP_OPTIONS_TARGET);
8100 ID2D1Bitmap_Release(bitmap2);
8101 ID2D1Bitmap_Release(bitmap);
8103 ID2D1BitmapRenderTarget_Release(compatible_rt);
8104 ID2D1DeviceContext_Release(context2);
8106 else
8108 hr = ID2D1RenderTarget_CreateCompatibleRenderTarget(rt, NULL, NULL, NULL,
8109 D2D1_COMPATIBLE_RENDER_TARGET_OPTIONS_NONE, &compatible_rt);
8110 ok_(__FILE__, line)(hr == WINCODEC_ERR_UNSUPPORTEDPIXELFORMAT, "Unexpected hr %#x.\n", hr);
8113 ID2D1DeviceContext_Release(context);
8114 if (target)
8115 ID2D1Image_Release(target);
8116 if (dc_rt)
8117 ID2D1DCRenderTarget_Release(dc_rt);
8120 static IDXGISurface *create_surface(IDXGIDevice *dxgi_device, DXGI_FORMAT format)
8122 D3D10_TEXTURE2D_DESC texture_desc;
8123 ID3D10Texture2D *texture;
8124 ID3D10Device *d3d_device;
8125 IDXGISurface *surface;
8126 HRESULT hr;
8128 texture_desc.Width = 1;
8129 texture_desc.Height = 1;
8130 texture_desc.MipLevels = 1;
8131 texture_desc.ArraySize = 1;
8132 texture_desc.Format = format;
8133 texture_desc.SampleDesc.Count = 1;
8134 texture_desc.SampleDesc.Quality = 0;
8135 texture_desc.Usage = D3D10_USAGE_DEFAULT;
8136 texture_desc.BindFlags = D3D10_BIND_SHADER_RESOURCE;
8137 texture_desc.CPUAccessFlags = 0;
8138 texture_desc.MiscFlags = 0;
8140 hr = IDXGIDevice_QueryInterface(dxgi_device, &IID_ID3D10Device, (void **)&d3d_device);
8141 ok(SUCCEEDED(hr), "Failed to get device interface, hr %#x.\n", hr);
8143 hr = ID3D10Device_CreateTexture2D(d3d_device, &texture_desc, NULL, &texture);
8144 ok(SUCCEEDED(hr), "Failed to create a texture, hr %#x.\n", hr);
8146 hr = ID3D10Texture2D_QueryInterface(texture, &IID_IDXGISurface, (void **)&surface);
8147 ok(SUCCEEDED(hr), "Failed to get surface interface, hr %#x.\n", hr);
8149 ID3D10Device_Release(d3d_device);
8150 ID3D10Texture2D_Release(texture);
8152 return surface;
8155 static void test_bitmap_surface(void)
8157 static const struct bitmap_format_test
8159 D2D1_PIXEL_FORMAT original;
8160 D2D1_PIXEL_FORMAT result;
8161 HRESULT hr;
8163 bitmap_format_tests[] =
8165 { { DXGI_FORMAT_UNKNOWN, D2D1_ALPHA_MODE_PREMULTIPLIED },
8166 { DXGI_FORMAT_B8G8R8A8_UNORM, D2D1_ALPHA_MODE_PREMULTIPLIED } },
8168 { { DXGI_FORMAT_B8G8R8A8_UNORM, D2D1_ALPHA_MODE_STRAIGHT }, { 0 }, WINCODEC_ERR_UNSUPPORTEDPIXELFORMAT },
8170 { { DXGI_FORMAT_UNKNOWN, D2D1_ALPHA_MODE_IGNORE },
8171 { DXGI_FORMAT_B8G8R8A8_UNORM, D2D1_ALPHA_MODE_IGNORE } },
8173 { { DXGI_FORMAT_UNKNOWN, D2D1_ALPHA_MODE_UNKNOWN }, { 0 }, WINCODEC_ERR_UNSUPPORTEDPIXELFORMAT },
8175 { { DXGI_FORMAT_B8G8R8A8_UNORM, D2D1_ALPHA_MODE_UNKNOWN }, { 0 }, WINCODEC_ERR_UNSUPPORTEDPIXELFORMAT },
8177 { { DXGI_FORMAT_B8G8R8A8_UNORM, D2D1_ALPHA_MODE_IGNORE },
8178 { DXGI_FORMAT_B8G8R8A8_UNORM, D2D1_ALPHA_MODE_IGNORE } },
8180 { { DXGI_FORMAT_UNKNOWN, D2D1_ALPHA_MODE_STRAIGHT }, { 0 }, WINCODEC_ERR_UNSUPPORTEDPIXELFORMAT },
8182 D2D1_HWND_RENDER_TARGET_PROPERTIES hwnd_rt_desc;
8183 D2D1_RENDER_TARGET_PROPERTIES rt_desc;
8184 D2D1_BITMAP_PROPERTIES1 bitmap_desc;
8185 ID2D1DeviceContext *device_context;
8186 IDXGISurface *surface, *surface2;
8187 D2D1_PIXEL_FORMAT pixel_format;
8188 ID3D10Device1 *d3d_device;
8189 IDXGISwapChain *swapchain;
8190 IDXGIDevice *dxgi_device;
8191 ID2D1Factory1 *factory;
8192 ID2D1RenderTarget *rt;
8193 ID2D1Bitmap1 *bitmap;
8194 ID2D1Device *device;
8195 ID2D1Image *target;
8196 D2D1_SIZE_U size;
8197 D2D1_TAG t1, t2;
8198 unsigned int i;
8199 HWND window;
8200 HRESULT hr;
8202 IWICBitmap *wic_bitmap;
8203 IWICImagingFactory *wic_factory;
8205 if (!(d3d_device = create_device()))
8207 skip("Failed to create device, skipping tests.\n");
8208 return;
8211 if (FAILED(D2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED, &IID_ID2D1Factory1, NULL, (void **)&factory)))
8213 win_skip("ID2D1Factory1 is not supported.\n");
8214 ID3D10Device1_Release(d3d_device);
8215 return;
8218 /* DXGI target */
8219 window = create_window();
8220 swapchain = create_swapchain(d3d_device, window, TRUE);
8221 hr = IDXGISwapChain_GetBuffer(swapchain, 0, &IID_IDXGISurface, (void **)&surface);
8222 ok(SUCCEEDED(hr), "Failed to get buffer, hr %#x.\n", hr);
8223 rt = create_render_target(surface);
8224 ok(!!rt, "Failed to create render target.\n");
8226 hr = ID2D1RenderTarget_QueryInterface(rt, &IID_ID2D1DeviceContext, (void **)&device_context);
8227 ok(SUCCEEDED(hr), "Failed to get device context, hr %#x.\n", hr);
8229 bitmap = NULL;
8230 ID2D1DeviceContext_GetTarget(device_context, (ID2D1Image **)&bitmap);
8231 ok(!!bitmap, "Unexpected target.\n");
8232 check_bitmap_surface((ID2D1Bitmap *)bitmap, TRUE, D2D1_BITMAP_OPTIONS_TARGET | D2D1_BITMAP_OPTIONS_CANNOT_DRAW);
8233 ID2D1Bitmap1_Release(bitmap);
8235 check_rt_bitmap_surface(rt, TRUE, D2D1_BITMAP_OPTIONS_NONE);
8237 ID2D1DeviceContext_Release(device_context);
8239 ID2D1RenderTarget_Release(rt);
8241 /* Bitmap created from DXGI surface. */
8242 hr = ID3D10Device1_QueryInterface(d3d_device, &IID_IDXGIDevice, (void **)&dxgi_device);
8243 ok(SUCCEEDED(hr), "Failed to get IDXGIDevice interface, hr %#x.\n", hr);
8245 hr = ID2D1Factory1_CreateDevice(factory, dxgi_device, &device);
8246 ok(SUCCEEDED(hr), "Failed to get ID2D1Device, hr %#x.\n", hr);
8248 hr = ID2D1Device_CreateDeviceContext(device, D2D1_DEVICE_CONTEXT_OPTIONS_NONE, &device_context);
8249 ok(SUCCEEDED(hr), "Failed to create device context, hr %#x.\n", hr);
8251 for (i = 0; i < ARRAY_SIZE(bitmap_format_tests); ++i)
8253 memset(&bitmap_desc, 0, sizeof(bitmap_desc));
8254 bitmap_desc.pixelFormat = bitmap_format_tests[i].original;
8255 bitmap_desc.bitmapOptions = D2D1_BITMAP_OPTIONS_TARGET | D2D1_BITMAP_OPTIONS_CANNOT_DRAW;
8257 hr = ID2D1DeviceContext_CreateBitmapFromDxgiSurface(device_context, surface, &bitmap_desc, &bitmap);
8258 todo_wine_if(bitmap_format_tests[i].hr == WINCODEC_ERR_UNSUPPORTEDPIXELFORMAT)
8259 ok(hr == bitmap_format_tests[i].hr, "%u: unexpected hr %#x.\n", i, hr);
8261 if (SUCCEEDED(bitmap_format_tests[i].hr))
8263 pixel_format = ID2D1Bitmap1_GetPixelFormat(bitmap);
8265 ok(pixel_format.format == bitmap_format_tests[i].result.format, "%u: unexpected pixel format %#x.\n",
8266 i, pixel_format.format);
8267 ok(pixel_format.alphaMode == bitmap_format_tests[i].result.alphaMode, "%u: unexpected alpha mode %d.\n",
8268 i, pixel_format.alphaMode);
8270 ID2D1Bitmap1_Release(bitmap);
8274 /* A8 surface */
8275 hr = IDXGISurface_GetDevice(surface, &IID_IDXGIDevice, (void **)&dxgi_device);
8276 ok(SUCCEEDED(hr), "Failed to get the device, hr %#x.\n", hr);
8278 surface2 = create_surface(dxgi_device, DXGI_FORMAT_A8_UNORM);
8280 hr = ID2D1DeviceContext_CreateBitmapFromDxgiSurface(device_context, surface2, NULL, &bitmap);
8281 ok(SUCCEEDED(hr) || broken(hr == WINCODEC_ERR_UNSUPPORTEDPIXELFORMAT) /* Win7 */,
8282 "Failed to create a bitmap, hr %#x.\n", hr);
8284 if (SUCCEEDED(hr))
8286 pixel_format = ID2D1Bitmap1_GetPixelFormat(bitmap);
8287 ok(pixel_format.alphaMode == D2D1_ALPHA_MODE_PREMULTIPLIED,
8288 "Unexpected alpha mode %#x.\n", pixel_format.alphaMode);
8290 ID2D1Bitmap1_Release(bitmap);
8293 IDXGIDevice_Release(dxgi_device);
8294 IDXGISurface_Release(surface2);
8296 hr = ID2D1DeviceContext_CreateBitmapFromDxgiSurface(device_context, surface, NULL, &bitmap);
8297 ok(SUCCEEDED(hr), "Failed to create a bitmap, hr %#x.\n", hr);
8299 pixel_format = ID2D1Bitmap1_GetPixelFormat(bitmap);
8300 ok(pixel_format.alphaMode == D2D1_ALPHA_MODE_PREMULTIPLIED,
8301 "Unexpected alpha mode %#x.\n", pixel_format.alphaMode);
8303 check_bitmap_surface((ID2D1Bitmap *)bitmap, TRUE, D2D1_BITMAP_OPTIONS_TARGET | D2D1_BITMAP_OPTIONS_CANNOT_DRAW);
8304 check_rt_bitmap_surface((ID2D1RenderTarget *)device_context, TRUE, D2D1_BITMAP_OPTIONS_NONE);
8306 ID2D1DeviceContext_SetTarget(device_context, (ID2D1Image *)bitmap);
8307 ID2D1DeviceContext_GetTarget(device_context, &target);
8308 ok(target == (ID2D1Image *)bitmap, "Unexpected target.\n");
8310 check_rt_bitmap_surface((ID2D1RenderTarget *)device_context, TRUE, D2D1_BITMAP_OPTIONS_NONE);
8312 ID2D1Bitmap1_Release(bitmap);
8314 /* Without D2D1_BITMAP_OPTIONS_TARGET. */
8315 memset(&bitmap_desc, 0, sizeof(bitmap_desc));
8316 bitmap_desc.pixelFormat = ID2D1DeviceContext_GetPixelFormat(device_context);
8317 size.width = size.height = 4;
8318 hr = ID2D1DeviceContext_CreateBitmap(device_context, size, NULL, 0, &bitmap_desc, &bitmap);
8319 ok(SUCCEEDED(hr), "Failed to create a bitmap, hr %#x.\n", hr);
8320 check_bitmap_surface((ID2D1Bitmap *)bitmap, TRUE, D2D1_BITMAP_OPTIONS_NONE);
8321 ID2D1DeviceContext_SetTags(device_context, 1, 2);
8323 ID2D1DeviceContext_BeginDraw(device_context);
8324 ID2D1DeviceContext_SetTarget(device_context, (ID2D1Image *)bitmap);
8325 hr = ID2D1DeviceContext_EndDraw(device_context, &t1, &t2);
8326 ok(hr == D2DERR_INVALID_TARGET, "Unexpected hr %#x.\n", hr);
8327 ok(t1 == 1 && t2 == 2, "Unexpected tags %s:%s.\n", wine_dbgstr_longlong(t1), wine_dbgstr_longlong(t2));
8329 ID2D1Bitmap1_Release(bitmap);
8331 ID2D1DeviceContext_GetTarget(device_context, (ID2D1Image **)&bitmap);
8332 ok(!!bitmap, "Expected target bitmap.\n");
8333 ID2D1Bitmap1_Release(bitmap);
8335 bitmap_desc.bitmapOptions = D2D1_BITMAP_OPTIONS_TARGET;
8336 hr = ID2D1DeviceContext_CreateBitmap(device_context, size, NULL, 0, &bitmap_desc, &bitmap);
8337 ok(SUCCEEDED(hr), "Failed to create a bitmap, hr %#x.\n", hr);
8338 check_bitmap_surface((ID2D1Bitmap *)bitmap, TRUE, D2D1_BITMAP_OPTIONS_TARGET);
8339 ID2D1DeviceContext_SetTarget(device_context, NULL);
8340 ID2D1DeviceContext_SetTags(device_context, 3, 4);
8342 ID2D1DeviceContext_BeginDraw(device_context);
8343 ID2D1DeviceContext_SetTarget(device_context, (ID2D1Image *)bitmap);
8344 hr = ID2D1DeviceContext_EndDraw(device_context, &t1, &t2);
8345 ok(SUCCEEDED(hr), "Failed to end draw, hr %#x.\n", hr);
8346 ok(!t1 && !t2, "Unexpected tags %s:%s.\n", wine_dbgstr_longlong(t1), wine_dbgstr_longlong(t2));
8348 ID2D1Bitmap1_Release(bitmap);
8350 ID2D1DeviceContext_Release(device_context);
8352 ID2D1Device_Release(device);
8353 IDXGIDevice_Release(dxgi_device);
8354 IDXGISurface_Release(surface);
8356 /* DC target */
8357 rt_desc.type = D2D1_RENDER_TARGET_TYPE_DEFAULT;
8358 rt_desc.pixelFormat.format = DXGI_FORMAT_B8G8R8A8_UNORM;
8359 rt_desc.pixelFormat.alphaMode = D2D1_ALPHA_MODE_PREMULTIPLIED;
8360 rt_desc.dpiX = 96.0f;
8361 rt_desc.dpiY = 96.0f;
8362 rt_desc.usage = D2D1_RENDER_TARGET_USAGE_NONE;
8363 rt_desc.minLevel = D2D1_FEATURE_LEVEL_DEFAULT;
8364 hr = ID2D1Factory1_CreateDCRenderTarget(factory, &rt_desc, (ID2D1DCRenderTarget **)&rt);
8365 ok(SUCCEEDED(hr), "Failed to create target, hr %#x.\n", hr);
8367 hr = ID2D1RenderTarget_QueryInterface(rt, &IID_ID2D1DeviceContext, (void **)&device_context);
8368 ok(SUCCEEDED(hr), "Failed to get device context, hr %#x.\n", hr);
8370 ID2D1DeviceContext_GetTarget(device_context, (ID2D1Image **)&bitmap);
8371 ok(!bitmap, "Unexpected target.\n");
8373 ID2D1DeviceContext_Release(device_context);
8374 ID2D1RenderTarget_Release(rt);
8376 /* HWND target */
8377 hwnd_rt_desc.hwnd = NULL;
8378 hwnd_rt_desc.pixelSize.width = 64;
8379 hwnd_rt_desc.pixelSize.height = 64;
8380 hwnd_rt_desc.presentOptions = D2D1_PRESENT_OPTIONS_NONE;
8381 hwnd_rt_desc.hwnd = CreateWindowA("static", "d2d_test", 0, 0, 0, 0, 0, 0, 0, 0, 0);
8382 ok(!!hwnd_rt_desc.hwnd, "Failed to create target window.\n");
8384 hr = ID2D1Factory1_CreateHwndRenderTarget(factory, &rt_desc, &hwnd_rt_desc, (ID2D1HwndRenderTarget **)&rt);
8385 ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr);
8387 check_rt_bitmap_surface(rt, FALSE, D2D1_BITMAP_OPTIONS_NONE);
8388 ID2D1RenderTarget_Release(rt);
8389 DestroyWindow(hwnd_rt_desc.hwnd);
8391 /* WIC target */
8392 CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
8394 hr = CoCreateInstance(&CLSID_WICImagingFactory, NULL, CLSCTX_INPROC_SERVER,
8395 &IID_IWICImagingFactory, (void **)&wic_factory);
8396 ok(SUCCEEDED(hr), "Failed to create WIC imaging factory, hr %#x.\n", hr);
8397 hr = IWICImagingFactory_CreateBitmap(wic_factory, 16, 16,
8398 &GUID_WICPixelFormat32bppPBGRA, WICBitmapCacheOnDemand, &wic_bitmap);
8399 ok(SUCCEEDED(hr), "Failed to create bitmap, hr %#x.\n", hr);
8400 IWICImagingFactory_Release(wic_factory);
8402 hr = ID2D1Factory1_CreateWicBitmapRenderTarget(factory, wic_bitmap, &rt_desc, &rt);
8403 ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr);
8405 check_rt_bitmap_surface(rt, FALSE, D2D1_BITMAP_OPTIONS_NONE);
8406 ID2D1RenderTarget_Release(rt);
8408 CoUninitialize();
8410 ID2D1Factory1_Release(factory);
8411 ID3D10Device1_Release(d3d_device);
8414 static void test_device_context(void)
8416 D2D1_HWND_RENDER_TARGET_PROPERTIES hwnd_rt_desc;
8417 D2D1_RENDER_TARGET_PROPERTIES rt_desc;
8418 ID2D1DeviceContext *device_context;
8419 IDXGISurface *surface, *surface2;
8420 ID2D1Device *device, *device2;
8421 D2D1_BITMAP_OPTIONS options;
8422 ID2D1DCRenderTarget *dc_rt;
8423 ID3D10Device1 *d3d_device;
8424 IDXGISwapChain *swapchain;
8425 IDXGIDevice *dxgi_device;
8426 D2D1_UNIT_MODE unit_mode;
8427 ID2D1Factory1 *factory;
8428 ID2D1RenderTarget *rt;
8429 ID2D1Bitmap1 *bitmap;
8430 ID2D1Image *target;
8431 HWND window;
8432 HRESULT hr;
8433 RECT rect;
8434 HDC hdc;
8436 IWICBitmap *wic_bitmap;
8437 IWICImagingFactory *wic_factory;
8439 if (!(d3d_device = create_device()))
8441 skip("Failed to create device, skipping tests.\n");
8442 return;
8445 if (FAILED(D2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED, &IID_ID2D1Factory1, NULL, (void **)&factory)))
8447 win_skip("ID2D1Factory1 is not supported.\n");
8448 ID3D10Device1_Release(d3d_device);
8449 return;
8452 hr = ID3D10Device1_QueryInterface(d3d_device, &IID_IDXGIDevice, (void **)&dxgi_device);
8453 ok(SUCCEEDED(hr), "Failed to get IDXGIDevice interface, hr %#x.\n", hr);
8455 hr = ID2D1Factory1_CreateDevice(factory, dxgi_device, &device);
8456 ok(SUCCEEDED(hr), "Failed to get ID2D1Device, hr %#x.\n", hr);
8457 IDXGIDevice_Release(dxgi_device);
8459 hr = ID2D1Device_CreateDeviceContext(device, D2D1_DEVICE_CONTEXT_OPTIONS_NONE, &device_context);
8460 ok(SUCCEEDED(hr), "Failed to create device context, hr %#x.\n", hr);
8462 ID2D1DeviceContext_GetDevice(device_context, &device2);
8463 ok(device2 == device, "Unexpected device instance.\n");
8464 ID2D1Device_Release(device2);
8466 target = (void *)0xdeadbeef;
8467 ID2D1DeviceContext_GetTarget(device_context, &target);
8468 ok(target == NULL, "Unexpected target instance %p.\n", target);
8470 unit_mode = ID2D1DeviceContext_GetUnitMode(device_context);
8471 ok(unit_mode == D2D1_UNIT_MODE_DIPS, "Unexpected unit mode %d.\n", unit_mode);
8473 ID2D1DeviceContext_Release(device_context);
8475 /* DXGI target */
8476 window = create_window();
8477 swapchain = create_swapchain(d3d_device, window, TRUE);
8478 hr = IDXGISwapChain_GetBuffer(swapchain, 0, &IID_IDXGISurface, (void **)&surface);
8479 ok(SUCCEEDED(hr), "Failed to get buffer, hr %#x.\n", hr);
8480 rt = create_render_target(surface);
8481 ok(!!rt, "Failed to create render target.\n");
8483 hr = ID2D1RenderTarget_QueryInterface(rt, &IID_ID2D1DeviceContext, (void **)&device_context);
8484 ok(SUCCEEDED(hr), "Failed to get device context interface, hr %#x.\n", hr);
8485 ID2D1DeviceContext_GetTarget(device_context, (ID2D1Image **)&bitmap);
8486 options = ID2D1Bitmap1_GetOptions(bitmap);
8487 ok(options == (D2D1_BITMAP_OPTIONS_TARGET | D2D1_BITMAP_OPTIONS_CANNOT_DRAW),
8488 "Unexpected bitmap options %#x.\n", options);
8489 hr = ID2D1Bitmap1_GetSurface(bitmap, &surface2);
8490 ok(SUCCEEDED(hr), "Failed to get bitmap surface, hr %#x.\n", hr);
8491 ok(surface2 == surface, "Unexpected surface instance.\n");
8492 IDXGISurface_Release(surface2);
8494 ID2D1DeviceContext_BeginDraw(device_context);
8495 hr = ID2D1Bitmap1_GetSurface(bitmap, &surface2);
8496 ok(SUCCEEDED(hr), "Failed to get bitmap surface, hr %#x.\n", hr);
8497 ok(surface2 == surface, "Unexpected surface instance.\n");
8498 IDXGISurface_Release(surface2);
8499 ID2D1DeviceContext_EndDraw(device_context, NULL, NULL);
8500 ID2D1Bitmap1_Release(bitmap);
8502 ID2D1DeviceContext_SetTarget(device_context, NULL);
8503 ID2D1DeviceContext_GetTarget(device_context, (ID2D1Image **)&bitmap);
8504 ok(bitmap == NULL, "Unexpected target instance.\n");
8506 ID2D1DeviceContext_Release(device_context);
8507 ID2D1RenderTarget_Release(rt);
8508 IDXGISurface_Release(surface);
8509 DestroyWindow(window);
8511 /* WIC target */
8512 CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
8514 hr = CoCreateInstance(&CLSID_WICImagingFactory, NULL, CLSCTX_INPROC_SERVER,
8515 &IID_IWICImagingFactory, (void **)&wic_factory);
8516 ok(SUCCEEDED(hr), "Failed to create WIC imaging factory, hr %#x.\n", hr);
8517 hr = IWICImagingFactory_CreateBitmap(wic_factory, 16, 16,
8518 &GUID_WICPixelFormat32bppPBGRA, WICBitmapCacheOnDemand, &wic_bitmap);
8519 ok(SUCCEEDED(hr), "Failed to create bitmap, hr %#x.\n", hr);
8520 IWICImagingFactory_Release(wic_factory);
8522 rt_desc.type = D2D1_RENDER_TARGET_TYPE_DEFAULT;
8523 rt_desc.pixelFormat.format = DXGI_FORMAT_B8G8R8A8_UNORM;
8524 rt_desc.pixelFormat.alphaMode = D2D1_ALPHA_MODE_PREMULTIPLIED;
8525 rt_desc.dpiX = 96.0f;
8526 rt_desc.dpiY = 96.0f;
8527 rt_desc.usage = D2D1_RENDER_TARGET_USAGE_NONE;
8528 rt_desc.minLevel = D2D1_FEATURE_LEVEL_DEFAULT;
8529 hr = ID2D1Factory1_CreateWicBitmapRenderTarget(factory, wic_bitmap, &rt_desc, &rt);
8530 ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr);
8532 hr = ID2D1RenderTarget_QueryInterface(rt, &IID_ID2D1DeviceContext, (void **)&device_context);
8533 ok(SUCCEEDED(hr), "Failed to get device context interface, hr %#x.\n", hr);
8534 ID2D1DeviceContext_GetTarget(device_context, (ID2D1Image **)&bitmap);
8535 options = ID2D1Bitmap1_GetOptions(bitmap);
8536 ok(options == (D2D1_BITMAP_OPTIONS_TARGET | D2D1_BITMAP_OPTIONS_CANNOT_DRAW),
8537 "Unexpected bitmap options %#x.\n", options);
8538 hr = ID2D1Bitmap1_GetSurface(bitmap, &surface);
8539 todo_wine
8540 ok(hr == E_FAIL, "Unexpected hr %#x.\n", hr);
8541 ID2D1Bitmap1_Release(bitmap);
8543 ID2D1DeviceContext_SetTarget(device_context, NULL);
8544 ID2D1DeviceContext_GetTarget(device_context, (ID2D1Image **)&bitmap);
8545 ok(bitmap == NULL, "Unexpected target instance.\n");
8547 ID2D1DeviceContext_Release(device_context);
8548 ID2D1RenderTarget_Release(rt);
8550 CoUninitialize();
8552 /* HWND target */
8553 hwnd_rt_desc.hwnd = NULL;
8554 hwnd_rt_desc.pixelSize.width = 64;
8555 hwnd_rt_desc.pixelSize.height = 64;
8556 hwnd_rt_desc.presentOptions = D2D1_PRESENT_OPTIONS_NONE;
8557 hwnd_rt_desc.hwnd = CreateWindowA("static", "d2d_test", 0, 0, 0, 0, 0, 0, 0, 0, 0);
8558 ok(!!hwnd_rt_desc.hwnd, "Failed to create target window.\n");
8560 hr = ID2D1Factory1_CreateHwndRenderTarget(factory, &rt_desc, &hwnd_rt_desc, (ID2D1HwndRenderTarget **)&rt);
8561 ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr);
8563 hr = ID2D1RenderTarget_QueryInterface(rt, &IID_ID2D1DeviceContext, (void **)&device_context);
8564 ok(SUCCEEDED(hr), "Failed to get device context interface, hr %#x.\n", hr);
8565 ID2D1DeviceContext_GetTarget(device_context, (ID2D1Image **)&bitmap);
8566 options = ID2D1Bitmap1_GetOptions(bitmap);
8567 ok(options == (D2D1_BITMAP_OPTIONS_TARGET | D2D1_BITMAP_OPTIONS_CANNOT_DRAW),
8568 "Unexpected bitmap options %#x.\n", options);
8569 hr = ID2D1Bitmap1_GetSurface(bitmap, &surface);
8570 ok(hr == D2DERR_INVALID_CALL, "Unexpected hr %#x.\n", hr);
8571 ID2D1Bitmap1_Release(bitmap);
8573 ID2D1DeviceContext_SetTarget(device_context, NULL);
8574 ID2D1DeviceContext_GetTarget(device_context, (ID2D1Image **)&bitmap);
8575 ok(bitmap == NULL, "Unexpected target instance.\n");
8577 ID2D1DeviceContext_Release(device_context);
8578 ID2D1RenderTarget_Release(rt);
8579 DestroyWindow(hwnd_rt_desc.hwnd);
8581 /* DC target */
8582 hr = ID2D1Factory1_CreateDCRenderTarget(factory, &rt_desc, &dc_rt);
8583 ok(SUCCEEDED(hr), "Failed to create target, hr %#x.\n", hr);
8585 hr = ID2D1DCRenderTarget_QueryInterface(dc_rt, &IID_ID2D1DeviceContext, (void **)&device_context);
8586 ok(SUCCEEDED(hr), "Failed to get device context interface, hr %#x.\n", hr);
8587 ID2D1DeviceContext_GetTarget(device_context, (ID2D1Image **)&bitmap);
8588 ok(bitmap == NULL, "Unexpected bitmap instance.\n");
8590 hdc = CreateCompatibleDC(NULL);
8591 ok(hdc != NULL, "Failed to create an HDC.\n");
8593 create_target_dibsection(hdc, 16, 16);
8595 SetRect(&rect, 0, 0, 16, 16);
8596 hr = ID2D1DCRenderTarget_BindDC(dc_rt, hdc, &rect);
8597 ok(SUCCEEDED(hr), "BindDC() failed, hr %#x.\n", hr);
8599 ID2D1DeviceContext_GetTarget(device_context, (ID2D1Image **)&bitmap);
8600 options = ID2D1Bitmap1_GetOptions(bitmap);
8601 ok(options == (D2D1_BITMAP_OPTIONS_TARGET | D2D1_BITMAP_OPTIONS_CANNOT_DRAW | D2D1_BITMAP_OPTIONS_GDI_COMPATIBLE),
8602 "Unexpected bitmap options %#x.\n", options);
8603 hr = ID2D1Bitmap1_GetSurface(bitmap, &surface);
8604 ok(hr == D2DERR_INVALID_CALL, "Unexpected hr %#x.\n", hr);
8605 ID2D1Bitmap1_Release(bitmap);
8607 ID2D1DeviceContext_SetTarget(device_context, NULL);
8608 ID2D1DeviceContext_GetTarget(device_context, (ID2D1Image **)&bitmap);
8609 ok(bitmap == NULL, "Unexpected target instance.\n");
8611 ID2D1DeviceContext_Release(device_context);
8612 ID2D1DCRenderTarget_Release(dc_rt);
8613 DeleteDC(hdc);
8615 ID2D1Device_Release(device);
8616 ID2D1Factory1_Release(factory);
8617 ID3D10Device1_Release(d3d_device);
8620 static void test_invert_matrix(void)
8622 static const struct
8624 D2D1_MATRIX_3X2_F matrix;
8625 D2D1_MATRIX_3X2_F inverse;
8626 BOOL invertible;
8628 invert_tests[] =
8630 { {{{ 0 }}}, {{{ 0 }}}, FALSE },
8633 1.0f, 2.0f,
8634 1.0f, 2.0f,
8635 4.0f, 8.0f
8636 }}},
8638 1.0f, 2.0f,
8639 1.0f, 2.0f,
8640 4.0f, 8.0f
8641 }}},
8642 FALSE
8646 2.0f, 0.0f,
8647 0.0f, 2.0f,
8648 4.0f, 8.0f
8649 }}},
8651 0.5f, -0.0f,
8652 -0.0f, 0.5f,
8653 -2.0f, -4.0f
8654 }}},
8655 TRUE
8659 2.0f, 1.0f,
8660 2.0f, 2.0f,
8661 4.0f, 8.0f
8662 }}},
8664 1.0f, -0.5f,
8665 -1.0f, 1.0f,
8666 4.0f, -6.0f
8667 }}},
8668 TRUE
8672 2.0f, 1.0f,
8673 3.0f, 1.0f,
8674 4.0f, 8.0f
8675 }}},
8677 -1.0f, 1.0f,
8678 3.0f, -2.0f,
8679 -20.0f, 12.0f
8680 }}},
8681 TRUE
8684 unsigned int i;
8686 for (i = 0; i < ARRAY_SIZE(invert_tests); ++i)
8688 D2D1_MATRIX_3X2_F m;
8689 BOOL ret;
8691 m = invert_tests[i].matrix;
8692 ret = D2D1InvertMatrix(&m);
8693 ok(ret == invert_tests[i].invertible, "%u: unexpected return value %d.\n", i, ret);
8694 ok(!memcmp(&m, &invert_tests[i].inverse, sizeof(m)),
8695 "%u: unexpected matrix value {%.8e, %.8e, %.8e, %.8e, %.8e, %.8e}.\n", i,
8696 m._11, m._12, m._21, m._22, m._31, m._32);
8698 ret = D2D1IsMatrixInvertible(&invert_tests[i].matrix);
8699 ok(ret == invert_tests[i].invertible, "%u: unexpected return value %d.\n", i, ret);
8703 static void test_skew_matrix(void)
8705 static const struct
8707 float angle_x;
8708 float angle_y;
8709 D2D1_POINT_2F center;
8710 D2D1_MATRIX_3X2_F matrix;
8712 skew_tests[] =
8714 { 0.0f, 0.0f, { 0.0f, 0.0f }, {{{ 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f }}} },
8715 { 45.0f, 0.0f, { 0.0f, 0.0f }, {{{ 1.0f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f }}} },
8716 { 0.0f, 0.0f, { 10.0f, -3.0f }, {{{ 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f }}} },
8717 { -45.0f, 45.0f, { 0.1f, 0.5f }, {{{ 1.0f, 1.0f, -1.0f, 1.0f, 0.5f, -0.1f }}} },
8718 { -45.0f, 45.0f, { 1.0f, 2.0f }, {{{ 1.0f, 1.0f, -1.0f, 1.0f, 2.0f, -1.0f }}} },
8719 { 45.0f, -45.0f, { 1.0f, 2.0f }, {{{ 1.0f, -1.0f, 1.0f, 1.0f, -2.0f, 1.0f }}} },
8720 { 30.0f, -60.0f, { 12.0f, -5.0f }, {{{ 1.0f, -1.7320509f, 0.577350259f, 1.0f, 2.88675117f, 20.7846107f }}} },
8722 unsigned int i;
8724 for (i = 0; i < ARRAY_SIZE(skew_tests); ++i)
8726 const D2D1_MATRIX_3X2_F *expected = &skew_tests[i].matrix;
8727 D2D1_MATRIX_3X2_F m;
8728 BOOL ret;
8730 D2D1MakeSkewMatrix(skew_tests[i].angle_x, skew_tests[i].angle_y, skew_tests[i].center, &m);
8731 ret = compare_float(m._11, expected->_11, 3) && compare_float(m._12, expected->_12, 3)
8732 && compare_float(m._21, expected->_21, 3) && compare_float(m._22, expected->_22, 3)
8733 && compare_float(m._31, expected->_31, 3) && compare_float(m._32, expected->_32, 3);
8735 ok(ret, "%u: unexpected matrix value {%.8e, %.8e, %.8e, %.8e, %.8e, %.8e}, expected "
8736 "{%.8e, %.8e, %.8e, %.8e, %.8e, %.8e}.\n", i, m._11, m._12, m._21, m._22, m._31, m._32,
8737 expected->_11, expected->_12, expected->_21, expected->_22, expected->_31, expected->_32);
8741 static ID2D1DeviceContext *create_device_context(ID2D1Factory1 *factory, ID3D10Device1 *d3d_device)
8743 ID2D1DeviceContext *device_context;
8744 IDXGIDevice *dxgi_device;
8745 ID2D1Device *device;
8746 HRESULT hr;
8748 hr = ID3D10Device1_QueryInterface(d3d_device, &IID_IDXGIDevice, (void **)&dxgi_device);
8749 ok(SUCCEEDED(hr), "Failed to get IDXGIDevice interface, hr %#x.\n", hr);
8751 hr = ID2D1Factory1_CreateDevice(factory, dxgi_device, &device);
8752 ok(SUCCEEDED(hr), "Failed to get ID2D1Device, hr %#x.\n", hr);
8753 IDXGIDevice_Release(dxgi_device);
8755 hr = ID2D1Device_CreateDeviceContext(device, D2D1_DEVICE_CONTEXT_OPTIONS_NONE, &device_context);
8756 ok(SUCCEEDED(hr), "Failed to create device context, hr %#x.\n", hr);
8757 ID2D1Device_Release(device);
8759 return device_context;
8762 static void test_command_list(void)
8764 static const DWORD bitmap_data[] =
8766 0xffff0000, 0xffffff00, 0xff00ff00, 0xff00ffff,
8768 static const D2D1_GRADIENT_STOP stops[] =
8770 {0.0f, {1.0f, 0.0f, 0.0f, 1.0f}},
8771 {0.5f, {0.0f, 1.0f, 0.0f, 1.0f}},
8772 {1.0f, {0.0f, 0.0f, 1.0f, 1.0f}},
8774 D2D1_RADIAL_GRADIENT_BRUSH_PROPERTIES radial_gradient_properties;
8775 D2D1_LINEAR_GRADIENT_BRUSH_PROPERTIES linear_gradient_properties;
8776 ID2D1DeviceContext *device_context, *device_context2;
8777 D2D1_STROKE_STYLE_PROPERTIES stroke_desc;
8778 ID2D1GradientStopCollection *gradient;
8779 D2D1_BITMAP_PROPERTIES bitmap_desc;
8780 ID2D1StrokeStyle *stroke_style;
8781 ID2D1CommandList *command_list;
8782 ID3D10Device1 *d3d_device;
8783 ID2D1Geometry *geometry;
8784 ID2D1Factory1 *factory;
8785 ID2D1RenderTarget *rt;
8786 D2D1_POINT_2F p0, p1;
8787 ID2D1Bitmap *bitmap;
8788 ID2D1Image *target;
8789 D2D1_COLOR_F color;
8790 ID2D1Brush *brush;
8791 D2D1_RECT_F rect;
8792 D2D_SIZE_U size;
8793 ULONG refcount;
8794 HRESULT hr;
8796 if (!(d3d_device = create_device()))
8798 skip("Failed to create device, skipping tests.\n");
8799 return;
8802 if (FAILED(D2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED, &IID_ID2D1Factory1, NULL, (void **)&factory)))
8804 win_skip("ID2D1Factory1 is not supported.\n");
8805 ID3D10Device1_Release(d3d_device);
8806 return;
8809 device_context = create_device_context(factory, d3d_device);
8810 ok(device_context != NULL, "Failed to create device context.\n");
8812 hr = ID2D1DeviceContext_CreateCommandList(device_context, &command_list);
8813 todo_wine
8814 ok(SUCCEEDED(hr), "Failed to create command list, hr %#x.\n", hr);
8816 if (FAILED(hr))
8818 ID2D1DeviceContext_Release(device_context);
8819 ID2D1Factory1_Release(factory);
8820 return;
8823 ID2D1DeviceContext_SetTarget(device_context, (ID2D1Image *)command_list);
8824 ID2D1DeviceContext_BeginDraw(device_context);
8826 hr = ID2D1DeviceContext_QueryInterface(device_context, &IID_ID2D1RenderTarget, (void **)&rt);
8827 ok(SUCCEEDED(hr), "Failed to get rt interface, hr %#x.\n", hr);
8829 /* Test how resources are referenced by the list. */
8831 /* Bitmap. */
8832 set_size_u(&size, 4, 1);
8833 bitmap_desc.pixelFormat.format = DXGI_FORMAT_B8G8R8A8_UNORM;
8834 bitmap_desc.pixelFormat.alphaMode = D2D1_ALPHA_MODE_IGNORE;
8835 bitmap_desc.dpiX = 96.0f;
8836 bitmap_desc.dpiY = 96.0f;
8837 hr = ID2D1RenderTarget_CreateBitmap(rt, size, bitmap_data, 4 * sizeof(*bitmap_data), &bitmap_desc, &bitmap);
8838 ok(SUCCEEDED(hr), "Failed to create bitmap, hr %#x.\n", hr);
8840 ID2D1RenderTarget_DrawBitmap(rt, bitmap, NULL, 0.25f, D2D1_BITMAP_INTERPOLATION_MODE_NEAREST_NEIGHBOR, NULL);
8842 refcount = ID2D1Bitmap_Release(bitmap);
8843 ok(refcount == 1, "Got unexpected refcount %u.\n", refcount);
8845 /* Solid color brush. */
8846 set_color(&color, 0.0f, 0.0f, 0.0f, 0.0f);
8847 hr = ID2D1RenderTarget_CreateSolidColorBrush(rt, &color, NULL, (ID2D1SolidColorBrush **)&brush);
8848 ok(SUCCEEDED(hr), "Failed to create a brush, hr %#x.\n", hr);
8850 set_rect(&rect, 0.0f, 0.0f, 16.0f, 16.0f);
8851 ID2D1RenderTarget_FillRectangle(rt, &rect, brush);
8853 refcount = ID2D1Brush_Release(brush);
8854 ok(refcount == 0, "Got unexpected refcount %u.\n", refcount);
8856 /* Bitmap brush. */
8857 hr = ID2D1RenderTarget_CreateBitmap(rt, size, bitmap_data, 4 * sizeof(*bitmap_data), &bitmap_desc, &bitmap);
8858 ok(SUCCEEDED(hr), "Failed to create bitmap, hr %#x.\n", hr);
8860 hr = ID2D1RenderTarget_CreateBitmapBrush(rt, bitmap, NULL, NULL, (ID2D1BitmapBrush **)&brush);
8861 ok(SUCCEEDED(hr), "Failed to create bitmap brush, hr %#x.\n", hr);
8863 set_rect(&rect, 0.0f, 0.0f, 16.0f, 16.0f);
8864 ID2D1RenderTarget_FillRectangle(rt, &rect, brush);
8866 refcount = ID2D1Brush_Release(brush);
8867 ok(refcount == 0, "Got unexpected refcount %u.\n", refcount);
8869 refcount = ID2D1Bitmap_Release(bitmap);
8870 ok(refcount == 1, "Got unexpected refcount %u.\n", refcount);
8872 /* Linear gradient brush. */
8873 hr = ID2D1RenderTarget_CreateGradientStopCollection(rt, stops, ARRAY_SIZE(stops),
8874 D2D1_GAMMA_2_2, D2D1_EXTEND_MODE_CLAMP, &gradient);
8875 ok(SUCCEEDED(hr), "Failed to create stop collection, hr %#x.\n", hr);
8877 set_point(&linear_gradient_properties.startPoint, 320.0f, 0.0f);
8878 set_point(&linear_gradient_properties.endPoint, 0.0f, 960.0f);
8879 hr = ID2D1RenderTarget_CreateLinearGradientBrush(rt, &linear_gradient_properties, NULL, gradient,
8880 (ID2D1LinearGradientBrush **)&brush);
8881 ok(SUCCEEDED(hr), "Failed to create brush, hr %#x.\n", hr);
8883 set_rect(&rect, -1.0f, -1.0f, 1.0f, 1.0f);
8884 hr = ID2D1Factory1_CreateRectangleGeometry(factory, &rect, (ID2D1RectangleGeometry **)&geometry);
8885 ok(SUCCEEDED(hr), "Failed to create geometry, hr %#x.\n", hr);
8887 ID2D1RenderTarget_FillGeometry(rt, geometry, brush, NULL);
8889 refcount = ID2D1Brush_Release(brush);
8890 ok(refcount == 0, "Got unexpected refcount %u.\n", refcount);
8892 refcount = ID2D1Geometry_Release(geometry);
8893 ok(refcount == 1, "Got unexpected refcount %u.\n", refcount);
8895 refcount = ID2D1GradientStopCollection_Release(gradient);
8896 ok(refcount == 1, "Got unexpected refcount %u.\n", refcount);
8898 /* Radial gradient brush. */
8899 hr = ID2D1RenderTarget_CreateGradientStopCollection(rt, stops, ARRAY_SIZE(stops),
8900 D2D1_GAMMA_2_2, D2D1_EXTEND_MODE_CLAMP, &gradient);
8901 ok(SUCCEEDED(hr), "Failed to create stop collection, hr %#x.\n", hr);
8903 set_point(&radial_gradient_properties.center, 160.0f, 480.0f);
8904 set_point(&radial_gradient_properties.gradientOriginOffset, 40.0f, -120.0f);
8905 radial_gradient_properties.radiusX = 160.0f;
8906 radial_gradient_properties.radiusY = 480.0f;
8907 hr = ID2D1RenderTarget_CreateRadialGradientBrush(rt, &radial_gradient_properties, NULL, gradient,
8908 (ID2D1RadialGradientBrush **)&brush);
8909 ok(SUCCEEDED(hr), "Failed to create brush, hr %#x.\n", hr);
8911 set_rect(&rect, -1.0f, -1.0f, 1.0f, 1.0f);
8912 hr = ID2D1Factory1_CreateRectangleGeometry(factory, &rect, (ID2D1RectangleGeometry **)&geometry);
8913 ok(SUCCEEDED(hr), "Failed to create geometry, hr %#x.\n", hr);
8915 ID2D1RenderTarget_FillGeometry(rt, geometry, brush, NULL);
8917 refcount = ID2D1Brush_Release(brush);
8918 ok(refcount == 0, "Got unexpected refcount %u.\n", refcount);
8920 refcount = ID2D1Geometry_Release(geometry);
8921 ok(refcount == 1, "Got unexpected refcount %u.\n", refcount);
8923 refcount = ID2D1GradientStopCollection_Release(gradient);
8924 ok(refcount == 1, "Got unexpected refcount %u.\n", refcount);
8926 /* Geometry. */
8927 set_rect(&rect, -1.0f, -1.0f, 1.0f, 1.0f);
8928 hr = ID2D1Factory1_CreateRectangleGeometry(factory, &rect, (ID2D1RectangleGeometry **)&geometry);
8929 ok(SUCCEEDED(hr), "Failed to create geometry, hr %#x.\n", hr);
8931 set_color(&color, 0.0f, 0.0f, 0.0f, 0.0f);
8932 hr = ID2D1RenderTarget_CreateSolidColorBrush(rt, &color, NULL, (ID2D1SolidColorBrush **)&brush);
8933 ok(SUCCEEDED(hr), "Failed to create a brush, hr %#x.\n", hr);
8935 ID2D1RenderTarget_FillGeometry(rt, geometry, brush, NULL);
8937 refcount = ID2D1Brush_Release(brush);
8938 ok(refcount == 0, "Got unexpected refcount %u.\n", refcount);
8940 refcount = ID2D1Geometry_Release(geometry);
8941 ok(refcount == 1, "Got unexpected refcount %u.\n", refcount);
8943 /* Stroke style. */
8944 stroke_desc.startCap = D2D1_CAP_STYLE_SQUARE;
8945 stroke_desc.endCap = D2D1_CAP_STYLE_ROUND;
8946 stroke_desc.dashCap = D2D1_CAP_STYLE_TRIANGLE;
8947 stroke_desc.lineJoin = D2D1_LINE_JOIN_BEVEL;
8948 stroke_desc.miterLimit = 1.5f;
8949 stroke_desc.dashStyle = D2D1_DASH_STYLE_DOT;
8950 stroke_desc.dashOffset = -1.0f;
8952 hr = ID2D1Factory_CreateStrokeStyle((ID2D1Factory *)factory, &stroke_desc, NULL, 0, &stroke_style);
8953 ok(SUCCEEDED(hr), "Failed to create stroke style, %#x.\n", hr);
8955 set_color(&color, 0.0f, 0.0f, 0.0f, 0.0f);
8956 hr = ID2D1RenderTarget_CreateSolidColorBrush(rt, &color, NULL, (ID2D1SolidColorBrush **)&brush);
8957 ok(SUCCEEDED(hr), "Failed to create a brush, hr %#x.\n", hr);
8959 set_point(&p0, 100.0f, 160.0f);
8960 set_point(&p1, 140.0f, 160.0f);
8961 ID2D1RenderTarget_DrawLine(rt, p0, p1, brush, 1.0f, stroke_style);
8963 refcount = ID2D1Brush_Release(brush);
8964 ok(refcount == 0, "Got unexpected refcount %u.\n", refcount);
8966 refcount = ID2D1StrokeStyle_Release(stroke_style);
8967 ok(refcount == 1, "Got unexpected refcount %u.\n", refcount);
8969 /* Close on attached list. */
8970 ID2D1DeviceContext_GetTarget(device_context, &target);
8971 ok(target == (ID2D1Image *)command_list, "Unexpected context target.\n");
8972 ID2D1Image_Release(target);
8974 hr = ID2D1CommandList_Close(command_list);
8975 ok(SUCCEEDED(hr), "Failed to close a list, hr %#x.\n", hr);
8977 ID2D1DeviceContext_GetTarget(device_context, &target);
8978 ok(target == NULL, "Unexpected context target.\n");
8980 hr = ID2D1CommandList_Close(command_list);
8981 ok(hr == D2DERR_WRONG_STATE, "Unexpected hr %#x.\n", hr);
8983 ID2D1CommandList_Release(command_list);
8985 /* Close empty list. */
8986 hr = ID2D1DeviceContext_CreateCommandList(device_context, &command_list);
8987 ok(SUCCEEDED(hr), "Failed to create command list, hr %#x.\n", hr);
8989 hr = ID2D1CommandList_Close(command_list);
8990 ok(SUCCEEDED(hr), "Failed to close a list, hr %#x.\n", hr);
8992 ID2D1CommandList_Release(command_list);
8994 /* List created with different context. */
8995 device_context2 = create_device_context(factory, d3d_device);
8996 ok(device_context2 != NULL, "Failed to create device context.\n");
8998 hr = ID2D1DeviceContext_CreateCommandList(device_context, &command_list);
8999 ok(SUCCEEDED(hr), "Failed to create command list, hr %#x.\n", hr);
9001 ID2D1DeviceContext_SetTarget(device_context2, (ID2D1Image *)command_list);
9002 ID2D1DeviceContext_GetTarget(device_context2, &target);
9003 ok(target == NULL, "Unexpected target.\n");
9005 ID2D1CommandList_Release(command_list);
9006 ID2D1DeviceContext_Release(device_context2);
9008 ID2D1RenderTarget_Release(rt);
9009 ID2D1DeviceContext_Release(device_context);
9010 refcount = ID2D1Factory1_Release(factory);
9011 ok(!refcount, "Factory has %u references left.\n", refcount);
9014 static void test_max_bitmap_size(void)
9016 D2D1_RENDER_TARGET_PROPERTIES desc;
9017 D2D1_BITMAP_PROPERTIES bitmap_desc;
9018 IDXGISwapChain *swapchain;
9019 ID2D1Factory *factory;
9020 IDXGISurface *surface;
9021 ID2D1RenderTarget *rt;
9022 ID3D10Device1 *device;
9023 ID2D1Bitmap *bitmap;
9024 UINT32 bitmap_size;
9025 unsigned int i, j;
9026 HWND window;
9027 HRESULT hr;
9029 static const struct
9031 const char *name;
9032 DWORD type;
9034 device_types[] =
9036 { "HW", D3D10_DRIVER_TYPE_HARDWARE },
9037 { "WARP", D3D10_DRIVER_TYPE_WARP },
9038 { "REF", D3D10_DRIVER_TYPE_REFERENCE },
9040 static const struct
9042 const char *name;
9043 DWORD type;
9045 target_types[] =
9047 { "DEFAULT", D2D1_RENDER_TARGET_TYPE_DEFAULT },
9048 { "HW", D2D1_RENDER_TARGET_TYPE_HARDWARE },
9051 hr = D2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED, &IID_ID2D1Factory, NULL, (void **)&factory);
9052 ok(SUCCEEDED(hr), "Failed to create factory, hr %#x.\n", hr);
9054 for (i = 0; i < ARRAY_SIZE(device_types); ++i)
9056 if (FAILED(hr = D3D10CreateDevice1(NULL, device_types[i].type, NULL, D3D10_CREATE_DEVICE_BGRA_SUPPORT,
9057 D3D10_FEATURE_LEVEL_10_0, D3D10_1_SDK_VERSION, &device)))
9059 skip("Failed to create %s d3d device, hr %#x.\n", device_types[i].name, hr);
9060 continue;
9063 window = create_window();
9064 swapchain = create_swapchain(device, window, TRUE);
9065 hr = IDXGISwapChain_GetBuffer(swapchain, 0, &IID_IDXGISurface, (void **)&surface);
9066 ok(SUCCEEDED(hr), "Failed to get buffer, hr %#x.\n", hr);
9068 for (j = 0; j < ARRAY_SIZE(target_types); ++j)
9070 D3D10_TEXTURE2D_DESC texture_desc;
9071 ID3D10Texture2D *texture;
9072 D2D1_SIZE_U size;
9074 desc.type = target_types[j].type;
9075 desc.pixelFormat.format = DXGI_FORMAT_UNKNOWN;
9076 desc.pixelFormat.alphaMode = D2D1_ALPHA_MODE_PREMULTIPLIED;
9077 desc.dpiX = 0.0f;
9078 desc.dpiY = 0.0f;
9079 desc.usage = D2D1_RENDER_TARGET_USAGE_NONE;
9080 desc.minLevel = D2D1_FEATURE_LEVEL_DEFAULT;
9082 hr = ID2D1Factory_CreateDxgiSurfaceRenderTarget(factory, surface, &desc, &rt);
9083 ok(SUCCEEDED(hr), "%s/%s: failed to create render target, hr %#x.\n", device_types[i].name,
9084 target_types[j].name, hr);
9086 bitmap_size = ID2D1RenderTarget_GetMaximumBitmapSize(rt);
9087 ok(bitmap_size >= D3D10_REQ_TEXTURE2D_U_OR_V_DIMENSION, "%s/%s: unexpected bitmap size %u.\n",
9088 device_types[i].name, target_types[j].name, bitmap_size);
9090 bitmap_desc.dpiX = 96.0f;
9091 bitmap_desc.dpiY = 96.0f;
9092 bitmap_desc.pixelFormat.format = DXGI_FORMAT_B8G8R8A8_UNORM;
9093 bitmap_desc.pixelFormat.alphaMode = D2D1_ALPHA_MODE_PREMULTIPLIED;
9095 size.width = bitmap_size;
9096 size.height = 1;
9097 hr = ID2D1RenderTarget_CreateBitmap(rt, size, NULL, 0, &bitmap_desc, &bitmap);
9098 ok(SUCCEEDED(hr), "Failed to create a bitmap, hr %#x.\n", hr);
9099 ID2D1Bitmap_Release(bitmap);
9101 ID2D1RenderTarget_Release(rt);
9103 texture_desc.Width = bitmap_size;
9104 texture_desc.Height = 1;
9105 texture_desc.MipLevels = 1;
9106 texture_desc.ArraySize = 1;
9107 texture_desc.Format = DXGI_FORMAT_B8G8R8A8_UNORM;
9108 texture_desc.SampleDesc.Count = 1;
9109 texture_desc.SampleDesc.Quality = 0;
9110 texture_desc.Usage = D3D10_USAGE_DEFAULT;
9111 texture_desc.BindFlags = 0;
9112 texture_desc.CPUAccessFlags = 0;
9113 texture_desc.MiscFlags = 0;
9115 hr = ID3D10Device1_CreateTexture2D(device, &texture_desc, NULL, &texture);
9116 ok(SUCCEEDED(hr) || broken(hr == E_INVALIDARG && device_types[i].type == D3D10_DRIVER_TYPE_WARP) /* Vista */,
9117 "%s/%s: failed to create texture, hr %#x.\n", device_types[i].name, target_types[j].name, hr);
9118 if (SUCCEEDED(hr))
9119 ID3D10Texture2D_Release(texture);
9122 IDXGISurface_Release(surface);
9123 IDXGISwapChain_Release(swapchain);
9124 DestroyWindow(window);
9126 ID3D10Device1_Release(device);
9129 ID2D1Factory_Release(factory);
9132 static void test_dpi(void)
9134 D2D1_BITMAP_PROPERTIES1 bitmap_desc;
9135 ID2D1DeviceContext *device_context;
9136 IWICImagingFactory *wic_factory;
9137 IDXGISwapChain *swapchain;
9138 ID3D10Device1 *d3d_device;
9139 ID2D1Factory1 *factory;
9140 IDXGISurface *surface;
9141 ID2D1Bitmap1 *bitmap;
9142 float dpi_x, dpi_y;
9143 HWND window;
9144 HRESULT hr;
9146 static const struct
9148 float dpi_x, dpi_y;
9149 HRESULT hr;
9151 create_dpi_tests[] =
9153 { 0.0f, 0.0f, S_OK},
9154 {192.0f, 0.0f, E_INVALIDARG},
9155 { 0.0f, 192.0f, E_INVALIDARG},
9156 {192.0f, -10.0f, E_INVALIDARG},
9157 {-10.0f, 192.0f, E_INVALIDARG},
9158 {-10.0f, -10.0f, E_INVALIDARG},
9159 { 48.0f, 96.0f, S_OK},
9160 { 96.0f, 48.0f, S_OK},
9162 static const float init_dpi_x = 60.0f, init_dpi_y = 288.0f;
9163 static const float dc_dpi_x = 120.0f, dc_dpi_y = 144.0f;
9164 unsigned int i;
9166 if (!(d3d_device = create_device()))
9168 skip("Failed to create device, skipping tests.\n");
9169 return;
9172 if (FAILED(D2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED, &IID_ID2D1Factory1, NULL, (void **)&factory)))
9174 win_skip("ID2D1Factory1 is not supported.\n");
9175 ID3D10Device1_Release(d3d_device);
9176 return;
9179 window = create_window();
9180 swapchain = create_swapchain(d3d_device, window, TRUE);
9181 hr = IDXGISwapChain_GetBuffer(swapchain, 0, &IID_IDXGISurface, (void **)&surface);
9182 ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
9184 device_context = create_device_context(factory, d3d_device);
9185 ok(!!device_context, "Failed to create device context.\n");
9187 ID2D1DeviceContext_GetDpi(device_context, &dpi_x, &dpi_y);
9188 ok(dpi_x == 96.0f, "Got unexpected dpi_x %.8e.\n", dpi_x);
9189 ok(dpi_y == 96.0f, "Got unexpected dpi_y %.8e.\n", dpi_y);
9191 /* DXGI surface */
9192 for (i = 0; i < ARRAY_SIZE(create_dpi_tests); ++i)
9194 ID2D1DeviceContext_SetDpi(device_context, init_dpi_x, init_dpi_y);
9196 bitmap_desc.pixelFormat.format = DXGI_FORMAT_UNKNOWN;
9197 bitmap_desc.pixelFormat.alphaMode = D2D1_ALPHA_MODE_PREMULTIPLIED;
9198 bitmap_desc.dpiX = create_dpi_tests[i].dpi_x;
9199 bitmap_desc.dpiY = create_dpi_tests[i].dpi_y;
9200 bitmap_desc.bitmapOptions = D2D1_BITMAP_OPTIONS_TARGET | D2D1_BITMAP_OPTIONS_CANNOT_DRAW;
9201 bitmap_desc.colorContext = NULL;
9202 hr = ID2D1DeviceContext_CreateBitmapFromDxgiSurface(device_context, surface, &bitmap_desc, &bitmap);
9203 /* Native accepts negative DPI values for DXGI surface bitmap. */
9204 ok(hr == S_OK, "Test %u: Got unexpected hr %#x.\n", i, hr);
9206 ID2D1DeviceContext_SetDpi(device_context, dc_dpi_x, dc_dpi_y);
9208 ID2D1Bitmap1_GetDpi(bitmap, &dpi_x, &dpi_y);
9209 todo_wine_if(bitmap_desc.dpiX == 0.0f)
9210 ok(dpi_x == bitmap_desc.dpiX, "Test %u: Got unexpected dpi_x %.8e, expected %.8e.\n",
9211 i, dpi_x, bitmap_desc.dpiX);
9212 todo_wine_if(bitmap_desc.dpiY == 0.0f)
9213 ok(dpi_y == bitmap_desc.dpiY, "Test %u: Got unexpected dpi_y %.8e, expected %.8e.\n",
9214 i, dpi_y, bitmap_desc.dpiY);
9216 ID2D1DeviceContext_BeginDraw(device_context);
9217 ID2D1DeviceContext_SetTarget(device_context, (ID2D1Image *)bitmap);
9218 hr = ID2D1DeviceContext_EndDraw(device_context, NULL, NULL);
9219 ok(hr == S_OK, "Test %u: Got unexpected hr %#x.\n", i, hr);
9221 /* Device context DPI values aren't updated by SetTarget. */
9222 ID2D1DeviceContext_GetDpi(device_context, &dpi_x, &dpi_y);
9223 ok(dpi_x == dc_dpi_x, "Test %u: Got unexpected dpi_x %.8e, expected %.8e.\n", i, dpi_x, dc_dpi_x);
9224 ok(dpi_y == dc_dpi_y, "Test %u: Got unexpected dpi_y %.8e, expected %.8e.\n", i, dpi_y, dc_dpi_y);
9226 ID2D1Bitmap1_Release(bitmap);
9229 /* WIC bitmap */
9230 CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
9231 hr = CoCreateInstance(&CLSID_WICImagingFactory, NULL, CLSCTX_INPROC_SERVER,
9232 &IID_IWICImagingFactory, (void **)&wic_factory);
9233 ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
9234 for (i = 0; i < ARRAY_SIZE(create_dpi_tests); ++i)
9236 IWICBitmapSource *wic_bitmap_src;
9237 IWICBitmap *wic_bitmap;
9239 ID2D1DeviceContext_SetDpi(device_context, init_dpi_x, init_dpi_y);
9241 hr = IWICImagingFactory_CreateBitmap(wic_factory, 16, 16,
9242 &GUID_WICPixelFormat32bppPBGRA, WICBitmapCacheOnDemand, &wic_bitmap);
9243 ok(hr == S_OK, "Test %u: Got unexpected hr %#x.\n", i, hr);
9244 hr = IWICBitmap_QueryInterface(wic_bitmap, &IID_IWICBitmapSource, (void **)&wic_bitmap_src);
9245 ok(hr == S_OK, "Test %u: Got unexpected hr %#x.\n", i, hr);
9246 IWICBitmap_Release(wic_bitmap);
9248 bitmap_desc.pixelFormat.format = DXGI_FORMAT_UNKNOWN;
9249 bitmap_desc.pixelFormat.alphaMode = D2D1_ALPHA_MODE_PREMULTIPLIED;
9250 bitmap_desc.dpiX = create_dpi_tests[i].dpi_x;
9251 bitmap_desc.dpiY = create_dpi_tests[i].dpi_y;
9252 bitmap_desc.bitmapOptions = D2D1_BITMAP_OPTIONS_TARGET | D2D1_BITMAP_OPTIONS_CANNOT_DRAW;
9253 bitmap_desc.colorContext = NULL;
9254 hr = ID2D1DeviceContext_CreateBitmapFromWicBitmap(device_context, wic_bitmap_src, &bitmap_desc, &bitmap);
9255 ok(hr == create_dpi_tests[i].hr, "Test %u: Got unexpected hr %#x, expected %#x.\n",
9256 i, hr, create_dpi_tests[i].hr);
9257 IWICBitmapSource_Release(wic_bitmap_src);
9259 if (FAILED(hr))
9260 continue;
9262 ID2D1DeviceContext_SetDpi(device_context, dc_dpi_x, dc_dpi_y);
9264 ID2D1Bitmap1_GetDpi(bitmap, &dpi_x, &dpi_y);
9265 if (bitmap_desc.dpiX == 0.0f && bitmap_desc.dpiY == 0.0f)
9267 /* Bitmap DPI values are inherited at creation time. */
9268 ok(dpi_x == init_dpi_x, "Test %u: Got unexpected dpi_x %.8e, expected %.8e.\n", i, dpi_x, init_dpi_x);
9269 ok(dpi_y == init_dpi_y, "Test %u: Got unexpected dpi_y %.8e, expected %.8e.\n", i, dpi_y, init_dpi_y);
9271 else
9273 ok(dpi_x == bitmap_desc.dpiX, "Test %u: Got unexpected dpi_x %.8e, expected %.8e.\n",
9274 i, dpi_x, bitmap_desc.dpiX);
9275 ok(dpi_y == bitmap_desc.dpiY, "Test %u: Got unexpected dpi_y %.8e, expected %.8e.\n",
9276 i, dpi_y, bitmap_desc.dpiY);
9279 ID2D1DeviceContext_BeginDraw(device_context);
9280 ID2D1DeviceContext_SetTarget(device_context, (ID2D1Image *)bitmap);
9281 hr = ID2D1DeviceContext_EndDraw(device_context, NULL, NULL);
9282 ok(hr == S_OK, "Test %u: Got unexpected hr %#x.\n", i, hr);
9284 /* Device context DPI values aren't updated by SetTarget. */
9285 ID2D1DeviceContext_GetDpi(device_context, &dpi_x, &dpi_y);
9286 ok(dpi_x == dc_dpi_x, "Test %u: Got unexpected dpi_x %.8e, expected %.8e.\n", i, dpi_x, dc_dpi_x);
9287 ok(dpi_y == dc_dpi_y, "Test %u: Got unexpected dpi_y %.8e, expected %.8e.\n", i, dpi_y, dc_dpi_y);
9289 ID2D1Bitmap1_Release(bitmap);
9291 IWICImagingFactory_Release(wic_factory);
9292 CoUninitialize();
9294 /* D2D bitmap */
9295 for (i = 0; i < ARRAY_SIZE(create_dpi_tests); ++i)
9297 const D2D1_SIZE_U size = {16, 16};
9299 ID2D1DeviceContext_SetDpi(device_context, init_dpi_x, init_dpi_y);
9301 bitmap_desc.pixelFormat.format = DXGI_FORMAT_B8G8R8A8_UNORM;
9302 bitmap_desc.pixelFormat.alphaMode = D2D1_ALPHA_MODE_PREMULTIPLIED;
9303 bitmap_desc.dpiX = create_dpi_tests[i].dpi_x;
9304 bitmap_desc.dpiY = create_dpi_tests[i].dpi_y;
9305 bitmap_desc.bitmapOptions = D2D1_BITMAP_OPTIONS_TARGET | D2D1_BITMAP_OPTIONS_CANNOT_DRAW;
9306 bitmap_desc.colorContext = NULL;
9307 hr = ID2D1DeviceContext_CreateBitmap(device_context, size, NULL, 0, &bitmap_desc, &bitmap);
9308 ok(hr == create_dpi_tests[i].hr, "Test %u: Got unexpected hr %#x, expected %#x.\n",
9309 i, hr, create_dpi_tests[i].hr);
9311 if (FAILED(hr))
9312 continue;
9314 ID2D1DeviceContext_SetDpi(device_context, dc_dpi_x, dc_dpi_y);
9316 ID2D1Bitmap1_GetDpi(bitmap, &dpi_x, &dpi_y);
9317 if (bitmap_desc.dpiX == 0.0f && bitmap_desc.dpiY == 0.0f)
9319 /* Bitmap DPI values are inherited at creation time. */
9320 ok(dpi_x == init_dpi_x, "Test %u: Got unexpected dpi_x %.8e, expected %.8e.\n", i, dpi_x, init_dpi_x);
9321 ok(dpi_y == init_dpi_y, "Test %u: Got unexpected dpi_y %.8e, expected %.8e.\n", i, dpi_y, init_dpi_y);
9323 else
9325 ok(dpi_x == bitmap_desc.dpiX, "Test %u: Got unexpected dpi_x %.8e, expected %.8e.\n",
9326 i, dpi_x, bitmap_desc.dpiX);
9327 ok(dpi_y == bitmap_desc.dpiY, "Test %u: Got unexpected dpi_y %.8e, expected %.8e.\n",
9328 i, dpi_y, bitmap_desc.dpiY);
9331 ID2D1DeviceContext_BeginDraw(device_context);
9332 ID2D1DeviceContext_SetTarget(device_context, (ID2D1Image *)bitmap);
9333 hr = ID2D1DeviceContext_EndDraw(device_context, NULL, NULL);
9334 ok(hr == S_OK, "Test %u: Got unexpected hr %#x.\n", i, hr);
9336 /* Device context DPI values aren't updated by SetTarget. */
9337 ID2D1DeviceContext_GetDpi(device_context, &dpi_x, &dpi_y);
9338 ok(dpi_x == dc_dpi_x, "Test %u: Got unexpected dpi_x %.8e, expected %.8e.\n", i, dpi_x, dc_dpi_x);
9339 ok(dpi_y == dc_dpi_y, "Test %u: Got unexpected dpi_y %.8e, expected %.8e.\n", i, dpi_y, dc_dpi_y);
9341 ID2D1Bitmap1_Release(bitmap);
9344 ID2D1DeviceContext_SetTarget(device_context, NULL);
9345 ID2D1DeviceContext_GetDpi(device_context, &dpi_x, &dpi_y);
9346 ok(dpi_x == dc_dpi_x, "Got unexpected dpi_x %.8e, expected %.8e.\n", dpi_x, dc_dpi_x);
9347 ok(dpi_y == dc_dpi_y, "Got unexpected dpi_y %.8e, expected %.8e.\n", dpi_y, dc_dpi_y);
9349 ID2D1DeviceContext_Release(device_context);
9350 IDXGISurface_Release(surface);
9351 IDXGISwapChain_Release(swapchain);
9352 ID2D1Factory1_Release(factory);
9353 ID3D10Device1_Release(d3d_device);
9354 DestroyWindow(window);
9357 static void test_wic_bitmap_format(void)
9359 IWICImagingFactory *wic_factory;
9360 IDXGISwapChain *swapchain;
9361 D2D1_PIXEL_FORMAT format;
9362 IWICBitmap *wic_bitmap;
9363 ID2D1RenderTarget *rt;
9364 ID3D10Device1 *device;
9365 IDXGISurface *surface;
9366 ID2D1Bitmap *bitmap;
9367 unsigned int i;
9368 HWND window;
9369 HRESULT hr;
9371 static const struct
9373 const WICPixelFormatGUID *wic;
9374 D2D1_PIXEL_FORMAT d2d;
9376 tests[] =
9378 {&GUID_WICPixelFormat32bppPBGRA, {DXGI_FORMAT_B8G8R8A8_UNORM, D2D1_ALPHA_MODE_PREMULTIPLIED}},
9379 {&GUID_WICPixelFormat32bppPRGBA, {DXGI_FORMAT_R8G8B8A8_UNORM, D2D1_ALPHA_MODE_PREMULTIPLIED}},
9380 {&GUID_WICPixelFormat32bppBGR, {DXGI_FORMAT_B8G8R8A8_UNORM, D2D1_ALPHA_MODE_IGNORE}},
9383 if (!(device = create_device()))
9385 skip("Failed to create device, skipping tests.\n");
9386 return;
9388 window = create_window();
9389 swapchain = create_swapchain(device, window, TRUE);
9390 hr = IDXGISwapChain_GetBuffer(swapchain, 0, &IID_IDXGISurface, (void **)&surface);
9391 ok(hr == S_OK, "Failed to get buffer, hr %#x.\n", hr);
9392 rt = create_render_target(surface);
9393 ok(!!rt, "Failed to create render target.\n");
9394 CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
9396 hr = CoCreateInstance(&CLSID_WICImagingFactory, NULL, CLSCTX_INPROC_SERVER,
9397 &IID_IWICImagingFactory, (void **)&wic_factory);
9398 ok(hr == S_OK, "Failed to create WIC imaging factory, hr %#x.\n", hr);
9400 for (i = 0; i < ARRAY_SIZE(tests); ++i)
9402 hr = IWICImagingFactory_CreateBitmap(wic_factory, 16, 16,
9403 tests[i].wic, WICBitmapCacheOnDemand, &wic_bitmap);
9404 ok(hr == S_OK, "%s: Failed to create WIC bitmap, hr %#x.\n", debugstr_guid(tests[i].wic), hr);
9406 hr = ID2D1RenderTarget_CreateBitmapFromWicBitmap(rt, (IWICBitmapSource *)wic_bitmap, NULL, &bitmap);
9407 ok(hr == S_OK, "%s: Failed to create bitmap from WIC source, hr %#x.\n", debugstr_guid(tests[i].wic), hr);
9409 format = ID2D1Bitmap_GetPixelFormat(bitmap);
9410 ok(format.format == tests[i].d2d.format, "%s: Got unexpected DXGI format %#x.\n",
9411 debugstr_guid(tests[i].wic), format.format);
9412 ok(format.alphaMode == tests[i].d2d.alphaMode, "%s: Got unexpected alpha mode %#x.\n",
9413 debugstr_guid(tests[i].wic), format.alphaMode);
9415 ID2D1Bitmap_Release(bitmap);
9416 IWICBitmap_Release(wic_bitmap);
9419 IWICImagingFactory_Release(wic_factory);
9420 CoUninitialize();
9421 ID2D1RenderTarget_Release(rt);
9422 IDXGISurface_Release(surface);
9423 IDXGISwapChain_Release(swapchain);
9424 ID3D10Device1_Release(device);
9425 DestroyWindow(window);
9428 static void test_math(void)
9430 unsigned int i;
9431 float s, c, t;
9433 static const struct
9435 float x;
9436 float s;
9437 float c;
9439 sc_data[] =
9441 {0.0f, 0.0f, 1.0f},
9442 {1.0f, 8.41470957e-001f, 5.40302277e-001f},
9443 {2.0f, 9.09297407e-001f, -4.16146845e-001f},
9444 {M_PI / 2.0f, 1.0f, -4.37113883e-008f},
9445 {M_PI, -8.74227766e-008f, -1.0f},
9448 static const struct
9450 float x;
9451 float t;
9453 t_data[] =
9455 {0.0f, 0.0f},
9456 {1.0f, 1.55740774f},
9457 {2.0f, -2.18503976f},
9458 {M_PI / 2.0f, -2.28773320e+007f},
9459 {M_PI, 8.74227766e-008f},
9462 for (i = 0; i < ARRAY_SIZE(sc_data); ++i)
9464 D2D1SinCos(sc_data[i].x, &s, &c);
9465 ok(compare_float(s, sc_data[i].s, 0),
9466 "Test %u: Got unexpected sin %.8e, expected %.8e.\n", i, s, sc_data[i].s);
9467 ok(compare_float(c, sc_data[i].c, 0),
9468 "Test %u: Got unexpected cos %.8e, expected %.8e.\n", i, c, sc_data[i].c);
9471 for (i = 0; i < ARRAY_SIZE(t_data); ++i)
9473 t = D2D1Tan(t_data[i].x);
9474 ok(compare_float(t, t_data[i].t, 1),
9475 "Test %u: Got unexpected tan %.8e, expected %.8e.\n", i, t, t_data[i].t);
9479 START_TEST(d2d1)
9481 unsigned int argc, i;
9482 char **argv;
9484 pD2D1CreateDevice = (void *)GetProcAddress(GetModuleHandleA("d2d1.dll"), "D2D1CreateDevice");
9486 use_mt = !getenv("WINETEST_NO_MT_D3D");
9488 argc = winetest_get_mainargs(&argv);
9489 for (i = 2; i < argc; ++i)
9491 if (!strcmp(argv[i], "--single"))
9492 use_mt = FALSE;
9495 queue_test(test_clip);
9496 queue_test(test_state_block);
9497 queue_test(test_color_brush);
9498 queue_test(test_bitmap_brush);
9499 queue_test(test_linear_brush);
9500 queue_test(test_radial_brush);
9501 queue_test(test_path_geometry);
9502 queue_test(test_rectangle_geometry);
9503 queue_test(test_rounded_rectangle_geometry);
9504 queue_test(test_bitmap_formats);
9505 queue_test(test_alpha_mode);
9506 queue_test(test_shared_bitmap);
9507 queue_test(test_bitmap_updates);
9508 queue_test(test_opacity_brush);
9509 queue_test(test_create_target);
9510 queue_test(test_draw_text_layout);
9511 queue_test(test_dc_target);
9512 queue_test(test_hwnd_target);
9513 queue_test(test_bitmap_target);
9514 queue_test(test_desktop_dpi);
9515 queue_test(test_stroke_style);
9516 queue_test(test_gradient);
9517 queue_test(test_draw_geometry);
9518 queue_test(test_fill_geometry);
9519 queue_test(test_gdi_interop);
9520 queue_test(test_layer);
9521 queue_test(test_bezier_intersect);
9522 queue_test(test_create_device);
9523 queue_test(test_bitmap_surface);
9524 queue_test(test_device_context);
9525 queue_test(test_invert_matrix);
9526 queue_test(test_skew_matrix);
9527 queue_test(test_command_list);
9528 queue_test(test_max_bitmap_size);
9529 queue_test(test_dpi);
9530 queue_test(test_wic_bitmap_format);
9531 queue_test(test_math);
9533 run_queued_tests();