Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,4 @@ _scratch/
/spec/gen_spec/spec*.db
tags
/tests/debug.py
uv.lock
121 changes: 121 additions & 0 deletions examples/horizontal_overflow_example.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
#!/usr/bin/env python3
"""Example demonstrating horizontal overflow detection in python-pptx.

This example shows how to detect when text will overflow horizontally,
which occurs when:
1. Word wrap is enabled: Individual words are too wide to fit
2. Word wrap is disabled: Entire lines exceed the available width
"""

import sys

from pptx import Presentation
from pptx.util import Inches, Pt

prs = Presentation()
slide = prs.slides.add_slide(prs.slide_layouts[1])

shape = slide.shapes.placeholders[1]
text_frame = shape.text_frame

# Font path varies by platform - adjust for your system
if sys.platform == "darwin":
font_file = "/System/Library/Fonts/Geneva.ttf"
elif sys.platform == "win32":
font_file = "C:\\Windows\\Fonts\\arial.ttf"
else:
font_file = "/usr/share/fonts/truetype/dejavu/DejaVuSans.ttf"

print("=" * 70)
print("Horizontal Overflow Detection Examples")
print("=" * 70)
print()

# Example 1: Checking for horizontal overflow (word wrap enabled)
print("Example 1: Long URL that won't fit")
print("-" * 70)
text_frame.word_wrap = True
text_frame.text = "Visit https://very-long-subdomain.example.com/path/to/resource for more info"

# Quick check
if text_frame.will_overflow(direction='horizontal', font_size=18, font_file=font_file):
print("⚠️ Text will overflow horizontally!")

# Detailed information
info = text_frame.overflow_info(direction='horizontal', font_size=18, font_file=font_file)
print(f"Widest element: {info.widest_element}")
print(f"Required width: {info.required_width.inches:.2f} inches")
print(f"Available width: {info.available_width.inches:.2f} inches")
print(f"Overflow: {info.overflow_width_percentage:.1f}%")
print(f"Will fit at: {info.fits_at_font_size_horizontal}pt font size")
print()

# Example 2: Checking both vertical and horizontal overflow
print("Example 2: Checking both dimensions")
print("-" * 70)
text_frame.text = "Short text"

# Check both directions at once
if text_frame.will_overflow(direction='both', font_size=18, font_file=font_file):
print("Text overflows in at least one direction")
else:
print("✓ Text fits perfectly in both dimensions")
print()

# Example 3: Word wrap disabled
print("Example 3: Long line with word wrap disabled")
print("-" * 70)
text_frame.word_wrap = False
text_frame.text = "This is a very long line that will not wrap and may overflow horizontally"

info = text_frame.overflow_info(direction='horizontal', font_size=14, font_file=font_file)
if info.will_overflow_horizontally:
print(f"⚠️ Line is too wide!")
print(f"Widest line: '{info.widest_element[:50]}...'")
print(f"Overflow: {info.overflow_width_percentage:.1f}%")
print()

# Example 4: Backward compatibility - vertical overflow still works
print("Example 4: Backward compatibility (vertical overflow)")
print("-" * 70)
text_frame.word_wrap = True
text_frame.text = " ".join(["Lorem ipsum"] * 100) # Lots of text

# Default direction is 'vertical' for backward compatibility
if text_frame.will_overflow(font_size=24, font_file=font_file):
print("⚠️ Text will overflow vertically (backward compatible check)")

info = text_frame.overflow_info(font_size=24, font_file=font_file)
print(f"Estimated lines: {info.estimated_lines}")
print(f"Vertical overflow: {info.overflow_percentage:.1f}%")
print()

# Example 5: Comprehensive check
print("Example 5: Comprehensive overflow analysis")
print("-" * 70)
text_frame.word_wrap = True
text_frame.text = "Check https://example.com/very/long/url/path and " + " ".join(["text"] * 50)

# Check both directions
info = text_frame.overflow_info(direction='both', font_size=20, font_file=font_file)

print(f"Overall overflow status: {info.will_overflow}")
print()
print("Horizontal:")
print(f" Overflow: {info.will_overflow_horizontally}")
if info.will_overflow_horizontally:
print(f" Widest element: '{info.widest_element}'")
print(f" Percentage: {info.overflow_width_percentage:.1f}%")
print()
print("Vertical:")
if info.overflow_percentage and info.overflow_percentage > 0:
print(f" Overflow: True")
print(f" Percentage: {info.overflow_percentage:.1f}%")
print(f" Lines: {info.estimated_lines}")
else:
print(f" Overflow: False")

print()
print("=" * 70)
print("Examples completed!")
print("=" * 70)
66 changes: 66 additions & 0 deletions examples/overflow_detection_example.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
"""Example: Text Overflow Detection

This example demonstrates how to detect when text will overflow a text frame
before applying changes to the presentation.
"""

from pptx import Presentation
from pptx.util import Inches, Pt

# Create a presentation with a text box
prs = Presentation()
blank_slide_layout = prs.slide_layouts[6]
slide = prs.slides.add_slide(blank_slide_layout)

# Add a text box
textbox = slide.shapes.add_textbox(Inches(1), Inches(1), Inches(8), Inches(3))
text_frame = textbox.text_frame
text_frame.word_wrap = True

# Add some content
text_frame.text = "Project Overview"
for i in range(1, 11):
p = text_frame.add_paragraph()
p.text = f"Key point #{i}: Important information about the project"

# Example 1: Simple overflow check
if text_frame.will_overflow(font_family="Arial", font_size=18):
print("Warning: Content will be cut off at 18pt!")
else:
print("All content fits at 18pt")

# Example 2: Get detailed overflow information
info = text_frame.overflow_info(font_family="Arial", font_size=18)

if info.will_overflow:
print(f"\nOverflow detected:")
print(f" Required height: {info.required_height.inches:.2f} inches")
print(f" Available height: {info.available_height.inches:.2f} inches")
print(f" Overflow: {info.overflow_percentage:.1f}%")
print(f" Recommendation: Use {info.fits_at_font_size}pt font to fit")
else:
print("\nAll content fits!")

# Example 3: Find the best font size
for size in [20, 18, 16, 14, 12]:
if not text_frame.will_overflow(font_family="Arial", font_size=size):
print(f"\nLargest fitting font size: {size}pt")
break

# Example 4: Validate before applying font size
desired_size = 18
if text_frame.will_overflow(font_family="Arial", font_size=desired_size):
print(f"\nWarning: Cannot use {desired_size}pt - would overflow!")
info = text_frame.overflow_info(font_family="Arial", font_size=desired_size)
print(f"Using recommended size: {info.fits_at_font_size}pt instead")
if info.fits_at_font_size is not None:
for paragraph in text_frame.paragraphs:
for run in paragraph.runs:
run.font.size = Pt(info.fits_at_font_size)
else:
# Apply the desired size
for paragraph in text_frame.paragraphs:
for run in paragraph.runs:
run.font.size = Pt(desired_size)

prs.save("overflow_example.pptx")
Loading