Пример #1
0
 def add_resources(self):
     r = Dictionary()
     if self.opacities:
         extgs = Dictionary()
         for opref, name in iteritems(self.opacities):
             extgs[name] = opref
         r['ExtGState'] = extgs
     if self.fonts:
         fonts = Dictionary()
         for ref, name in iteritems(self.fonts):
             fonts[name] = ref
         r['Font'] = fonts
     if self.xobjects:
         xobjects = Dictionary()
         for ref, name in iteritems(self.xobjects):
             xobjects[name] = ref
         r['XObject'] = xobjects
     if self.patterns:
         r['ColorSpace'] = Dictionary(
             {'PCSp': Array([Name('Pattern'),
                             Name('DeviceRGB')])})
         patterns = Dictionary()
         for ref, name in iteritems(self.patterns):
             patterns[name] = ref
         r['Pattern'] = patterns
     if r:
         self.page_dict['Resources'] = r
Пример #2
0
    def __init__(self, brush, matrix, pdf, pixel_page_width, pixel_page_height):
        self.matrix = (matrix.m11(), matrix.m12(), matrix.m21(), matrix.m22(),
                       matrix.dx(), matrix.dy())
        gradient = sip.cast(brush.gradient(), QLinearGradient)

        start, stop, stops = self.spread_gradient(gradient, pixel_page_width,
                                                  pixel_page_height, matrix)

        # TODO: Handle colors with different opacities
        self.const_opacity = stops[0].color[-1]

        funcs = Array()
        bounds = Array()
        encode = Array()

        for i, current_stop in enumerate(stops):
            if i < len(stops) - 1:
                next_stop = stops[i+1]
                func = Dictionary({
                    'FunctionType': 2,
                    'Domain': Array([0, 1]),
                    'C0': Array(current_stop.color[:3]),
                    'C1': Array(next_stop.color[:3]),
                    'N': 1,
                })
                funcs.append(func)
                encode.extend((0, 1))
                if i+1 < len(stops) - 1:
                    bounds.append(next_stop.t)

        func = Dictionary({
            'FunctionType': 3,
            'Domain': Array([stops[0].t, stops[-1].t]),
            'Functions': funcs,
            'Bounds': bounds,
            'Encode': encode,
        })

        shader = Dictionary({
            'ShadingType': 2,
            'ColorSpace': Name('DeviceRGB'),
            'AntiAlias': True,
            'Coords': Array([start.x(), start.y(), stop.x(), stop.y()]),
            'Function': func,
            'Extend': Array([True, True]),
        })

        Dictionary.__init__(self, {
            'Type': Name('Pattern'),
            'PatternType': 2,
            'Shading': shader,
            'Matrix': Array(self.matrix),
        })

        self.cache_key = (self.__class__.__name__, self.matrix,
                          tuple(shader['Coords']), stops)
Пример #3
0
 def add_standard_font(self, name):
     if name not in STANDARD_FONTS:
         raise ValueError('%s is not a standard font'%name)
     if name not in self.std_map:
         self.std_map[name] = self.objects.add(Dictionary({
             'Type':Name('Font'),
             'Subtype':Name('Type1'),
             'BaseFont':Name(name)
         }))
     return self.std_map[name]
Пример #4
0
 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))
Пример #5
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))
Пример #6
0
 def __init__(self, page_size):
     super().__init__({
         'Type': Name('Pages'),
         'MediaBox': Array([0, 0, page_size[0], page_size[1]]),
         'Kids': Array(),
         'Count': 0,
     })
Пример #7
0
 def draw_image(self, x, y, width, height, imgref):
     name = self.current_page.add_image(imgref)
     self.current_page.write(
         'q %s 0 0 %s %s %s cm ' %
         (fmtnum(width), fmtnum(-height), fmtnum(x), fmtnum(y + height)))
     serialize(Name(name), self.current_page)
     self.current_page.write_line(' Do Q')
Пример #8
0
 def add_extra_keys(self, d):
     d['Type'] = Name('XObject')
     d['Subtype'] = Name('Image')
     d['Width'] = self.width
     d['Height'] = self.height
     if self.depth == 1:
         d['ImageMask'] = True
         d['Decode'] = Array([1, 0])
     else:
         d['BitsPerComponent'] = 8
         d['ColorSpace'] = Name('Device' +
                                ('RGB' if self.depth == 32 else 'Gray'))
     if self.mask is not None:
         d['Mask'] = self.mask
     if self.soft_mask is not None:
         d['SMask'] = self.soft_mask
Пример #9
0
 def __init__(self, start_page, pos, get_pageref):
     pnum = start_page + pos['column']
     try:
         pref = get_pageref(pnum)
     except IndexError:
         pref = get_pageref(pnum - 1)
     super(Destination, self).__init__(
         [pref, Name('XYZ'), pos['left'], pos['top'], None])
Пример #10
0
 def __init__(self, data, w, h, depth, mask, soft_mask, dct):
     Stream.__init__(self)
     self.width, self.height, self.depth = w, h, depth
     self.mask, self.soft_mask = mask, soft_mask
     if dct:
         self.filters.append(Name('DCTDecode'))
     else:
         self.compress = True
     self.write(data)
Пример #11
0
 def draw_image_with_transform(self,
                               imgref,
                               translation=(0, 0),
                               scaling=(1, 1)):
     name = self.current_page.add_image(imgref)
     self.current_page.write('q {} 0 0 {} {} {} cm '.format(
         *(tuple(scaling) + tuple(translation))))
     serialize(Name(name), self.current_page)
     self.current_page.write_line(' Do Q')
Пример #12
0
 def __init__(self, parentref, *args, **kwargs):
     super(Page, self).__init__(*args, **kwargs)
     self.page_dict = Dictionary({
         'Type': Name('Page'),
         'Parent': parentref,
     })
     self.opacities = {}
     self.fonts = {}
     self.xobjects = {}
     self.patterns = {}
Пример #13
0
 def add_extra_keys(self, d):
     d['Type'] = Name('Pattern')
     d['PatternType'] = 1
     d['PaintType'] = self.paint_type
     d['TilingType'] = 1
     d['BBox'] = Array([0, 0, self.w, self.h])
     d['XStep'] = self.w
     d['YStep'] = self.h
     d['Matrix'] = Array(self.matrix)
     d['Resources'] = self.resources
Пример #14
0
 def draw_glyph_run(self, transform, size, font_metrics, glyphs):
     glyph_ids = {x[-1] for x in glyphs}
     fontref = self.font_manager.add_font(font_metrics, glyph_ids)
     name = self.current_page.add_font(fontref)
     self.current_page.write(b'BT ')
     serialize(Name(name), self.current_page)
     self.current_page.write(' %s Tf '%fmtnum(size))
     self.current_page.write('%s Tm '%' '.join(map(fmtnum, transform)))
     for x, y, glyph_id in glyphs:
         self.current_page.write_raw(('%s %s Td <%04X> Tj '%(
             fmtnum(x), fmtnum(y), glyph_id)).encode('ascii'))
     self.current_page.write_line(b' ET')
Пример #15
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()
Пример #16
0
 def __init__(self, start_page, pos, get_pageref):
     pnum = start_page + max(0, pos['column'])
     q = pnum
     while q > -1:
         try:
             pref = get_pageref(q)
             break
         except IndexError:
             pos['left'] = pos['top'] = 0
             q -= 1
     if q != pnum:
         current_log().warn(
             'Could not find page {} for link destination, using page {} instead'
             .format(pnum, q))
     super().__init__([pref, Name('XYZ'), pos['left'], pos['top'], None])
Пример #17
0
 def set_opacity(self, opref):
     if opref not in self.opacities:
         self.opacities[opref] = 'Opa%d' % len(self.opacities)
     name = self.opacities[opref]
     serialize(Name(name), self)
     self.write(b' gs ')
Пример #18
0
 def set_fill_opacity(self, opacity):
     opacity = float(opacity)
     if opacity not in self.fill_opacities:
         op = Dictionary({'Type': Name('ExtGState'), 'ca': opacity})
         self.fill_opacities[opacity] = self.objects.add(op)
     self.current_page.set_opacity(self.fill_opacities[opacity])
Пример #19
0
 def set_stroke_opacity(self, opacity):
     if opacity not in self.stroke_opacities:
         op = Dictionary({'Type': Name('ExtGState'), 'CA': opacity})
         self.stroke_opacities[opacity] = self.objects.add(op)
     self.current_page.set_opacity(self.stroke_opacities[opacity])
Пример #20
0
 def add_extra_keys(self, d):
     d['Type'] = Name('Metadata')
     d['Subtype'] = Name('XML')
Пример #21
0
 def add_outline(self, toc):
     parent = Dictionary({'Type': Name('Outlines')})
     parentref = self.pdf.objects.add(parent)
     self.process_children(toc, parentref, parent_is_root=True)
     self.pdf.catalog.obj['Outlines'] = parentref
Пример #22
0
 def add_extra_keys(self, d):
     d['Length1'] = d['DL']
     if self.is_otf:
         d['Subtype'] = Name('CIDFontType0C')
Пример #23
0
 def __init__(self, pagetree):
     super(Catalog, self).__init__({
         'Type': Name('Catalog'),
         'Pages': pagetree
     })