Skip to content

Commit

Permalink
Merge pull request #599 from MyreMylar/draw-text-row-chunk-height
Browse files Browse the repository at this point in the history
Fix line spacing issues
  • Loading branch information
MyreMylar authored Jun 9, 2024
2 parents 0e4cc3f + 5dcd1ff commit 7d0686e
Show file tree
Hide file tree
Showing 14 changed files with 80 additions and 41 deletions.
1 change: 1 addition & 0 deletions pygame_gui/core/text/horiz_rule_layout_rect.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ def finalise(self, target_surface: Surface,
row_chunk_origin: int,
row_chunk_height: int,
row_bg_height: int,
row_line_spacing_height: int,
x_scroll_offset: int = 0,
letter_end: Optional[int] = None):

Expand Down
1 change: 1 addition & 0 deletions pygame_gui/core/text/image_layout_rect.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ def finalise(self,
row_chunk_origin: int,
row_chunk_height: int,
row_bg_height: int,
row_line_spacing_height: int,
x_scroll_offset: int = 0,
letter_end: Optional[int] = None):
blit_rect = self.copy()
Expand Down
4 changes: 3 additions & 1 deletion pygame_gui/core/text/line_break_layout_rect.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,10 +33,12 @@ def finalise(self,
row_chunk_origin: int,
row_chunk_height: int,
row_bg_height: int,
row_line_spacing_height: int,
x_scroll_offset: int = 0,
letter_end: Optional[int] = None):
self.height = row_bg_height
if self.is_selected:
self.select_surf = Surface((self.selection_chunk_width, row_bg_height), flags=pygame.SRCALPHA)
self.select_surf = Surface((self.selection_chunk_width, self.height), flags=pygame.SRCALPHA)
self.select_surf.fill(self.selection_colour)
target_surface.blit(self.select_surf, self.topleft, special_flags=pygame.BLEND_PREMULTIPLIED)
# should be cleared by row
Expand Down
1 change: 1 addition & 0 deletions pygame_gui/core/text/simple_test_layout_rect.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ def finalise(self,
row_chunk_origin: int,
row_chunk_height: int,
row_bg_height: int,
row_line_spacing_height: int,
x_scroll_offset: int = 0,
letter_end: Optional[int] = None):
surface = Surface(self.size, depth=32, flags=pygame.SRCALPHA)
Expand Down
24 changes: 14 additions & 10 deletions pygame_gui/core/text/text_box_layout.py
Original file line number Diff line number Diff line change
Expand Up @@ -193,7 +193,10 @@ def _add_row_to_layout(self, current_row: TextBoxLayoutRow, last_row=False):
if current_row.bottom - self.layout_rect.y > self.layout_rect.height:
self.layout_rect.height = current_row.bottom - self.layout_rect.y
self._refresh_row_letter_counts()
self.last_row_height = current_row.height
if len(current_row.items) != 0:
self.last_row_height = current_row.items[-1].height
else:
self.last_row_height = current_row.height

def _handle_regular_rect(self, current_row, text_layout_rect, input_queue):
rhs_limit = self.layout_rect.right
Expand Down Expand Up @@ -292,7 +295,7 @@ def _handle_span_rect(self, current_row, test_layout_rect):
self._add_row_to_layout(current_row)
# ...and start new one
current_row = TextBoxLayoutRow(row_start_x=self.layout_rect.x,
row_start_y=current_row.bottom,
row_start_y=current_row.top + current_row.line_spacing_height,
row_index=len(self.layout_rows),
layout=self, line_spacing=self.line_spacing)
current_row.fall_back_font = prev_row_font
Expand All @@ -306,7 +309,7 @@ def _handle_span_rect(self, current_row, test_layout_rect):
self._add_row_to_layout(current_row)
# ...then start a new row
current_row = TextBoxLayoutRow(row_start_x=self.layout_rect.x,
row_start_y=current_row.bottom,
row_start_y=current_row.top + current_row.line_spacing_height,
row_index=len(self.layout_rows),
layout=self, line_spacing=self.line_spacing)
current_row.fall_back_font = prev_row_font
Expand All @@ -320,7 +323,7 @@ def _handle_line_break_rect(self, current_row, test_layout_rect):

# ...then start a new row
new_row = TextBoxLayoutRow(row_start_x=self.layout_rect.x,
row_start_y=current_row.bottom,
row_start_y=current_row.top + current_row.line_spacing_height,
row_index=len(self.layout_rows),
layout=self, line_spacing=self.line_spacing)
new_row.fall_back_font = prev_row_font
Expand Down Expand Up @@ -373,7 +376,7 @@ def _split_rect_and_move_to_next_line(self, current_row, rhs_limit,
layout=self, line_spacing=self.line_spacing)
else:
new_row = TextBoxLayoutRow(row_start_x=self.layout_rect.x,
row_start_y=current_row.bottom,
row_start_y=current_row.top + current_row.line_spacing_height,
row_index=len(self.layout_rows),
layout=self, line_spacing=self.line_spacing)
new_row.fall_back_font = prev_row_font
Expand Down Expand Up @@ -402,7 +405,8 @@ def finalise_to_surf(self, surface: Surface):
# print("row height:", row.height)

for floating_rect in self.floating_rects:
floating_rect.finalise(surface, self.view_rect, 0, 0, 0)
floating_rect.finalise(surface, self.view_rect,
0, 0, 0, 0)

self.finalised_surface = surface

Expand Down Expand Up @@ -451,7 +455,7 @@ def update_text_with_new_text_end_pos(self, new_end_pos: int):
if self.finalised_surface is not None:
rect.clear()
rect.finalise(self.finalised_surface, self.view_rect,
row.y_origin, row.text_chunk_height, row.height,
row.y_origin, row.text_chunk_height, row.height, row.line_spacing_height,
self.x_scroll_offset,
index_in_row - cumulative_row_letter_count)

Expand Down Expand Up @@ -585,7 +589,7 @@ def vert_center_all_rows(self):
for row in self.layout_rows:
row.y = new_y
row.vert_align_items_to_row()
new_y += row.height
new_y += row.line_spacing_height

def vert_align_top_all_rows(self, y_padding):
"""
Expand All @@ -598,7 +602,7 @@ def vert_align_top_all_rows(self, y_padding):
for row in self.layout_rows:
row.y = new_y
row.vert_align_items_to_row()
new_y += row.height
new_y += row.line_spacing_height

def vert_align_bottom_all_rows(self, y_padding):
"""
Expand All @@ -611,7 +615,7 @@ def vert_align_bottom_all_rows(self, y_padding):
for row in reversed(self.layout_rows):
row.bottom = new_y
row.vert_align_items_to_row()
new_y -= row.height
new_y -= row.line_spacing_height

def set_cursor_to_end_of_current_row(self):
"""
Expand Down
14 changes: 9 additions & 5 deletions pygame_gui/core/text/text_box_layout_row.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ def __init__(self, row_start_x, row_start_y, row_index, line_spacing, layout):
# this one.
self.fall_back_font = self.layout.default_font
self.surf_row_dirty = False
self.line_spacing_height = 0

def __hash__(self):
return self.row_index
Expand Down Expand Up @@ -69,10 +70,12 @@ def add_item(self, item: TextLayoutRect):
self.text_chunk_height = item.row_chunk_height
if self.layout.layout_rect.height != -1:
self.height = min(self.layout.layout_rect.height, # noqa pylint: disable=attribute-defined-outside-init; pylint getting confused
item.row_chunk_height)
self.line_spacing_height = min(self.layout.layout_rect.height, # noqa pylint: disable=attribute-defined-outside-init; pylint getting confused
int(item.row_chunk_height * self.line_spacing))
else:
self.height = int(item.row_chunk_height * self.line_spacing) # noqa pylint: disable=attribute-defined-outside-init; pylint getting confused

self.height = int(item.row_chunk_height) # noqa pylint: disable=attribute-defined-outside-init; pylint getting confused
self.line_spacing_height = int(item.row_chunk_height * self.line_spacing) # noqa pylint: disable=attribute-defined-outside-init; pylint getting confused
self.cursor_rect = pygame.Rect(self.x, self.y, self.layout.edit_cursor_width, self.height - 2)

if isinstance(item, TextLineChunkFTFont):
Expand Down Expand Up @@ -103,6 +106,7 @@ def rewind_row(self, layout_rect_queue):
self.width = 0 # pylint: disable=attribute-defined-outside-init; pylint getting confused
self.height = 0 # pylint: disable=attribute-defined-outside-init; pylint getting confused
self.text_chunk_height = 0
self.line_spacing_height = 0
self.letter_count = 0
self.y_origin = 0

Expand Down Expand Up @@ -264,17 +268,17 @@ def finalise(self, surface: pygame.Surface, current_end_pos: Optional[int] = Non
if current_end_pos is not None and cumulative_letter_count is not None:
if cumulative_letter_count < current_end_pos:
text_chunk.finalise(surface, chunk_view_rect, self.y_origin,
self.text_chunk_height, self.height,
self.text_chunk_height, self.height, self.line_spacing_height,
self.layout.x_scroll_offset,
current_end_pos - cumulative_letter_count)
cumulative_letter_count += text_chunk.letter_count
else:
text_chunk.finalise(surface, chunk_view_rect, self.y_origin,
self.text_chunk_height, self.height,
self.text_chunk_height, self.height, self.line_spacing_height,
self.layout.x_scroll_offset)
else:
text_chunk.finalise(surface, chunk_view_rect, self.y_origin,
self.text_chunk_height, self.height,
self.text_chunk_height, self.height, self.line_spacing_height,
self.layout.x_scroll_offset)
else:
print(self.items)
Expand Down
2 changes: 2 additions & 0 deletions pygame_gui/core/text/text_layout_rect.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ def finalise(self,
row_chunk_origin: int,
row_chunk_height: int,
row_bg_height: int,
row_line_spacing_height: int,
x_scroll_offset: int = 0,
letter_end: Optional[int] = None):
"""
Expand All @@ -64,6 +65,7 @@ def finalise(self,
:param row_chunk_origin:
:param row_chunk_height:
:param row_bg_height:
:param row_line_spacing_height:
:param x_scroll_offset:
:param letter_end:
"""
Expand Down
4 changes: 4 additions & 0 deletions pygame_gui/core/text/text_line_chunk.py
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ def __init__(self, text: str,
self.row_chunk_origin = 0
self.row_chunk_height = text_height
self.row_bg_height = 0
self.row_line_spacing_height = 0
self.layout_x_offset = 0

self.selection_rect = None
Expand Down Expand Up @@ -167,6 +168,7 @@ def finalise(self,
row_chunk_origin: int,
row_chunk_height: int,
row_bg_height: int,
row_line_spacing_height: int,
x_scroll_offset: int = 0,
letter_end: Optional[int] = None):
if len(self.text) == 0:
Expand Down Expand Up @@ -206,6 +208,7 @@ def finalise(self,
self.row_chunk_origin = row_chunk_origin
self.row_chunk_height = row_chunk_height
self.row_bg_height = row_bg_height
self.row_line_spacing_height = row_line_spacing_height
self.layout_x_offset = x_scroll_offset
self.letter_end = letter_end

Expand Down Expand Up @@ -650,6 +653,7 @@ def redraw(self):
self.row_chunk_origin,
self.row_chunk_height,
self.row_bg_height,
self.row_line_spacing_height,
self.layout_x_offset,
self.letter_end)
if self.pre_effect_target_surface is not None:
Expand Down
9 changes: 6 additions & 3 deletions tests/test_core/test_text/test_horiz_rule_layout_rect.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,8 @@ def test_finalise(self, _init_pygame, _display_surface_return_none):
target_area=pygame.Rect(0, 0, 200, 20),
row_chunk_origin=0,
row_chunk_height=20,
row_bg_height=20)
row_bg_height=20,
row_line_spacing_height=20)

assert rule_surface.get_at((10, 2)) == pygame.Color(0, 0, 0, 0)
assert rule_surface.get_at((10, 10)) == pygame.Color(255, 255, 255, 255)
Expand All @@ -42,7 +43,8 @@ def test_finalise(self, _init_pygame, _display_surface_return_none):
target_area=pygame.Rect(0, 0, 200, 20),
row_chunk_origin=0,
row_chunk_height=20,
row_bg_height=20)
row_bg_height=20,
row_line_spacing_height=20)

horiz_rule = HorizRuleLayoutRect(height=20,
colour_or_gradient=pygame.Color('#FFFFFF'),
Expand All @@ -55,7 +57,8 @@ def test_finalise(self, _init_pygame, _display_surface_return_none):
target_area=pygame.Rect(0, 0, 200, 20),
row_chunk_origin=0,
row_chunk_height=20,
row_bg_height=20)
row_bg_height=20,
row_line_spacing_height=20)


if __name__ == '__main__':
Expand Down
12 changes: 8 additions & 4 deletions tests/test_core/test_text/test_hyperlink_text_chunk.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,8 @@ def test_on_hovered(self, _init_pygame, _display_surface_return_none, default_ui
target_area=pygame.Rect(0, 0, 200, 30),
row_chunk_origin=19,
row_chunk_height=20,
row_bg_height=20)
row_bg_height=20,
row_line_spacing_height=20)

assert rendered_chunk_surf.get_at((2, 6)) == pygame.Color('#FF0000')
hyper_chunk.on_hovered()
Expand Down Expand Up @@ -88,7 +89,8 @@ def test_on_unhovered(self, _init_pygame, _display_surface_return_none, default_
target_area=pygame.Rect(0, 0, 200, 30),
row_chunk_origin=19,
row_chunk_height=20,
row_bg_height=20)
row_bg_height=20,
row_line_spacing_height=20)

assert rendered_chunk_surf.get_at((2, 6)) == pygame.Color('#FF0000')
hyper_chunk.on_hovered()
Expand Down Expand Up @@ -125,7 +127,8 @@ def test_set_active(self, _init_pygame, _display_surface_return_none, default_ui
target_area=pygame.Rect(0, 0, 200, 30),
row_chunk_origin=19,
row_chunk_height=20,
row_bg_height=20)
row_bg_height=20,
row_line_spacing_height=20)

assert rendered_chunk_surf.get_at((2, 6)) == pygame.Color('#FF0000')
hyper_chunk.set_active()
Expand Down Expand Up @@ -159,7 +162,8 @@ def test_set_inactive(self, _init_pygame, _display_surface_return_none, default_
target_area=pygame.Rect(0, 0, 200, 30),
row_chunk_origin=19,
row_chunk_height=20,
row_bg_height=20)
row_bg_height=20,
row_line_spacing_height=20)

assert rendered_chunk_surf.get_at((2, 6)) == pygame.Color('#FF0000')
hyper_chunk.set_active()
Expand Down
5 changes: 3 additions & 2 deletions tests/test_core/test_text/test_line_break_layout_rect.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,12 @@ def test_finalise(self, _init_pygame, _display_surface_return_none, default_ui_m
target_area=pygame.Rect(0, 0, 200, 30),
row_chunk_origin=0,
row_chunk_height=20,
row_bg_height=20)
row_bg_height=20,
row_line_spacing_height=20)

assert rendered_chunk_surf.get_at((1, 5)) == pygame.Color(0, 0, 0)
assert line_break_rect.width == 200
assert line_break_rect.height == 30
assert line_break_rect.height == 20


if __name__ == '__main__':
Expand Down
3 changes: 2 additions & 1 deletion tests/test_core/test_text/test_simple_test_layout_rect.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,8 @@ def test_finalise(self, _init_pygame, _display_surface_return_none, default_ui_m
target_area=pygame.Rect(0, 0, 200, 30),
row_chunk_origin=0,
row_chunk_height=20,
row_bg_height=20)
row_bg_height=20,
row_line_spacing_height=20)

assert rendered_chunk_surf.get_at((1, 5)) != pygame.Color(0, 0, 0)
assert simple_rect.width == 200
Expand Down
11 changes: 6 additions & 5 deletions tests/test_core/test_text/test_text_box_layout_row.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import pytest
import pygame

from pygame_gui.core.gui_font_pygame import GUIFontPygame
from pygame_gui.core.gui_font_freetype import GUIFontFreetype
from pygame_gui.core.text import HTMLParser, TextBoxLayoutRow, TextBoxLayout, TextFloatPosition
from pygame_gui.core.text import SimpleTestLayoutRect, TextLineChunkFTFont
Expand Down Expand Up @@ -56,7 +57,7 @@ def test_at_start(self, _init_pygame, _display_surface_return_none, default_ui_m

def test_add_item(self, _init_pygame, _display_surface_return_none, default_ui_manager: UIManager):
input_data = deque([])
line_spacing = 1.25
line_spacing = 1.0
default_font = default_ui_manager.get_theme().get_font_dictionary().get_default_font()
default_font_data = {"font": default_font,
"font_colour": pygame.Color("#FFFFFF"),
Expand All @@ -79,7 +80,7 @@ def test_add_item(self, _init_pygame, _display_surface_return_none, default_ui_m
assert len(layout_row.items) == 1
assert layout_row.width == simple_rect.width
assert layout_row.text_chunk_height == simple_rect.height
assert layout_row.height == int(simple_rect.height * line_spacing)
assert layout_row.height == int(simple_rect.height)

def test_rewind_row(self, _init_pygame, _display_surface_return_none, default_ui_manager: UIManager):
input_data = deque([])
Expand Down Expand Up @@ -361,8 +362,8 @@ def test_finalise(self, _init_pygame, _display_surface_return_none, default_ui_m
line_spacing=line_spacing,
layout=text_box_layout)

font_1 = GUIFontFreetype(None, 30)
font_2 = GUIFontFreetype(None, 20)
font_1 = GUIFontPygame(None, 30)
font_2 = GUIFontPygame(None, 20)
text_chunk_1 = TextLineChunkFTFont(text='hello ',
font=font_1,
underlined=False,
Expand All @@ -389,7 +390,7 @@ def test_finalise(self, _init_pygame, _display_surface_return_none, default_ui_m
layout_surface.fill((0, 0, 0, 0))
layout_row.finalise(layout_surface)

assert layout_surface.get_at((3, 3)) == pygame.Color(255, 0, 0, 255)
assert layout_surface.get_at((0, 0)) == pygame.Color(255, 0, 0, 255)

def test_set_default_text_colour(self, _init_pygame, _display_surface_return_none, default_ui_manager: UIManager):
input_data = deque([])
Expand Down
Loading

0 comments on commit 7d0686e

Please sign in to comment.