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
4 changes: 3 additions & 1 deletion src/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -12881,7 +12881,9 @@ def get_textbox(
) -> str:
tp = textpage
if tp is None:
tp = page.get_textpage()
# Leave out text that a clip path hides, as get_text() and
# search_for() do. Otherwise the default flags (0) are kept.
tp = page.get_textpage(flags=TEXT_MEDIABOX_CLIP)
elif getattr(tp, "parent") != page:
raise ValueError("not a textpage of this page")
rc = tp.extractTextbox(rect)
Expand Down
9 changes: 7 additions & 2 deletions src/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -276,7 +276,9 @@ def get_textbox(
) -> str:
tp = textpage
if tp is None:
tp = page.get_textpage()
# Leave out text that a clip path hides, as get_text() and
# search_for() do. Otherwise the default flags (0) are kept.
tp = page.get_textpage(flags=pymupdf.TEXT_MEDIABOX_CLIP)
elif getattr(tp, "parent") != page:
raise ValueError("not a textpage of this page")
rc = tp.extractTextbox(rect)
Expand All @@ -295,7 +297,10 @@ def get_text_selection(
pymupdf.CheckParent(page)
tp = textpage
if tp is None:
tp = page.get_textpage(clip=clip, flags=pymupdf.TEXT_DEHYPHENATE)
tp = page.get_textpage(
clip=clip,
flags=pymupdf.TEXT_DEHYPHENATE | pymupdf.TEXT_MEDIABOX_CLIP,
)
elif getattr(tp, "parent") != page:
raise ValueError("not a textpage of this page")
rc = tp.extractSelection(p1, p2)
Expand Down
24 changes: 24 additions & 0 deletions tests/test_textextract.py
Original file line number Diff line number Diff line change
Expand Up @@ -1033,3 +1033,27 @@ def test_4994():
assert len(search_results) == 2
#assert text == 'planet-warming gas driving climate change.'
sys.stdout.flush()


def test_textbox_clipped_text():
# Text hidden by a clip path is not on the rendered page. get_text() and
# search_for() leave it out; get_textbox() and get_text_selection() must
# leave it out too, unless the caller passes a textpage of their own.
src = pymupdf.open()
src_page = src.new_page(width=400, height=200)
src_page.insert_text((20, 50), 'VISIBLE left part', fontsize=12)
src_page.insert_text((250, 50), 'HIDDEN right part', fontsize=12)

doc = pymupdf.open()
page = doc.new_page(width=400, height=200)
left = pymupdf.Rect(0, 0, 200, 200)
page.show_pdf_page(left, src, 0, clip=left) # clips away the right half

assert 'HIDDEN' not in page.get_text()
assert page.search_for('HIDDEN') == []
assert page.get_textbox(page.rect) == 'VISIBLE left part'
assert page.get_text_selection((0, 40), (400, 60)) == 'VISIBLE left part'

# An explicit textpage still decides what is extracted.
tp = page.get_textpage(flags=0)
assert 'HIDDEN' in page.get_textbox(page.rect, textpage=tp)
Loading