dwrite: Improve empty contours handling in GetGlyphRunOutline().
Signed-off-by: Nikolay Sivov <nsivov@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
1b16af0062
commit
1df4e64bbf
|
@ -320,7 +320,6 @@ struct decompose_context {
|
|||
FLOAT xoffset;
|
||||
FLOAT yoffset;
|
||||
BOOL figure_started;
|
||||
BOOL figure_closed;
|
||||
BOOL move_to; /* last call was 'move_to' */
|
||||
FT_Vector origin; /* 'pen' position from last call */
|
||||
};
|
||||
|
@ -331,21 +330,29 @@ static inline void ft_vector_to_d2d_point(const FT_Vector *v, FLOAT xoffset, FLO
|
|||
p->y = (v->y / 64.0f) + yoffset;
|
||||
}
|
||||
|
||||
static void decompose_beginfigure(struct decompose_context *ctxt)
|
||||
{
|
||||
D2D1_POINT_2F point;
|
||||
|
||||
if (!ctxt->move_to)
|
||||
return;
|
||||
|
||||
ft_vector_to_d2d_point(&ctxt->origin, ctxt->xoffset, ctxt->yoffset, &point);
|
||||
ID2D1SimplifiedGeometrySink_BeginFigure(ctxt->sink, point, D2D1_FIGURE_BEGIN_FILLED);
|
||||
|
||||
ctxt->figure_started = TRUE;
|
||||
ctxt->move_to = FALSE;
|
||||
}
|
||||
|
||||
static int decompose_move_to(const FT_Vector *to, void *user)
|
||||
{
|
||||
struct decompose_context *ctxt = (struct decompose_context*)user;
|
||||
D2D1_POINT_2F point;
|
||||
|
||||
if (ctxt->figure_started) {
|
||||
ID2D1SimplifiedGeometrySink_EndFigure(ctxt->sink, D2D1_FIGURE_END_CLOSED);
|
||||
ctxt->figure_closed = TRUE;
|
||||
ctxt->figure_started = FALSE;
|
||||
}
|
||||
else
|
||||
ctxt->figure_closed = FALSE;
|
||||
ctxt->figure_started = TRUE;
|
||||
|
||||
ft_vector_to_d2d_point(to, ctxt->xoffset, ctxt->yoffset, &point);
|
||||
ID2D1SimplifiedGeometrySink_BeginFigure(ctxt->sink, point, D2D1_FIGURE_BEGIN_FILLED);
|
||||
ctxt->move_to = TRUE;
|
||||
ctxt->origin = *to;
|
||||
return 0;
|
||||
|
@ -354,18 +361,17 @@ static int decompose_move_to(const FT_Vector *to, void *user)
|
|||
static int decompose_line_to(const FT_Vector *to, void *user)
|
||||
{
|
||||
struct decompose_context *ctxt = (struct decompose_context*)user;
|
||||
/* special case for empty contours, in a way freetype returns them */
|
||||
if (ctxt->move_to && !memcmp(to, &ctxt->origin, sizeof(*to))) {
|
||||
ID2D1SimplifiedGeometrySink_EndFigure(ctxt->sink, D2D1_FIGURE_END_CLOSED);
|
||||
ctxt->figure_closed = TRUE;
|
||||
}
|
||||
else {
|
||||
D2D1_POINT_2F point;
|
||||
|
||||
/* Special case for empty contours, in a way freetype returns them. */
|
||||
if (ctxt->move_to && !memcmp(to, &ctxt->origin, sizeof(*to)))
|
||||
return 0;
|
||||
|
||||
decompose_beginfigure(ctxt);
|
||||
|
||||
ft_vector_to_d2d_point(to, ctxt->xoffset, ctxt->yoffset, &point);
|
||||
ID2D1SimplifiedGeometrySink_AddLines(ctxt->sink, &point, 1);
|
||||
ctxt->figure_closed = FALSE;
|
||||
}
|
||||
ctxt->move_to = FALSE;
|
||||
|
||||
ctxt->origin = *to;
|
||||
return 0;
|
||||
}
|
||||
|
@ -376,6 +382,8 @@ static int decompose_conic_to(const FT_Vector *control, const FT_Vector *to, voi
|
|||
D2D1_POINT_2F points[3];
|
||||
FT_Vector cubic[3];
|
||||
|
||||
decompose_beginfigure(ctxt);
|
||||
|
||||
/* convert from quadratic to cubic */
|
||||
|
||||
/*
|
||||
|
@ -410,8 +418,6 @@ static int decompose_conic_to(const FT_Vector *control, const FT_Vector *to, voi
|
|||
ft_vector_to_d2d_point(cubic + 1, ctxt->xoffset, ctxt->yoffset, points + 1);
|
||||
ft_vector_to_d2d_point(cubic + 2, ctxt->xoffset, ctxt->yoffset, points + 2);
|
||||
ID2D1SimplifiedGeometrySink_AddBeziers(ctxt->sink, (D2D1_BEZIER_SEGMENT*)points, 1);
|
||||
ctxt->figure_closed = FALSE;
|
||||
ctxt->move_to = FALSE;
|
||||
ctxt->origin = *to;
|
||||
return 0;
|
||||
}
|
||||
|
@ -422,12 +428,12 @@ static int decompose_cubic_to(const FT_Vector *control1, const FT_Vector *contro
|
|||
struct decompose_context *ctxt = (struct decompose_context*)user;
|
||||
D2D1_POINT_2F points[3];
|
||||
|
||||
decompose_beginfigure(ctxt);
|
||||
|
||||
ft_vector_to_d2d_point(control1, ctxt->xoffset, ctxt->yoffset, points);
|
||||
ft_vector_to_d2d_point(control2, ctxt->xoffset, ctxt->yoffset, points + 1);
|
||||
ft_vector_to_d2d_point(to, ctxt->xoffset, ctxt->yoffset, points + 2);
|
||||
ID2D1SimplifiedGeometrySink_AddBeziers(ctxt->sink, (D2D1_BEZIER_SEGMENT*)points, 1);
|
||||
ctxt->figure_closed = FALSE;
|
||||
ctxt->move_to = FALSE;
|
||||
ctxt->origin = *to;
|
||||
return 0;
|
||||
}
|
||||
|
@ -448,14 +454,13 @@ static void decompose_outline(FT_Outline *outline, FLOAT xoffset, FLOAT yoffset,
|
|||
context.xoffset = xoffset;
|
||||
context.yoffset = yoffset;
|
||||
context.figure_started = FALSE;
|
||||
context.figure_closed = FALSE;
|
||||
context.move_to = FALSE;
|
||||
context.origin.x = 0;
|
||||
context.origin.y = 0;
|
||||
|
||||
pFT_Outline_Decompose(outline, &decompose_funcs, &context);
|
||||
|
||||
if (!context.figure_closed && outline->n_points)
|
||||
if (context.figure_started)
|
||||
ID2D1SimplifiedGeometrySink_EndFigure(sink, D2D1_FIGURE_END_CLOSED);
|
||||
}
|
||||
|
||||
|
|
|
@ -3061,7 +3061,7 @@ if (face2) {
|
|||
|
||||
hr = IDWriteFontFace_GetGlyphIndices(face, codePoints, 1, indices);
|
||||
ok(hr == S_OK, "got 0x%08x\n", hr);
|
||||
ok(indices[0] == 6, "got index %i\n", indices[0]);
|
||||
ok(indices[0] == 7, "Unexpected glyph index, %u.\n", indices[0]);
|
||||
IDWriteFontFace_Release(face);
|
||||
IDWriteFontFile_Release(file);
|
||||
|
||||
|
@ -4420,6 +4420,18 @@ static void test_GetGlyphRunOutline(void)
|
|||
hr = IDWriteFontFace_GetGlyphRunOutline(face, 1024.0, glyphs, NULL, NULL, 0, FALSE, FALSE, &test_geomsink2);
|
||||
ok(hr == S_OK, "got 0x%08x\n", hr);
|
||||
|
||||
/* Glyph with open figure, single contour point. */
|
||||
codepoint = 'B';
|
||||
glyphs[0] = 0;
|
||||
hr = IDWriteFontFace_GetGlyphIndices(face, &codepoint, 1, glyphs);
|
||||
ok(hr == S_OK, "got 0x%08x\n", hr);
|
||||
ok(glyphs[0] > 0, "got %u\n", glyphs[0]);
|
||||
|
||||
SET_EXPECT(setfillmode);
|
||||
hr = IDWriteFontFace_GetGlyphRunOutline(face, 1024.0, glyphs, NULL, NULL, 1, FALSE, FALSE, &test_geomsink2);
|
||||
ok(hr == S_OK, "got 0x%08x\n", hr);
|
||||
CHECK_CALLED(setfillmode);
|
||||
|
||||
IDWriteFactory_Release(factory);
|
||||
IDWriteFontFace_Release(face);
|
||||
DELETE_FONTFILE(path);
|
||||
|
@ -4578,7 +4590,7 @@ static void test_GetGlyphCount(void)
|
|||
IDWriteFontFile_Release(file);
|
||||
|
||||
count = IDWriteFontFace_GetGlyphCount(fontface);
|
||||
ok(count == 7, "got %u\n", count);
|
||||
ok(count == 8, "got %u\n", count);
|
||||
|
||||
IDWriteFontFace_Release(fontface);
|
||||
ref = IDWriteFactory_Release(factory);
|
||||
|
|
|
@ -83,10 +83,10 @@ NameList: Adobe Glyph List
|
|||
DisplaySize: -24
|
||||
AntiAlias: 1
|
||||
FitToEm: 1
|
||||
WinInfo: 48 16 4
|
||||
WinInfo: 47 47 13
|
||||
BeginPrivate: 0
|
||||
EndPrivate
|
||||
BeginChars: 65539 7
|
||||
BeginChars: 65539 8
|
||||
|
||||
StartChar: .notdef
|
||||
Encoding: 65536 -1 0
|
||||
|
@ -207,7 +207,7 @@ StartChar: A
|
|||
Encoding: 65 65 5
|
||||
Width: 1000
|
||||
VWidth: 0
|
||||
Flags: WO
|
||||
Flags: W
|
||||
LayerCount: 2
|
||||
Fore
|
||||
SplineSet
|
||||
|
@ -226,7 +226,7 @@ StartChar: D
|
|||
Encoding: 68 68 6
|
||||
Width: 1000
|
||||
VWidth: 0
|
||||
Flags: WO
|
||||
Flags: W
|
||||
LayerCount: 2
|
||||
Fore
|
||||
SplineSet
|
||||
|
@ -240,5 +240,17 @@ SplineSet
|
|||
461 -30.7998 l 25,0,-1
|
||||
EndSplineSet
|
||||
EndChar
|
||||
|
||||
StartChar: B
|
||||
Encoding: 66 66 7
|
||||
Width: 2048
|
||||
VWidth: 0
|
||||
Flags: W
|
||||
LayerCount: 2
|
||||
Fore
|
||||
SplineSet
|
||||
500 500 m 24,0,-1
|
||||
EndSplineSet
|
||||
EndChar
|
||||
EndChars
|
||||
EndSplineFont
|
||||
|
|
Binary file not shown.
Loading…
Reference in New Issue