Implement stroking

Implement gsk_contour_default_add_stroke, which takes a contour
and stroke parameters, and adds contours to a path builder for
the outline that woul be produced by stroking the path with these
parameters.

The current implementation does not try to handle short segments
in the vicinity of sharp joins in any special way, so there can
be some artifacts in that situation.
This commit is contained in:
Matthias Clasen
2020-11-27 14:05:25 -05:00
parent bd5f4bcea9
commit 7f62eba270
7 changed files with 1227 additions and 1 deletions

View File

@@ -527,6 +527,8 @@ gsk_rect_contour_add_stroke (const GskContour *contour,
rect.size.width = - rect.size.width;
gsk_path_builder_add_rect (builder, &rect);
}
else
gsk_contour_default_add_stroke (contour, builder, stroke);
}
static const GskContourClass GSK_RECT_CONTOUR_CLASS =
@@ -922,6 +924,8 @@ gsk_circle_contour_add_stroke (const GskContour *contour,
self->start_angle);
gsk_path_builder_add_contour (builder, c);
}
else
gsk_contour_default_add_stroke (contour, builder, stroke);
}
static const GskContourClass GSK_CIRCLE_CONTOUR_CLASS =
@@ -1634,6 +1638,7 @@ gsk_standard_contour_add_stroke (const GskContour *contour,
GskPathBuilder *builder,
GskStroke *stroke)
{
gsk_contour_default_add_stroke (contour, builder, stroke);
}
static const GskContourClass GSK_STANDARD_CONTOUR_CLASS =

View File

@@ -24,6 +24,10 @@
#include "gskcurveprivate.h"
#include "gskpathbuilder.h"
#include "gskstrokeprivate.h"
#include "gdk/gdk-private.h"
/**
* SECTION:gskpath
* @Title: Path

View File

@@ -20,6 +20,7 @@
#include "config.h"
#include "gskpathmeasure.h"
#include "gskpathbuilder.h"
#include "gskpathbuilder.h"
#include "gskpathprivate.h"
@@ -625,4 +626,3 @@ gsk_path_builder_add_segment (GskPathBuilder *self,
gsk_path_builder_close (self);
}
}

1148
gsk/gskpathstroke.c Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -28,6 +28,7 @@ gsk_public_sources = files([
'gskpathbuilder.c',
'gskpathdash.c',
'gskpathmeasure.c',
'gskpathstroke.c',
'gskrenderer.c',
'gskrendernode.c',
'gskrendernodeimpl.c',

View File

@@ -199,6 +199,7 @@ tests = [
['curve-performance', ['../../gsk/gskcurve.c', '../../gsk/gskcurveintersect.c'], ['-DGTK_COMPILATION']],
['path'],
['path-special-cases'],
['path-stroke'],
['rounded-rect'],
['transform'],
['shader'],

View File

@@ -0,0 +1,67 @@
/*
* Copyright © 2020 Red Hat, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*
* Authors: Matthias Clasen <mclasen@redhat.com>
*/
#include <gtk/gtk.h>
/* Test that single-point contours don't crash the stroker */
static void
test_point_to_stroke (void)
{
GskPathBuilder *builder;
GskPath *path;
GskStroke *stroke;
GskPath *path1;
char *string;
builder = gsk_path_builder_new ();
gsk_path_builder_move_to (builder, 100, 100);
gsk_path_builder_curve_to (builder, 190, 110,
200, 120,
210, 210);
gsk_path_builder_curve_to (builder, 220, 210,
230, 200,
230, 100);
gsk_path_builder_move_to (builder, 200, 200);
path = gsk_path_builder_free_to_path (builder);
string = gsk_path_to_string (path);
g_assert_cmpstr (string, ==, "M 100 100 C 190 110, 200 120, 210 210 C 220 210, 230 200, 230 100 M 200 200");
g_free (string);
stroke = gsk_stroke_new (20.f);
path1 = gsk_path_stroke (path, stroke);
gsk_stroke_free (stroke);
g_assert_nonnull (path1);
gsk_path_unref (path1);
gsk_path_unref (path);
}
int
main (int argc,
char *argv[])
{
gtk_test_init (&argc, &argv, NULL);
g_test_add_func ("/path/point_to_stroke", test_point_to_stroke);
return g_test_run ();
}