modm_data.pdf.render
1# Copyright 2022, Niklas Hauser 2# SPDX-License-Identifier: MPL-2.0 3 4import math 5import ctypes 6from ..utils import VLine, HLine 7import pypdfium2 as pp 8 9def _vline(pageobj, rotation, x, y0, y1, **kw): 10 _line(pageobj, rotation, VLine(x, y0, y1), **kw) 11 12def _hline(pageobj, rotation, y, x0, x1, **kw): 13 _line(pageobj, rotation, HLine(y, x0, x1), **kw) 14 15def _line(pageobj, rotation, line, **kw): 16 if rotation: 17 obj = pp.raw.FPDFPageObj_CreateNewPath(height - line.p0.y, line.p0.x) 18 assert pp.raw.FPDFPath_LineTo(obj, height - line.p1.y, line.p1.x) 19 else: 20 obj = pp.raw.FPDFPageObj_CreateNewPath(line.p0.x, line.p0.y) 21 assert pp.raw.FPDFPath_LineTo(obj, line.p1.x, line.p1.y) 22 if fill := kw.get("fill"): 23 assert pp.raw.FPDFPageObj_SetFillColor(obj, (fill >> 16) & 0xff, (fill >> 8) & 0xff, fill & 0xff, 0xC0) 24 if stroke := kw.get("stroke"): 25 assert pp.raw.FPDFPageObj_SetStrokeColor(obj, (stroke >> 16) & 0xff, (stroke >> 8) & 0xff, stroke & 0xff, 0xC0) 26 if width := kw.get("width"): 27 assert pp.raw.FPDFPageObj_SetStrokeWidth(obj, width) 28 assert pp.raw.FPDFPath_SetDrawMode(obj, 1 if kw.get("fill") else 0, 29 kw.get("width") is not None) 30 pp.raw.FPDFPage_InsertObject(pageobj, obj) 31 32def _rect(pageobj, rotation, rect, **kw): 33 if rotation: 34 obj = pp.raw.FPDFPageObj_CreateNewRect( 35 height - rect.bottom - rect.height, rect.left, rect.height, rect.width) 36 else: 37 obj = pp.raw.FPDFPageObj_CreateNewRect(rect.left, rect.bottom, rect.width, rect.height) 38 if fill := kw.get("fill"): 39 assert pp.raw.FPDFPageObj_SetFillColor(obj, (fill >> 16) & 0xff, (fill >> 8) & 0xff, fill & 0xff, 0xC0) 40 if stroke := kw.get("stroke"): 41 assert pp.raw.FPDFPageObj_SetStrokeColor(obj, (stroke >> 16) & 0xff, (stroke >> 8) & 0xff, stroke & 0xff, 0xC0) 42 if width := kw.get("width"): 43 assert pp.raw.FPDFPageObj_SetStrokeWidth(obj, width) 44 assert pp.raw.FPDFPath_SetDrawMode(obj, 1 if kw.get("fill") else 0, 45 kw.get("width") is not None) 46 pp.raw.FPDFPage_InsertObject(pageobj, obj) 47 48 49 50def render_page_pdf(doc, page, new_doc = None, index = 0): 51 width, height = page.width, page.height 52 53 if new_doc is None: 54 new_doc = pp.raw.FPDF_CreateNewDocument() 55 # copy page over to new doc 56 assert pp.raw.FPDF_ImportPages(new_doc, doc, str(page.number).encode("ascii"), index) 57 new_page = pp.raw.FPDF_LoadPage(new_doc, index) 58 rotation = page.rotation 59 60 for path in page.paths: 61 p0 = path.points[0] 62 if rotation: obj = pp.raw.FPDFPageObj_CreateNewPath(height - p0.y, p0.x) 63 else: obj = pp.raw.FPDFPageObj_CreateNewPath(p0.x, p0.y) 64 assert pp.raw.FPDFPageObj_SetStrokeColor(obj, 0,0,0xff, 0xC0) 65 assert pp.raw.FPDFPageObj_SetStrokeWidth(obj, 0.25) 66 assert pp.raw.FPDFPageObj_SetLineJoin(obj, pp.raw.FPDF_LINEJOIN_ROUND) 67 assert pp.raw.FPDFPageObj_SetLineCap(obj, pp.raw.FPDF_LINECAP_ROUND) 68 assert pp.raw.FPDFPath_SetDrawMode(obj, 0, True) 69 for point in path.points[1:]: 70 if point.type == path.Type.MOVE: 71 if rotation: assert pp.raw.FPDFPath_MoveTo(obj, height - point.y, point.x) 72 else: assert pp.raw.FPDFPath_MoveTo(obj, point.x, point.y) 73 else: 74 if rotation: assert pp.raw.FPDFPath_LineTo(obj, height - point.y, point.x) 75 else: assert pp.raw.FPDFPath_LineTo(obj, point.x, point.y) 76 pp.raw.FPDFPage_InsertObject(new_page, obj) 77 78 for bbox, _ in page.graphic_clusters(): 79 _rect(new_page, rotation, bbox, width=2, stroke=0x00FFFF) 80 81 for link in page.objlinks: 82 _rect(new_page, rotation, link.bbox, width=0.75, stroke=0x9ACD32) 83 84 for link in page.weblinks: 85 for bbox in link.bboxes: 86 _rect(new_page, rotation, bbox, width=0.75, stroke=0x00ff00) 87 88 for char in page.chars: 89 color = 0x0000ff 90 if char.bbox.width: 91 _rect(new_page, rotation, char.bbox, width=0.5, stroke=0xff0000) 92 _vline(new_page, rotation, char.bbox.midpoint.x, char.bbox.midpoint.y - 1, char.bbox.midpoint.y + 1, width=0.25, stroke=0xff0000) 93 _hline(new_page, rotation, char.bbox.midpoint.y, char.bbox.midpoint.x - 1, char.bbox.midpoint.x + 1, width=0.25, stroke=0xff0000) 94 color = 0x000000 95 _vline(new_page, rotation, char.origin.x, char.origin.y - 1, char.origin.y + 1, width=0.25, stroke=color) 96 _hline(new_page, rotation, char.origin.y, char.origin.x - 1, char.origin.x + 1, width=0.25, stroke=color) 97 98 assert pp.raw.FPDFPage_GenerateContent(new_page) 99 pp.raw.FPDF_ClosePage(new_page) 100 return new_doc
def
render_page_pdf(doc, page, new_doc=None, index=0):
51def render_page_pdf(doc, page, new_doc = None, index = 0): 52 width, height = page.width, page.height 53 54 if new_doc is None: 55 new_doc = pp.raw.FPDF_CreateNewDocument() 56 # copy page over to new doc 57 assert pp.raw.FPDF_ImportPages(new_doc, doc, str(page.number).encode("ascii"), index) 58 new_page = pp.raw.FPDF_LoadPage(new_doc, index) 59 rotation = page.rotation 60 61 for path in page.paths: 62 p0 = path.points[0] 63 if rotation: obj = pp.raw.FPDFPageObj_CreateNewPath(height - p0.y, p0.x) 64 else: obj = pp.raw.FPDFPageObj_CreateNewPath(p0.x, p0.y) 65 assert pp.raw.FPDFPageObj_SetStrokeColor(obj, 0,0,0xff, 0xC0) 66 assert pp.raw.FPDFPageObj_SetStrokeWidth(obj, 0.25) 67 assert pp.raw.FPDFPageObj_SetLineJoin(obj, pp.raw.FPDF_LINEJOIN_ROUND) 68 assert pp.raw.FPDFPageObj_SetLineCap(obj, pp.raw.FPDF_LINECAP_ROUND) 69 assert pp.raw.FPDFPath_SetDrawMode(obj, 0, True) 70 for point in path.points[1:]: 71 if point.type == path.Type.MOVE: 72 if rotation: assert pp.raw.FPDFPath_MoveTo(obj, height - point.y, point.x) 73 else: assert pp.raw.FPDFPath_MoveTo(obj, point.x, point.y) 74 else: 75 if rotation: assert pp.raw.FPDFPath_LineTo(obj, height - point.y, point.x) 76 else: assert pp.raw.FPDFPath_LineTo(obj, point.x, point.y) 77 pp.raw.FPDFPage_InsertObject(new_page, obj) 78 79 for bbox, _ in page.graphic_clusters(): 80 _rect(new_page, rotation, bbox, width=2, stroke=0x00FFFF) 81 82 for link in page.objlinks: 83 _rect(new_page, rotation, link.bbox, width=0.75, stroke=0x9ACD32) 84 85 for link in page.weblinks: 86 for bbox in link.bboxes: 87 _rect(new_page, rotation, bbox, width=0.75, stroke=0x00ff00) 88 89 for char in page.chars: 90 color = 0x0000ff 91 if char.bbox.width: 92 _rect(new_page, rotation, char.bbox, width=0.5, stroke=0xff0000) 93 _vline(new_page, rotation, char.bbox.midpoint.x, char.bbox.midpoint.y - 1, char.bbox.midpoint.y + 1, width=0.25, stroke=0xff0000) 94 _hline(new_page, rotation, char.bbox.midpoint.y, char.bbox.midpoint.x - 1, char.bbox.midpoint.x + 1, width=0.25, stroke=0xff0000) 95 color = 0x000000 96 _vline(new_page, rotation, char.origin.x, char.origin.y - 1, char.origin.y + 1, width=0.25, stroke=color) 97 _hline(new_page, rotation, char.origin.y, char.origin.x - 1, char.origin.x + 1, width=0.25, stroke=color) 98 99 assert pp.raw.FPDFPage_GenerateContent(new_page) 100 pp.raw.FPDF_ClosePage(new_page) 101 return new_doc