d2d1: Implement d2d_path_geometry_Simplify().
Signed-off-by: Henri Verbeet <hverbeet@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
208eb09e3c
commit
09ff685aa0
|
@ -26,6 +26,9 @@
|
|||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(d2d);
|
||||
|
||||
#define D2D_FIGURE_FLAG_CLOSED 0x00000001u
|
||||
#define D2D_FIGURE_FLAG_HOLLOW 0x00000002u
|
||||
|
||||
#define D2D_CDT_EDGE_FLAG_FREED 0x80000000u
|
||||
#define D2D_CDT_EDGE_FLAG_VISITED(r) (1u << (r))
|
||||
|
||||
|
@ -66,6 +69,7 @@ struct d2d_figure
|
|||
size_t bezier_control_count;
|
||||
|
||||
D2D1_RECT_F bounds;
|
||||
unsigned int flags;
|
||||
};
|
||||
|
||||
struct d2d_cdt_edge_ref
|
||||
|
@ -2054,6 +2058,8 @@ static void STDMETHODCALLTYPE d2d_geometry_sink_SetFillMode(ID2D1GeometrySink *i
|
|||
|
||||
TRACE("iface %p, mode %#x.\n", iface, mode);
|
||||
|
||||
if (geometry->u.path.state == D2D_GEOMETRY_STATE_CLOSED)
|
||||
return;
|
||||
geometry->u.path.fill_mode = mode;
|
||||
}
|
||||
|
||||
|
@ -2066,6 +2072,7 @@ static void STDMETHODCALLTYPE d2d_geometry_sink_BeginFigure(ID2D1GeometrySink *i
|
|||
D2D1_POINT_2F start_point, D2D1_FIGURE_BEGIN figure_begin)
|
||||
{
|
||||
struct d2d_geometry *geometry = impl_from_ID2D1GeometrySink(iface);
|
||||
struct d2d_figure *figure;
|
||||
|
||||
TRACE("iface %p, start_point {%.8e, %.8e}, figure_begin %#x.\n",
|
||||
iface, start_point.x, start_point.y, figure_begin);
|
||||
|
@ -2086,7 +2093,11 @@ static void STDMETHODCALLTYPE d2d_geometry_sink_BeginFigure(ID2D1GeometrySink *i
|
|||
return;
|
||||
}
|
||||
|
||||
if (!d2d_figure_add_vertex(&geometry->u.path.figures[geometry->u.path.figure_count - 1], start_point))
|
||||
figure = &geometry->u.path.figures[geometry->u.path.figure_count - 1];
|
||||
if (figure_begin == D2D1_FIGURE_BEGIN_HOLLOW)
|
||||
figure->flags |= D2D_FIGURE_FLAG_HOLLOW;
|
||||
|
||||
if (!d2d_figure_add_vertex(figure, start_point))
|
||||
{
|
||||
ERR("Failed to add vertex.\n");
|
||||
geometry->u.path.state = D2D_GEOMETRY_STATE_ERROR;
|
||||
|
@ -2183,9 +2194,12 @@ static void STDMETHODCALLTYPE d2d_geometry_sink_EndFigure(ID2D1GeometrySink *ifa
|
|||
|
||||
figure = &geometry->u.path.figures[geometry->u.path.figure_count - 1];
|
||||
figure->vertex_types[figure->vertex_count - 1] = D2D_VERTEX_TYPE_LINE;
|
||||
if (figure_end == D2D1_FIGURE_END_CLOSED && !memcmp(&figure->vertices[0],
|
||||
&figure->vertices[figure->vertex_count - 1], sizeof(*figure->vertices)))
|
||||
--figure->vertex_count;
|
||||
if (figure_end == D2D1_FIGURE_END_CLOSED)
|
||||
{
|
||||
figure->flags |= D2D_FIGURE_FLAG_CLOSED;
|
||||
if (!memcmp(&figure->vertices[0], &figure->vertices[figure->vertex_count - 1], sizeof(*figure->vertices)))
|
||||
--figure->vertex_count;
|
||||
}
|
||||
|
||||
if (!d2d_geometry_add_figure_outline(geometry, figure, figure_end))
|
||||
{
|
||||
|
@ -2526,14 +2540,153 @@ static HRESULT STDMETHODCALLTYPE d2d_path_geometry_CompareWithGeometry(ID2D1Path
|
|||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
static void d2d_geometry_flatten_cubic(ID2D1SimplifiedGeometrySink *sink, const D2D1_POINT_2F *p0,
|
||||
const D2D1_BEZIER_SEGMENT *b, float tolerance)
|
||||
{
|
||||
D2D1_BEZIER_SEGMENT b0, b1;
|
||||
D2D1_POINT_2F q;
|
||||
float d;
|
||||
|
||||
/* It's certainly possible to calculate the maximum deviation of the
|
||||
* approximation from the curve, but it's a little involved. Instead, note
|
||||
* that if the control points were evenly spaced and collinear, p1 would
|
||||
* be exactly between p0 and p2, and p2 would be exactly between p1 and
|
||||
* p3. The deviation is a decent enough approximation, and much easier to
|
||||
* calculate.
|
||||
*
|
||||
* p1' = (p0 + p2) / 2
|
||||
* p2' = (p1 + p3) / 2
|
||||
* d = ‖p1 - p1'‖₁ + ‖p2 - p2'‖₁ */
|
||||
d2d_point_lerp(&q, p0, &b->point2, 0.5f);
|
||||
d2d_point_subtract(&q, &b->point1, &q);
|
||||
d = fabsf(q.x) + fabsf(q.y);
|
||||
d2d_point_lerp(&q, &b->point1, &b->point3, 0.5f);
|
||||
d2d_point_subtract(&q, &b->point2, &q);
|
||||
d += fabsf(q.x) + fabsf(q.y);
|
||||
if (d < tolerance)
|
||||
{
|
||||
ID2D1SimplifiedGeometrySink_AddLines(sink, &b->point3, 1);
|
||||
return;
|
||||
}
|
||||
|
||||
d2d_point_lerp(&q, &b->point1, &b->point2, 0.5f);
|
||||
|
||||
b1.point3 = b->point3;
|
||||
d2d_point_lerp(&b1.point2, &b1.point3, &b->point2, 0.5f);
|
||||
d2d_point_lerp(&b1.point1, &b1.point2, &q, 0.5f);
|
||||
|
||||
d2d_point_lerp(&b0.point1, p0, &b->point1, 0.5f);
|
||||
d2d_point_lerp(&b0.point2, &b0.point1, &q, 0.5f);
|
||||
d2d_point_lerp(&b0.point3, &b0.point2, &b1.point1, 0.5f);
|
||||
|
||||
d2d_geometry_flatten_cubic(sink, p0, &b0, tolerance);
|
||||
ID2D1SimplifiedGeometrySink_SetSegmentFlags(sink, D2D1_PATH_SEGMENT_FORCE_ROUND_LINE_JOIN);
|
||||
d2d_geometry_flatten_cubic(sink, &b0.point3, &b1, tolerance);
|
||||
ID2D1SimplifiedGeometrySink_SetSegmentFlags(sink, D2D1_PATH_SEGMENT_NONE);
|
||||
}
|
||||
|
||||
static void d2d_geometry_simplify_quadratic(ID2D1SimplifiedGeometrySink *sink,
|
||||
D2D1_GEOMETRY_SIMPLIFICATION_OPTION option, const D2D1_POINT_2F *p0,
|
||||
const D2D1_POINT_2F *p1, const D2D1_POINT_2F *p2, float tolerance)
|
||||
{
|
||||
D2D1_BEZIER_SEGMENT b;
|
||||
|
||||
d2d_point_lerp(&b.point1, p0, p1, 2.0f / 3.0f);
|
||||
d2d_point_lerp(&b.point2, p2, p1, 2.0f / 3.0f);
|
||||
b.point3 = *p2;
|
||||
|
||||
if (option == D2D1_GEOMETRY_SIMPLIFICATION_OPTION_LINES)
|
||||
d2d_geometry_flatten_cubic(sink, p0, &b, tolerance);
|
||||
else
|
||||
ID2D1SimplifiedGeometrySink_AddBeziers(sink, &b, 1);
|
||||
}
|
||||
|
||||
static HRESULT STDMETHODCALLTYPE d2d_path_geometry_Simplify(ID2D1PathGeometry *iface,
|
||||
D2D1_GEOMETRY_SIMPLIFICATION_OPTION option, const D2D1_MATRIX_3X2_F *transform, float tolerance,
|
||||
ID2D1SimplifiedGeometrySink *sink)
|
||||
{
|
||||
FIXME("iface %p, option %#x, transform %p, tolerance %.8e, sink %p stub!\n",
|
||||
struct d2d_geometry *geometry = impl_from_ID2D1PathGeometry(iface);
|
||||
enum d2d_vertex_type type = D2D_VERTEX_TYPE_NONE;
|
||||
unsigned int i, j, bezier_idx;
|
||||
D2D1_FIGURE_BEGIN begin;
|
||||
D2D1_POINT_2F p, p1, p2;
|
||||
D2D1_FIGURE_END end;
|
||||
|
||||
TRACE("iface %p, option %#x, transform %p, tolerance %.8e, sink %p.\n",
|
||||
iface, option, transform, tolerance, sink);
|
||||
|
||||
return E_NOTIMPL;
|
||||
ID2D1SimplifiedGeometrySink_SetFillMode(sink, geometry->u.path.fill_mode);
|
||||
for (i = 0; i < geometry->u.path.figure_count; ++i)
|
||||
{
|
||||
const struct d2d_figure *figure = &geometry->u.path.figures[i];
|
||||
|
||||
for (j = 0; j < figure->vertex_count; ++j)
|
||||
{
|
||||
if (figure->vertex_types[j] == D2D_VERTEX_TYPE_NONE)
|
||||
continue;
|
||||
|
||||
p = figure->vertices[j];
|
||||
if (transform)
|
||||
d2d_point_transform(&p, transform, p.x, p.y);
|
||||
begin = figure->flags & D2D_FIGURE_FLAG_HOLLOW ? D2D1_FIGURE_BEGIN_HOLLOW : D2D1_FIGURE_BEGIN_FILLED;
|
||||
ID2D1SimplifiedGeometrySink_BeginFigure(sink, p, begin);
|
||||
type = figure->vertex_types[j];
|
||||
break;
|
||||
}
|
||||
|
||||
for (bezier_idx = 0, ++j; j < figure->vertex_count; ++j)
|
||||
{
|
||||
if (figure->vertex_types[j] == D2D_VERTEX_TYPE_NONE)
|
||||
continue;
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case D2D_VERTEX_TYPE_LINE:
|
||||
p = figure->vertices[j];
|
||||
if (transform)
|
||||
d2d_point_transform(&p, transform, p.x, p.y);
|
||||
ID2D1SimplifiedGeometrySink_AddLines(sink, &p, 1);
|
||||
break;
|
||||
|
||||
case D2D_VERTEX_TYPE_BEZIER:
|
||||
p1 = figure->bezier_controls[bezier_idx++];
|
||||
if (transform)
|
||||
d2d_point_transform(&p1, transform, p1.x, p1.y);
|
||||
p2 = figure->vertices[j];
|
||||
if (transform)
|
||||
d2d_point_transform(&p2, transform, p2.x, p2.y);
|
||||
d2d_geometry_simplify_quadratic(sink, option, &p, &p1, &p2, tolerance);
|
||||
p = p2;
|
||||
break;
|
||||
|
||||
default:
|
||||
FIXME("Unhandled vertex type %#x.\n", type);
|
||||
p = figure->vertices[j];
|
||||
if (transform)
|
||||
d2d_point_transform(&p, transform, p.x, p.y);
|
||||
ID2D1SimplifiedGeometrySink_AddLines(sink, &p, 1);
|
||||
break;
|
||||
}
|
||||
|
||||
type = figure->vertex_types[j];
|
||||
}
|
||||
|
||||
if (type == D2D_VERTEX_TYPE_BEZIER)
|
||||
{
|
||||
p1 = figure->bezier_controls[bezier_idx++];
|
||||
if (transform)
|
||||
d2d_point_transform(&p1, transform, p1.x, p1.y);
|
||||
p2 = figure->vertices[0];
|
||||
if (transform)
|
||||
d2d_point_transform(&p2, transform, p2.x, p2.y);
|
||||
d2d_geometry_simplify_quadratic(sink, option, &p, &p1, &p2, tolerance);
|
||||
}
|
||||
|
||||
end = figure->flags & D2D_FIGURE_FLAG_CLOSED ? D2D1_FIGURE_END_CLOSED : D2D1_FIGURE_END_OPEN;
|
||||
ID2D1SimplifiedGeometrySink_EndFigure(sink, end);
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT STDMETHODCALLTYPE d2d_path_geometry_Tessellate(ID2D1PathGeometry *iface,
|
||||
|
|
|
@ -54,6 +54,7 @@ struct geometry_sink
|
|||
D2D1_BEZIER_SEGMENT bezier;
|
||||
D2D1_POINT_2F line;
|
||||
} u;
|
||||
DWORD flags;
|
||||
} *segments;
|
||||
unsigned int segments_size;
|
||||
unsigned int segment_count;
|
||||
|
@ -62,6 +63,7 @@ struct geometry_sink
|
|||
unsigned int figure_count;
|
||||
|
||||
D2D1_FILL_MODE fill_mode;
|
||||
DWORD segment_flags;
|
||||
BOOL closed;
|
||||
};
|
||||
|
||||
|
@ -709,7 +711,9 @@ static void STDMETHODCALLTYPE geometry_sink_SetFillMode(ID2D1SimplifiedGeometryS
|
|||
static void STDMETHODCALLTYPE geometry_sink_SetSegmentFlags(ID2D1SimplifiedGeometrySink *iface,
|
||||
D2D1_PATH_SEGMENT flags)
|
||||
{
|
||||
ok(0, "Got unexpected segment flags %#x.\n", flags);
|
||||
struct geometry_sink *sink = impl_from_ID2D1SimplifiedGeometrySink(iface);
|
||||
|
||||
sink->segment_flags = flags;
|
||||
}
|
||||
|
||||
static void STDMETHODCALLTYPE geometry_sink_BeginFigure(ID2D1SimplifiedGeometrySink *iface,
|
||||
|
@ -757,6 +761,7 @@ static void STDMETHODCALLTYPE geometry_sink_AddLines(ID2D1SimplifiedGeometrySink
|
|||
segment = geometry_figure_add_segment(figure);
|
||||
segment->type = SEGMENT_LINE;
|
||||
segment->u.line = points[i];
|
||||
segment->flags = sink->segment_flags;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -773,6 +778,7 @@ static void STDMETHODCALLTYPE geometry_sink_AddBeziers(ID2D1SimplifiedGeometrySi
|
|||
segment = geometry_figure_add_segment(figure);
|
||||
segment->type = SEGMENT_BEZIER;
|
||||
segment->u.bezier = beziers[i];
|
||||
segment->flags = sink->segment_flags;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -828,6 +834,84 @@ static void geometry_sink_cleanup(struct geometry_sink *sink)
|
|||
HeapFree(GetProcessHeap(), 0, sink->figures);
|
||||
}
|
||||
|
||||
#define geometry_sink_check(a, b, c, d, e) geometry_sink_check_(__LINE__, a, b, c, d, e)
|
||||
static void geometry_sink_check_(unsigned int line, const struct geometry_sink *sink, D2D1_FILL_MODE fill_mode,
|
||||
unsigned int figure_count, const struct expected_geometry_figure *expected_figures, unsigned int ulps)
|
||||
{
|
||||
const struct geometry_segment *segment, *expected_segment;
|
||||
const struct expected_geometry_figure *expected_figure;
|
||||
const struct geometry_figure *figure;
|
||||
unsigned int i, j;
|
||||
BOOL match;
|
||||
|
||||
ok_(__FILE__, line)(sink->fill_mode == fill_mode,
|
||||
"Got unexpected fill mode %#x.\n", sink->fill_mode);
|
||||
ok_(__FILE__, line)(sink->figure_count == figure_count,
|
||||
"Got unexpected figure count %u, expected %u.\n", sink->figure_count, figure_count);
|
||||
ok_(__FILE__, line)(!sink->closed, "Sink is closed.\n");
|
||||
|
||||
for (i = 0; i < figure_count; ++i)
|
||||
{
|
||||
expected_figure = &expected_figures[i];
|
||||
figure = &sink->figures[i];
|
||||
|
||||
ok_(__FILE__, line)(figure->begin == expected_figure->begin,
|
||||
"Got unexpected figure %u begin %#x, expected %#x.\n",
|
||||
i, figure->begin, expected_figure->begin);
|
||||
ok_(__FILE__, line)(figure->end == expected_figure->end,
|
||||
"Got unexpected figure %u end %#x, expected %#x.\n",
|
||||
i, figure->end, expected_figure->end);
|
||||
match = compare_point(&figure->start_point,
|
||||
expected_figure->start_point.x, expected_figure->start_point.y, ulps);
|
||||
ok_(__FILE__, line)(match, "Got unexpected figure %u start point {%.8e, %.8e}, expected {%.8e, %.8e}.\n",
|
||||
i, figure->start_point.x, figure->start_point.y,
|
||||
expected_figure->start_point.x, expected_figure->start_point.y);
|
||||
ok_(__FILE__, line)(figure->segment_count == expected_figure->segment_count,
|
||||
"Got unexpected figure %u segment count %u, expected %u.\n",
|
||||
i, figure->segment_count, expected_figure->segment_count);
|
||||
|
||||
for (j = 0; j < figure->segment_count; ++j)
|
||||
{
|
||||
expected_segment = &expected_figure->segments[j];
|
||||
segment = &figure->segments[j];
|
||||
ok_(__FILE__, line)(segment->type == expected_segment->type,
|
||||
"Got unexpected figure %u, segment %u type %#x, expected %#x.\n",
|
||||
i, j, segment->type, expected_segment->type);
|
||||
ok_(__FILE__, line)(segment->flags == expected_segment->flags,
|
||||
"Got unexpected figure %u, segment %u flags %#x, expected %#x.\n",
|
||||
i, j, segment->flags, expected_segment->flags);
|
||||
switch (segment->type)
|
||||
{
|
||||
case SEGMENT_LINE:
|
||||
match = compare_point(&segment->u.line,
|
||||
expected_segment->u.line.x, expected_segment->u.line.y, ulps);
|
||||
ok_(__FILE__, line)(match, "Got unexpected figure %u segment %u {%.8e, %.8e}, "
|
||||
"expected {%.8e, %.8e}.\n",
|
||||
i, j, segment->u.line.x, segment->u.line.y,
|
||||
expected_segment->u.line.x, expected_segment->u.line.y);
|
||||
break;
|
||||
|
||||
case SEGMENT_BEZIER:
|
||||
match = compare_bezier_segment(&segment->u.bezier,
|
||||
expected_segment->u.bezier.point1.x, expected_segment->u.bezier.point1.y,
|
||||
expected_segment->u.bezier.point2.x, expected_segment->u.bezier.point2.y,
|
||||
expected_segment->u.bezier.point3.x, expected_segment->u.bezier.point3.y,
|
||||
ulps);
|
||||
ok_(__FILE__, line)(match, "Got unexpected figure %u segment %u "
|
||||
"{%.8e, %.8e, %.8e, %.8e, %.8e, %.8e}, "
|
||||
"expected {%.8e, %.8e, %.8e, %.8e, %.8e, %.8e}.\n",
|
||||
i, j, segment->u.bezier.point1.x, segment->u.bezier.point1.y,
|
||||
segment->u.bezier.point2.x, segment->u.bezier.point2.y,
|
||||
segment->u.bezier.point3.x, segment->u.bezier.point3.y,
|
||||
expected_segment->u.bezier.point1.x, expected_segment->u.bezier.point1.y,
|
||||
expected_segment->u.bezier.point2.x, expected_segment->u.bezier.point2.y,
|
||||
expected_segment->u.bezier.point3.x, expected_segment->u.bezier.point3.y);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void test_clip(void)
|
||||
{
|
||||
IDXGISwapChain *swapchain;
|
||||
|
@ -1571,6 +1655,7 @@ static void test_path_geometry(void)
|
|||
ID2D1TransformedGeometry *transformed_geometry;
|
||||
D2D1_MATRIX_3X2_F matrix, tmp_matrix;
|
||||
ID2D1GeometrySink *sink, *tmp_sink;
|
||||
struct geometry_sink simplify_sink;
|
||||
D2D1_POINT_2F point = {0.0f, 0.0f};
|
||||
ID2D1SolidColorBrush *brush;
|
||||
ID2D1PathGeometry *geometry;
|
||||
|
@ -1587,6 +1672,320 @@ static void test_path_geometry(void)
|
|||
HWND window;
|
||||
HRESULT hr;
|
||||
|
||||
static const struct geometry_segment expected_segments[] =
|
||||
{
|
||||
/* Figure 0. */
|
||||
{SEGMENT_LINE, {{{ 55.0f, 20.0f}}}},
|
||||
{SEGMENT_LINE, {{{ 55.0f, 220.0f}}}},
|
||||
{SEGMENT_LINE, {{{ 25.0f, 220.0f}}}},
|
||||
{SEGMENT_LINE, {{{ 25.0f, 100.0f}}}},
|
||||
{SEGMENT_LINE, {{{ 75.0f, 100.0f}}}},
|
||||
{SEGMENT_LINE, {{{ 75.0f, 300.0f}}}},
|
||||
{SEGMENT_LINE, {{{ 5.0f, 300.0f}}}},
|
||||
{SEGMENT_LINE, {{{ 5.0f, 60.0f}}}},
|
||||
{SEGMENT_LINE, {{{ 45.0f, 60.0f}}}},
|
||||
{SEGMENT_LINE, {{{ 45.0f, 180.0f}}}},
|
||||
{SEGMENT_LINE, {{{ 35.0f, 180.0f}}}},
|
||||
{SEGMENT_LINE, {{{ 35.0f, 140.0f}}}},
|
||||
{SEGMENT_LINE, {{{ 65.0f, 140.0f}}}},
|
||||
{SEGMENT_LINE, {{{ 65.0f, 260.0f}}}},
|
||||
{SEGMENT_LINE, {{{ 15.0f, 260.0f}}}},
|
||||
/* Figure 1. */
|
||||
{SEGMENT_LINE, {{{155.0f, 160.0f}}}},
|
||||
{SEGMENT_LINE, {{{ 85.0f, 160.0f}}}},
|
||||
{SEGMENT_LINE, {{{ 85.0f, 300.0f}}}},
|
||||
{SEGMENT_LINE, {{{120.0f, 300.0f}}}},
|
||||
{SEGMENT_LINE, {{{120.0f, 20.0f}}}},
|
||||
{SEGMENT_LINE, {{{155.0f, 20.0f}}}},
|
||||
{SEGMENT_LINE, {{{155.0f, 160.0f}}}},
|
||||
{SEGMENT_LINE, {{{ 85.0f, 160.0f}}}},
|
||||
{SEGMENT_LINE, {{{ 85.0f, 20.0f}}}},
|
||||
{SEGMENT_LINE, {{{120.0f, 20.0f}}}},
|
||||
{SEGMENT_LINE, {{{120.0f, 300.0f}}}},
|
||||
/* Figure 2. */
|
||||
{SEGMENT_LINE, {{{165.0f, 300.0f}}}},
|
||||
{SEGMENT_LINE, {{{235.0f, 300.0f}}}},
|
||||
{SEGMENT_LINE, {{{235.0f, 20.0f}}}},
|
||||
/* Figure 3. */
|
||||
{SEGMENT_LINE, {{{225.0f, 260.0f}}}},
|
||||
{SEGMENT_LINE, {{{175.0f, 260.0f}}}},
|
||||
{SEGMENT_LINE, {{{175.0f, 60.0f}}}},
|
||||
/* Figure 4. */
|
||||
{SEGMENT_LINE, {{{185.0f, 220.0f}}}},
|
||||
{SEGMENT_LINE, {{{185.0f, 100.0f}}}},
|
||||
{SEGMENT_LINE, {{{215.0f, 100.0f}}}},
|
||||
/* Figure 5. */
|
||||
{SEGMENT_LINE, {{{205.0f, 180.0f}}}},
|
||||
{SEGMENT_LINE, {{{205.0f, 140.0f}}}},
|
||||
{SEGMENT_LINE, {{{195.0f, 140.0f}}}},
|
||||
/* Figure 6. */
|
||||
{SEGMENT_LINE, {{{135.0f, 620.0f}}}},
|
||||
{SEGMENT_LINE, {{{135.0f, 420.0f}}}},
|
||||
{SEGMENT_LINE, {{{105.0f, 420.0f}}}},
|
||||
{SEGMENT_LINE, {{{105.0f, 540.0f}}}},
|
||||
{SEGMENT_LINE, {{{155.0f, 540.0f}}}},
|
||||
{SEGMENT_LINE, {{{155.0f, 340.0f}}}},
|
||||
{SEGMENT_LINE, {{{ 85.0f, 340.0f}}}},
|
||||
{SEGMENT_LINE, {{{ 85.0f, 580.0f}}}},
|
||||
{SEGMENT_LINE, {{{125.0f, 580.0f}}}},
|
||||
{SEGMENT_LINE, {{{125.0f, 460.0f}}}},
|
||||
{SEGMENT_LINE, {{{115.0f, 460.0f}}}},
|
||||
{SEGMENT_LINE, {{{115.0f, 500.0f}}}},
|
||||
{SEGMENT_LINE, {{{145.0f, 500.0f}}}},
|
||||
{SEGMENT_LINE, {{{145.0f, 380.0f}}}},
|
||||
{SEGMENT_LINE, {{{ 95.0f, 380.0f}}}},
|
||||
/* Figure 7. */
|
||||
{SEGMENT_LINE, {{{235.0f, 480.0f}}}},
|
||||
{SEGMENT_LINE, {{{165.0f, 480.0f}}}},
|
||||
{SEGMENT_LINE, {{{165.0f, 340.0f}}}},
|
||||
{SEGMENT_LINE, {{{200.0f, 340.0f}}}},
|
||||
{SEGMENT_LINE, {{{200.0f, 620.0f}}}},
|
||||
{SEGMENT_LINE, {{{235.0f, 620.0f}}}},
|
||||
{SEGMENT_LINE, {{{235.0f, 480.0f}}}},
|
||||
{SEGMENT_LINE, {{{165.0f, 480.0f}}}},
|
||||
{SEGMENT_LINE, {{{165.0f, 620.0f}}}},
|
||||
{SEGMENT_LINE, {{{200.0f, 620.0f}}}},
|
||||
{SEGMENT_LINE, {{{200.0f, 340.0f}}}},
|
||||
/* Figure 8. */
|
||||
{SEGMENT_LINE, {{{245.0f, 340.0f}}}},
|
||||
{SEGMENT_LINE, {{{315.0f, 340.0f}}}},
|
||||
{SEGMENT_LINE, {{{315.0f, 620.0f}}}},
|
||||
/* Figure 9. */
|
||||
{SEGMENT_LINE, {{{305.0f, 380.0f}}}},
|
||||
{SEGMENT_LINE, {{{255.0f, 380.0f}}}},
|
||||
{SEGMENT_LINE, {{{255.0f, 580.0f}}}},
|
||||
/* Figure 10. */
|
||||
{SEGMENT_LINE, {{{265.0f, 420.0f}}}},
|
||||
{SEGMENT_LINE, {{{265.0f, 540.0f}}}},
|
||||
{SEGMENT_LINE, {{{295.0f, 540.0f}}}},
|
||||
/* Figure 11. */
|
||||
{SEGMENT_LINE, {{{285.0f, 460.0f}}}},
|
||||
{SEGMENT_LINE, {{{285.0f, 500.0f}}}},
|
||||
{SEGMENT_LINE, {{{275.0f, 500.0f}}}},
|
||||
/* Figure 12. */
|
||||
{SEGMENT_BEZIER, {{{2.83333340e+01f, 1.60000000e+02f},
|
||||
{4.00000000e+01f, 1.13333336e+02f},
|
||||
{4.00000000e+01f, 2.00000000e+01f}}}},
|
||||
{SEGMENT_BEZIER, {{{4.00000000e+01f, 1.13333336e+02f},
|
||||
{5.16666641e+01f, 1.60000000e+02f},
|
||||
{7.50000000e+01f, 1.60000000e+02f}}}},
|
||||
{SEGMENT_BEZIER, {{{5.16666641e+01f, 1.60000000e+02f},
|
||||
{4.00000000e+01f, 2.06666656e+02f},
|
||||
{4.00000000e+01f, 3.00000000e+02f}}}},
|
||||
{SEGMENT_BEZIER, {{{4.00000000e+01f, 2.06666656e+02f},
|
||||
{2.83333340e+01f, 1.60000000e+02f},
|
||||
{5.00000000e+00f, 1.60000000e+02f}}}},
|
||||
/* Figure 13. */
|
||||
{SEGMENT_BEZIER, {{{2.00000000e+01f, 1.06666664e+02f},
|
||||
{2.66666660e+01f, 8.00000000e+01f},
|
||||
{4.00000000e+01f, 8.00000000e+01f}}}},
|
||||
{SEGMENT_BEZIER, {{{5.33333321e+01f, 8.00000000e+01f},
|
||||
{6.00000000e+01f, 1.06666664e+02f},
|
||||
{6.00000000e+01f, 1.60000000e+02f}}}},
|
||||
{SEGMENT_BEZIER, {{{6.00000000e+01f, 2.13333328e+02f},
|
||||
{5.33333321e+01f, 2.40000000e+02f},
|
||||
{4.00000000e+01f, 2.40000000e+02f}}}},
|
||||
{SEGMENT_BEZIER, {{{2.66666660e+01f, 2.40000000e+02f},
|
||||
{2.00000000e+01f, 2.13333328e+02f},
|
||||
{2.00000000e+01f, 1.60000000e+02f}}}},
|
||||
/* Figure 14. */
|
||||
{SEGMENT_BEZIER, {{{2.83333340e+01f, 6.12000000e+02f},
|
||||
{4.00000000e+01f, 6.58666687e+02f},
|
||||
{4.00000000e+01f, 7.52000000e+02f}}}},
|
||||
{SEGMENT_BEZIER, {{{4.00000000e+01f, 6.58666687e+02f},
|
||||
{5.16666641e+01f, 6.12000000e+02f},
|
||||
{7.50000000e+01f, 6.12000000e+02f}}}},
|
||||
{SEGMENT_BEZIER, {{{5.16666641e+01f, 6.12000000e+02f},
|
||||
{4.00000000e+01f, 5.65333313e+02f},
|
||||
{4.00000000e+01f, 4.72000000e+02f}}}},
|
||||
{SEGMENT_BEZIER, {{{4.00000000e+01f, 5.65333313e+02f},
|
||||
{2.83333340e+01f, 6.12000000e+02f},
|
||||
{5.00000000e+00f, 6.12000000e+02f}}}},
|
||||
/* Figure 15. */
|
||||
{SEGMENT_BEZIER, {{{2.00000000e+01f, 6.65333313e+02f},
|
||||
{2.66666660e+01f, 6.92000000e+02f},
|
||||
{4.00000000e+01f, 6.92000000e+02f}}}},
|
||||
{SEGMENT_BEZIER, {{{5.33333321e+01f, 6.92000000e+02f},
|
||||
{6.00000000e+01f, 6.65333313e+02f},
|
||||
{6.00000000e+01f, 6.12000000e+02f}}}},
|
||||
{SEGMENT_BEZIER, {{{6.00000000e+01f, 5.58666687e+02f},
|
||||
{5.33333321e+01f, 5.32000000e+02f},
|
||||
{4.00000000e+01f, 5.32000000e+02f}}}},
|
||||
{SEGMENT_BEZIER, {{{2.66666660e+01f, 5.32000000e+02f},
|
||||
{2.00000000e+01f, 5.58666687e+02f},
|
||||
{2.00000000e+01f, 6.12000000e+02f}}}},
|
||||
/* Figure 16. */
|
||||
{SEGMENT_BEZIER, {{{1.91750427e+02f, 1.27275856e+02f},
|
||||
{2.08249573e+02f, 1.27275856e+02f},
|
||||
{2.24748734e+02f, 6.12792168e+01f}}}},
|
||||
{SEGMENT_BEZIER, {{{2.08249573e+02f, 1.27275856e+02f},
|
||||
{2.08249573e+02f, 1.93272476e+02f},
|
||||
{2.24748734e+02f, 2.59269104e+02f}}}},
|
||||
{SEGMENT_BEZIER, {{{2.08249573e+02f, 1.93272476e+02f},
|
||||
{1.91750427e+02f, 1.93272476e+02f},
|
||||
{1.75251266e+02f, 2.59269104e+02f}}}},
|
||||
{SEGMENT_BEZIER, {{{1.91750427e+02f, 1.93272476e+02f},
|
||||
{1.91750427e+02f, 1.27275856e+02f},
|
||||
{1.75251266e+02f, 6.12792168e+01f}}}},
|
||||
/* Figure 17. */
|
||||
{SEGMENT_BEZIER, {{{1.95285950e+02f, 6.59932632e+01f},
|
||||
{2.04714050e+02f, 6.59932632e+01f},
|
||||
{2.14142136e+02f, 1.03705627e+02f}}}},
|
||||
{SEGMENT_BEZIER, {{{2.23570221e+02f, 1.41417984e+02f},
|
||||
{2.23570221e+02f, 1.79130356e+02f},
|
||||
{2.14142136e+02f, 2.16842712e+02f}}}},
|
||||
{SEGMENT_BEZIER, {{{2.04714050e+02f, 2.54555069e+02f},
|
||||
{1.95285950e+02f, 2.54555069e+02f},
|
||||
{1.85857864e+02f, 2.16842712e+02f}}}},
|
||||
{SEGMENT_BEZIER, {{{1.76429779e+02f, 1.79130356e+02f},
|
||||
{1.76429779e+02f, 1.41417984e+02f},
|
||||
{1.85857864e+02f, 1.03705627e+02f}}}},
|
||||
/* Figure 18. */
|
||||
{SEGMENT_BEZIER, {{{1.11847351e+02f, 4.46888092e+02f},
|
||||
{1.11847351e+02f, 5.12884705e+02f},
|
||||
{9.53481979e+01f, 5.78881348e+02f}}}},
|
||||
{SEGMENT_BEZIER, {{{1.11847351e+02f, 5.12884705e+02f},
|
||||
{1.28346512e+02f, 5.12884705e+02f},
|
||||
{1.44845673e+02f, 5.78881348e+02f}}}},
|
||||
{SEGMENT_BEZIER, {{{1.28346512e+02f, 5.12884705e+02f},
|
||||
{1.28346512e+02f, 4.46888092e+02f},
|
||||
{1.44845673e+02f, 3.80891479e+02f}}}},
|
||||
{SEGMENT_BEZIER, {{{1.28346512e+02f, 4.46888092e+02f},
|
||||
{1.11847351e+02f, 4.46888092e+02f},
|
||||
{9.53481979e+01f, 3.80891479e+02f}}}},
|
||||
/* Figure 19. */
|
||||
{SEGMENT_BEZIER, {{{9.65267105e+01f, 4.61030243e+02f},
|
||||
{9.65267105e+01f, 4.98742584e+02f},
|
||||
{1.05954803e+02f, 5.36454956e+02f}}}},
|
||||
{SEGMENT_BEZIER, {{{1.15382889e+02f, 5.74167297e+02f},
|
||||
{1.24810982e+02f, 5.74167297e+02f},
|
||||
{1.34239075e+02f, 5.36454956e+02f}}}},
|
||||
{SEGMENT_BEZIER, {{{1.43667160e+02f, 4.98742584e+02f},
|
||||
{1.43667160e+02f, 4.61030243e+02f},
|
||||
{1.34239075e+02f, 4.23317871e+02f}}}},
|
||||
{SEGMENT_BEZIER, {{{1.24810982e+02f, 3.85605499e+02f},
|
||||
{1.15382889e+02f, 3.85605499e+02f},
|
||||
{1.05954803e+02f, 4.23317871e+02f}}}},
|
||||
/* Figure 20. */
|
||||
{SEGMENT_LINE, {{{ 40.0f, 20.0f}}}},
|
||||
{SEGMENT_LINE, {{{ 75.0f, 160.0f}}}},
|
||||
{SEGMENT_LINE, {{{ 40.0f, 300.0f}}}},
|
||||
{SEGMENT_LINE, {{{ 5.0f, 160.0f}}}},
|
||||
/* Figure 21. */
|
||||
{SEGMENT_LINE, {{{ 40.0f, 80.0f}}}},
|
||||
{SEGMENT_LINE, {{{ 60.0f, 160.0f}}}},
|
||||
{SEGMENT_LINE, {{{ 40.0f, 240.0f}}}},
|
||||
{SEGMENT_LINE, {{{ 20.0f, 160.0f}}}},
|
||||
/* Figure 22. */
|
||||
{SEGMENT_LINE, {{{ 40.0f, 752.0f}}}},
|
||||
{SEGMENT_LINE, {{{ 75.0f, 612.0f}}}},
|
||||
{SEGMENT_LINE, {{{ 40.0f, 472.0f}}}},
|
||||
{SEGMENT_LINE, {{{ 5.0f, 612.0f}}}},
|
||||
/* Figure 23. */
|
||||
{SEGMENT_LINE, {{{ 40.0f, 692.0f}}}},
|
||||
{SEGMENT_LINE, {{{ 60.0f, 612.0f}}}},
|
||||
{SEGMENT_LINE, {{{ 40.0f, 532.0f}}}},
|
||||
{SEGMENT_LINE, {{{ 20.0f, 612.0f}}}},
|
||||
/* Figure 24. */
|
||||
{SEGMENT_LINE, {{{2.03125019e+01f, 1.51250000e+02f}}}},
|
||||
{SEGMENT_LINE, {{{3.12500019e+01f, 1.25000008e+02f}}}, D2D1_PATH_SEGMENT_FORCE_ROUND_LINE_JOIN},
|
||||
{SEGMENT_LINE, {{{3.78125000e+01f, 8.12500076e+01f}}}, D2D1_PATH_SEGMENT_FORCE_ROUND_LINE_JOIN},
|
||||
{SEGMENT_LINE, {{{4.00000000e+01f, 2.00000000e+01f}}}, D2D1_PATH_SEGMENT_FORCE_ROUND_LINE_JOIN},
|
||||
{SEGMENT_LINE, {{{4.21875000e+01f, 8.12500076e+01f}}}},
|
||||
{SEGMENT_LINE, {{{4.87500000e+01f, 1.25000008e+02f}}}, D2D1_PATH_SEGMENT_FORCE_ROUND_LINE_JOIN},
|
||||
{SEGMENT_LINE, {{{5.96875000e+01f, 1.51250000e+02f}}}, D2D1_PATH_SEGMENT_FORCE_ROUND_LINE_JOIN},
|
||||
{SEGMENT_LINE, {{{7.50000000e+01f, 1.60000000e+02f}}}, D2D1_PATH_SEGMENT_FORCE_ROUND_LINE_JOIN},
|
||||
{SEGMENT_LINE, {{{5.96875000e+01f, 1.68750000e+02f}}}},
|
||||
{SEGMENT_LINE, {{{4.87500000e+01f, 1.95000000e+02f}}}, D2D1_PATH_SEGMENT_FORCE_ROUND_LINE_JOIN},
|
||||
{SEGMENT_LINE, {{{4.21875000e+01f, 2.38750000e+02f}}}, D2D1_PATH_SEGMENT_FORCE_ROUND_LINE_JOIN},
|
||||
{SEGMENT_LINE, {{{4.00000000e+01f, 3.00000000e+02f}}}, D2D1_PATH_SEGMENT_FORCE_ROUND_LINE_JOIN},
|
||||
{SEGMENT_LINE, {{{3.78125000e+01f, 2.38750000e+02f}}}},
|
||||
{SEGMENT_LINE, {{{3.12500019e+01f, 1.95000000e+02f}}}, D2D1_PATH_SEGMENT_FORCE_ROUND_LINE_JOIN},
|
||||
{SEGMENT_LINE, {{{2.03125019e+01f, 1.68750000e+02f}}}, D2D1_PATH_SEGMENT_FORCE_ROUND_LINE_JOIN},
|
||||
{SEGMENT_LINE, {{{5.00000000e+00f, 1.60000000e+02f}}}, D2D1_PATH_SEGMENT_FORCE_ROUND_LINE_JOIN},
|
||||
/* Figure 25. */
|
||||
{SEGMENT_LINE, {{{2.50000000e+01f, 1.00000000e+02f}}}},
|
||||
{SEGMENT_LINE, {{{4.00000000e+01f, 8.00000000e+01f}}}, D2D1_PATH_SEGMENT_FORCE_ROUND_LINE_JOIN},
|
||||
{SEGMENT_LINE, {{{5.50000000e+01f, 1.00000000e+02f}}}},
|
||||
{SEGMENT_LINE, {{{6.00000000e+01f, 1.60000000e+02f}}}, D2D1_PATH_SEGMENT_FORCE_ROUND_LINE_JOIN},
|
||||
{SEGMENT_LINE, {{{5.50000000e+01f, 2.20000000e+02f}}}},
|
||||
{SEGMENT_LINE, {{{4.00000000e+01f, 2.40000000e+02f}}}, D2D1_PATH_SEGMENT_FORCE_ROUND_LINE_JOIN},
|
||||
{SEGMENT_LINE, {{{2.50000000e+01f, 2.20000000e+02f}}}},
|
||||
{SEGMENT_LINE, {{{2.00000000e+01f, 1.60000000e+02f}}}, D2D1_PATH_SEGMENT_FORCE_ROUND_LINE_JOIN},
|
||||
/* Figure 26. */
|
||||
{SEGMENT_LINE, {{{2.03125019e+01f, 6.20750000e+02f}}}},
|
||||
{SEGMENT_LINE, {{{3.12500019e+01f, 6.47000000e+02f}}}, D2D1_PATH_SEGMENT_FORCE_ROUND_LINE_JOIN},
|
||||
{SEGMENT_LINE, {{{3.78125000e+01f, 6.90750000e+02f}}}, D2D1_PATH_SEGMENT_FORCE_ROUND_LINE_JOIN},
|
||||
{SEGMENT_LINE, {{{4.00000000e+01f, 7.52000000e+02f}}}, D2D1_PATH_SEGMENT_FORCE_ROUND_LINE_JOIN},
|
||||
{SEGMENT_LINE, {{{4.21875000e+01f, 6.90750000e+02f}}}},
|
||||
{SEGMENT_LINE, {{{4.87500000e+01f, 6.47000000e+02f}}}, D2D1_PATH_SEGMENT_FORCE_ROUND_LINE_JOIN},
|
||||
{SEGMENT_LINE, {{{5.96875000e+01f, 6.20750000e+02f}}}, D2D1_PATH_SEGMENT_FORCE_ROUND_LINE_JOIN},
|
||||
{SEGMENT_LINE, {{{7.50000000e+01f, 6.12000000e+02f}}}, D2D1_PATH_SEGMENT_FORCE_ROUND_LINE_JOIN},
|
||||
{SEGMENT_LINE, {{{5.96875000e+01f, 6.03250000e+02f}}}},
|
||||
{SEGMENT_LINE, {{{4.87500000e+01f, 5.77000000e+02f}}}, D2D1_PATH_SEGMENT_FORCE_ROUND_LINE_JOIN},
|
||||
{SEGMENT_LINE, {{{4.21875000e+01f, 5.33250000e+02f}}}, D2D1_PATH_SEGMENT_FORCE_ROUND_LINE_JOIN},
|
||||
{SEGMENT_LINE, {{{4.00000000e+01f, 4.72000000e+02f}}}, D2D1_PATH_SEGMENT_FORCE_ROUND_LINE_JOIN},
|
||||
{SEGMENT_LINE, {{{3.78125000e+01f, 5.33250000e+02f}}}},
|
||||
{SEGMENT_LINE, {{{3.12500019e+01f, 5.77000000e+02f}}}, D2D1_PATH_SEGMENT_FORCE_ROUND_LINE_JOIN},
|
||||
{SEGMENT_LINE, {{{2.03125019e+01f, 6.03250000e+02f}}}, D2D1_PATH_SEGMENT_FORCE_ROUND_LINE_JOIN},
|
||||
{SEGMENT_LINE, {{{5.00000000e+00f, 6.12000000e+02f}}}, D2D1_PATH_SEGMENT_FORCE_ROUND_LINE_JOIN},
|
||||
/* Figure 27. */
|
||||
{SEGMENT_LINE, {{{2.50000000e+01f, 6.72000000e+02f}}}},
|
||||
{SEGMENT_LINE, {{{4.00000000e+01f, 6.92000000e+02f}}}, D2D1_PATH_SEGMENT_FORCE_ROUND_LINE_JOIN},
|
||||
{SEGMENT_LINE, {{{5.50000000e+01f, 6.72000000e+02f}}}},
|
||||
{SEGMENT_LINE, {{{6.00000000e+01f, 6.12000000e+02f}}}, D2D1_PATH_SEGMENT_FORCE_ROUND_LINE_JOIN},
|
||||
{SEGMENT_LINE, {{{5.50000000e+01f, 5.52000000e+02f}}}},
|
||||
{SEGMENT_LINE, {{{4.00000000e+01f, 5.32000000e+02f}}}, D2D1_PATH_SEGMENT_FORCE_ROUND_LINE_JOIN},
|
||||
{SEGMENT_LINE, {{{2.50000000e+01f, 5.52000000e+02f}}}},
|
||||
{SEGMENT_LINE, {{{2.00000000e+01f, 6.12000000e+02f}}}, D2D1_PATH_SEGMENT_FORCE_ROUND_LINE_JOIN},
|
||||
/* Figure 28. */
|
||||
{SEGMENT_LINE, {{{ 75.0f, 300.0f}}}},
|
||||
{SEGMENT_LINE, {{{ 5.0f, 300.0f}}}},
|
||||
};
|
||||
static const struct expected_geometry_figure expected_figures[] =
|
||||
{
|
||||
/* 0 */
|
||||
{D2D1_FIGURE_BEGIN_FILLED, D2D1_FIGURE_END_CLOSED, { 15.0f, 20.0f}, 15, &expected_segments[0]},
|
||||
{D2D1_FIGURE_BEGIN_FILLED, D2D1_FIGURE_END_CLOSED, {155.0f, 300.0f}, 11, &expected_segments[15]},
|
||||
{D2D1_FIGURE_BEGIN_FILLED, D2D1_FIGURE_END_CLOSED, {165.0f, 20.0f}, 3, &expected_segments[26]},
|
||||
{D2D1_FIGURE_BEGIN_FILLED, D2D1_FIGURE_END_CLOSED, {225.0f, 60.0f}, 3, &expected_segments[29]},
|
||||
{D2D1_FIGURE_BEGIN_FILLED, D2D1_FIGURE_END_CLOSED, {215.0f, 220.0f}, 3, &expected_segments[32]},
|
||||
{D2D1_FIGURE_BEGIN_FILLED, D2D1_FIGURE_END_CLOSED, {195.0f, 180.0f}, 3, &expected_segments[35]},
|
||||
/* 6 */
|
||||
{D2D1_FIGURE_BEGIN_FILLED, D2D1_FIGURE_END_CLOSED, { 95.0f, 620.0f}, 15, &expected_segments[38]},
|
||||
{D2D1_FIGURE_BEGIN_FILLED, D2D1_FIGURE_END_CLOSED, {235.0f, 340.0f}, 11, &expected_segments[53]},
|
||||
{D2D1_FIGURE_BEGIN_FILLED, D2D1_FIGURE_END_CLOSED, {245.0f, 620.0f}, 3, &expected_segments[64]},
|
||||
{D2D1_FIGURE_BEGIN_FILLED, D2D1_FIGURE_END_CLOSED, {305.0f, 580.0f}, 3, &expected_segments[67]},
|
||||
{D2D1_FIGURE_BEGIN_FILLED, D2D1_FIGURE_END_CLOSED, {295.0f, 420.0f}, 3, &expected_segments[70]},
|
||||
{D2D1_FIGURE_BEGIN_FILLED, D2D1_FIGURE_END_CLOSED, {275.0f, 460.0f}, 3, &expected_segments[73]},
|
||||
/* 12 */
|
||||
{D2D1_FIGURE_BEGIN_FILLED, D2D1_FIGURE_END_CLOSED, { 5.0f, 160.0f}, 4, &expected_segments[76]},
|
||||
{D2D1_FIGURE_BEGIN_FILLED, D2D1_FIGURE_END_CLOSED, { 20.0f, 160.0f}, 4, &expected_segments[80]},
|
||||
{D2D1_FIGURE_BEGIN_FILLED, D2D1_FIGURE_END_CLOSED, { 5.0f, 612.0f}, 4, &expected_segments[84]},
|
||||
{D2D1_FIGURE_BEGIN_FILLED, D2D1_FIGURE_END_CLOSED, { 20.0f, 612.0f}, 4, &expected_segments[88]},
|
||||
/* 16 */
|
||||
{D2D1_FIGURE_BEGIN_FILLED, D2D1_FIGURE_END_CLOSED,
|
||||
{1.75251266e+02f, 6.12792168e+01f}, 4, &expected_segments[92]},
|
||||
{D2D1_FIGURE_BEGIN_FILLED, D2D1_FIGURE_END_CLOSED,
|
||||
{1.85857864e+02f, 1.03705627e+02f}, 4, &expected_segments[96]},
|
||||
{D2D1_FIGURE_BEGIN_FILLED, D2D1_FIGURE_END_CLOSED,
|
||||
{9.53481979e+01f, 3.80891479e+02f}, 4, &expected_segments[100]},
|
||||
{D2D1_FIGURE_BEGIN_FILLED, D2D1_FIGURE_END_CLOSED,
|
||||
{1.05954803e+02f, 4.23317871e+02f}, 4, &expected_segments[104]},
|
||||
/* 20 */
|
||||
{D2D1_FIGURE_BEGIN_FILLED, D2D1_FIGURE_END_CLOSED, { 5.0f, 160.0f}, 4, &expected_segments[108]},
|
||||
{D2D1_FIGURE_BEGIN_FILLED, D2D1_FIGURE_END_CLOSED, { 20.0f, 160.0f}, 4, &expected_segments[112]},
|
||||
{D2D1_FIGURE_BEGIN_FILLED, D2D1_FIGURE_END_CLOSED, { 5.0f, 612.0f}, 4, &expected_segments[116]},
|
||||
{D2D1_FIGURE_BEGIN_FILLED, D2D1_FIGURE_END_CLOSED, { 20.0f, 612.0f}, 4, &expected_segments[120]},
|
||||
/* 24 */
|
||||
{D2D1_FIGURE_BEGIN_FILLED, D2D1_FIGURE_END_CLOSED, { 5.0f, 160.0f}, 16, &expected_segments[124]},
|
||||
{D2D1_FIGURE_BEGIN_FILLED, D2D1_FIGURE_END_CLOSED, { 20.0f, 160.0f}, 8, &expected_segments[140]},
|
||||
{D2D1_FIGURE_BEGIN_FILLED, D2D1_FIGURE_END_CLOSED, { 5.0f, 612.0f}, 16, &expected_segments[148]},
|
||||
{D2D1_FIGURE_BEGIN_FILLED, D2D1_FIGURE_END_CLOSED, { 20.0f, 612.0f}, 8, &expected_segments[164]},
|
||||
/* 28 */
|
||||
{D2D1_FIGURE_BEGIN_HOLLOW, D2D1_FIGURE_END_OPEN, { 40.0f, 20.0f}, 2, &expected_segments[172]},
|
||||
};
|
||||
|
||||
if (!(device = create_device()))
|
||||
{
|
||||
skip("Failed to create device, skipping tests.\n");
|
||||
|
@ -1778,21 +2177,47 @@ static void test_path_geometry(void)
|
|||
ID2D1GeometrySink_SetFillMode(sink, D2D1_FILL_MODE_WINDING);
|
||||
ID2D1GeometrySink_Release(sink);
|
||||
|
||||
geometry_sink_init(&simplify_sink);
|
||||
hr = ID2D1PathGeometry_Simplify(geometry, D2D1_GEOMETRY_SIMPLIFICATION_OPTION_LINES,
|
||||
NULL, 0.0f, &simplify_sink.ID2D1SimplifiedGeometrySink_iface);
|
||||
ok(SUCCEEDED(hr), "Failed to simplify geometry, hr %#x.\n", hr);
|
||||
geometry_sink_check(&simplify_sink, D2D1_FILL_MODE_ALTERNATE, 6, &expected_figures[0], 0);
|
||||
geometry_sink_cleanup(&simplify_sink);
|
||||
geometry_sink_init(&simplify_sink);
|
||||
hr = ID2D1PathGeometry_Simplify(geometry, D2D1_GEOMETRY_SIMPLIFICATION_OPTION_CUBICS_AND_LINES,
|
||||
NULL, 0.0f, &simplify_sink.ID2D1SimplifiedGeometrySink_iface);
|
||||
ok(SUCCEEDED(hr), "Failed to simplify geometry, hr %#x.\n", hr);
|
||||
geometry_sink_check(&simplify_sink, D2D1_FILL_MODE_ALTERNATE, 6, &expected_figures[0], 0);
|
||||
geometry_sink_cleanup(&simplify_sink);
|
||||
|
||||
set_matrix_identity(&matrix);
|
||||
translate_matrix(&matrix, 80.0f, 640.0f);
|
||||
scale_matrix(&matrix, 1.0f, -1.0f);
|
||||
hr = ID2D1Factory_CreateTransformedGeometry(factory, (ID2D1Geometry *)geometry, &matrix, &transformed_geometry);
|
||||
ok(SUCCEEDED(hr), "Failed to create transformed geometry, hr %#x.\n", hr);
|
||||
|
||||
geometry_sink_init(&simplify_sink);
|
||||
hr = ID2D1TransformedGeometry_Simplify(transformed_geometry, D2D1_GEOMETRY_SIMPLIFICATION_OPTION_LINES,
|
||||
NULL, 0.0f, &simplify_sink.ID2D1SimplifiedGeometrySink_iface);
|
||||
ok(SUCCEEDED(hr), "Failed to simplify geometry, hr %#x.\n", hr);
|
||||
geometry_sink_check(&simplify_sink, D2D1_FILL_MODE_ALTERNATE, 6, &expected_figures[6], 0);
|
||||
geometry_sink_cleanup(&simplify_sink);
|
||||
|
||||
ID2D1TransformedGeometry_GetSourceGeometry(transformed_geometry, &tmp_geometry);
|
||||
ok(tmp_geometry == (ID2D1Geometry *)geometry,
|
||||
"Got unexpected source geometry %p, expected %p.\n", tmp_geometry, geometry);
|
||||
ID2D1Geometry_Release(tmp_geometry);
|
||||
ID2D1TransformedGeometry_GetTransform(transformed_geometry, &tmp_matrix);
|
||||
ok(!memcmp(&tmp_matrix, &matrix, sizeof(matrix)),
|
||||
"Got unexpected matrix {%.8e, %.8e, %.8e, %.8e, %.8e, %.8e}.\n",
|
||||
tmp_matrix._11, tmp_matrix._12, tmp_matrix._21,
|
||||
tmp_matrix._22, tmp_matrix._31, tmp_matrix._32);
|
||||
geometry_sink_init(&simplify_sink);
|
||||
hr = ID2D1Geometry_Simplify(tmp_geometry, D2D1_GEOMETRY_SIMPLIFICATION_OPTION_LINES,
|
||||
&tmp_matrix, 0.0f, &simplify_sink.ID2D1SimplifiedGeometrySink_iface);
|
||||
ok(SUCCEEDED(hr), "Failed to simplify geometry, hr %#x.\n", hr);
|
||||
geometry_sink_check(&simplify_sink, D2D1_FILL_MODE_ALTERNATE, 6, &expected_figures[6], 0);
|
||||
geometry_sink_cleanup(&simplify_sink);
|
||||
ID2D1Geometry_Release(tmp_geometry);
|
||||
|
||||
ID2D1RenderTarget_BeginDraw(rt);
|
||||
set_color(&color, 0.396f, 0.180f, 0.537f, 1.0f);
|
||||
|
@ -1845,6 +2270,13 @@ static void test_path_geometry(void)
|
|||
ok(count == 44, "Got unexpected segment count %u.\n", count);
|
||||
ID2D1GeometrySink_Release(sink);
|
||||
|
||||
geometry_sink_init(&simplify_sink);
|
||||
hr = ID2D1PathGeometry_Simplify(geometry, D2D1_GEOMETRY_SIMPLIFICATION_OPTION_LINES,
|
||||
NULL, 0.0f, &simplify_sink.ID2D1SimplifiedGeometrySink_iface);
|
||||
ok(SUCCEEDED(hr), "Failed to simplify geometry, hr %#x.\n", hr);
|
||||
geometry_sink_check(&simplify_sink, D2D1_FILL_MODE_WINDING, 6, &expected_figures[0], 0);
|
||||
geometry_sink_cleanup(&simplify_sink);
|
||||
|
||||
set_matrix_identity(&matrix);
|
||||
translate_matrix(&matrix, 320.0f, 320.0f);
|
||||
scale_matrix(&matrix, -1.0f, 1.0f);
|
||||
|
@ -1877,6 +2309,25 @@ static void test_path_geometry(void)
|
|||
ok(count == 20, "Got unexpected segment count %u.\n", count);
|
||||
ID2D1GeometrySink_Release(sink);
|
||||
|
||||
geometry_sink_init(&simplify_sink);
|
||||
hr = ID2D1PathGeometry_Simplify(geometry, D2D1_GEOMETRY_SIMPLIFICATION_OPTION_CUBICS_AND_LINES,
|
||||
NULL, 0.0f, &simplify_sink.ID2D1SimplifiedGeometrySink_iface);
|
||||
ok(SUCCEEDED(hr), "Failed to simplify geometry, hr %#x.\n", hr);
|
||||
geometry_sink_check(&simplify_sink, D2D1_FILL_MODE_ALTERNATE, 4, &expected_figures[12], 1);
|
||||
geometry_sink_cleanup(&simplify_sink);
|
||||
geometry_sink_init(&simplify_sink);
|
||||
hr = ID2D1PathGeometry_Simplify(geometry, D2D1_GEOMETRY_SIMPLIFICATION_OPTION_LINES,
|
||||
NULL, 100.0f, &simplify_sink.ID2D1SimplifiedGeometrySink_iface);
|
||||
ok(SUCCEEDED(hr), "Failed to simplify geometry, hr %#x.\n", hr);
|
||||
geometry_sink_check(&simplify_sink, D2D1_FILL_MODE_ALTERNATE, 4, &expected_figures[20], 1);
|
||||
geometry_sink_cleanup(&simplify_sink);
|
||||
geometry_sink_init(&simplify_sink);
|
||||
hr = ID2D1PathGeometry_Simplify(geometry, D2D1_GEOMETRY_SIMPLIFICATION_OPTION_LINES,
|
||||
NULL, 10.0f, &simplify_sink.ID2D1SimplifiedGeometrySink_iface);
|
||||
ok(SUCCEEDED(hr), "Failed to simplify geometry, hr %#x.\n", hr);
|
||||
geometry_sink_check(&simplify_sink, D2D1_FILL_MODE_ALTERNATE, 4, &expected_figures[24], 1);
|
||||
geometry_sink_cleanup(&simplify_sink);
|
||||
|
||||
set_matrix_identity(&matrix);
|
||||
scale_matrix(&matrix, 0.5f, 2.0f);
|
||||
translate_matrix(&matrix, 400.0f, -33.0f);
|
||||
|
@ -1885,6 +2336,13 @@ static void test_path_geometry(void)
|
|||
hr = ID2D1Factory_CreateTransformedGeometry(factory, (ID2D1Geometry *)geometry, &matrix, &transformed_geometry);
|
||||
ok(SUCCEEDED(hr), "Failed to create transformed geometry, hr %#x.\n", hr);
|
||||
|
||||
geometry_sink_init(&simplify_sink);
|
||||
hr = ID2D1TransformedGeometry_Simplify(transformed_geometry, D2D1_GEOMETRY_SIMPLIFICATION_OPTION_CUBICS_AND_LINES,
|
||||
NULL, 0.0f, &simplify_sink.ID2D1SimplifiedGeometrySink_iface);
|
||||
ok(SUCCEEDED(hr), "Failed to simplify geometry, hr %#x.\n", hr);
|
||||
geometry_sink_check(&simplify_sink, D2D1_FILL_MODE_ALTERNATE, 4, &expected_figures[16], 4);
|
||||
geometry_sink_cleanup(&simplify_sink);
|
||||
|
||||
ID2D1RenderTarget_BeginDraw(rt);
|
||||
ID2D1RenderTarget_Clear(rt, &color);
|
||||
ID2D1RenderTarget_FillGeometry(rt, (ID2D1Geometry *)geometry, (ID2D1Brush *)brush, NULL);
|
||||
|
@ -1954,6 +2412,25 @@ static void test_path_geometry(void)
|
|||
ok(count == 20, "Got unexpected segment count %u.\n", count);
|
||||
ID2D1GeometrySink_Release(sink);
|
||||
|
||||
geometry_sink_init(&simplify_sink);
|
||||
hr = ID2D1PathGeometry_Simplify(geometry, D2D1_GEOMETRY_SIMPLIFICATION_OPTION_CUBICS_AND_LINES,
|
||||
NULL, 0.0f, &simplify_sink.ID2D1SimplifiedGeometrySink_iface);
|
||||
ok(SUCCEEDED(hr), "Failed to simplify geometry, hr %#x.\n", hr);
|
||||
geometry_sink_check(&simplify_sink, D2D1_FILL_MODE_WINDING, 4, &expected_figures[12], 1);
|
||||
geometry_sink_cleanup(&simplify_sink);
|
||||
geometry_sink_init(&simplify_sink);
|
||||
hr = ID2D1PathGeometry_Simplify(geometry, D2D1_GEOMETRY_SIMPLIFICATION_OPTION_LINES,
|
||||
NULL, 100.0f, &simplify_sink.ID2D1SimplifiedGeometrySink_iface);
|
||||
ok(SUCCEEDED(hr), "Failed to simplify geometry, hr %#x.\n", hr);
|
||||
geometry_sink_check(&simplify_sink, D2D1_FILL_MODE_WINDING, 4, &expected_figures[20], 1);
|
||||
geometry_sink_cleanup(&simplify_sink);
|
||||
geometry_sink_init(&simplify_sink);
|
||||
hr = ID2D1PathGeometry_Simplify(geometry, D2D1_GEOMETRY_SIMPLIFICATION_OPTION_LINES,
|
||||
NULL, 10.0f, &simplify_sink.ID2D1SimplifiedGeometrySink_iface);
|
||||
ok(SUCCEEDED(hr), "Failed to simplify geometry, hr %#x.\n", hr);
|
||||
geometry_sink_check(&simplify_sink, D2D1_FILL_MODE_WINDING, 4, &expected_figures[24], 1);
|
||||
geometry_sink_cleanup(&simplify_sink);
|
||||
|
||||
set_matrix_identity(&matrix);
|
||||
scale_matrix(&matrix, 0.5f, 2.0f);
|
||||
translate_matrix(&matrix, 127.0f, 80.0f);
|
||||
|
@ -2039,6 +2516,28 @@ static void test_path_geometry(void)
|
|||
ok(match, "Surface does not match.\n");
|
||||
ID2D1PathGeometry_Release(geometry);
|
||||
|
||||
hr = ID2D1Factory_CreatePathGeometry(factory, &geometry);
|
||||
ok(SUCCEEDED(hr), "Failed to create path geometry, hr %#x.\n", hr);
|
||||
hr = ID2D1PathGeometry_Open(geometry, &sink);
|
||||
ok(SUCCEEDED(hr), "Failed to open geometry sink, hr %#x.\n", hr);
|
||||
set_point(&point, 40.0f, 20.0f);
|
||||
ID2D1GeometrySink_BeginFigure(sink, point, D2D1_FIGURE_BEGIN_HOLLOW);
|
||||
line_to(sink, 75.0f, 300.0f);
|
||||
line_to(sink, 5.0f, 300.0f);
|
||||
ID2D1GeometrySink_EndFigure(sink, D2D1_FIGURE_END_OPEN);
|
||||
hr = ID2D1GeometrySink_Close(sink);
|
||||
ok(SUCCEEDED(hr), "Failed to close geometry sink, hr %#x.\n", hr);
|
||||
ID2D1GeometrySink_Release(sink);
|
||||
|
||||
geometry_sink_init(&simplify_sink);
|
||||
hr = ID2D1PathGeometry_Simplify(geometry, D2D1_GEOMETRY_SIMPLIFICATION_OPTION_LINES,
|
||||
NULL, 0.0f, &simplify_sink.ID2D1SimplifiedGeometrySink_iface);
|
||||
ok(SUCCEEDED(hr), "Failed to simplify geometry, hr %#x.\n", hr);
|
||||
geometry_sink_check(&simplify_sink, D2D1_FILL_MODE_ALTERNATE, 1, &expected_figures[28], 1);
|
||||
geometry_sink_cleanup(&simplify_sink);
|
||||
|
||||
ID2D1PathGeometry_Release(geometry);
|
||||
|
||||
ID2D1SolidColorBrush_Release(brush);
|
||||
ID2D1RenderTarget_Release(rt);
|
||||
refcount = ID2D1Factory_Release(factory);
|
||||
|
@ -2049,80 +2548,6 @@ static void test_path_geometry(void)
|
|||
DestroyWindow(window);
|
||||
}
|
||||
|
||||
#define geometry_sink_check(a, b, c, d, e) geometry_sink_check_(__LINE__, a, b, c, d, e)
|
||||
static void geometry_sink_check_(unsigned int line, const struct geometry_sink *sink, D2D1_FILL_MODE fill_mode,
|
||||
unsigned int figure_count, const struct expected_geometry_figure *expected_figures, unsigned int ulps)
|
||||
{
|
||||
const struct geometry_segment *segment, *expected_segment;
|
||||
const struct expected_geometry_figure *expected_figure;
|
||||
const struct geometry_figure *figure;
|
||||
unsigned int i, j;
|
||||
BOOL match;
|
||||
|
||||
ok_(__FILE__, line)(sink->fill_mode == D2D1_FILL_MODE_ALTERNATE,
|
||||
"Got unexpected fill mode %#x.\n", sink->fill_mode);
|
||||
ok_(__FILE__, line)(sink->figure_count == 1, "Got unexpected figure count %u.\n", sink->figure_count);
|
||||
ok_(__FILE__, line)(!sink->closed, "Sink is closed.\n");
|
||||
|
||||
for (i = 0; i < figure_count; ++i)
|
||||
{
|
||||
expected_figure = &expected_figures[i];
|
||||
figure = &sink->figures[i];
|
||||
|
||||
ok_(__FILE__, line)(figure->begin == expected_figure->begin,
|
||||
"Got unexpected figure %u begin %#x, expected %#x.\n",
|
||||
i, figure->begin, expected_figure->begin);
|
||||
ok_(__FILE__, line)(figure->end == expected_figure->end,
|
||||
"Got unexpected figure %u end %#x, expected %#x.\n",
|
||||
i, figure->end, expected_figure->end);
|
||||
match = compare_point(&figure->start_point,
|
||||
expected_figure->start_point.x, expected_figure->start_point.y, ulps);
|
||||
ok_(__FILE__, line)(match, "Got unexpected figure %u start point {%.8e, %.8e}, expected {%.8e, %.8e}.\n",
|
||||
i, figure->start_point.x, figure->start_point.y,
|
||||
expected_figure->start_point.x, expected_figure->start_point.y);
|
||||
ok_(__FILE__, line)(figure->segment_count == expected_figure->segment_count,
|
||||
"Got unexpected figure %u segment count %u, expected %u.\n",
|
||||
i, figure->segment_count, expected_figure->segment_count);
|
||||
|
||||
for (j = 0; j < figure->segment_count; ++j)
|
||||
{
|
||||
expected_segment = &expected_figure->segments[j];
|
||||
segment = &figure->segments[j];
|
||||
ok_(__FILE__, line)(segment->type == expected_segment->type,
|
||||
"Got unexpected figure %u, segment %u type %#x, expected %#x.\n",
|
||||
i, j, segment->type, expected_segment->type);
|
||||
switch (segment->type)
|
||||
{
|
||||
case SEGMENT_LINE:
|
||||
match = compare_point(&segment->u.line,
|
||||
expected_segment->u.line.x, expected_segment->u.line.y, ulps);
|
||||
ok_(__FILE__, line)(match, "Got unexpected figure %u segment %u {%.8e, %.8e}, "
|
||||
"expected {%.8e, %.8e}.\n",
|
||||
i, j, segment->u.line.x, segment->u.line.y,
|
||||
expected_segment->u.line.x, expected_segment->u.line.y);
|
||||
break;
|
||||
|
||||
case SEGMENT_BEZIER:
|
||||
match = compare_bezier_segment(&segment->u.bezier,
|
||||
expected_segment->u.bezier.point1.x, expected_segment->u.bezier.point1.y,
|
||||
expected_segment->u.bezier.point2.x, expected_segment->u.bezier.point2.y,
|
||||
expected_segment->u.bezier.point3.x, expected_segment->u.bezier.point3.y,
|
||||
ulps);
|
||||
ok_(__FILE__, line)(match, "Got unexpected figure %u segment %u "
|
||||
"{%.8e, %.8e, %.8e, %.8e, %.8e, %.8e}, "
|
||||
"expected {%.8e, %.8e, %.8e, %.8e, %.8e, %.8e}.\n",
|
||||
i, j, segment->u.bezier.point1.x, segment->u.bezier.point1.y,
|
||||
segment->u.bezier.point2.x, segment->u.bezier.point2.y,
|
||||
segment->u.bezier.point3.x, segment->u.bezier.point3.y,
|
||||
expected_segment->u.bezier.point1.x, expected_segment->u.bezier.point1.y,
|
||||
expected_segment->u.bezier.point2.x, expected_segment->u.bezier.point2.y,
|
||||
expected_segment->u.bezier.point3.x, expected_segment->u.bezier.point3.y);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void test_rectangle_geometry(void)
|
||||
{
|
||||
ID2D1TransformedGeometry *transformed_geometry;
|
||||
|
|
Loading…
Reference in New Issue