Nikolay Sivov : dwrite: Improve empty contours handling in GetGlyphRunOutline().
Alexandre Julliard
julliard at winehq.org
Fri Aug 25 12:30:11 CDT 2017
Module: wine
Branch: master
Commit: 1df4e64bbff142a613787fcab9d68d21b3055822
URL: http://source.winehq.org/git/wine.git/?a=commit;h=1df4e64bbff142a613787fcab9d68d21b3055822
Author: Nikolay Sivov <nsivov at codeweavers.com>
Date: Fri Aug 25 08:29:46 2017 +0300
dwrite: Improve empty contours handling in GetGlyphRunOutline().
Signed-off-by: Nikolay Sivov <nsivov at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>
---
dlls/dwrite/freetype.c | 57 ++++++++++++++++++++++------------------
dlls/dwrite/tests/font.c | 16 +++++++++--
dlls/dwrite/tests/wine_test.sfd | 20 +++++++++++---
dlls/dwrite/tests/wine_test.ttf | Bin 1776 -> 1812 bytes
4 files changed, 61 insertions(+), 32 deletions(-)
diff --git a/dlls/dwrite/freetype.c b/dlls/dwrite/freetype.c
index 934ca80..571fa24 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 417cc21..54dcc75 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 c985b43..e533323 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 1562a32..72dadf5 100644
Binary files a/dlls/dwrite/tests/wine_test.ttf and b/dlls/dwrite/tests/wine_test.ttf differ
More information about the wine-cvs
mailing list