Пример #1
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)
Пример #2
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))
Пример #3
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))
Пример #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 "")
             purl = urlparse(url)
             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 __init__(self, metrics, num, objects, compress):
        self.metrics, self.compress = metrics, compress
        self.is_otf = self.metrics.is_otf
        self.subset_tag = bytes(
            re.sub('.', lambda m: chr(int(m.group()) + ord('A')),
                   oct(num))).rjust(6, b'A').decode('ascii')
        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()
Пример #6
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
Пример #7
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])
Пример #8
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])
Пример #9
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)