175 lines
6.2 KiB
Python
175 lines
6.2 KiB
Python
#!/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 = """
|
|
<html>
|
|
<body>
|
|
<h1>Test Long Paragraph</h1>
|
|
<p>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.</p>
|
|
<p>This is another paragraph to test multiple paragraph rendering and spacing between paragraphs.</p>
|
|
</body>
|
|
</html>
|
|
"""
|
|
|
|
# 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 = "<p>Short text</p>"
|
|
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 = """
|
|
<p>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.</p>
|
|
"""
|
|
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()
|