예제 #1
0
 def __init__(self,
              stream,
              page_size,
              compress=False,
              mark_links=False,
              debug=print):
     self.stream = HashingStream(stream)
     self.compress = compress
     self.write_line(PDFVER)
     self.write_line(u'%íì¦"'.encode('utf-8'))
     creator = ('%s %s [https://calibre-ebook.com]' %
                (__appname__, __version__))
     self.write_line('%% Created by %s' % creator)
     self.objects = IndirectObjects()
     self.objects.add(PageTree(page_size))
     self.objects.add(Catalog(self.page_tree))
     self.current_page = Page(self.page_tree, compress=self.compress)
     self.info = Dictionary({
         'Creator': String(creator),
         'Producer': String(creator),
         'CreationDate': utcnow(),
     })
     self.stroke_opacities, self.fill_opacities = {}, {}
     self.font_manager = FontManager(self.objects, self.compress)
     self.image_cache = {}
     self.pattern_cache, self.shader_cache = {}, {}
     self.debug = debug
     self.links = Links(self, mark_links, page_size)
     i = QImage(1, 1, QImage.Format_ARGB32)
     i.fill(qRgba(0, 0, 0, 255))
     self.alpha_bit = i.constBits().asstring(4).find(b'\xff')
예제 #2
0
 def set_metadata(self, title=None, author=None, tags=None):
     if title:
         self.info['Title'] = String(title)
     if author:
         self.info['Author'] = String(author)
     if tags:
         self.info['Keywords'] = String(tags)
예제 #3
0
 def set_metadata(self, title=None, author=None, tags=None, mi=None):
     if title:
         self.info['Title'] = String(title)
     if author:
         self.info['Author'] = String(author)
     if tags:
         self.info['Keywords'] = String(tags)
     if mi is not None:
         self.metadata = self.objects.add(Metadata(mi))
         self.catalog.obj['Metadata'] = self.metadata
예제 #4
0
    def __init__(self, metrics, num, objects, compress):
        self.metrics, self.compress = metrics, compress
        self.is_otf = self.metrics.is_otf
        self.subset_tag = str(
            re.sub('.', lambda m: codepoint_to_chr(int(m.group())+ord('A')), oct(num).replace('o', '')
        )).rjust(6, 'A')
        self.font_stream = FontStream(metrics.is_otf, compress=compress)
        try:
            psname = metrics.postscript_name
        except Exception:
            psname = uuid4()
        self.font_descriptor = Dictionary({
            'Type': Name('FontDescriptor'),
            'FontName': Name('%s+%s'%(self.subset_tag, psname)),
            'Flags': 0b100,  # Symbolic font
            'FontBBox': Array(metrics.pdf_bbox),
            'ItalicAngle': metrics.post.italic_angle,
            'Ascent': metrics.pdf_ascent,
            'Descent': metrics.pdf_descent,
            'CapHeight': metrics.pdf_capheight,
            'AvgWidth': metrics.pdf_avg_width,
            'StemV': metrics.pdf_stemv,
        })
        self.descendant_font = Dictionary({
            'Type':Name('Font'),
            'Subtype':Name('CIDFontType' + ('0' if metrics.is_otf else '2')),
            'BaseFont': self.font_descriptor['FontName'],
            'FontDescriptor':objects.add(self.font_descriptor),
            'CIDSystemInfo':Dictionary({
                'Registry':String('Adobe'),
                'Ordering':String('Identity'),
                'Supplement':0,
            }),
        })
        if not self.is_otf:
            self.descendant_font['CIDToGIDMap'] = Name('Identity')

        self.font_dict = Dictionary({
            'Type':Name('Font'),
            'Subtype':Name('Type0'),
            'Encoding':Name('Identity-H'),
            'BaseFont':self.descendant_font['BaseFont'],
            'DescendantFonts':Array([objects.add(self.descendant_font)]),
        })

        self.used_glyphs = set()
예제 #5
0
파일: links.py 프로젝트: zyhong/calibre
 def add_links(self):
     for link in self.links:
         path, href, frag = link[0]
         page, rect = link[1:]
         combined_path = os.path.normcase(
             os.path.abspath(
                 os.path.join(os.path.dirname(path),
                              *unquote(href).split('/'))))
         is_local = not href or combined_path in self.anchors
         annot = Dictionary({
             'Type': Name('Annot'),
             'Subtype': Name('Link'),
             'Rect': rect,
             'Border': Array([0, 0, 0]),
         })
         if self.mark_links:
             annot.update({
                 'Border': Array([16, 16, 1]),
                 'C': Array([1.0, 0, 0])
             })
         if is_local:
             path = combined_path if href else path
             try:
                 annot['Dest'] = self.anchors[path][frag]
             except KeyError:
                 try:
                     annot['Dest'] = self.anchors[path][None]
                 except KeyError:
                     pass
         else:
             url = href + (('#' + frag) if frag else '')
             try:
                 purl = urlparse(url)
             except Exception:
                 self.pdf.debug('Ignoring unparseable URL: %r' % url)
                 continue
             if purl.scheme and purl.scheme != 'file':
                 action = Dictionary({
                     'Type': Name('Action'),
                     'S': Name('URI'),
                 })
                 # Do not try to normalize/quote/unquote this URL as if it
                 # has a query part, it will get corrupted
                 action['URI'] = String(url)
                 annot['A'] = action
         if 'A' in annot or 'Dest' in annot:
             if 'Annots' not in page:
                 page['Annots'] = Array()
             page['Annots'].append(self.pdf.objects.add(annot))
         else:
             self.pdf.debug(
                 'Could not find destination for link: %s in file %s' %
                 (href, path))
예제 #6
0
 def process_toc_item(self, toc, parentref):
     path = toc.abspath or None
     frag = toc.fragment or None
     if path is None:
         return
     path = os.path.normcase(os.path.abspath(path))
     if path not in self.anchors:
         return None
     a = self.anchors[path]
     dest = a.get(frag, a[None])
     item = Dictionary({'Parent':parentref, 'Dest':dest,
                        'Title':String(toc.text or _('Unknown'))})
     return self.pdf.objects.add(item)
예제 #7
0
 def add_links(self):
     for link in self.links:
         path, href, frag = link[0]
         page, rect = link[1:]
         combined_path = os.path.abspath(
             os.path.join(os.path.dirname(path),
                          *unquote(href).split('/')))
         is_local = not href or combined_path in self.anchors
         annot = Dictionary({
             'Type': Name('Annot'),
             'Subtype': Name('Link'),
             'Rect': rect,
             'Border': Array([0, 0, 0]),
         })
         if self.mark_links:
             annot.update({
                 'Border': Array([16, 16, 1]),
                 'C': Array([1.0, 0, 0])
             })
         if is_local:
             path = combined_path if href else path
             try:
                 annot['Dest'] = self.anchors[path][frag]
             except KeyError:
                 try:
                     annot['Dest'] = self.anchors[path][None]
                 except KeyError:
                     pass
         else:
             url = href + (('#' + frag) if frag else '')
             purl = urlparse(url)
             if purl.scheme and purl.scheme != 'file':
                 action = Dictionary({
                     'Type': Name('Action'),
                     'S': Name('URI'),
                 })
                 parts = (x.encode('utf-8')
                          if isinstance(x, type(u'')) else x for x in purl)
                 url = urlunparse(map(quote, map(unquote,
                                                 parts))).decode('ascii')
                 action['URI'] = String(url)
                 annot['A'] = action
         if 'A' in annot or 'Dest' in annot:
             if 'Annots' not in page:
                 page['Annots'] = Array()
             page['Annots'].append(self.pdf.objects.add(annot))
         else:
             self.pdf.debug(
                 'Could not find destination for link: %s in file %s' %
                 (href, path))
예제 #8
0
파일: serialize.py 프로젝트: zyhong/calibre
 def end(self):
     if self.current_page.getvalue():
         self.end_page()
     self.font_manager.embed_fonts(self.debug)
     inforef = self.objects.add(self.info)
     self.links.add_links()
     self.objects.pdf_serialize(self.stream)
     self.write_line()
     startxref = self.objects.write_xref(self.stream)
     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})
     serialize(trailer, self.stream)
     self.write_line('startxref')
     self.write_line('%d'%startxref)
     self.stream.write('%%EOF')