diff --git a/tests/test_text.py b/tests/test_text.py index 0b630185eb..f4f138dd53 100644 --- a/tests/test_text.py +++ b/tests/test_text.py @@ -28,10 +28,10 @@ def test_line_content(): for width, remaining in [(100, 'text for test'), (45, 'is a text for test')]: text = 'This is a text for test' - _, length, resume_at, _, _, _ = make_text( + _, length, resume_index, _, _, _ = make_text( text, width, font_family=SANS_FONTS.split(','), font_size=19) - assert text[resume_at:] == remaining - assert length + 1 == resume_at # +1 is for the removed trailing space + assert text[resume_index:] == remaining + assert length + 1 == resume_index # +1 for the removed trailing space @assert_no_logs @@ -46,16 +46,16 @@ def test_line_breaking(): string = 'Thïs is a text for test' # These two tests do not really rely on installed fonts - _, _, resume_at, _, _, _ = make_text(string, 90, font_size=1) - assert resume_at is None + _, _, resume_index, _, _, _ = make_text(string, 90, font_size=1) + assert resume_index is None - _, _, resume_at, _, _, _ = make_text(string, 90, font_size=100) - assert string.encode('utf-8')[resume_at:].decode('utf-8') == ( + _, _, resume_index, _, _, _ = make_text(string, 90, font_size=100) + assert string.encode('utf-8')[resume_index:].decode('utf-8') == ( 'is a text for test') - _, _, resume_at, _, _, _ = make_text( + _, _, resume_index, _, _, _ = make_text( string, 100, font_family=SANS_FONTS.split(','), font_size=19) - assert string.encode('utf-8')[resume_at:].decode('utf-8') == ( + assert string.encode('utf-8')[resume_index:].decode('utf-8') == ( 'text for test') @@ -64,11 +64,11 @@ def test_line_breaking_rtl(): string = 'لوريم ايبسوم دولا' # These two tests do not really rely on installed fonts - _, _, resume_at, _, _, _ = make_text(string, 90, font_size=1) - assert resume_at is None + _, _, resume_index, _, _, _ = make_text(string, 90, font_size=1) + assert resume_index is None - _, _, resume_at, _, _, _ = make_text(string, 90, font_size=100) - assert string.encode('utf-8')[resume_at:].decode('utf-8') == ( + _, _, resume_index, _, _, _ = make_text(string, 90, font_size=100) + assert string.encode('utf-8')[resume_index:].decode('utf-8') == ( 'ايبسوم دولا') diff --git a/weasyprint/formatting_structure/build.py b/weasyprint/formatting_structure/build.py index 05bf78090c..319127a409 100644 --- a/weasyprint/formatting_structure/build.py +++ b/weasyprint/formatting_structure/build.py @@ -1489,12 +1489,12 @@ def _inner_block_in_inline(box, skip_stack=None): if is_start: skip = 0 else: - skip, skip_stack = skip_stack + (skip, skip_stack), = skip_stack.items() for i, child in enumerate(box.children[skip:]): index = i + skip - if isinstance(child, boxes.BlockLevelBox) and \ - child.is_in_normal_flow(): + if (isinstance(child, boxes.BlockLevelBox) and + child.is_in_normal_flow()): assert skip_stack is None # Should not skip here block_level_box = child index += 1 # Resume *after* the block @@ -1511,7 +1511,7 @@ def _inner_block_in_inline(box, skip_stack=None): changed = True new_children.append(new_child) if block_level_box is not None: - resume_at = (index, resume_at) + resume_at = {index: resume_at} box = box.copy_with_children(new_children) break else: diff --git a/weasyprint/layout/__init__.py b/weasyprint/layout/__init__.py index 3cc4388662..729532ff1f 100644 --- a/weasyprint/layout/__init__.py +++ b/weasyprint/layout/__init__.py @@ -152,8 +152,7 @@ def layout_document(html, root_box, context, max_loops=8): watch_elements_after = [] for i, page in enumerate(pages): # We need the updated page_counter_values - resume_at, next_page, right_page, page_state, remake_state = ( - context.page_maker[i + 1]) + _, _, _, page_state, _ = context.page_maker[i + 1] page_counter_values = page_state[1] for child in page.descendants(): diff --git a/weasyprint/layout/blocks.py b/weasyprint/layout/blocks.py index 1250fc92aa..c188c34a9a 100644 --- a/weasyprint/layout/blocks.py +++ b/weasyprint/layout/blocks.py @@ -101,7 +101,6 @@ def block_box_layout(context, box, max_position_y, skip_stack, result = columns_layout( context, box, max_position_y, skip_stack, containing_block, page_is_empty, absolute_boxes, fixed_boxes, adjoining_margins) - resume_at = result[1] # TODO: this condition and the whole relayout are probably wrong if resume_at is None: @@ -115,17 +114,16 @@ def block_box_layout(context, box, max_position_y, skip_stack, context, box, max_position_y, skip_stack, containing_block, page_is_empty, absolute_boxes, fixed_boxes, adjoining_margins) - return result elif box.is_table_wrapper: table_wrapper_width( context, box, (containing_block.width, containing_block.height)) block_level_width(box, containing_block) - new_box, resume_at, next_page, adjoining_margins, collapsing_through = \ - block_container_layout( - context, box, max_position_y, skip_stack, page_is_empty, - absolute_boxes, fixed_boxes, adjoining_margins, discard) + result = block_container_layout( + context, box, max_position_y, skip_stack, page_is_empty, + absolute_boxes, fixed_boxes, adjoining_margins, discard) + new_box = result[0] if new_box and new_box.is_table_wrapper: # Don't collide with floats # http://www.w3.org/TR/CSS21/visuren.html#floats @@ -133,7 +131,7 @@ def block_box_layout(context, box, max_position_y, skip_stack, context, new_box, containing_block, outer=False) new_box.translate( position_x - new_box.position_x, position_y - new_box.position_y) - return new_box, resume_at, next_page, adjoining_margins, collapsing_through + return result @handle_min_max_width @@ -316,10 +314,9 @@ def block_container_layout(context, box, max_position_y, skip_stack, skip = 0 first_letter_style = getattr(box, 'first_letter_style', None) else: - skip, skip_stack = skip_stack + (skip, skip_stack), = skip_stack.items() first_letter_style = None - for i, child in enumerate(box.children[skip:]): - index = i + skip + for index, child in enumerate(box.children[skip:], start=(skip or 0)): child.position_x = position_x # XXX does not count margins in adjoining_margins: child.position_y = position_y @@ -356,7 +353,7 @@ def block_container_layout(context, box, max_position_y, skip_stack, if result: new_children, resume_at = result break - resume_at = (index, None) + resume_at = {index: None} break elif child.is_running(): running_name = child.style['position'][1] @@ -419,7 +416,7 @@ def block_container_layout(context, box, max_position_y, skip_stack, # Remove lines to keep them for the next page del new_children[-needed:] # Page break here, resume before this line - resume_at = (index, skip_stack) + resume_at = {index: skip_stack} is_page_break = True break # TODO: this is incomplete. @@ -444,7 +441,7 @@ def block_container_layout(context, box, max_position_y, skip_stack, break if new_children: - resume_at = (index, new_children[-1].resume_at) + resume_at = {index: new_children[-1].resume_at} if is_page_break: break else: @@ -462,7 +459,7 @@ def block_container_layout(context, box, max_position_y, skip_stack, 'page', 'left', 'right', 'recto', 'verso'): page_name = child.page_values()[0] next_page = {'break': page_break, 'page': page_name} - resume_at = (index, None) + resume_at = {index: None} break else: page_break = 'auto' @@ -589,7 +586,7 @@ def block_container_layout(context, box, max_position_y, skip_stack, new_children = [] if new_children: - resume_at = (index, None) + resume_at = {index: None} break else: # This was the first child of this box, cancel the box @@ -602,7 +599,7 @@ def block_container_layout(context, box, max_position_y, skip_stack, # TODO: back-track somehow when all lines fit but not borders new_children.append(new_child) if resume_at is not None: - resume_at = (index, resume_at) + resume_at = {index: resume_at} break else: resume_at = None @@ -817,7 +814,7 @@ def find_earlier_page_break(children, absolute_boxes, fixed_boxes): if index < orphans: return None new_children = children[:index] - resume_at = (0, new_children[-1].resume_at) + resume_at = {0: new_children[-1].resume_at} remove_placeholders(children[index:], absolute_boxes, fixed_boxes) return new_children, resume_at @@ -838,7 +835,7 @@ def find_earlier_page_break(children, absolute_boxes, fixed_boxes): index += 1 # break after child new_children = children[:index] # Get the index in the original parent - resume_at = (children[index].index, None) + resume_at = {children[index].index: None} break previous_in_flow = child @@ -862,7 +859,7 @@ def find_earlier_page_break(children, absolute_boxes, fixed_boxes): new_children.append(next_child) # Index in the original parent - resume_at = (new_child.index, resume_at) + resume_at = {new_child.index: resume_at} index += 1 # Remove placeholders after child break else: diff --git a/weasyprint/layout/flex.py b/weasyprint/layout/flex.py index c6d99d747f..230ad9111f 100644 --- a/weasyprint/layout/flex.py +++ b/weasyprint/layout/flex.py @@ -261,7 +261,7 @@ def flex_layout(context, box, max_position_y, skip_stack, containing_block, child.padding_top + child.padding_bottom) if getattr(box, axis) == 'auto' and ( child_height + box.height > available_main_space): - resume_at = (i, None) + resume_at = {i: None} children = children[:i + 1] break box.height += child_height @@ -844,8 +844,10 @@ def flex_layout(context, box, max_position_y, skip_stack, containing_block, page_is_empty, absolute_boxes, fixed_boxes, adjoining_margins=[], discard=False)[:2] if new_child is None: - if resume_at and resume_at[0]: - resume_at = (resume_at[0] + i - 1, None) + if resume_at: + index, = resume_at + if index: + resume_at = (index + i - 1, None) else: box.children.append(new_child) if child_resume_at is not None: @@ -854,8 +856,8 @@ def flex_layout(context, box, max_position_y, skip_stack, containing_block, else: first_level_skip = 0 if resume_at: - first_level_skip += resume_at[0] - resume_at = (first_level_skip + i, child_resume_at) + first_level_skip += tuple(resume_at)[0] + resume_at = {first_level_skip + i: child_resume_at} if resume_at: break diff --git a/weasyprint/layout/inlines.py b/weasyprint/layout/inlines.py index 05532ef9aa..d26181c60a 100644 --- a/weasyprint/layout/inlines.py +++ b/weasyprint/layout/inlines.py @@ -265,7 +265,7 @@ def skip_first_whitespace(box, skip_stack): index = 0 next_skip_stack = None else: - index, next_skip_stack = skip_stack + (index, next_skip_stack), = skip_stack.items() if isinstance(box, boxes.TextBox): assert next_skip_stack is None @@ -277,7 +277,7 @@ def skip_first_whitespace(box, skip_stack): if white_space in ('normal', 'nowrap', 'pre-line'): while index < length and box.text[index] == ' ': index += 1 - return (index, None) if index else None + return {index: None} if index else None if isinstance(box, (boxes.LineBox, boxes.InlineBox)): if index == 0 and not box.children: @@ -288,7 +288,7 @@ def skip_first_whitespace(box, skip_stack): if index >= len(box.children): return 'continue' result = skip_first_whitespace(box.children[index], None) - return (index, result) if (index or result) else None + return {index: result} if (index or result) else None assert skip_stack is None, f'unexpected skip inside {box}' return None @@ -375,9 +375,9 @@ def first_letter_to_box(box, skip_stack, first_letter_style): elif child.text: character_found = False if skip_stack: - child_skip_stack = skip_stack[1] + child_skip_stack, = skip_stack.values() if child_skip_stack: - index = child_skip_stack[0] + index, = child_skip_stack child.text = child.text[index:] skip_stack = None while child.text: @@ -417,17 +417,21 @@ def first_letter_to_box(box, skip_stack, first_letter_style): line_box.children = (text_box,) box.children = (letter_box,) + tuple(box.children) if skip_stack and child_skip_stack: - skip_stack = (skip_stack[0], ( - child_skip_stack[0] + 1, child_skip_stack[1])) + index, = skip_stack + (child_index, grandchild_skip_stack), = ( + child_skip_stack.items()) + skip_stack = { + index: {child_index + 1: grandchild_skip_stack}} elif isinstance(child, boxes.ParentBox): if skip_stack: - child_skip_stack = skip_stack[1] + child_skip_stack, = skip_stack.values() else: child_skip_stack = None child_skip_stack = first_letter_to_box( child, child_skip_stack, first_letter_style) if skip_stack: - skip_stack = (skip_stack[0], child_skip_stack) + index, = skip_stack + skip_stack = {index: child_skip_stack} return skip_stack @@ -672,7 +676,7 @@ def split_inline_level(context, box, position_x, max_x, skip_stack, if skip_stack is None: skip = 0 else: - skip, skip_stack = skip_stack + (skip, skip_stack), = skip_stack.items() skip = skip or 0 assert skip_stack is None @@ -682,7 +686,7 @@ def split_inline_level(context, box, position_x, max_x, skip_stack, if skip is None: resume_at = None else: - resume_at = (skip, None) + resume_at = {skip: None} if box.text: first_letter = box.text[0] if skip is None: @@ -759,7 +763,7 @@ def split_inline_box(context, box, position_x, max_x, skip_stack, preserved_line_break = False first_letter = last_letter = None float_widths = {'left': 0, 'right': 0} - float_resume_at = 0 + float_resume_index = 0 if box.style['position'] == 'relative': absolute_boxes = [] @@ -767,7 +771,7 @@ def split_inline_box(context, box, position_x, max_x, skip_stack, if is_start: skip = 0 else: - skip, skip_stack = skip_stack + (skip, skip_stack), = skip_stack.items() for i, child in enumerate(box.children[skip:]): index = i + skip @@ -827,7 +831,7 @@ def split_inline_box(context, box, position_x, max_x, skip_stack, (child.style['float'] == 'right' and box.style['direction'] == 'rtl')): old_child.translate(dx=dx) - float_resume_at = index + 1 + float_resume_index = index + 1 continue elif child.is_running(): running_name = child.style['position'][1] @@ -940,7 +944,7 @@ def split_inline_box(context, box, position_x, max_x, skip_stack, break_found = child_resume_at is not None if child_resume_at is None: # PangoLayout decided not to break the child - child_resume_at = (0, None) + child_resume_at = {0: None} # TODO: use this when Pango is always 1.40.13+: # break_found = True @@ -968,36 +972,36 @@ def split_inline_box(context, box, position_x, max_x, skip_stack, current_skip_stack = None initial_index = 0 else: - initial_index, current_skip_stack = ( - initial_skip_stack) + (initial_index, current_skip_stack), = ( + initial_skip_stack.items()) # child_resume_at is an absolute skip stack if child_index > initial_index: - resume_at = (child_index, child_resume_at) + resume_at = {child_index: child_resume_at} break # combine the stacks current_resume_at = child_resume_at stack = [] while current_skip_stack and current_resume_at: - skip, current_skip_stack = ( - current_skip_stack) - resume, current_resume_at = ( - current_resume_at) + (skip, current_skip_stack), = ( + current_skip_stack.items()) + (resume, current_resume_at), = ( + current_resume_at.items()) stack.append(skip + resume) if resume != 0: break resume_at = current_resume_at while stack: - resume_at = (stack.pop(), resume_at) + resume_at = {stack.pop(): resume_at} # insert the child index - resume_at = (child_index, resume_at) + resume_at = {child_index: resume_at} break if break_found: break if children: # Too wide, can't break waiting children and the inline is # non-empty: put child entirely on the next line. - resume_at = (children[-1][0] + 1, None) + resume_at = {children[-1][0] + 1: None} child_waiting_floats = [] break @@ -1007,7 +1011,7 @@ def split_inline_box(context, box, position_x, max_x, skip_stack, waiting_floats.extend(child_waiting_floats) if resume_at is not None: children.extend(waiting_children) - resume_at = (index, resume_at) + resume_at = {index: resume_at} break else: children.extend(waiting_children) @@ -1068,8 +1072,9 @@ def split_inline_box(context, box, position_x, max_x, skip_stack, absolute_layout(context, absolute_box, new_box, fixed_boxes) if resume_at is not None: - if resume_at[0] < float_resume_at: - resume_at = (float_resume_at, None) + index = tuple(resume_at)[0] + if index < float_resume_index: + resume_at = {float_resume_index: None} if box.is_leader: first_letter = True @@ -1097,9 +1102,9 @@ def split_text_box(context, box, available_width, skip): text = box.text[skip:] if font_size == 0 or not text: return None, None, False - layout, length, resume_at, width, height, baseline = split_first_line( + layout, length, resume_index, width, height, baseline = split_first_line( text, box.style, context, available_width, box.justification_spacing) - assert resume_at != 0 + assert resume_index != 0 # Convert ``length`` and ``resume_at`` from UTF-8 indexes in text # to Unicode indexes. @@ -1108,9 +1113,9 @@ def split_text_box(context, box, available_width, skip): # UTF-8 indexes are always bigger or equal to Unicode indexes. new_text = layout.text encoded = text.encode('utf8') - if resume_at is not None: - between = encoded[length:resume_at].decode('utf8') - resume_at = len(encoded[:resume_at].decode('utf8')) + if resume_index is not None: + between = encoded[length:resume_index].decode('utf8') + resume_index = len(encoded[:resume_index].decode('utf8')) length = len(encoded[:length].decode('utf8')) if length > 0: @@ -1136,10 +1141,11 @@ def split_text_box(context, box, available_width, skip): else: box = None - if resume_at is None: + if resume_index is None: preserved_line_break = False else: - preserved_line_break = (length != resume_at) and between.strip(' ') + preserved_line_break = ( + (length != resume_index) and between.strip(' ')) if preserved_line_break: # See http://unicode.org/reports/tr14/ # \r is already handled by process_whitespace @@ -1147,9 +1153,9 @@ def split_text_box(context, box, available_width, skip): assert between in line_breaks, ( 'Got %r between two lines. ' 'Expected nothing or a preserved line break' % (between,)) - resume_at += skip + resume_index += skip - return box, resume_at, preserved_line_break + return box, resume_index, preserved_line_break def line_box_verticality(box): diff --git a/weasyprint/layout/preferred.py b/weasyprint/layout/preferred.py index 47251644d6..ba22b9ecaa 100644 --- a/weasyprint/layout/preferred.py +++ b/weasyprint/layout/preferred.py @@ -268,7 +268,7 @@ def inline_line_widths(context, box, outer, is_line_start, minimum, if skip_stack is None: skip = 0 else: - skip, skip_stack = skip_stack + (skip, skip_stack), = skip_stack.items() for child in box.children[skip:]: if child.is_absolutely_positioned(): continue # Skip @@ -292,7 +292,7 @@ def inline_line_widths(context, box, outer, is_line_start, minimum, if skip_stack is None: skip = 0 else: - skip, skip_stack = skip_stack + (skip, skip_stack), = skip_stack.items() assert skip_stack is None child_text = child.text[(skip or 0):] if is_line_start and space_collapse: @@ -302,18 +302,18 @@ def inline_line_widths(context, box, outer, is_line_start, minimum, else: max_width = 0 if minimum else None lines = [] - resume_at = new_resume_at = 0 - while new_resume_at is not None: - resume_at += new_resume_at - _, _, new_resume_at, width, _, _ = ( + resume_index = new_resume_index = 0 + while new_resume_index is not None: + resume_index += new_resume_index + _, _, new_resume_index, width, _, _ = ( split_first_line( - child_text[resume_at:], child.style, context, + child_text[resume_index:], child.style, context, max_width, child.justification_spacing, minimum=True)) lines.append(width) if first_line: break - if first_line and new_resume_at: + if first_line and new_resume_index: current_line += lines[0] break else: diff --git a/weasyprint/layout/tables.py b/weasyprint/layout/tables.py index 5e9c0ca4b0..74464fd7ef 100644 --- a/weasyprint/layout/tables.py +++ b/weasyprint/layout/tables.py @@ -49,9 +49,9 @@ def table_layout(context, table, max_position_y, skip_stack, containing_block, if table.style['border_collapse'] == 'collapse': if skip_stack: - skipped_groups, group_skip_stack = skip_stack + (skipped_groups, group_skip_stack), = skip_stack.items() if group_skip_stack: - skipped_rows, _ = group_skip_stack + skipped_rows, = group_skip_stack else: skipped_rows = 0 for group in table.children[:skipped_groups]: @@ -66,8 +66,8 @@ def table_layout(context, table, max_position_y, skip_stack, containing_block, # Make this a sub-function so that many local variables like rows_x # don't need to be passed as parameters. - def group_layout(group, position_y, max_position_y, - page_is_empty, skip_stack): + def group_layout(group, position_y, max_position_y, page_is_empty, + skip_stack): resume_at = None next_page = {'break': 'any', 'page': None} original_page_is_empty = page_is_empty @@ -83,7 +83,7 @@ def group_layout(group, position_y, max_position_y, if is_group_start: skip = 0 else: - skip, skip_stack = skip_stack + (skip, skip_stack), = skip_stack.items() assert not skip_stack # No breaks inside rows for now for i, row in enumerate(group.children[skip:]): index_row = i + skip @@ -94,7 +94,7 @@ def group_layout(group, position_y, max_position_y, new_group_children[-1], row) if page_break in ('page', 'recto', 'verso', 'left', 'right'): next_page['break'] = page_break - resume_at = (index_row, None) + resume_at = {index_row: None} break resolve_percentages(row, containing_block=table) @@ -239,10 +239,10 @@ def group_layout(group, position_y, max_position_y, new_group_children, resume_at = earlier_page_break break else: - resume_at = (index_row, None) + resume_at = {index_row: None} break if original_page_is_empty: - resume_at = (index_row, None) + resume_at = {index_row: None} else: return None, None, next_page break @@ -284,7 +284,7 @@ def body_groups_layout(skip_stack, position_y, max_position_y, if skip_stack is None: skip = 0 else: - skip, skip_stack = skip_stack + (skip, skip_stack), = skip_stack.items() new_table_children = [] resume_at = None next_page = {'break': 'any', 'page': None} @@ -303,7 +303,7 @@ def body_groups_layout(skip_stack, position_y, max_position_y, new_table_children[-1], group) if page_break in ('page', 'recto', 'verso', 'left', 'right'): next_page['break'] = page_break - resume_at = (index_group, None) + resume_at = {index_group: None} break new_group, resume_at, next_page = group_layout( @@ -320,7 +320,7 @@ def body_groups_layout(skip_stack, position_y, max_position_y, if earlier_page_break is not None: new_table_children, resume_at = earlier_page_break break - resume_at = (index_group, None) + resume_at = {index_group: None} else: return None, None, next_page, position_y break @@ -330,7 +330,7 @@ def body_groups_layout(skip_stack, position_y, max_position_y, page_is_empty = False if resume_at: - resume_at = (index_group, resume_at) + resume_at = {index_group: resume_at} break return new_table_children, resume_at, next_page, position_y @@ -381,7 +381,10 @@ def all_groups_layout(): footer = None # Don't remove headers and footers if breaks are avoided in line groups - skip = skip_stack[0] if skip_stack else 0 + if skip_stack: + skip, = skip_stack + else: + skip = 0 avoid_breaks = False for group in table.children[skip:]: if not group.is_header and not group.is_footer: @@ -400,8 +403,9 @@ def all_groups_layout(): if new_table_children or not table_rows or not page_is_empty: footer.translate(dy=end_position_y - footer.position_y) end_position_y += footer_height - return (header, new_table_children, footer, - end_position_y, resume_at, next_page) + return ( + header, new_table_children, footer, end_position_y, + resume_at, next_page) else: # We could not fit any content, drop the footer footer = None @@ -415,8 +419,9 @@ def all_groups_layout(): max_position_y=max_position_y, page_is_empty=avoid_breaks)) if new_table_children or not table_rows or not page_is_empty: - return (header, new_table_children, footer, - end_position_y, resume_at, next_page) + return ( + header, new_table_children, footer, end_position_y, + resume_at, next_page) else: # We could not fit any content, drop the header header = None @@ -432,8 +437,9 @@ def all_groups_layout(): if new_table_children or not table_rows or not page_is_empty: footer.translate(dy=end_position_y - footer.position_y) end_position_y += footer_height - return (header, new_table_children, footer, - end_position_y, resume_at, next_page) + return ( + header, new_table_children, footer, end_position_y, + resume_at, next_page) else: # We could not fit any content, drop the footer footer = None @@ -455,8 +461,8 @@ def get_column_cells(table, column): for cell in row.children if cell.grid_x == column.grid_x] - header, new_table_children, footer, position_y, resume_at, next_page = \ - all_groups_layout() + header, new_table_children, footer, position_y, resume_at, next_page = ( + all_groups_layout()) if new_table_children is None: assert resume_at is None diff --git a/weasyprint/svg/text.py b/weasyprint/svg/text.py index 2d0415003e..b774963f18 100644 --- a/weasyprint/svg/text.py +++ b/weasyprint/svg/text.py @@ -43,7 +43,7 @@ def text(svg, node, font_size): except ValueError: style['font_weight'] = 400 - layout, length, resume_at, width, height, baseline = split_first_line( + layout, _, _, width, height, _ = split_first_line( node.text, style, svg.context, float('inf'), 0) # TODO: get real values x_bearing, y_bearing = 0, 0 diff --git a/weasyprint/text/line_break.py b/weasyprint/text/line_break.py index ed17d0fe3b..3408b91c5b 100644 --- a/weasyprint/text/line_break.py +++ b/weasyprint/text/line_break.py @@ -292,14 +292,14 @@ def split_first_line(text, style, context, max_width, justification_spacing, minimum=False): """Fit as much as possible in the available width for one line of text. - Return ``(layout, length, resume_at, width, height, baseline)``. + Return ``(layout, length, resume_index, width, height, baseline)``. ``layout``: a pango Layout with the first line ``length``: length in UTF-8 bytes of the first line - ``resume_at``: The number of UTF-8 bytes to skip for the next line. - May be ``None`` if the whole text fits in one line. - This may be greater than ``length`` in case of preserved - newline characters. + ``resume_index``: The number of UTF-8 bytes to skip for the next line. + May be ``None`` if the whole text fits in one line. + This may be greater than ``length`` in case of preserved + newline characters. ``width``: width in pixels of the first line ``height``: height in pixels of the first line ``baseline``: baseline in pixels of the first line @@ -341,18 +341,18 @@ def split_first_line(text, style, context, max_width, justification_spacing, layout = create_layout( text, style, context, original_max_width, justification_spacing) first_line, index = layout.get_first_line() - resume_at = index + resume_index = index # Step #2: Don't split lines when it's not needed if max_width is None: # The first line can take all the place needed return first_line_metrics( - first_line, text, layout, resume_at, space_collapse, style) + first_line, text, layout, resume_index, space_collapse, style) first_line_width, _ = line_size(first_line, style) if index is None and first_line_width <= max_width: # The first line fits in the available width return first_line_metrics( - first_line, text, layout, resume_at, space_collapse, style) + first_line, text, layout, resume_index, space_collapse, style) # Step #3: Try to put the first word of the second line on the first line # https://mail.gnome.org/archives/gtk-i18n-list/2013-September/msg00006 @@ -383,22 +383,23 @@ def split_first_line(text, style, context, max_width, justification_spacing, first_line_width, _ = line_size(first_line, style) if index is None and first_line_text: # The next word fits in the first line, keep the layout - resume_at = len(new_first_line_text.encode('utf-8')) + 1 + resume_index = len(new_first_line_text.encode('utf-8')) + 1 return first_line_metrics( - first_line, text, layout, resume_at, space_collapse, style) + first_line, text, layout, resume_index, space_collapse, + style) elif index: # Text may have been split elsewhere by Pango earlier - resume_at = index + resume_index = index else: # Second line is none - resume_at = first_line.length + 1 - if resume_at >= len(text.encode('utf-8')): - resume_at = None + resume_index = first_line.length + 1 + if resume_index >= len(text.encode('utf-8')): + resume_index = None elif first_line_text: # We found something on the first line but we did not find a word on # the next line, no need to hyphenate, we can keep the current layout return first_line_metrics( - first_line, text, layout, resume_at, space_collapse, style) + first_line, text, layout, resume_index, space_collapse, style) # Step #4: Try to hyphenate hyphens = style['hyphens'] @@ -453,7 +454,7 @@ def split_first_line(text, style, context, max_width, justification_spacing, next_word = f' {next_word}' layout.set_text(first_line_text) first_line, index = layout.get_first_line() - resume_at = len((first_line_text + ' ').encode('utf8')) + resume_index = len((first_line_text + ' ').encode('utf8')) else: first_line_text, next_word = '', first_line_text soft_hyphen_indexes = [ @@ -493,13 +494,13 @@ def split_first_line(text, style, context, max_width, justification_spacing, layout = new_layout first_line = new_first_line index = new_index - resume_at = len(new_first_line_text.encode('utf8')) + resume_index = len(new_first_line_text.encode('utf8')) if text[len(new_first_line_text)] == soft_hyphen: # Recreate the layout with no max_width to be sure that # we don't break before the soft hyphen pango.pango_layout_set_width( layout.layout, units_from_double(-1)) - resume_at += len(soft_hyphen.encode('utf8')) + resume_index += len(soft_hyphen.encode('utf8')) break if not hyphenated and not first_line_text: @@ -510,9 +511,9 @@ def split_first_line(text, style, context, max_width, justification_spacing, pango.pango_layout_set_width( layout.layout, units_from_double(-1)) first_line, index = layout.get_first_line() - resume_at = len(new_first_line_text.encode('utf8')) + resume_index = len(new_first_line_text.encode('utf8')) if text[len(first_line_text)] == soft_hyphen: - resume_at += len(soft_hyphen.encode('utf8')) + resume_index += len(soft_hyphen.encode('utf8')) if not hyphenated and first_line_text.endswith(soft_hyphen): # Recreate the layout with no max_width to be sure that @@ -524,7 +525,7 @@ def split_first_line(text, style, context, max_width, justification_spacing, pango.pango_layout_set_width( layout.layout, units_from_double(-1)) first_line, index = layout.get_first_line() - resume_at = len(first_line_text.encode('utf8')) + resume_index = len(first_line_text.encode('utf8')) # Step 5: Try to break word if it's too long for the line overflow_wrap = style['overflow_wrap'] @@ -546,13 +547,13 @@ def split_first_line(text, style, context, max_width, justification_spacing, pango.pango_layout_set_wrap( layout.layout, PANGO_WRAP_MODE['WRAP_CHAR']) first_line, index = layout.get_first_line() - resume_at = index or first_line.length - if resume_at >= len(text.encode('utf-8')): - resume_at = None + resume_index = index or first_line.length + if resume_index >= len(text.encode('utf-8')): + resume_index = None return first_line_metrics( - first_line, text, layout, resume_at, space_collapse, style, hyphenated, - style['hyphenate_character']) + first_line, text, layout, resume_index, space_collapse, style, + hyphenated, style['hyphenate_character']) def get_log_attrs(text, lang):