コード例 #1
0
    def coalesce_points(path: ICurveCollection):
        """
        gathers all small steps and stores them as floats in "change"
        if one of coordinates (or both) changes more than by one after some number of points,
        new shift point is generated conserving leftover step that are smaller than 1
        """

        for curve in path.get_curves():
            curve_points = curve.components
            new_curve_points = []

            change: Point = curve.start
            curve.start = Point(round(change.x), round(change.y))
            change -= curve.start

            i = 0
            while i < len(curve_points):
                while change.in_range(-1, 1) and i < len(curve_points):
                    change.shift_inplace(curve_points[i])
                    i += 1

                new_point = Point(round(change.x), round(change.y))

                # conserve all changes that are less than integer value
                change -= new_point
                new_curve_points.append(new_point)

            # replace all elements of shifts list with new shifts
            curve.components.clear()
            curve.components.extend(new_curve_points)
コード例 #2
0
 def init_path():
     return HandwrittenPath(curves=[
         Curve([Point(1, 1), Point(1, 1),
                Point(1, 1)]),
         Curve(start=Point(10, 10)),
         Curve([Point(1, 1)])
     ])
コード例 #3
0
    def write_text(self, text_input: str) -> PathsCollection:
        text_path = PathsCollection()

        self.dict_transformer.scale(0.5, 0.5)
        transformed_dict = self.dict_transformer.get_result()

        letter_size: list = transformed_dict.get_max_letter_size()
        cur_write_position = Point(0, self.line_height)

        for letter_index, char in enumerate(text_input):
            try:
                char_variants = transformed_dict[char]
                char_path = char_variants[0]

                boxed_path = PathShiftBox(char_path)
                boxed_path.extend_height(letter_size[1])
                boxed_path.set_position(cur_write_position)

                text_path.append(boxed_path)
                cur_write_position.x += boxed_path.box.get_size_x()
            except ObjectNotFound:
                if char == '\n':
                    self.current_line += 1
                    cur_write_position = Point(0, self.current_line * self.line_height)
                elif char == ' ':
                    cur_write_position.x += self.space_size
                else:
                    raise ObjectNotFound(f"'{repr(char)}' not found in dictionary")

        return text_path
コード例 #4
0
    def new_curve(self, start: Point, previous: Point = None):
        previous = previous if previous is not None else Point(0, 0)
        curve_shift = start.get_shift(previous)

        curve = Curve(start=curve_shift)
        curve.last_absolute_point = start  # must be assigned to continue adding points to curve

        self.components.append(curve)
コード例 #5
0
 def handle_motion_draw(self, event):
     if self.path_drawer.try_draw():
         if self._mouse_released:
             self._mouse_released = False
             self.path_drawer.start_curve(Point(event.x, event.y))
         else:
             self.path_drawer.continue_curve(Point(event.x, event.y))
     else:
         messagebox.showinfo("Warning", self.message_warning_cannot_draw)
コード例 #6
0
 def init_path_plus_5():
     return HandwrittenPath(curves=[
         Curve([
             Point(1, 0),
             Point(1, 0),
             Point(1, 0),
             Point(1, 0),
             Point(1, 0)
         ])
     ])
コード例 #7
0
    def test_draw_multiple_anchors(self):
        self.app.page_iterator.get_page().lines_points = [[
            Point(100, 150), Point(120, 80),
            Point(116, 90)
        ]]
        self.app.handle_edit_page_points()

        self.app.mouse_position = Point(128, 128)
        self.assertEqual(
            self.app.mouse_position,
            self.app.page_iterator.anchor_manager.get_current_point())
コード例 #8
0
    def test_create_new_curve_from_iterator(self):
        self.get_lines(self.path_iter)
        self.path_iter._new_curve(Point(50, 50))
        self.path_iter.append_absolute(Point(55, 55))
        self.path_iter.append_absolute(Point(60, 80))
        self.path_iter.append_absolute(Point(65, 85))

        lines = self.get_lines(self.path_iter)
        self.assertListEqual(lines, [
                                 (Point(50, 50), Point(55, 55)),
                                 (Point(55, 55), Point(60, 80)),
                                 (Point(60, 80), Point(65, 85))
                             ])
コード例 #9
0
    def test_path_with_shift_to_bytes(self):
        self.path.set_position(Point(10, 10))
        a = copy.deepcopy(self.path)
        bt = a.get_bytes()

        b = HandwrittenPath.read_next(io.BytesIO(bt))
        self.assertEqual(a, b)
コード例 #10
0
    def test_empty_path_filled(self):
        path = HandwrittenPath()

        itr = path.get_lines()

        itr._new_curve(Point(50, 50))
        itr.append_absolute(Point(55, 55))
        itr.append_absolute(Point(60, 80))
        itr.append_absolute(Point(65, 85))

        lines = self.get_lines(itr)
        self.assertListEqual(lines, [
            (Point(50, 50), Point(55, 55)),
            (Point(55, 55), Point(60, 80)),
            (Point(60, 80), Point(65, 85))
        ])
コード例 #11
0
    def test_anchor_draw(self):

        self.app.mouse_position = Point(128, 128)
        self.app.handle_edit_page_points()
        self.assertEqual(
            self.app.mouse_position,
            self.app.page_iterator.anchor_manager.get_current_point())
コード例 #12
0
    def test_space_written(self):
        test_text = 'a a'

        writer = PathTextWriter(self.page, self.dictionary)
        writer.set_space_size(5)
        text_path_iter = iter(writer.write_text(test_text))

        self.path_group_a[0].set_position(Point(0, 0))
        last_point = self.path_group_a[0].get_last_point()

        self.check_iterator_continues_with_other(text_path_iter,
                                                 iter(self.path_group_a[0]))

        a_iter_shifted = self.path_group_a[0].get_lines(
            last_point.shift(Point(5, 0)))
        self.check_iterator_continues_with_other(text_path_iter,
                                                 a_iter_shifted)
コード例 #13
0
    def __init__(self, display: CanvasDisplay, page: Page):
        self.display = DisplayDrawHistory(display)
        self.page = page
        self.point_draw_objects: Dict[Point, DrawTransaction] = {}
        self.temp_point = Point(0, 0)

        self.points_iterator = CyclicIterator(
            self.page.get_line_transform().anchors)
        # must be called to init iterators. or else will not work!
        self.reset_iterator()
コード例 #14
0
    def redraw(self):

        try:
            self.reset()
            current_path = self.dictionary_manager.iterator.get_variant_or_raise(
            )

            # place path at (0, 0) and shift according to entered shift point
            current_path.set_position(Point(0, 0))
            self.path_lines_iterator = current_path.get_lines(self.shift_point)
            self.draw_lines_to_end(self.path_lines_iterator)
        except ObjectNotFound:
            pass
コード例 #15
0
    def __init__(self, path: ICurveCollection):
        """
        Parameters
        ----------
        path        iterable path
        box_size    collection of two numbers (width, height)
        """
        self.box_position: Point = Point(0, 0)
        self.path = path

        self.box = self.get_lines_box(self.path.get_lines())
        self.box_size = self.box.get_size()
        self.rectangle_shift: Point = self.get_rectangle_shift(self.box)
コード例 #16
0
    def get_rectangle_shift(cls, box: Box) -> Point:
        """
        Rectangle will be aligned to bottom left corner
        top left corner is (0, 0)
        y axis is inverted

        path_box: contains box from function get_path_box()
        """
        shift = Point(0, 0)
        # displacement from start to left border
        shift.x -= box.min_x
        # desired box height minus displacement down from beginning
        shift.y += box.get_size_y() - box.max_y

        return shift
コード例 #17
0
    def __init__(self, root):
        tk.Frame.__init__(self, root)
        self.parent = root
        self.parent.title("Handwriting manager")

        self._mouse_released = True
        grid_width = 15

        # dict_manager of path groups with default value
        self.dictionary_manager = DictionaryManager()

        self.canvas = tk.Canvas(root, width=500, height=450, bg="white")
        display = CanvasDisplay(self.canvas)
        self.path_drawer = PathDrawer(self.dictionary_manager, display)

        self.point_entry = PointEntry(root, grid_width)
        self.point_entry.set(Point(100, 100))

        self.path_drawer.set_global_shift(self.point_entry.get_point())

        self.path_cursor = PathCursorWidget(root, grid_width, self.path_drawer)
        self.path_cursor.update_menu_labels()

        self.dictionary_opener = DictionaryOpenerWidget(root,
                                                        grid_width,
                                                        self.dictionary_manager,
                                                        self.path_drawer.redraw,
                                                        self.path_cursor.update_menus)

        self.dictionary_editor = DictionaryEditorWidget(root,
                                                        grid_width,
                                                        self.dictionary_manager,
                                                        self.path_cursor.update_menus,
                                                        self.path_drawer.redraw)

        put_objects_on_grid(self, [
            [tk.Label(root, text="Base shift: "), self.point_entry],
            [(self.dictionary_opener, {"columnspan": 2})],
            [(self.path_cursor, {"columnspan": 2})],
            [(self.dictionary_editor, {"columnspan": 2})],
            [(self.canvas, {"columnspan": 2})],
        ])

        self.bind_handlers(self.create_events_dict())
コード例 #18
0
 def init_absolute_points():
     return [
         Point(*elem) for elem in [(15, 15), (20, 15), (30, 40), (80, 60)]
     ]
コード例 #19
0
 def setUp(self) -> None:
     self.path = HandwrittenPath()
     self.path.new_curve(Point(20, 20))
     self.path.append_absolute(Point(25, 30))  # (+5, +10)
     self.path.append_absolute(Point(28, 28))  # (+3, -2)
コード例 #20
0
 def test_get_rectangle_shift(self):
     box = PathShiftBox.get_lines_box(self.path.get_lines())
     shift = PathShiftBox.get_rectangle_shift(box, (50, 50))
     self.assertEqual(Point(-20, 20), shift)
コード例 #21
0
 def test_get_shifted_path_box(self):
     self.path.set_position(Point(0, 0))
     box = PathShiftBox.get_lines_box(self.path.get_lines())
     self.assertEqual(Box(min_x=0, max_x=8, min_y=0, max_y=10), box)
コード例 #22
0
 def get_letter_position(self, text_index, size):
     return Point(text_index * size[0], 0)
コード例 #23
0
 def set_space_size(self, space_size):
     self.space_size = Point(space_size, 0)
コード例 #24
0
 def set_parameters(self, width, height, line_height):
     self.top_left = Point(0, 0)
     self.bottom_right = Point(0, height)
     self.top_right = Point(width, 0)
     self.line_bottom_start = Point(0, line_height)
コード例 #25
0
 def __init__(self, shifts: list = None, start: Point = None):
     self.start = start if start is not None else Point(0, 0)
     self.components = shifts if shifts is not None else []
     self.last_absolute_point = self.get_last_point()
コード例 #26
0
 def test_curve_last_point(self):
     self.assertEqual(self.curve.get_last_point(), Point(3, 3))
     self.assertEqual(self.curve.get_last_point(Point(10, 10)),
                      Point(13, 13))
コード例 #27
0
 def test_append_shift_to_path(self):
     self.empty_path.append_shift(Point(1, 1))
     self.assertEqual(self.empty_path.get_last_point(), Point(1, 1))
     self.empty_path.append_shift(Point(10, 10))
     self.assertEqual(self.empty_path.get_last_point(), Point(11, 11))
コード例 #28
0
 def test_set_path_position(self):
     self.path.set_position(Point(10, 10))
     self.assertEqual(self.path.get_last_point(), Point(24, 24))
コード例 #29
0
 def test_create_empty_path(self):
     self.assertEqual(self.empty_path.get_last_point(), Point(0, 0))
     self.assertTrue(self.empty_path.empty())
コード例 #30
0
 def append_absolute(self, point: Point):
     self.components.append(point.get_shift(self.last_absolute_point))
     self.last_absolute_point = point