Add support for badge PDFs also

* Add a greyscale filter to text for more accurate preview
* Always default to SVG preview as it's the most accurate (cairo
  doesn't do a great job of handling custom fonts when it converts to
  png/pdf)
* Always use roboto font.
This commit is contained in:
James Polley 2017-12-26 23:55:09 +11:00
parent fcbacc82e6
commit f675580d6b
3 changed files with 24 additions and 14 deletions

View file

@ -18,11 +18,15 @@ xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve"
xmlns:serif="http://www.serif.com/" xmlns:serif="http://www.serif.com/"
style="fill-rule:evenodd;clip-rule:evenodd;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:1.5;"> style="fill-rule:evenodd;clip-rule:evenodd;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:1.5;">
<filter id="grayscale">
<feColorMatrix type="saturate" values="0"/>
</filter>
<g transform="matrix(1.40952,0,0,0.70946,0,0)"> <g transform="matrix(1.40952,0,0,0.70946,0,0)">
<rect x="0" y="0" width="1240.16" height="1748.03" <rect x="0" y="0" width="1240.16" height="1748.03"
style="fill:none;stroke:black;stroke-width:12.5px;" /> style="fill:white;stroke:black;stroke-width:12.5px;" />
</g> </g>
<g transform="matrix(0.999321,0,0,0.999446,0,-507.874)"> <g transform="matrix(0.999321,0,0,0.999446,0,-507.874)">
@ -1042,18 +1046,18 @@ style="font-family:'Roboto-Regular', 'Roboto';font-size:88.353px;">
<g transform="matrix(0.607846,0,0,0.607922,138.923,372.07)"> <g transform="matrix(0.607846,0,0,0.607922,138.923,372.07)">
<text x="0px" y="0px" <text x="0px" y="0px"
style="font-family:'Roboto-Regular', 'Roboto';font-size:144.577px;"> style="font-family:'Roboto-Regular', 'Roboto';font-size:144.577px;" filter="url(#grayscale)">
{{ user.attendee.attendeeprofilebase.attendeeprofile.name }}</text> {{ user.attendee.attendeeprofilebase.attendeeprofile.name }}</text>
</g> </g>
<g transform="matrix(0.607846,0,0,0.607922,138.923,449.05)"> <g transform="matrix(0.607846,0,0,0.607922,138.923,449.05)">
<text x="0px" y="0px" <text x="0px" y="0px"
style="font-family:'Roboto-Regular', 'Roboto';font-size:96.385px;"> style="font-family:'Roboto-Regular', 'Roboto';font-size:96.385px;" filter="url(grayscale)">
{{ user.attendee.attendeeprofilebase.attendeeprofile.company }}</text> {{ user.attendee.attendeeprofilebase.attendeeprofile.company }}</text>
</g> </g>
<g transform="matrix(0.607846,0,0,0.607922,140.5,504.582)"> <g transform="matrix(0.607846,0,0,0.607922,140.5,504.582)" filter="url(#grayscale)">
<text x="0px" y="0px" <text x="0px" y="0px"
style="font-family:'Roboto-Regular', 'Roboto';font-size:60.24px;"> style="font-family:'Roboto-Regular', 'Roboto';font-size:60.24px;">
@ -1063,7 +1067,7 @@ style="font-family:'Roboto-Regular', 'Roboto';font-size:60.24px;">
<g transform="matrix(0.607846,0,0,0.607922,140.5,550.359)"> <g transform="matrix(0.607846,0,0,0.607922,140.5,550.359)">
<text x="0px" y="0px" <text x="0px" y="0px"
style="font-family:'Roboto-Regular', 'Roboto';font-size:60.24px;"> style="font-family:'Roboto-Regular', 'Roboto';font-size:60.24px;" filter="url(#grayscale)">
{{ user.attendee.attendeeprofilebase.attendeeprofile.free_text_2 }}</text> {{ user.attendee.attendeeprofilebase.attendeeprofile.free_text_2 }}</text>
</g> </g>
@ -1072,21 +1076,21 @@ style="font-family:'Roboto-Regular', 'Roboto';font-size:60.24px;">
<g id="text23417" transform="matrix(1,0,0,1,353.552,780.612)"> <g id="text23417" transform="matrix(1,0,0,1,353.552,780.612)">
<text x="0px" y="0px" <text x="0px" y="0px"
style="font-family:'LucidaGrande-Bold', 'Lucida Grande', sans-serif;font-weight:600;font-size:72.288px;"> style="font-family:'Roboto-Bold', 'Roboto', sans-serif;font-weight:600;font-size:72.288px;">
{{ penguin_dinner_count }}</text> {{ penguin_dinner_count }}</text>
</g> </g>
<g id="text23421" transform="matrix(1,0,0,1,555.167,780.612)"> <g id="text23421" transform="matrix(1,0,0,1,555.167,780.612)">
<text x="0px" y="0px" <text x="0px" y="0px"
style="font-family:'LucidaGrande-Bold', 'Lucida Grande', sans-serif;font-weight:600;font-size:72.288px;"> style="font-family:'Roboto-Bold', 'Roboto', sans-serif;font-weight:600;font-size:72.288px;">
{{ speakers_dinner_count }}</text> {{ speakers_dinner_count }}</text>
</g> </g>
<g id="text23425" transform="matrix(1,0,0,1,753.962,780.612)"> <g id="text23425" transform="matrix(1,0,0,1,753.962,780.612)">
<text x="0px" y="0px" <text x="0px" y="0px"
style="font-family:'LucidaGrande-Bold', 'Lucida Grande', sans-serif;font-weight:600;font-size:72.288px;"> style="font-family:'Roboto-Bold', 'Roboto', sans-serif;font-weight:600;font-size:72.288px;">
{{ pdns_count }}</text> {{ pdns_count }}</text>
</g> </g>
@ -1379,7 +1383,7 @@ style="fill:white;fill-rule:nonzero;" />
<g id="text4601" transform="matrix(1,0,0,1,138.88,770.07)"> <g id="text4601" transform="matrix(1,0,0,1,138.88,770.07)">
<text x="0px" y="0px" <text x="0px" y="0px"
style="font-family:'LucidaGrande-Bold', 'Lucida Grande', sans-serif;font-weight:600;font-size:40.16px;"> style="font-family:'Roboto-Bold', 'Roboto', sans-serif;font-weight:600;font-size:40.16px;">
{% if user.attendee.attendeeprofilebase.attendeeprofile.of_legal_age %}18+{% endif %}</text> {% if user.attendee.attendeeprofilebase.attendeeprofile.of_legal_age %}18+{% endif %}</text>
</g> </g>
</g> </g>

Before

Width:  |  Height:  |  Size: 137 KiB

After

Width:  |  Height:  |  Size: 137 KiB

View file

@ -27,9 +27,9 @@ from .views import (
public = [ public = [
url(r"^amend/([0-9]+)$", amend_registration, name="amend_registration"), url(r"^amend/([0-9]+)$", amend_registration, name="amend_registration"),
url(r"^mybadge$", user_badge, name="user_badge"), url(r"^mybadge$", user_badge, name="user_badge"),
url(r"^mybadge/(png|svg)", user_badge, name="user_badge"), url(r"^mybadge\.(png|svg|pdf)", user_badge, name="user_badge"),
url(r"^badge/([0-9]+)$", badge, name="badge"), url(r"^badge/([0-9]+)$", badge, name="badge"),
url(r"^badge/([0-9]+).(png|svg)$", badge, name="badge"), url(r"^badge/([0-9]+).(png|svg|pdf)$", badge, name="badge"),
url(r"^badger/([A-Za-z0-9]+)$", badger, name="badger"), url(r"^badger/([A-Za-z0-9]+)$", badger, name="badger"),
url(r"^badger/", badger, name="badger"), url(r"^badger/", badger, name="badger"),
url(r"^category/([0-9]+)$", product_category, name="product_category"), url(r"^category/([0-9]+)$", product_category, name="product_category"),

View file

@ -38,7 +38,7 @@ from django.template import Context, Template, loader
from lxml import etree from lxml import etree
from copy import deepcopy from copy import deepcopy
from cairosvg import svg2png from cairosvg import svg2pdf, svg2png
from registrasion.forms import BadgeForm, ticket_selection from registrasion.forms import BadgeForm, ticket_selection
from registrasion.contrib.badger import ( from registrasion.contrib.badger import (
@ -1114,7 +1114,7 @@ def _get_badge_template_name():
return os.path.join(settings.PROJECT_ROOT, 'pinaxcon', 'templates', return os.path.join(settings.PROJECT_ROOT, 'pinaxcon', 'templates',
settings.BADGER_DEFAULT_SVG) settings.BADGER_DEFAULT_SVG)
@login_required @login_required
def user_badge(request, format="png"): def user_badge(request, format="svg"):
'''Shows the logged-in user their badge''' '''Shows the logged-in user their badge'''
return render_badge(request.user, format) return render_badge(request.user, format)
@ -1131,7 +1131,9 @@ def badge(request, user_id, format="svg"):
def render_badge(user, format="svg"): def render_badge(user, format="svg"):
rendered = render_badge_svg(user) rendered = render_badge_svg(user)
if format == "png": if format == "png":
rendered = svg2png(bytestring=svg, dpi=72, scale=3) rendered = svg2png(bytestring=rendered, dpi=72, scale=3)
elif format == "pdf":
rendered = svg2pdf(bytestring=rendered, dpi=72, scale=3)
response = HttpResponse(rendered) response = HttpResponse(rendered)
@ -1141,6 +1143,10 @@ def render_badge(user, format="svg"):
elif format == "png": elif format == "png":
response["Content-Type"] = "image/png" response["Content-Type"] = "image/png"
response["Content-Disposition"] = 'inline; filename="badge.png"' response["Content-Disposition"] = 'inline; filename="badge.png"'
elif format == "pdf":
response["Content-Type"] = "application/pdf"
response["Content-Disposition"] = 'inline; filename="badge.pdf"'
return response return response
def render_badge_svg(user): def render_badge_svg(user):