diff --git a/PyPDFForm/core/font.py b/PyPDFForm/core/font.py index 48b2f249..d3c0edca 100644 --- a/PyPDFForm/core/font.py +++ b/PyPDFForm/core/font.py @@ -181,4 +181,4 @@ def update_text_field_attributes( elements[key].text_wrap_length = get_paragraph_auto_wrap_length( _element, elements[key] ) - elements[key].text_lines = get_paragraph_lines(elements[key]) + elements[key].text_lines = get_paragraph_lines(_element, elements[key]) diff --git a/PyPDFForm/core/template.py b/PyPDFForm/core/template.py index c976d713..71de94ed 100644 --- a/PyPDFForm/core/template.py +++ b/PyPDFForm/core/template.py @@ -167,9 +167,32 @@ def get_character_x_paddings(element: PdfDict, element_middleware: Text) -> List return result -def get_paragraph_lines(element_middleware: Text) -> List[str]: +def calculate_wrap_length(element: PdfDict, element_middleware: Text, v: str) -> int: + """Increments the substring until reaching maximum horizontal width.""" + + width = abs( + float(element[ANNOTATION_RECTANGLE_KEY][0]) + - float(element[ANNOTATION_RECTANGLE_KEY][2]) + ) + value = element_middleware.value or "" + value = value.replace(NEW_LINE_SYMBOL, " ") + + counter = 0 + _width = 0 + while _width <= width and counter < len(value): + counter += 1 + _width = stringWidth( + v[:counter], + element_middleware.font, + element_middleware.font_size, + ) + return counter - 1 + + +def get_paragraph_lines(element: PdfDict, element_middleware: Text) -> List[str]: """Splits the paragraph field's text to a list of lines.""" + # pylint: disable=R0912 lines = [] result = [] text_wrap_length = element_middleware.text_wrap_length @@ -177,6 +200,11 @@ def get_paragraph_lines(element_middleware: Text) -> List[str]: if element_middleware.max_length is not None: value = value[: element_middleware.max_length] + width = abs( + float(element[ANNOTATION_RECTANGLE_KEY][0]) + - float(element[ANNOTATION_RECTANGLE_KEY][2]) + ) + split_by_new_line_symbol = value.split(NEW_LINE_SYMBOL) for line in split_by_new_line_symbol: characters = line.split(" ") @@ -194,11 +222,18 @@ def get_paragraph_lines(element_middleware: Text) -> List[str]: else current_line ) + for line in lines: + while stringWidth( + line[:text_wrap_length], + element_middleware.font, + element_middleware.font_size, + ) > width: + text_wrap_length -= 1 + for each in lines: while len(each) > text_wrap_length: - last_index = text_wrap_length - 1 - result.append(each[:last_index]) - each = each[last_index:] + result.append(each[:text_wrap_length]) + each = each[text_wrap_length:] if each: if ( result @@ -221,20 +256,6 @@ def get_paragraph_lines(element_middleware: Text) -> List[str]: def get_paragraph_auto_wrap_length(element: PdfDict, element_middleware: Text) -> int: """Calculates the text wrap length of a paragraph field.""" - def calculate_wrap_length(v: str) -> int: - """Increments the substring until reaching maximum horizontal width.""" - - counter = 0 - _width = 0 - while _width <= width and counter < len(value): - counter += 1 - _width = stringWidth( - v[:counter], - element_middleware.font, - element_middleware.font_size, - ) - return counter - 1 - value = element_middleware.value or "" value = value.replace(NEW_LINE_SYMBOL, " ") width = abs( @@ -251,7 +272,7 @@ def calculate_wrap_length(v: str) -> int: if lines > 1: current_min = 0 while len(value) and current_min < len(value): - result = calculate_wrap_length(value) + result = calculate_wrap_length(element, element_middleware, value) value = value[result:] if current_min == 0: current_min = result diff --git a/pdf_samples/paragraph/test_paragraph_auto_wrap.pdf b/pdf_samples/paragraph/test_paragraph_auto_wrap.pdf index afe553c7..9efc3148 100644 Binary files a/pdf_samples/paragraph/test_paragraph_auto_wrap.pdf and b/pdf_samples/paragraph/test_paragraph_auto_wrap.pdf differ