#!/usr/bin/env python3 """ Test paragraph layout specifically to diagnose the line breaking issue """ from pyWebLayout.concrete.page import Page from pyWebLayout.style.fonts import Font from pyWebLayout.abstract.block import Paragraph from pyWebLayout.abstract.inline import Word from pyWebLayout.typesetting.paragraph_layout import ParagraphLayout from pyWebLayout.style.layout import Alignment from PIL import Image def test_paragraph_layout_directly(): """Test the paragraph layout system directly""" print("Testing paragraph layout system directly...") # Create a paragraph with multiple words paragraph = Paragraph() font = Font(font_size=14) # Add many words to force line breaking words_text = [ "This", "is", "a", "very", "long", "paragraph", "that", "should", "definitely", "wrap", "across", "multiple", "lines", "when", "rendered", "in", "a", "narrow", "width", "container", "to", "test", "the", "paragraph", "layout", "system", "and", "ensure", "proper", "line", "breaking", "functionality", "works", "correctly", "as", "expected." ] for word_text in words_text: word = Word(word_text, font) paragraph.add_word(word) # Create paragraph layout with narrow width to force wrapping layout = ParagraphLayout( line_width=300, # Narrow width line_height=20, word_spacing=(3, 8), line_spacing=3, halign=Alignment.LEFT ) # Layout the paragraph lines = layout.layout_paragraph(paragraph) print(f"✓ Created paragraph with {len(words_text)} words") print(f"✓ Layout produced {len(lines)} lines") # Check each line for i, line in enumerate(lines): word_count = len(line.renderable_words) if hasattr(line, 'renderable_words') else 0 print(f" Line {i+1}: {word_count} words") return len(lines) > 1 # Should have multiple lines def test_page_with_long_paragraph(): """Test a page with a long paragraph to see line breaking""" print("\nTesting page with long paragraph...") html_content = """
This is a very long paragraph that should definitely wrap across multiple lines when rendered in the page. It contains many words and should demonstrate the line breaking functionality of the paragraph layout system. The paragraph layout should break this text into multiple lines based on the available width, and each line should be rendered separately on the page. This allows for proper text flow and readability in the final rendered output.
This is another paragraph to test multiple paragraph rendering and spacing between paragraphs.
""" # Create a page with narrower width to force wrapping page = Page(size=(400, 600)) page.load_html_string(html_content) print(f"✓ Page loaded with {len(page._children)} top-level elements") # Check the structure of the page for i, child in enumerate(page._children): child_type = type(child).__name__ print(f" Element {i+1}: {child_type}") # If it's a container (paragraph), check its children if hasattr(child, '_children'): print(f" Contains {len(child._children)} child elements") for j, subchild in enumerate(child._children): subchild_type = type(subchild).__name__ print(f" Sub-element {j+1}: {subchild_type}") # Try to render the page try: image = page.render() print(f"✓ Page rendered successfully: {image.size}") # Save for inspection image.save("test_paragraph_layout_output.png") print("✓ Saved rendered page to: test_paragraph_layout_output.png") return True except Exception as e: print(f"✗ Error rendering page: {e}") import traceback traceback.print_exc() return False def test_simple_text_vs_paragraph(): """Compare simple text vs paragraph rendering""" print("\nTesting simple text vs paragraph rendering...") # Test 1: Simple HTML with short text simple_html = "Short text
" page1 = Page(size=(400, 200)) page1.load_html_string(simple_html) print(f"Simple text page has {len(page1._children)} children") # Test 2: Complex HTML with long text complex_html = """This is a much longer paragraph that should wrap across multiple lines and demonstrate the difference between simple text rendering and proper paragraph layout with line breaking functionality.
""" page2 = Page(size=(400, 200)) page2.load_html_string(complex_html) print(f"Complex text page has {len(page2._children)} children") # Render both try: img1 = page1.render() img2 = page2.render() img1.save("test_simple_text.png") img2.save("test_complex_text.png") print("✓ Saved both test images") return True except Exception as e: print(f"✗ Error rendering: {e}") return False def main(): """Run all paragraph layout tests""" print("Testing paragraph layout fixes...") print("=" * 50) tests = [ ("Direct Paragraph Layout", test_paragraph_layout_directly), ("Page with Long Paragraph", test_page_with_long_paragraph), ("Simple vs Complex Text", test_simple_text_vs_paragraph), ] results = [] for test_name, test_func in tests: print(f"\nTesting: {test_name}") print("-" * 30) try: success = test_func() results.append((test_name, success)) except Exception as e: print(f"✗ Test failed with exception: {e}") import traceback traceback.print_exc() results.append((test_name, False)) # Summary print("\n" + "=" * 50) print("Test Summary:") for test_name, success in results: status = "PASS" if success else "FAIL" print(f" {test_name}: {status}") total_tests = len(results) passed_tests = sum(1 for _, success in results if success) print(f"\nPassed: {passed_tests}/{total_tests}") if __name__ == "__main__": main()