Skip to content

Commit

Permalink
Font rendering in weasyprint pdf fixed (SEA-1597).
Browse files Browse the repository at this point in the history
Using relative urls in weasyprint ins error pront, better create urls.
  • Loading branch information
cyrillkuettel committed Nov 14, 2024
1 parent ac13197 commit 5677fc2
Show file tree
Hide file tree
Showing 43 changed files with 85 additions and 52,499 deletions.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file removed src/privatim/reporting/fonts/fa-brands-400.eot
Binary file not shown.
3,717 changes: 0 additions & 3,717 deletions src/privatim/reporting/fonts/fa-brands-400.svg

This file was deleted.

Binary file removed src/privatim/reporting/fonts/fa-brands-400.ttf
Binary file not shown.
Binary file removed src/privatim/reporting/fonts/fa-brands-400.woff
Binary file not shown.
Binary file removed src/privatim/reporting/fonts/fa-brands-400.woff2
Binary file not shown.
Binary file removed src/privatim/reporting/fonts/fa-duotone-900.eot
Binary file not shown.
15,328 changes: 0 additions & 15,328 deletions src/privatim/reporting/fonts/fa-duotone-900.svg

This file was deleted.

Binary file removed src/privatim/reporting/fonts/fa-duotone-900.ttf
Binary file not shown.
Binary file removed src/privatim/reporting/fonts/fa-duotone-900.woff
Binary file not shown.
Binary file removed src/privatim/reporting/fonts/fa-duotone-900.woff2
Binary file not shown.
Binary file removed src/privatim/reporting/fonts/fa-light-300.eot
Binary file not shown.
12,423 changes: 0 additions & 12,423 deletions src/privatim/reporting/fonts/fa-light-300.svg

This file was deleted.

Binary file removed src/privatim/reporting/fonts/fa-light-300.ttf
Binary file not shown.
Binary file removed src/privatim/reporting/fonts/fa-light-300.woff
Binary file not shown.
Binary file removed src/privatim/reporting/fonts/fa-light-300.woff2
Binary file not shown.
Binary file removed src/privatim/reporting/fonts/fa-regular-400.eot
Binary file not shown.
11,323 changes: 0 additions & 11,323 deletions src/privatim/reporting/fonts/fa-regular-400.svg

This file was deleted.

Binary file removed src/privatim/reporting/fonts/fa-regular-400.ttf
Binary file not shown.
Binary file removed src/privatim/reporting/fonts/fa-regular-400.woff
Binary file not shown.
Binary file removed src/privatim/reporting/fonts/fa-regular-400.woff2
Binary file not shown.
Binary file removed src/privatim/reporting/fonts/fa-solid-900.eot
Binary file not shown.
9,653 changes: 0 additions & 9,653 deletions src/privatim/reporting/fonts/fa-solid-900.svg

This file was deleted.

Binary file removed src/privatim/reporting/fonts/fa-solid-900.ttf
Binary file not shown.
Binary file removed src/privatim/reporting/fonts/fa-solid-900.woff
Binary file not shown.
Binary file removed src/privatim/reporting/fonts/fa-solid-900.woff2
Binary file not shown.
100 changes: 78 additions & 22 deletions src/privatim/reporting/report.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,13 @@
from datetime import datetime
from io import BytesIO
from pathlib import Path

from babel.dates import format_datetime

from privatim.i18n import translate, _
from privatim.layouts.layout import DEFAULT_TIMEZONE
from privatim.utils import datetime_format
from pyramid.renderers import render
from weasyprint import HTML # type: ignore
from weasyprint import HTML, CSS # type: ignore
from weasyprint.text.fonts import FontConfiguration # type: ignore


from typing import TYPE_CHECKING, Protocol
Expand Down Expand Up @@ -100,44 +99,37 @@ def build(self) -> PDFDocument:
class HTMLReportRenderer:
"""
Render meeting report with WeasyPrint, using HTML and CSS.
You can turn on logging for weasyprint to debug issues:
>>> import logging, sys
>>> logger = logging.getLogger('weasyprint')
>>> logger.setLevel(logging.DEBUG)
>>> logger.addHandler(logging.StreamHandler(sys.stdout))
"""

template = 'privatim:reporting/template/report.pt'

def render(
self,
meeting: 'Meeting',
timestamp: str,
request: 'IRequest'
self,
meeting: 'Meeting',
timestamp: str,
request: 'IRequest'
) -> bytes:
html = self.render_template(meeting, timestamp, request)
return self.render_pdf(html)
return self.render_pdf(html, request)

def render_template(
self,
meeting: 'Meeting',
timestamp: str,
request: 'IRequest'
self,
meeting: 'Meeting',
timestamp: str,
request: 'IRequest'
) -> str:
"""Render chameleon report template."""

document_context = {'title': meeting.name, 'created_at': timestamp}

title = translate(
_(
"Protocol of meeting ${title}",
mapping={'title': document_context['title']},
)
)

ctx = {
'title': title,
'meeting': meeting,
Expand All @@ -147,12 +139,76 @@ def render_template(
}
return render(self.template, ctx)

def render_pdf(self, html: str) -> bytes:
def render_pdf(self, html: str, request: 'IRequest') -> bytes:
"""
Render processed chameleon template as PDF.
"""

resource_base_url = Path.cwd() / 'privatim' / 'reporting'
buffer = BytesIO()
HTML(string=html, base_url=str(resource_base_url)).write_pdf(buffer)

italic_font_name = 'dm-sans-v6-latin-ext_latin-500italic.woff'
italic_font_name_woff2 = 'dm-sans-v6-latin-ext_latin-500italic.woff2'
regular_font_name = 'dm-sans-v6-latin-ext_latin-500.woff'
regular_font_name_woff2 = 'dm-sans-v6-latin-ext_latin-500.woff2'
normal_font_name = 'dm-sans-v6-latin-ext_latin-regular.woff'
normal_font_name_woff2 = 'dm-sans-v6-latin-ext_latin-regular.woff2'
normal_italic_font_name = 'dm-sans-v6-latin-ext_latin-italic.woff'
normal_italic_font_name_wo2 = 'dm-sans-v6-latin-ext_latin-italic.woff2'
base_font_url = 'privatim:static/fonts/'

# Create URLs first
font_paths = {
'regular': f'{base_font_url}{regular_font_name}',
'regular_woff2': f'{base_font_url}{regular_font_name_woff2}',
'italic': f'{base_font_url}{italic_font_name}',
'italic_woff2': f'{base_font_url}{italic_font_name_woff2}',
'normal': f'{base_font_url}{normal_font_name}',
'normal_woff2': f'{base_font_url}{normal_font_name_woff2}',
'normal_italic': f'{base_font_url}{normal_italic_font_name}',
'normal_italic_woff2': f'{base_font_url}'
f'{normal_italic_font_name_wo2}',
}

font_urls = {
key: request.static_url(path) for key, path in font_paths.items()
}

font_config = FontConfiguration()
css_font_face = f'''
@font-face {{
font-family: 'DM Sans';
font-style: normal;
font-weight: 400;
src: url({font_urls['normal_woff2']}) format('woff2'),
url({font_urls['normal']}) format('woff');
}}
@font-face {{
font-family: 'DM Sans';
font-style: italic;
font-weight: 400;
src: url({font_urls['normal_italic_woff2']}) format('woff2'),
url({font_urls['normal_italic']}) format('woff');
}}
@font-face {{
font-family: 'DM Sans';
font-style: normal;
font-weight: 500;
src: url({font_urls['regular_woff2']}) format('woff2'),
url({font_urls['regular']}) format('woff');
}}
@font-face {{
font-family: 'DM Sans';
font-style: italic;
font-weight: 500;
src: url({font_urls['italic_woff2']}) format('woff2'),
url({font_urls['italic']}) format('woff');
}}
'''

css = CSS(string=css_font_face, font_config=font_config)
HTML(string=html, base_url=str(resource_base_url)).write_pdf(
buffer,
stylesheets=[css],
font_config=font_config
)
return buffer.getvalue()
40 changes: 7 additions & 33 deletions src/privatim/reporting/template/report.pt

Large diffs are not rendered by default.

0 comments on commit 5677fc2

Please sign in to comment.