From 6ece1309d322f43a7f7a38bfbc699216be903030 Mon Sep 17 00:00:00 2001 From: Antoine Beyeler Date: Sun, 16 Jan 2022 12:08:48 +0100 Subject: [PATCH] Fixed inconsistent default color in `vp.write_svg()`. The default color (from the default color scheme) for a layer would depend on whether previous layer would have their color specified on not. This is an inconsistent behaviour in itself, and it is inconsistent with the viewer's behaviour. Also, the default color scheme as been moved to vpype/metadata.py. --- CHANGELOG.md | 2 +- vpype/io.py | 24 +++++++++++------------- vpype/metadata.py | 12 ++++++++++++ vpype_viewer/engine.py | 15 +++------------ 4 files changed, 27 insertions(+), 26 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0298f74c..f72ec16b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,7 +9,7 @@ New features and improvements: This feature is intended as a generic mechanism whereby a set of properties may be attached to specific layers (layer property) or all of them (global property). Properties are identified by a name and may be of arbitrary type (e.g. integer, floating point, color, etc.). This new infrastructure is used by several of the features introduced in this release, paves the way for future features, and further empowers plug-in writers. See the [documentation](https://vpype.readthedocs.io/en/latest/metadata) for more background information on metadata. -* Layer color, pen width, and name are now customizable (#359) +* Layer color, pen width, and name are now customizable (#359, #376) * The `read` commands now sets layer color, pen width, and name based on the input SVG if possible. * The new `color`, `penwdith`, and `name` commands can be used to modify layer color, pen width, and name. * The new `pens` command can apply a predefined or custom scheme on multiple layers at once. Two schemes, `rgb` and `cmyk`, are included and others may be defined in the configuration file. diff --git a/vpype/io.py b/vpype/io.py index af501c4e..c441ffec 100644 --- a/vpype/io.py +++ b/vpype/io.py @@ -18,6 +18,7 @@ from .config import PaperConfig, PlotterConfig, config_manager from .metadata import ( + METADATA_DEFAULT_COLOR_SCHEME, METADATA_FIELD_COLOR, METADATA_FIELD_NAME, METADATA_FIELD_PEN_WIDTH, @@ -31,17 +32,6 @@ __all__ = ["read_svg", "read_multilayer_svg", "write_svg", "write_hpgl"] -_COLORS = [ - "#00f", - "#080", - "#f00", - "#0cc", - "#0f0", - "#c0c", - "#cc0", - "black", -] - _DEFAULT_WIDTH = 1000 _DEFAULT_HEIGHT = 1000 @@ -583,10 +573,16 @@ def write_svg( if color_mode == "layer" or ( color_mode == "default" and not layer.property_exists(METADATA_FIELD_COLOR) ): - group.attribs["stroke"] = _COLORS[color_idx % len(_COLORS)] + group.attribs["stroke"] = METADATA_DEFAULT_COLOR_SCHEME[ + color_idx % len(METADATA_DEFAULT_COLOR_SCHEME) + ] color_idx += 1 elif color_mode == "default": group.attribs["stroke"] = str(layer.property(METADATA_FIELD_COLOR)) + + # we want to avoid a subsequent layer whose color is undefined to have its color + # affected by whether or not previous layer have their color defined + color_idx += 1 elif color_mode == "none": group.attribs["stroke"] = "black" group.attribs["style"] = "display:inline" @@ -612,7 +608,9 @@ def write_svg( path = dwg.polyline((c.real, c.imag) for c in line) if color_mode == "path": - path.attribs["stroke"] = _COLORS[color_idx % len(_COLORS)] + path.attribs["stroke"] = METADATA_DEFAULT_COLOR_SCHEME[ + color_idx % len(METADATA_DEFAULT_COLOR_SCHEME) + ] color_idx += 1 group.add(path) diff --git a/vpype/metadata.py b/vpype/metadata.py index d8829676..42f7f208 100644 --- a/vpype/metadata.py +++ b/vpype/metadata.py @@ -147,3 +147,15 @@ def __str__(self) -> str: "stroke-width", "text-rendering", } + + +METADATA_DEFAULT_COLOR_SCHEME = [ + Color("#00f"), + Color("#080"), + Color("#f00"), + Color("#0cc"), + Color("#0f0"), + Color("#c0c"), + Color("#cc0"), + Color("black"), +] diff --git a/vpype_viewer/engine.py b/vpype_viewer/engine.py index 5b7a3295..8bed0020 100644 --- a/vpype_viewer/engine.py +++ b/vpype_viewer/engine.py @@ -23,17 +23,6 @@ from ._scales import DEFAULT_SCALE_SPEC, SCALES_MAP, ScaleSpec, UnitType from ._utils import ColorType, orthogonal_projection_matrix -_COLORS: List[ColorType] = [ - (0, 0, 1, 1), - (0, 0.5, 0, 1), - (1, 0, 0, 1), - (0, 0.75, 0.75, 1), - (0, 1, 0, 1), - (0.75, 0, 0.75, 1), - (0.75, 0.75, 0, 1), - (0, 0, 0, 1), -] - __all__ = ["DEFAULT_PEN_WIDTH", "DEFAULT_PEN_OPACITY", "ViewMode", "Engine"] DEFAULT_PEN_WIDTH = 1.1 # about 0.3mm @@ -426,7 +415,9 @@ def _rebuild(self): if self._document is not None: color_index = 0 for layer_id in sorted(self._document.layers): - layer_color: ColorType = _COLORS[color_index % len(_COLORS)] + layer_color: ColorType = vp.METADATA_DEFAULT_COLOR_SCHEME[ + color_index % len(vp.METADATA_DEFAULT_COLOR_SCHEME) + ].as_floats() color_index += 1 lc = self._document.layers[layer_id]