diff --git a/dlls/dwrite/freetype.c b/dlls/dwrite/freetype.c index 934ca80a51d..571fa24c336 100644 --- a/dlls/dwrite/freetype.c +++ b/dlls/dwrite/freetype.c @@ -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; - 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; + 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->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); } diff --git a/dlls/dwrite/tests/font.c b/dlls/dwrite/tests/font.c index 417cc21aa21..54dcc75c81f 100644 --- a/dlls/dwrite/tests/font.c +++ b/dlls/dwrite/tests/font.c @@ -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); diff --git a/dlls/dwrite/tests/wine_test.sfd b/dlls/dwrite/tests/wine_test.sfd index c985b433d66..e533323db75 100644 --- a/dlls/dwrite/tests/wine_test.sfd +++ b/dlls/dwrite/tests/wine_test.sfd @@ -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 diff --git a/dlls/dwrite/tests/wine_test.ttf b/dlls/dwrite/tests/wine_test.ttf index 1562a326ac7..72dadf5d543 100644 Binary files a/dlls/dwrite/tests/wine_test.ttf and b/dlls/dwrite/tests/wine_test.ttf differ