Custom fonts for PDF no longer working in 2.8.4

Asked by Daniel Owens on 2016-01-12

Previously I was able to set up Schooltool to use Dejavu fonts instead of Ubuntu (to get the full set of glyphs for Vietnamese).

I did the following:

* I installed the Dejavu font package.
* In /etc/schooltool/standard/schooltool.conf, under reportlab_fontdir, I added: reportlab_fontdir /usr/share/fonts/opentype/liberation:/usr/share/fonts/truetype/dejavu
* In /usr/lib/python2.7/dist-packages/schooltool/app/pdf.py: for font_map I changed to the following:
font_map = {
    'Arial_Normal': 'LiberationSans-Regular.ttf',
    'Arial_Bold': 'LiberationSans-Bold.ttf',
    'Arial_Italic': 'LiberationSans-Italic.ttf',
    'Arial_Bold_Italic': 'LiberationSans-BoldItalic.ttf',
    'Times_New_Roman': 'LiberationSerif-Regular.ttf',
    'Times_New_Roman_Bold': 'LiberationSerif-Bold.ttf',
    'Times_New_Roman_Italic': 'LiberationSerif-Italic.ttf',
    'Times_New_Roman_Bold_Italic': 'LiberationSerif-BoldItalic.ttf',
# 'Ubuntu_Regular': 'Ubuntu-R.ttf',
# 'Ubuntu_Bold': 'Ubuntu-B.ttf',
# 'Ubuntu_Italic': 'Ubuntu-RI.ttf',
# 'Ubuntu_Bold_Italic': 'Ubuntu-BI.ttf',
    'Ubuntu_Regular': 'DejaVuSans.ttf',
    'Ubuntu_Bold': 'DejaVuSans-Bold.ttf',
# 'Ubuntu_Italic': 'DejaVuSans-Italic.ttf',
# 'Ubuntu_Bold_Italic': 'DejaVuSans-BoldItalic.ttf',
    }

Previously this worked. But I see now with 2.8.4 it does not work. Is there any way to fix this? Ideally I would like the PDF output to be configurable so that I can choose the font easily within Schooltool. But if not, I would like to be able to make this change myself. Another option would be to choose the Noto fonts rather than Ubuntu fonts since the former support the full range of glyphs.

Anyway, any guidance would be welcome. Traceback is below the asterisks.

***

System failure.

Ticket nr. 40ed54ac-5bec-4ada-b383-d0fac652b141.

Please contact your administrator.

Exception
'Ubuntu_Regular'
Traceback
File "/usr/lib/python2.7/dist-packages/schooltool/task/tasks.py", line 184, in runTransaction
  result = callable(*args, **kw)
File "/usr/lib/python2.7/dist-packages/schooltool/report/report.py", line 451, in execute
  report_file = self.renderToFile(renderer, *args, **kwargs)
File "/usr/lib/python2.7/dist-packages/schooltool/report/report.py", line 500, in renderToFile
  self.renderReport(renderer, stream, *args, **kw)
File "/usr/lib/python2.7/dist-packages/schooltool/report/report.py", line 540, in renderReport
  rml = renderer.render()
File "/usr/lib/python2.7/dist-packages/schooltool/skin/flourish/page.py", line 56, in render
  return self.template(*args, **kw)
File "/usr/lib/python2.7/dist-packages/zope/browserpage/viewpagetemplatefile.py", line 81, in __call__
  return self.im_func(im_self, *args, **kw)
File "/usr/lib/python2.7/dist-packages/zope/browserpage/viewpagetemplatefile.py", line 49, in __call__
  sourceAnnotations=getattr(debug_flags, 'sourceAnnotations', 0),
File "/usr/lib/python2.7/dist-packages/zope/pagetemplate/pagetemplate.py", line 132, in pt_render
  strictinsert=0, sourceAnnotations=sourceAnnotations
Template "/usr/lib/python2.7/dist-packages/schooltool/skin/flourish/rml/pdf.pt"
File "/usr/lib/python2.7/dist-packages/zope/pagetemplate/pagetemplate.py", line 241, in __call__
  interpreter()
File "/usr/lib/python2.7/dist-packages/zope/tal/talinterpreter.py", line 271, in __call__
  self.interpret(self.program)
File "/usr/lib/python2.7/dist-packages/zope/tal/talinterpreter.py", line 343, in interpret
  handlers[opcode](self, args)
File "/usr/lib/python2.7/dist-packages/zope/tal/talinterpreter.py", line 533, in do_optTag_tal
  self.do_optTag(stuff)
File "/usr/lib/python2.7/dist-packages/zope/tal/talinterpreter.py", line 518, in do_optTag
  return self.no_tag(start, program)
File "/usr/lib/python2.7/dist-packages/zope/tal/talinterpreter.py", line 513, in no_tag
  self.interpret(program)
File "/usr/lib/python2.7/dist-packages/zope/tal/talinterpreter.py", line 343, in interpret
  handlers[opcode](self, args)
File "/usr/lib/python2.7/dist-packages/zope/tal/talinterpreter.py", line 533, in do_optTag_tal
  self.do_optTag(stuff)
File "/usr/lib/python2.7/dist-packages/zope/tal/talinterpreter.py", line 518, in do_optTag
  return self.no_tag(start, program)
File "/usr/lib/python2.7/dist-packages/zope/tal/talinterpreter.py", line 513, in no_tag
  self.interpret(program)
File "/usr/lib/python2.7/dist-packages/zope/tal/talinterpreter.py", line 343, in interpret
  handlers[opcode](self, args)
File "/usr/lib/python2.7/dist-packages/zope/tal/talinterpreter.py", line 533, in do_optTag_tal
  self.do_optTag(stuff)
File "/usr/lib/python2.7/dist-packages/zope/tal/talinterpreter.py", line 518, in do_optTag
  return self.no_tag(start, program)
File "/usr/lib/python2.7/dist-packages/zope/tal/talinterpreter.py", line 513, in no_tag
  self.interpret(program)
File "/usr/lib/python2.7/dist-packages/zope/tal/talinterpreter.py", line 343, in interpret
  handlers[opcode](self, args)
File "/usr/lib/python2.7/dist-packages/zope/tal/talinterpreter.py", line 742, in do_insertStructure_tal
  structure = self.engine.evaluateStructure(expr)
File "/usr/lib/python2.7/dist-packages/zope/tales/tales.py", line 696, in evaluate
  return expression(self)
Template "/usr/lib/python2.7/dist-packages/schooltool/skin/flourish/rml/pdf.pt", line 20, column 8
  Expression: <PathExpr standard:u'view/providers/story'>
File "/usr/lib/python2.7/dist-packages/zope/tales/expressions.py", line 217, in __call__
  return self._eval(econtext)
File "/usr/lib/python2.7/dist-packages/zope/tales/expressions.py", line 211, in _eval
  return ob()
File "/usr/lib/python2.7/dist-packages/schooltool/skin/flourish/content.py", line 56, in __call__
  return self.render(*args, **kw)
File "/usr/lib/python2.7/dist-packages/schooltool/skin/flourish/viewlet.py", line 235, in <lambda>
  render = lambda self, *args, **kw: self.template(*args, **kw)
File "/usr/lib/python2.7/dist-packages/zope/browserpage/viewpagetemplatefile.py", line 81, in __call__
  return self.im_func(im_self, *args, **kw)
File "/usr/lib/python2.7/dist-packages/schooltool/common/inlinept.py", line 110, in __call__
  showtal=getattr(instance.request.debug, 'showTAL', False),
File "/usr/lib/python2.7/dist-packages/zope/pagetemplate/pagetemplate.py", line 132, in pt_render
  strictinsert=0, sourceAnnotations=sourceAnnotations
File "/usr/lib/python2.7/dist-packages/zope/pagetemplate/pagetemplate.py", line 241, in __call__
  interpreter()
File "/usr/lib/python2.7/dist-packages/zope/tal/talinterpreter.py", line 271, in __call__
  self.interpret(self.program)
File "/usr/lib/python2.7/dist-packages/zope/tal/talinterpreter.py", line 343, in interpret
  handlers[opcode](self, args)
File "/usr/lib/python2.7/dist-packages/zope/tal/talinterpreter.py", line 821, in do_loop_tal
  self.interpret(block)
File "/usr/lib/python2.7/dist-packages/zope/tal/talinterpreter.py", line 343, in interpret
  handlers[opcode](self, args)
File "/usr/lib/python2.7/dist-packages/zope/tal/talinterpreter.py", line 533, in do_optTag_tal
  self.do_optTag(stuff)
File "/usr/lib/python2.7/dist-packages/zope/tal/talinterpreter.py", line 518, in do_optTag
  return self.no_tag(start, program)
File "/usr/lib/python2.7/dist-packages/zope/tal/talinterpreter.py", line 513, in no_tag
  self.interpret(program)
File "/usr/lib/python2.7/dist-packages/zope/tal/talinterpreter.py", line 343, in interpret
  handlers[opcode](self, args)
File "/usr/lib/python2.7/dist-packages/zope/tal/talinterpreter.py", line 531, in do_optTag_tal
  self.no_tag(stuff[-2], stuff[-1])
File "/usr/lib/python2.7/dist-packages/zope/tal/talinterpreter.py", line 513, in no_tag
  self.interpret(program)
File "/usr/lib/python2.7/dist-packages/zope/tal/talinterpreter.py", line 343, in interpret
  handlers[opcode](self, args)
File "/usr/lib/python2.7/dist-packages/zope/tal/talinterpreter.py", line 742, in do_insertStructure_tal
  structure = self.engine.evaluateStructure(expr)
File "/usr/lib/python2.7/dist-packages/zope/tales/tales.py", line 696, in evaluate
  return expression(self)
Template "None", line 3, column 6
  Expression: <PathExpr standard:'student/schooltool:content/transcript'>
File "/usr/lib/python2.7/dist-packages/zope/tales/expressions.py", line 217, in __call__
  return self._eval(econtext)
File "/usr/lib/python2.7/dist-packages/zope/tales/expressions.py", line 211, in _eval
  return ob()
File "/usr/lib/python2.7/dist-packages/schooltool/skin/flourish/content.py", line 56, in __call__
  return self.render(*args, **kw)
File "/usr/lib/python2.7/dist-packages/schooltool/skin/flourish/viewlet.py", line 235, in <lambda>
  render = lambda self, *args, **kw: self.template(*args, **kw)
File "/usr/lib/python2.7/dist-packages/zope/browserpage/viewpagetemplatefile.py", line 81, in __call__
  return self.im_func(im_self, *args, **kw)
File "/usr/lib/python2.7/dist-packages/schooltool/common/inlinept.py", line 110, in __call__
  showtal=getattr(instance.request.debug, 'showTAL', False),
File "/usr/lib/python2.7/dist-packages/zope/pagetemplate/pagetemplate.py", line 132, in pt_render
  strictinsert=0, sourceAnnotations=sourceAnnotations
File "/usr/lib/python2.7/dist-packages/zope/pagetemplate/pagetemplate.py", line 241, in __call__
  interpreter()
File "/usr/lib/python2.7/dist-packages/zope/tal/talinterpreter.py", line 271, in __call__
  self.interpret(self.program)
File "/usr/lib/python2.7/dist-packages/zope/tal/talinterpreter.py", line 343, in interpret
  handlers[opcode](self, args)
File "/usr/lib/python2.7/dist-packages/zope/tal/talinterpreter.py", line 821, in do_loop_tal
  self.interpret(block)
File "/usr/lib/python2.7/dist-packages/zope/tal/talinterpreter.py", line 343, in interpret
  handlers[opcode](self, args)
File "/usr/lib/python2.7/dist-packages/zope/tal/talinterpreter.py", line 533, in do_optTag_tal
  self.do_optTag(stuff)
File "/usr/lib/python2.7/dist-packages/zope/tal/talinterpreter.py", line 518, in do_optTag
  return self.no_tag(start, program)
File "/usr/lib/python2.7/dist-packages/zope/tal/talinterpreter.py", line 513, in no_tag
  self.interpret(program)
File "/usr/lib/python2.7/dist-packages/zope/tal/talinterpreter.py", line 343, in interpret
  handlers[opcode](self, args)
File "/usr/lib/python2.7/dist-packages/zope/tal/talinterpreter.py", line 583, in do_setLocal_tal
  self.engine.setLocal(name, self.engine.evaluateValue(expr))
File "/usr/lib/python2.7/dist-packages/zope/tales/tales.py", line 696, in evaluate
  return expression(self)
Template "None", line 3, column 10
  Expression: <PathExpr standard:'viewlet'>
File "/usr/lib/python2.7/dist-packages/zope/tales/expressions.py", line 217, in __call__
  return self._eval(econtext)
File "/usr/lib/python2.7/dist-packages/zope/tales/expressions.py", line 211, in _eval
  return ob()
File "/usr/lib/python2.7/dist-packages/schooltool/skin/flourish/viewlet.py", line 73, in __call__
  return self.render(*args, **kw)
File "/usr/lib/python2.7/dist-packages/schooltool/skin/flourish/zcml_content.py", line 186, in <lambda>
  setattr(new_class, attr, lambda *a, **kw: method(*a, **kw))
File "/usr/lib/python2.7/dist-packages/zope/browserpage/viewpagetemplatefile.py", line 81, in __call__
  return self.im_func(im_self, *args, **kw)
File "/usr/lib/python2.7/dist-packages/schooltool/common/inlinept.py", line 110, in __call__
  showtal=getattr(instance.request.debug, 'showTAL', False),
File "/usr/lib/python2.7/dist-packages/zope/pagetemplate/pagetemplate.py", line 132, in pt_render
  strictinsert=0, sourceAnnotations=sourceAnnotations
File "/usr/lib/python2.7/dist-packages/zope/pagetemplate/pagetemplate.py", line 241, in __call__
  interpreter()
File "/usr/lib/python2.7/dist-packages/zope/tal/talinterpreter.py", line 271, in __call__
  self.interpret(self.program)
File "/usr/lib/python2.7/dist-packages/zope/tal/talinterpreter.py", line 343, in interpret
  handlers[opcode](self, args)
File "/usr/lib/python2.7/dist-packages/zope/tal/talinterpreter.py", line 821, in do_loop_tal
  self.interpret(block)
File "/usr/lib/python2.7/dist-packages/zope/tal/talinterpreter.py", line 343, in interpret
  handlers[opcode](self, args)
File "/usr/lib/python2.7/dist-packages/zope/tal/talinterpreter.py", line 533, in do_optTag_tal
  self.do_optTag(stuff)
File "/usr/lib/python2.7/dist-packages/zope/tal/talinterpreter.py", line 518, in do_optTag
  return self.no_tag(start, program)
File "/usr/lib/python2.7/dist-packages/zope/tal/talinterpreter.py", line 513, in no_tag
  self.interpret(program)
File "/usr/lib/python2.7/dist-packages/zope/tal/talinterpreter.py", line 343, in interpret
  handlers[opcode](self, args)
File "/usr/lib/python2.7/dist-packages/zope/tal/talinterpreter.py", line 583, in do_setLocal_tal
  self.engine.setLocal(name, self.engine.evaluateValue(expr))
File "/usr/lib/python2.7/dist-packages/zope/tales/tales.py", line 696, in evaluate
  return expression(self)
Template "None", line 3, column 6
  Expression: <PythonExpr (view.report_card_grid(year))>
File "/usr/lib/python2.7/dist-packages/zope/tales/pythonexpr.py", line 59, in __call__
  return eval(self._code, vars)
Extra information: '(view.report_card_grid(year))'
File "<string>", line 1, in <module>

File "/usr/lib/python2.7/dist-packages/schooltool/gradebook/browser/pdf_views.py", line 1954, in report_card_grid
  grid.update()
File "/usr/lib/python2.7/dist-packages/schooltool/table/pdf.py", line 759, in update
  self.updateTables()
File "/usr/lib/python2.7/dist-packages/schooltool/table/pdf.py", line 745, in updateTables
  table.update()
File "/usr/lib/python2.7/dist-packages/schooltool/table/pdf.py", line 618, in update
  self.updateColumns(self.columns, self.table_width)
File "/usr/lib/python2.7/dist-packages/schooltool/table/pdf.py", line 715, in updateColumns
  self.fitColumns(columns, table_width)
File "/usr/lib/python2.7/dist-packages/schooltool/table/pdf.py", line 690, in fitColumns
  if self.columnsFit(columns, table_width, font_size):
File "/usr/lib/python2.7/dist-packages/schooltool/table/pdf.py", line 673, in columnsFit
  min_headers_column_width = self.getMinHeadersWidth(columns, font_size)
File "/usr/lib/python2.7/dist-packages/schooltool/table/pdf.py", line 665, in getMinHeadersWidth
  columns, self.config.header_font, font_size)
File "/usr/lib/python2.7/dist-packages/schooltool/table/pdf.py", line 449, in getMaxTextSize
  for column in columns
File "/usr/lib/python2.7/dist-packages/reportlab/pdfbase/pdfmetrics.py", line 707, in stringWidth
  return getFont(fontName).stringWidth(text, fontSize, encoding=encoding)
File "/usr/lib/python2.7/dist-packages/reportlab/pdfbase/pdfmetrics.py", line 673, in getFont
  return findFontAndRegister(fontName)
File "/usr/lib/python2.7/dist-packages/reportlab/pdfbase/pdfmetrics.py", line 655, in findFontAndRegister
  face = getTypeFace(fontName)
File "/usr/lib/python2.7/dist-packages/reportlab/pdfbase/pdfmetrics.py", line 612, in getTypeFace
  return _typefaces[faceName]
Exception
<ExceptionWithTraceback (KeyError('Ubuntu_Regular',))>
Traceback
File "/usr/lib/python2.7/dist-packages/schooltool/task/tasks.py", line 211, in __call__
  result = self.runTransaction('execute', True, self, *args, **kwargs)
File "/usr/lib/python2.7/dist-packages/schooltool/task/tasks.py", line 201, in runTransaction
  raise failure

Question information

Language:
English Edit question
Status:
Expired
For:
SchoolTool Edit question
Assignee:
No assignee Edit question
Last query:
2016-01-13
Last reply:
2016-01-28
Tom Hoffman (tom-hoffman) said : #1

When do you get this error message?

Daniel Owens (dh-owens) said : #2

Sorry, forgot that part. I get the message when I try to generate something like a report card or transcript. Schooltool tries to create the PDF but then fails with an error message, so I ran the traceback.

Launchpad Janitor (janitor) said : #3

This question was expired because it remained in the 'Open' state without activity for the last 15 days.

Vannak (vannak) said : #4

I too have the exact same issue. Is there any way we can change fonts easier. I couldn't get reports to render Khmer script correctly.