diff --git a/src/calibre/ebooks/pdf/render/common.py b/src/calibre/ebooks/pdf/render/common.py index b146b7faac..52ccd8b396 100644 --- a/src/calibre/ebooks/pdf/render/common.py +++ b/src/calibre/ebooks/pdf/render/common.py @@ -13,7 +13,7 @@ from datetime import datetime from calibre.constants import plugins, ispy3 from calibre.utils.logging import default_log -from polyglot.builtins import iteritems, unicode_type +from polyglot.builtins import iteritems, unicode_type, codepoint_to_chr from polyglot.binary import as_hex_bytes pdf_float = plugins['speedup'][0].pdf_float @@ -90,8 +90,11 @@ class Name(unicode_type): raw = self.encode('ascii') if len(raw) > 126: raise ValueError('Name too long: %r'%self) - buf = [x if 33 < ord(x) < 126 and x != b'#' else b'#'+hex(ord(x)) for x - in raw] + raw = bytearray(raw) + sharp = ord(b'#') + buf = ( + codepoint_to_chr(x).encode('ascii') if 33 < x < 126 and x != sharp else + b'#'+hex(x).encode('ascii') for x in raw) stream.write(b'/'+b''.join(buf)) diff --git a/src/calibre/ebooks/pdf/render/qt_hack.cpp b/src/calibre/ebooks/pdf/render/qt_hack.cpp index 81f54d7591..5974feb878 100644 --- a/src/calibre/ebooks/pdf/render/qt_hack.cpp +++ b/src/calibre/ebooks/pdf/render/qt_hack.cpp @@ -12,6 +12,12 @@ #include "private/qtextengine_p.h" #include "private/qfontengine_p.h" +#if PY_MAJOR_VERSION > 2 +#define BYTES_FMT "y#" +#else +#define BYTES_FMT "s#" +#endif + PyObject* get_glyphs(const QPointF &p, const QTextItem &text_item) { const quint32 *tag = reinterpret_cast("name"); QTextItemInt ti = static_cast(text_item); @@ -57,14 +63,14 @@ PyObject* get_glyphs(const QPointF &p, const QTextItem &text_item) { PyTuple_SET_ITEM(indices, i, temp); temp = NULL; } const QByteArray table(fe->getSfntTable(qToBigEndian(*tag))); - return Py_BuildValue("s#ffOO", table.constData(), table.size(), size, stretch, points, indices); + return Py_BuildValue(BYTES_FMT "ffOO", table.constData(), table.size(), size, stretch, points, indices); } PyObject* get_sfnt_table(const QTextItem &text_item, const char* tag_name) { QTextItemInt ti = static_cast(text_item); const quint32 *tag = reinterpret_cast(tag_name); const QByteArray table(ti.fontEngine->getSfntTable(qToBigEndian(*tag))); - return Py_BuildValue("s#", table.constData(), table.size()); + return Py_BuildValue(BYTES_FMT, table.constData(), table.size()); } PyObject* get_glyph_map(const QTextItem &text_item) { diff --git a/src/calibre/ebooks/pdf/render/serialize.py b/src/calibre/ebooks/pdf/render/serialize.py index c5cee3b20f..1deea12f27 100644 --- a/src/calibre/ebooks/pdf/render/serialize.py +++ b/src/calibre/ebooks/pdf/render/serialize.py @@ -19,6 +19,7 @@ from calibre.ebooks.pdf.render.common import ( from calibre.ebooks.pdf.render.fonts import FontManager from calibre.ebooks.pdf.render.links import Links from calibre.utils.date import utcnow +from polyglot.builtins import as_unicode PDFVER = b'%PDF-1.4' # 1.4 is needed for XMP metadata @@ -520,7 +521,7 @@ class PDFStream(object): self.objects.pdf_serialize(self.stream) self.write_line() startxref = self.objects.write_xref(self.stream) - file_id = String(self.stream.hashobj.hexdigest().decode('ascii')) + file_id = String(as_unicode(self.stream.hashobj.hexdigest())) self.write_line('trailer') trailer = Dictionary({'Root':self.catalog, 'Size':len(self.objects)+1, 'ID':Array([file_id, file_id]), 'Info':inforef})