From 6a4df78bc060b0fcedc713d400fda788816f8242 Mon Sep 17 00:00:00 2001 From: "James R. Barlow" Date: Tue, 27 Mar 2018 13:32:38 -0700 Subject: [PATCH] Add _naive_find_text to search for text when fitz is not available --- src/ocrmypdf/pdfinfo.py | 37 ++++++++++++++++++++++++++----------- tests/test_pageinfo.py | 8 ++++++++ 2 files changed, 34 insertions(+), 11 deletions(-) diff --git a/src/ocrmypdf/pdfinfo.py b/src/ocrmypdf/pdfinfo.py index c18d05dd..a5c9d50d 100644 --- a/src/ocrmypdf/pdfinfo.py +++ b/src/ocrmypdf/pdfinfo.py @@ -554,20 +554,35 @@ def _find_images(*, pdf, container, shorthand=None): yield from _find_form_xobject_images(pdf, container, contentsinfo) -def _naive_find_text(*, pdf, container): - if container.get('/Type') == '/Page' and '/Contents' in container: - # For a /Page the content stream is attached to the page's /Contents - page = container - contentstream = pypdf.pdf.ContentStream(page.getContents(), pdf) - elif container.get('/Type') == '/XObject' and \ - container['/Subtype'] == '/Form': - # For a Form XObject that content stream is attached to the XObject - contentstream = pypdf.pdf.ContentStream(container, pdf) +def _naive_find_text(*, pdf, page): + if not(page.get('/Type') == '/Page' and '/Contents' in page): + # Not a page, or has no /Contents => no text + return False + # First we check the main content stream + contentstream = pypdf.pdf.ContentStream(page.getContents(), pdf) contentsinfo = _interpret_contents(contentstream, UNIT_SQUARE) - if contentsinfo.found_text: return True + + # Then see if there is a Form XObject with with a content stream + # that might have text. For full completeness we should recursively + # search nested Form XObjects, as we do with images. But that is + # rare. + if '/Resources' in page: + resources = page['/Resources'] + if '/XObject' in resources: + for xobj in resources['/XObject']: + candidate = resources['/XObject'][xobj] + if candidate['/Subtype'] != '/Form': + continue + form_xobject = candidate + # Content stream is attached to Form XObject dictionary + contentstream = pypdf.pdf.ContentStream(form_xobject, pdf) + sub_contentsinfo = _interpret_contents( + contentstream, UNIT_SQUARE) + if sub_contentsinfo.found_text: + return True return False @@ -594,7 +609,7 @@ def _pdf_get_pageinfo(pdf, pageno: int, infile): if fitz: pageinfo['has_text'] = _page_has_text(str(infile), pageno) else: - pageinfo['has_text'] = _naive_find_text(pdf=pdf, container=page) + pageinfo['has_text'] = _naive_find_text(pdf=pdf, page=page) width_pt = page.mediaBox.getWidth() height_pt = page.mediaBox.getHeight() diff --git a/tests/test_pageinfo.py b/tests/test_pageinfo.py index 2ef27428..e421ed52 100644 --- a/tests/test_pageinfo.py +++ b/tests/test_pageinfo.py @@ -28,6 +28,7 @@ import pytest import img2pdf import pytest import sys +import PyPDF2 as pypdf def test_single_page_text(outdir): @@ -125,6 +126,13 @@ def test_form_xobject(resources): assert pdfimage.width == 50 +def test_naive_find_text(resources): + filename = resources / 'formxobject.pdf' + reader = pypdf.PdfFileReader(str(filename)) + page = reader.getPage(0) + assert pdfinfo._naive_find_text(pdf=reader, page=page) + + def test_no_contents(resources): filename = resources / 'no_contents.pdf'