From f8526eb25c0e1cfd97716b58c25543f124a77379 Mon Sep 17 00:00:00 2001 From: Corran Webster Date: Wed, 10 Aug 2022 08:41:11 +0100 Subject: [PATCH 1/6] Fix the rendering of polygons in basecore2d-based backends This: - consistently uses Nx2 numpy arrays to store path points - doesn't create a new subpath after a LINES function A driveby fix gives a default implementation for show_text_at_point(). --- kiva/basecore2d.py | 20 +++++++------------- 1 file changed, 7 insertions(+), 13 deletions(-) diff --git a/kiva/basecore2d.py b/kiva/basecore2d.py index 9c7ab1028..532506980 100644 --- a/kiva/basecore2d.py +++ b/kiva/basecore2d.py @@ -1054,7 +1054,7 @@ def show_glyphs(self): def show_text_at_point(self, text, x, y): """ """ - pass + self.show_text(text, (x, y)) def show_glyphs_at_point(self): """ @@ -1129,17 +1129,16 @@ def draw_path(self, mode=FILL_STROKE): for func, args in subpath: if func == POINT: self.draw_subpath(mode) - self.add_point_to_subpath(args) + self.add_point_to_subpath(args.reshape(1, 2)) self.first_point = args elif func == LINE: - self.add_point_to_subpath(args) + self.add_point_to_subpath(args.reshape(1, 2)) elif func == LINES: - self.draw_subpath(mode) # add all points in list to subpath. self.add_point_to_subpath(args) self.first_point = args[0] elif func == CLOSE: - self.add_point_to_subpath(self.first_point) + self.add_point_to_subpath(self.first_point.reshape(1, 2)) self.draw_subpath(mode) elif func == RECT: self.draw_subpath(mode) @@ -1149,7 +1148,7 @@ def draw_path(self, mode=FILL_STROKE): elif func in ctm_funcs: self.device_transform_device_ctm(func, args) else: - print("oops:", func) + raise RuntimeError(f"Unrecognised subpath term: {func}") # finally, draw any remaining paths. self.draw_subpath(mode) @@ -1244,13 +1243,8 @@ def get_subpath_points(self, debug=0): be an array. If this is true, the other points are converted to an array and concatenated with the first """ - if self.draw_points and len(shape(self.draw_points[0])) > 1: - first_points = self.draw_points[0] - other_points = asarray(self.draw_points[1:]) - if len(other_points): - pts = concatenate((first_points, other_points), 0) - else: - pts = first_points + if self.draw_points: + pts = np.vstack(self.draw_points) else: pts = asarray(self.draw_points) return pts From db167f881b6f98fe361cd413c0ba385d14972048 Mon Sep 17 00:00:00 2001 From: Corran Webster Date: Wed, 10 Aug 2022 08:57:26 +0100 Subject: [PATCH 2/6] Clean-up comments. --- kiva/basecore2d.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/kiva/basecore2d.py b/kiva/basecore2d.py index 532506980..e6f8bae2e 100644 --- a/kiva/basecore2d.py +++ b/kiva/basecore2d.py @@ -1236,16 +1236,16 @@ def add_point_to_subpath(self, pt): def clear_subpath_points(self): self.draw_points = [] - def get_subpath_points(self, debug=0): - """ Gets the points that are in the current path. + def get_subpath_points(self, debug=False): + """ Gets the points that are in the current subpath as an Nx2 array. - The first entry in the draw_points list may actually - be an array. If this is true, the other points are - converted to an array and concatenated with the first + The draw_points attribute holds the current set of points as a + list of Nx2 arrays. """ if self.draw_points: pts = np.vstack(self.draw_points) else: + # list is empty, convert to an empty array pts = asarray(self.draw_points) return pts From c8b7b229092ab3c931d0da744be8d33f6c95599e Mon Sep 17 00:00:00 2001 From: Corran Webster Date: Wed, 10 Aug 2022 15:07:34 +0100 Subject: [PATCH 3/6] Fix some unused imports. --- kiva/basecore2d.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/kiva/basecore2d.py b/kiva/basecore2d.py index e6f8bae2e..0b4381eb8 100644 --- a/kiva/basecore2d.py +++ b/kiva/basecore2d.py @@ -29,7 +29,7 @@ """ import numpy as np -from numpy import alltrue, array, asarray, concatenate, float64, pi, shape +from numpy import alltrue, array, asarray, float64, pi from .constants import ( CAP_BUTT, CAP_ROUND, CAP_SQUARE, CLOSE, CONCAT_CTM, EOF_FILL_STROKE, @@ -40,7 +40,7 @@ TRANSLATE_CTM, ) from .abstract_graphics_context import AbstractGraphicsContext -from .line_state import LineState, line_state_equal +from .line_state import LineState from .graphics_state import GraphicsState from .fonttools import Font import kiva.affine as affine From 228be7b03331c1b83420927492df1e10b22f91d4 Mon Sep 17 00:00:00 2001 From: Corran Webster Date: Wed, 10 Aug 2022 15:18:48 +0100 Subject: [PATCH 4/6] Some of the unused imports are in fact used. --- kiva/basecore2d.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kiva/basecore2d.py b/kiva/basecore2d.py index 0b4381eb8..d06ec655d 100644 --- a/kiva/basecore2d.py +++ b/kiva/basecore2d.py @@ -40,7 +40,7 @@ TRANSLATE_CTM, ) from .abstract_graphics_context import AbstractGraphicsContext -from .line_state import LineState +from .line_state import LineState, line_state_equal from .graphics_state import GraphicsState from .fonttools import Font import kiva.affine as affine From b8a010d9f6f4424486d7fad4d544dde20ccefff6 Mon Sep 17 00:00:00 2001 From: Corran Webster Date: Wed, 10 Aug 2022 15:22:24 +0100 Subject: [PATCH 5/6] Improve the situation of line_state_equal a bit. --- kiva/basecore2d.py | 2 +- kiva/tests/test_basecore2d.py | 11 ++++++----- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/kiva/basecore2d.py b/kiva/basecore2d.py index d06ec655d..9574ceba4 100644 --- a/kiva/basecore2d.py +++ b/kiva/basecore2d.py @@ -40,7 +40,7 @@ TRANSLATE_CTM, ) from .abstract_graphics_context import AbstractGraphicsContext -from .line_state import LineState, line_state_equal +from .line_state import LineState, line_state_equal # noqa: F401 from .graphics_state import GraphicsState from .fonttools import Font import kiva.affine as affine diff --git a/kiva/tests/test_basecore2d.py b/kiva/tests/test_basecore2d.py index f0525fc7a..2792ce2ea 100644 --- a/kiva/tests/test_basecore2d.py +++ b/kiva/tests/test_basecore2d.py @@ -24,6 +24,7 @@ from kiva import affine from kiva import basecore2d from kiva import constants +from kiva.line_state import line_state_equal class TestIsFullyTransparent(unittest.TestCase): @@ -70,31 +71,31 @@ def test_color_on_copy(self): ls1 = self.create_ls() ls2 = ls1.copy() ls1.line_color[1] = 10 - self.assertTrue(not basecore2d.line_state_equal(ls1, ls2)) + self.assertTrue(not line_state_equal(ls1, ls2)) def test_dash_on_copy(self): ls1 = self.create_ls() ls2 = ls1.copy() ls1.line_dash[1][0] = 10 - self.assertTrue(not basecore2d.line_state_equal(ls1, ls2)) + self.assertTrue(not line_state_equal(ls1, ls2)) def test_cmp_for_different_length_dash_patterns(self): ls1 = self.create_ls() ls2 = ls1.copy() ls1.line_dash = (ls1.line_dash[0], array([10, 10, 10, 10])) - self.assertTrue(not basecore2d.line_state_equal(ls1, ls2)) + self.assertTrue(not line_state_equal(ls1, ls2)) def test_cmp(self): ls1 = self.create_ls() ls2 = ls1.copy() - self.assertTrue(basecore2d.line_state_equal(ls1, ls2)) + self.assertTrue(line_state_equal(ls1, ls2)) # line_dash no longer allowed to be none. # def test_cmp_with_dash_as_none(self): # ls1 = self.create_ls() # ls2 = ls1.copy() # #ls1.line_dash = None - # assert(not basecore2d.line_state_equal(ls1,ls2)) + # assert(not line_state_equal(ls1,ls2)) class GraphicsContextTestCase(unittest.TestCase): From 5a6405ad972bf21d245389445a464e89c7695aee Mon Sep 17 00:00:00 2001 From: Corran Webster Date: Fri, 12 Aug 2022 09:55:13 +0100 Subject: [PATCH 6/6] Ensure all subpath arguments are numpy arrays. --- kiva/basecore2d.py | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/kiva/basecore2d.py b/kiva/basecore2d.py index 9574ceba4..109f5aedd 100644 --- a/kiva/basecore2d.py +++ b/kiva/basecore2d.py @@ -504,6 +504,8 @@ def line_set(self, starts, ends): Starts and ends should have the same length. The current point is moved to the last point in 'ends'. """ + starts = asarray(starts) + ends = asarray(ends) self._new_subpath() for i in range(min(len(starts), len(ends))): self.active_subpath.append((POINT, starts[i])) @@ -1138,8 +1140,11 @@ def draw_path(self, mode=FILL_STROKE): self.add_point_to_subpath(args) self.first_point = args[0] elif func == CLOSE: - self.add_point_to_subpath(self.first_point.reshape(1, 2)) - self.draw_subpath(mode) + if self.first_point is not None: + self.add_point_to_subpath( + self.first_point.reshape(1, 2) + ) + self.draw_subpath(mode) elif func == RECT: self.draw_subpath(mode) self.device_draw_rect( @@ -1235,6 +1240,7 @@ def add_point_to_subpath(self, pt): def clear_subpath_points(self): self.draw_points = [] + self.first_point = None def get_subpath_points(self, debug=False): """ Gets the points that are in the current subpath as an Nx2 array.