tools: Add more commands to gtk4-path-tool
Add stroking and offsetting.
This commit is contained in:
@@ -12,6 +12,8 @@ SYNOPSIS
|
||||
--------
|
||||
| **gtk4-path-tool** <COMMAND> [OPTIONS...] <PATH>
|
||||
|
|
||||
| **gtk4-path-tool** stroke [OPTIONS...] <PATH>
|
||||
| **gtk4-path-tool** offset [OPTIONS...] <PATH>
|
||||
| **gtk4-path-tool** decompose [OPTIONS...] <PATH>
|
||||
| **gtk4-path-tool** transform [OPTIONS...] <PATH>
|
||||
| **gtk4-path-tool** reverse [OPTIONS...] <PATH>
|
||||
@@ -32,6 +34,70 @@ To read a path from stdin, use '-'.
|
||||
COMMANDS
|
||||
--------
|
||||
|
||||
Stroking
|
||||
^^^^^^^^
|
||||
|
||||
The ``stroke`` command performs a stroke operation along the path according to
|
||||
the parameters specified via options.
|
||||
|
||||
``--line-width=VALUE``
|
||||
|
||||
The line width to use for the stroke. ``VALUE`` must be a positive number.
|
||||
The default line width is 1.
|
||||
|
||||
``--line-cap=VALUE``
|
||||
|
||||
The cap style to use at line ends. The possible values are ``butt``, ``round``
|
||||
or ``square``. See the SVG specification for details on these styles.
|
||||
The default cap style is ``butt``.
|
||||
|
||||
``--line-join=VALUE``
|
||||
|
||||
The join style to use at line joins. The possible values are ``miter``,
|
||||
``miter-clip``, ``round``, ``bevel`` or ``arcs``. See the SVG specification
|
||||
for details on these styles.
|
||||
The default join style is ``miter``.
|
||||
|
||||
``--miter-limit=VALUE``
|
||||
|
||||
The limit at which to clip miters at line joins. The default value is 4.
|
||||
|
||||
``--dashes=VALUE``
|
||||
|
||||
The dash pattern to use for this stroke. A dash pattern is specified by
|
||||
a comma-separated list of alternating non-negative numbers. Each number
|
||||
provides the length of alternate "on" and "off" portions of the stroke.
|
||||
If the dash pattern is empty, dashing is disabled, which is the default.
|
||||
See the SVG specification for details on dashing.
|
||||
|
||||
``--dash-offset=VALUE``
|
||||
|
||||
The offset into the dash pattern where dashing should begin.
|
||||
The default value is 0.
|
||||
|
||||
Offsetting
|
||||
^^^^^^^^^^
|
||||
|
||||
The ``offset`` command applies a lateral offset to the path. Note that this
|
||||
is different from applying a translation transformation.
|
||||
|
||||
``--distance=VALUE``
|
||||
|
||||
The distance by which to offset the path. Positive values offset to the right,
|
||||
negative values to the left (wrt to the direction of the path). The default
|
||||
value is 0.
|
||||
|
||||
``--line-join=VALUE``
|
||||
|
||||
The join style to use at line joins. The possible values are ``miter``,
|
||||
``miter-clip``, ``round``, ``bevel`` or ``arcs``. See the SVG specification
|
||||
for details on these styles.
|
||||
The default join style is ``miter``.
|
||||
|
||||
``--miter-limit=VALUE``
|
||||
|
||||
The limit at which to clip miters at line joins. The default value is 4.
|
||||
|
||||
Decomposing
|
||||
^^^^^^^^^^^
|
||||
|
||||
@@ -132,7 +198,7 @@ Info
|
||||
^^^^
|
||||
|
||||
The ``info`` command shows various information about the given path,
|
||||
such as its bounding box and and its length.
|
||||
such as the number of contours, its bounding box and and its length.
|
||||
|
||||
REFERENCES
|
||||
----------
|
||||
|
||||
85
tools/gtk-path-tool-offset.c
Normal file
85
tools/gtk-path-tool-offset.c
Normal file
@@ -0,0 +1,85 @@
|
||||
/* Copyright 2023 Red Hat, Inc.
|
||||
*
|
||||
* GTK+ 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 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* GLib 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 GTK+; see the file COPYING. If not,
|
||||
* see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Author: Matthias Clasen
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
#include "gtk-path-tool.h"
|
||||
|
||||
#include <glib/gi18n-lib.h>
|
||||
|
||||
void
|
||||
do_offset (int *argc, const char ***argv)
|
||||
{
|
||||
GError *error = NULL;
|
||||
double distance = 0;
|
||||
const char *join = "miter";
|
||||
double miter_limit = 4;
|
||||
char **args = NULL;
|
||||
GOptionContext *context;
|
||||
GOptionEntry entries[] = {
|
||||
{ "distance", 0, 0, G_OPTION_ARG_DOUBLE, &distance, N_("Offset to apply (positive or negative number)"), N_("VALUE") },
|
||||
{ "line-join", 0, 0, G_OPTION_ARG_STRING, &join, N_("Line join (miter, miter-clip, round, bevel, arcs)"), N_("VALUE") },
|
||||
{ "miter-limit", 0, 0, G_OPTION_ARG_DOUBLE, &miter_limit, N_("Miter limit (number"), N_("VALUE") },
|
||||
{ G_OPTION_REMAINING, 0, 0, G_OPTION_ARG_FILENAME_ARRAY, &args, NULL, N_("PATH") },
|
||||
{ NULL, },
|
||||
};
|
||||
GskPath *path, *result;
|
||||
GskLineJoin line_join;
|
||||
|
||||
g_set_prgname ("gtk4-path-tool offset");
|
||||
|
||||
context = g_option_context_new (NULL);
|
||||
g_option_context_set_translation_domain (context, GETTEXT_PACKAGE);
|
||||
g_option_context_add_main_entries (context, entries, NULL);
|
||||
g_option_context_set_summary (context, _("Offset a path."));
|
||||
|
||||
if (!g_option_context_parse (context, argc, (char ***)argv, &error))
|
||||
{
|
||||
g_printerr ("%s\n", error->message);
|
||||
g_error_free (error);
|
||||
exit (1);
|
||||
}
|
||||
|
||||
g_option_context_free (context);
|
||||
|
||||
if (args == NULL)
|
||||
{
|
||||
g_printerr ("%s\n", _("No paths given."));
|
||||
exit (1);
|
||||
}
|
||||
|
||||
path = get_path (args[0]);
|
||||
|
||||
line_join = get_enum_value (GSK_TYPE_LINE_JOIN, _("line join"), join);
|
||||
|
||||
result = gsk_path_offset (path, distance, line_join, miter_limit);
|
||||
|
||||
if (result)
|
||||
{
|
||||
char *str = gsk_path_to_string (result);
|
||||
g_print ("%s\n", str);
|
||||
g_free (str);
|
||||
}
|
||||
else
|
||||
{
|
||||
g_printerr ("%s\n", _("That didn't work out."));
|
||||
exit (1);
|
||||
}
|
||||
}
|
||||
134
tools/gtk-path-tool-stroke.c
Normal file
134
tools/gtk-path-tool-stroke.c
Normal file
@@ -0,0 +1,134 @@
|
||||
/* Copyright 2023 Red Hat, Inc.
|
||||
*
|
||||
* GTK+ 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 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* GLib 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 GTK+; see the file COPYING. If not,
|
||||
* see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Author: Matthias Clasen
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
#include "gtk-path-tool.h"
|
||||
|
||||
#include <glib/gi18n-lib.h>
|
||||
|
||||
void
|
||||
do_stroke (int *argc, const char ***argv)
|
||||
{
|
||||
GError *error = NULL;
|
||||
double line_width = 1;
|
||||
const char *cap = "butt";
|
||||
const char *join = "miter";
|
||||
double miter_limit = 4;
|
||||
const char *dashes = NULL;
|
||||
double dash_offset = 0;
|
||||
char **args = NULL;
|
||||
GOptionContext *context;
|
||||
GOptionEntry entries[] = {
|
||||
{ "line-width", 0, 0, G_OPTION_ARG_DOUBLE, &line_width, N_("Line width (number)"), N_("VALUE") },
|
||||
{ "line-cap", 0, 0, G_OPTION_ARG_STRING, &cap, N_("Line cap (butt, round, square)"), N_("VALUE") },
|
||||
{ "line-join", 0, 0, G_OPTION_ARG_STRING, &join, N_("Line join (miter, miter-clip, round, bevel, arcs)"), N_("VALUE") },
|
||||
{ "miter-limit", 0, 0, G_OPTION_ARG_DOUBLE, &miter_limit, N_("Miter limit (number)"), N_("VALUE") },
|
||||
{ "dashes", 0, 0, G_OPTION_ARG_STRING, &dashes, N_("Dash pattern (comma-separated numbers)"), N_("VALUE") },
|
||||
{ "dash-offset", 0, 0, G_OPTION_ARG_DOUBLE, &dash_offset, N_("Dash offset (number)"), N_("VALUE") },
|
||||
{ G_OPTION_REMAINING, 0, 0, G_OPTION_ARG_FILENAME_ARRAY, &args, NULL, N_("PATH") },
|
||||
{ NULL, },
|
||||
};
|
||||
GskPath *path, *result;
|
||||
GskLineCap line_cap;
|
||||
GskLineJoin line_join;
|
||||
GskStroke *stroke;
|
||||
|
||||
g_set_prgname ("gtk4-path-tool stroke");
|
||||
|
||||
context = g_option_context_new (NULL);
|
||||
g_option_context_set_translation_domain (context, GETTEXT_PACKAGE);
|
||||
g_option_context_add_main_entries (context, entries, NULL);
|
||||
g_option_context_set_summary (context, _("Stroke a path."));
|
||||
|
||||
if (!g_option_context_parse (context, argc, (char ***)argv, &error))
|
||||
{
|
||||
g_printerr ("%s\n", error->message);
|
||||
g_error_free (error);
|
||||
exit (1);
|
||||
}
|
||||
|
||||
g_option_context_free (context);
|
||||
|
||||
if (args == NULL)
|
||||
{
|
||||
g_printerr (_("No paths given.\n"));
|
||||
exit (1);
|
||||
}
|
||||
|
||||
path = get_path (args[0]);
|
||||
|
||||
line_cap = get_enum_value (GSK_TYPE_LINE_CAP, _("line cap"), cap);
|
||||
line_join = get_enum_value (GSK_TYPE_LINE_JOIN, _("line join"), join);
|
||||
|
||||
stroke = gsk_stroke_new (line_width);
|
||||
gsk_stroke_set_line_cap (stroke, line_cap);
|
||||
gsk_stroke_set_line_join (stroke, line_join);
|
||||
|
||||
gsk_stroke_set_miter_limit (stroke, miter_limit);
|
||||
|
||||
if (dashes != NULL)
|
||||
{
|
||||
GArray *d = g_array_new (FALSE, FALSE, sizeof (float));
|
||||
char **strings;
|
||||
|
||||
strings = g_strsplit (dashes, ",", 0);
|
||||
|
||||
for (unsigned int i = 0; strings[i]; i++)
|
||||
{
|
||||
char *end = NULL;
|
||||
float f;
|
||||
|
||||
f = (float) g_ascii_strtod (strings[i], &end);
|
||||
|
||||
if (*end != '\0')
|
||||
{
|
||||
char *msg = g_strdup_printf (_("Failed to parse '%s' as number"), strings[i]);
|
||||
g_printerr ("%s\n", msg);
|
||||
exit (1);
|
||||
}
|
||||
|
||||
g_array_append_val (d, f);
|
||||
}
|
||||
|
||||
g_strfreev (strings);
|
||||
|
||||
gsk_stroke_set_dash (stroke, (const float *)d->data, d->len);
|
||||
|
||||
g_array_unref (d);
|
||||
}
|
||||
|
||||
gsk_stroke_set_dash_offset (stroke, dash_offset);
|
||||
|
||||
result = gsk_path_stroke (path, stroke);
|
||||
gsk_stroke_free (stroke);
|
||||
|
||||
if (result)
|
||||
{
|
||||
char *str = gsk_path_to_string (result);
|
||||
g_print ("%s\n", str);
|
||||
g_free (str);
|
||||
}
|
||||
else
|
||||
{
|
||||
g_printerr ("%s\n", _("That didn't work out."));
|
||||
exit (1);
|
||||
}
|
||||
}
|
||||
@@ -38,6 +38,8 @@ usage (void)
|
||||
"Perform various tasks on paths.\n"
|
||||
"\n"
|
||||
"Commands:\n"
|
||||
" stroke Stroke the path\n"
|
||||
" offset Offset the path\n"
|
||||
" decompose Decompose the path\n"
|
||||
" transform Transform the path\n"
|
||||
" reverse Reverse the path\n"
|
||||
@@ -131,6 +133,8 @@ main (int argc, const char *argv[])
|
||||
do_decompose (&argc, &argv);
|
||||
else if (strcmp (argv[0], "info") == 0)
|
||||
do_info (&argc, &argv);
|
||||
else if (strcmp (argv[0], "offset") == 0)
|
||||
do_offset (&argc, &argv);
|
||||
else if (strcmp (argv[0], "render") == 0)
|
||||
do_render (&argc, &argv);
|
||||
else if (strcmp (argv[0], "restrict") == 0)
|
||||
@@ -139,6 +143,8 @@ main (int argc, const char *argv[])
|
||||
do_reverse (&argc, &argv);
|
||||
else if (strcmp (argv[0], "show") == 0)
|
||||
do_show (&argc, &argv);
|
||||
else if (strcmp (argv[0], "stroke") == 0)
|
||||
do_stroke (&argc, &argv);
|
||||
else if (strcmp (argv[0], "transform") == 0)
|
||||
do_transform (&argc, &argv);
|
||||
else
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
#pragma once
|
||||
|
||||
void do_info (int *argc, const char ***argv);
|
||||
void do_stroke (int *argc, const char ***argv);
|
||||
void do_offset (int *argc, const char ***argv);
|
||||
void do_decompose (int *argc, const char ***argv);
|
||||
void do_transform (int *argc, const char ***argv);
|
||||
void do_reverse (int *argc, const char ***argv);
|
||||
|
||||
@@ -26,10 +26,12 @@ gtk_tools = [
|
||||
['gtk4-path-tool', ['gtk-path-tool.c',
|
||||
'gtk-path-tool-decompose.c',
|
||||
'gtk-path-tool-info.c',
|
||||
'gtk-path-tool-offset.c',
|
||||
'gtk-path-tool-render.c',
|
||||
'gtk-path-tool-restrict.c',
|
||||
'gtk-path-tool-reverse.c',
|
||||
'gtk-path-tool-show.c',
|
||||
'gtk-path-tool-stroke.c',
|
||||
'gtk-path-tool-transform.c',
|
||||
'gtk-path-tool-utils.c',
|
||||
'path-view.c'], [libgtk_dep]],
|
||||
|
||||
Reference in New Issue
Block a user