From 9462f0a28fd73f235ee4a79b440b144f4406f673 Mon Sep 17 00:00:00 2001 From: "James R. Barlow" Date: Thu, 7 May 2020 02:59:24 -0700 Subject: [PATCH] graft: more refactoring --- src/ocrmypdf/_graft.py | 92 ++++++++++++++++++++++-------------------- 1 file changed, 48 insertions(+), 44 deletions(-) diff --git a/src/ocrmypdf/_graft.py b/src/ocrmypdf/_graft.py index 768b94ca..de9ebda0 100644 --- a/src/ocrmypdf/_graft.py +++ b/src/ocrmypdf/_graft.py @@ -161,10 +161,13 @@ class OcrGrafter: self.save_and_reload() def save_and_reload(self): - # Periodically save and reload the Pdf object. This will keep a - # lid on our memory usage for very large files. Attach the font to - # page 1 even if page 1 doesn't use it, so we have a way to get it - # back. + """Save and reload the Pdf. + + This will keep a lid on our memory usage for very large files. Attach + the font to page 1 even if page 1 doesn't use it, so we have a way to get it + back. + """ + page0 = self.pdf_base.pages[0] _update_page_resources( page=page0, font=self.font, font_key=self.font_key, procset=self.procset @@ -237,55 +240,56 @@ class OcrGrafter: return # This is a pointer indicating a specific page in the base file - pdf_text = pikepdf.open(textpdf) - pdf_text_contents = pdf_text.pages[0].Contents.read_bytes() + with pikepdf.open(textpdf) as pdf_text: + pdf_text_contents = pdf_text.pages[0].Contents.read_bytes() - base_page = self.pdf_base.pages.p(page_num) + base_page = self.pdf_base.pages.p(page_num) - # The text page always will be oriented up by this stage but the original - # content may have a rotation applied. Wrap the text stream with a rotation - # so it will be oriented the same way as the rest of the page content. - # (Previous versions OCRmyPDF rotated the content layer to match the text.) - mediabox = [float(pdf_text.pages[0].MediaBox[v]) for v in range(4)] - wt, ht = mediabox[2] - mediabox[0], mediabox[3] - mediabox[1] + # The text page always will be oriented up by this stage but the original + # content may have a rotation applied. Wrap the text stream with a rotation + # so it will be oriented the same way as the rest of the page content. + # (Previous versions OCRmyPDF rotated the content layer to match the text.) + mediabox = [float(pdf_text.pages[0].MediaBox[v]) for v in range(4)] + wt, ht = mediabox[2] - mediabox[0], mediabox[3] - mediabox[1] - mediabox = [float(base_page.MediaBox[v]) for v in range(4)] - wp, hp = mediabox[2] - mediabox[0], mediabox[3] - mediabox[1] + mediabox = [float(base_page.MediaBox[v]) for v in range(4)] + wp, hp = mediabox[2] - mediabox[0], mediabox[3] - mediabox[1] - translate = pikepdf.PdfMatrix().translated(-wt / 2, -ht / 2) - untranslate = pikepdf.PdfMatrix().translated(wp / 2, hp / 2) - corner = pikepdf.PdfMatrix().translated(mediabox[0], mediabox[1]) - # -rotation because the input is a clockwise angle and this formula - # uses CCW - rotation = -rotation % 360 - rotate = pikepdf.PdfMatrix().rotated(rotation) + translate = pikepdf.PdfMatrix().translated(-wt / 2, -ht / 2) + untranslate = pikepdf.PdfMatrix().translated(wp / 2, hp / 2) + corner = pikepdf.PdfMatrix().translated(mediabox[0], mediabox[1]) + # -rotation because the input is a clockwise angle and this formula + # uses CCW + rotation = -rotation % 360 + rotate = pikepdf.PdfMatrix().rotated(rotation) - # Because of rounding of DPI, we might get a text layer that is not - # identically sized to the target page. Scale to adjust. Normally this - # is within 0.998. - if rotation in (90, 270): - wt, ht = ht, wt - scale_x = wp / wt - scale_y = hp / ht + # Because of rounding of DPI, we might get a text layer that is not + # identically sized to the target page. Scale to adjust. Normally this + # is within 0.998. + if rotation in (90, 270): + wt, ht = ht, wt + scale_x = wp / wt + scale_y = hp / ht - # log.debug('%r', scale_x, scale_y) - scale = pikepdf.PdfMatrix().scaled(scale_x, scale_y) + # log.debug('%r', scale_x, scale_y) + scale = pikepdf.PdfMatrix().scaled(scale_x, scale_y) - # Translate the text so it is centered at (0, 0), rotate it there, adjust - # for a size different between initial and text PDF, then untranslate, and - # finally move the lower left corner to match the mediabox - ctm = translate @ rotate @ scale @ untranslate @ corner + # Translate the text so it is centered at (0, 0), rotate it there, adjust + # for a size different between initial and text PDF, then untranslate, and + # finally move the lower left corner to match the mediabox + ctm = translate @ rotate @ scale @ untranslate @ corner - pdf_text_contents = b'q %s cm\n' % ctm.encode() + pdf_text_contents + b'\nQ\n' + pdf_text_contents = ( + b'q %s cm\n' % ctm.encode() + pdf_text_contents + b'\nQ\n' + ) - new_text_layer = pikepdf.Stream(self.pdf_base, pdf_text_contents) + new_text_layer = pikepdf.Stream(self.pdf_base, pdf_text_contents) - if strip_old_text: - strip_invisible_text(self.pdf_base, base_page) + if strip_old_text: + strip_invisible_text(self.pdf_base, base_page) - base_page.page_contents_add(new_text_layer, prepend=True) + base_page.page_contents_add(new_text_layer, prepend=True) - _update_page_resources( - page=base_page, font=font, font_key=font_key, procset=procset - ) - pdf_text.close() + _update_page_resources( + page=base_page, font=font, font_key=font_key, procset=procset + )