def _render_in_flowable(self): """Render the object to the scene, dispatching partial rendering calls when needed if an object flows across a break in the flowable. Returns: None """ # Calculate position within flowable pos_in_flowable = descendant_pos(self, self.flowable) remaining_x = self.length + self.flowable.dist_to_line_end( pos_in_flowable.x) if remaining_x < ZERO: self._render_complete( canvas_pos_of(self), self.flowable.dist_to_line_start(pos_in_flowable.x), pos_in_flowable.x, ) return # Render before break first_line_i = self.flowable.last_break_index_at(pos_in_flowable.x) current_line = self.flowable.layout_controllers[first_line_i] render_start_pos = canvas_pos_of(self) first_line_length = self.flowable.dist_to_line_end( pos_in_flowable.x) * -1 render_end_pos = Point(render_start_pos.x + first_line_length, render_start_pos.y) self._render_before_break( pos_in_flowable.x, render_start_pos, render_end_pos, self.flowable.dist_to_line_start(pos_in_flowable.x), ) # Iterate through remaining length for current_line_i in range(first_line_i + 1, len(self.flowable.layout_controllers)): current_line = self.flowable.layout_controllers[current_line_i] if remaining_x > current_line.length: # Render spanning continuation line_pos = canvas_pos_of(current_line) render_start_pos = Point(line_pos.x, line_pos.y + pos_in_flowable.y) render_end_pos = Point( render_start_pos.x + current_line.length, render_start_pos.y) self._render_spanning_continuation(self.length - remaining_x, render_start_pos, render_end_pos) remaining_x -= current_line.length else: break # Render end render_start_pos = self.flowable.map_to_canvas( Point(current_line.flowable_x, pos_in_flowable.y)) render_end_pos = Point(render_start_pos.x + remaining_x, render_start_pos.y) self._render_after_break(self.length - remaining_x, render_start_pos, render_end_pos)
def test_map_between(self): source = InvisibleObject((Unit(5), Unit(6)), neoscore.document.pages[1]) destination = InvisibleObject((Unit(99), Unit(90)), neoscore.document.pages[4]) relative_pos = map_between(source, destination) page_1_pos = canvas_pos_of(neoscore.document.pages[1]) page_4_pos = canvas_pos_of(neoscore.document.pages[4]) expected = (page_4_pos + Point(Unit(99), Unit(90))) - ( page_1_pos + Point(Unit(5), Unit(6))) assert_almost_equal(relative_pos, expected)
def map_to_canvas(self, local_point: Point) -> Point: """Convert a local point to its position in the canvas. Args: local_point: A position in the flowable's local space. """ line = self.last_break_at(local_point.x) line_canvas_pos = canvas_pos_of(line) return line_canvas_pos + Point(local_point.x - line.flowable_x, local_point.y)
def _render(self): """Render the object and all its children. Returns: None """ if self.flowable is not None: self._render_in_flowable() else: self._render_complete(canvas_pos_of(self)) for child in self.children: child._render()
def test_canvas_pos_of(self): item = InvisibleObject((Mm(5), Mm(6)), neoscore.document.pages[2]) canvas_pos = canvas_pos_of(item) page_pos = canvas_pos_of(neoscore.document.pages[2]) relative_pos = canvas_pos - page_pos assert_almost_equal(relative_pos, Point(Mm(5), Mm(6)))