def embedded_font_demo():
    my_canvas = canvas.Canvas("embed_font.pdf",
                              pagesize=letter)
    reportlab_folder = os.path.dirname(reportlab.__file__)
    fonts_folder = os.path.join(reportlab_folder, 'fonts')
    print('ReportLab font folder is located at {}'.format(
        fonts_folder))

    afm = os.path.join(fonts_folder, 'DarkGardenMK.afm')
    pfb = os.path.join(fonts_folder, 'DarkGardenMK.pfb')

    # Register the font so we can use it
    font_face = pdfmetrics.EmbeddedType1Face(afm, pfb)
    pdfmetrics.registerTypeFace(font_face)

    face_name = 'DarkGardenMK'
    font = pdfmetrics.Font('DarkGardenMK',
                           face_name,
                           'WinAnsiEncoding')
    pdfmetrics.registerFont(font)

    # Use the font!
    my_canvas.setFont('DarkGardenMK', 40)
    my_canvas.drawString(10, 730, 'The DarkGardenMK font')
    my_canvas.save()
Exemplo n.º 2
0
    def __init__(self, path, margin_x=48, margin_y=60, file_name='Untitled.pdf',
                 file_name_S3='Untitled.pdf', is_landscape=False, author=None, title=None):
        self.path = path
        self.margin_x = self.origin_x = margin_x
        self.margin_y = self.origin_y = margin_y
        self.file_name = file_name
        self.is_landscape = is_landscape
        self.author = author
        self.title = title

        # embeds "Hand of Sean" font:
        afmFile = os.path.join(settings.FONT_ROOT, 'HandOfSean.afm')
        pfbFile = os.path.join(settings.FONT_ROOT, 'HandOfSean.pfb')
        ttfFile = os.path.join(settings.FONT_ROOT, 'handsean.ttf')
        justFace = pdfmetrics.EmbeddedType1Face(afmFile, pfbFile) #embeds font
        faceName = 'HandOfSean' # pulled from AFM file
        pdfmetrics.registerTypeFace(justFace)
        justFont = pdfmetrics.Font('HandSean', faceName, 'WinAnsiEncoding')
        pdfmetrics.registerFont(justFont)
        pdfmetrics.registerFont(TTFont('HandSean', ttfFile))

        response = HttpResponse(content_type='application/pdf')
        response['Content-Disposition'] = 'attachment; filename=' + self.file_name

        self.set_orientation(self.is_landscape)

        self.canvas = canvas.Canvas(self.path + '/' + self.file_name,
                               pagesize=(self.page_width, self.page_height))
        if self.author is not None:
            self.canvas.setAuthor(self.author)
        if self.title is not None:
            self.canvas.setTitle(self.title)
Exemplo n.º 3
0
def set_cyr_font():
    # fname - the font file name without extension
    fname = 'a010013l'

    # faceName - view a010013l.AFM file as a plain text and look at
    # row beginning with 'FontName' word (it's usually the fourth row).
    # The word after 'FontName' is the faceName ('URWGothicL-Book' in this case).
    faceName = 'URWGothicL-Book'

    # Define new Type 1 font
    cyrFace = pdfmetrics.EmbeddedType1Face(fname + '.afm', fname + '.pfb')

    # Create a new encoding called 'CP1251'
    cyrenc = pdfmetrics.Encoding('CP1251')

    # Fill in the tuple with Unicode glyphs in accordance with cp1251 (win1251)
    # encoding
    cp1251 = (
        'afii10051', 'afii10052', 'quotesinglbase', 'afii10100', 'quotedblbase',
        'ellipsis', 'dagger', 'daggerdbl', 'Euro', 'perthousand', 'afii10058',
        'guilsinglleft', 'afii10059', 'afii10061', 'afii10060', 'afii10145',
        'afii10099', 'quoteleft', 'quoteright', 'quotedblleft', 'quotedblright',
        'bullet', 'endash', 'emdash', 'tilde', 'trademark', 'afii10106',
        'guilsinglright', 'afii10107', 'afii10109', 'afii10108', 'afii10193',
        'space', 'afii10062', 'afii10110', 'afii10057', 'currency', 'afii10050',
        'brokenbar', 'section', 'afii10023', 'copyright', 'afii10053',
        'guillemotleft', 'logicalnot', 'hyphen', 'registered', 'afii10056',
        'degree', 'plusminus', 'afii10055', 'afii10103', 'afii10098', 'mu1',
        'paragraph', 'periodcentered', 'afii10071', 'afii61352', 'afii10101',
        'guillemotright', 'afii10105', 'afii10054', 'afii10102', 'afii10104',
        'afii10017', 'afii10018', 'afii10019', 'afii10020', 'afii10021',
        'afii10022', 'afii10024', 'afii10025', 'afii10026', 'afii10027',
        'afii10028', 'afii10029', 'afii10030', 'afii10031', 'afii10032',
        'afii10033', 'afii10034', 'afii10035', 'afii10036', 'afii10037',
        'afii10038', 'afii10039', 'afii10040', 'afii10041', 'afii10042',
        'afii10043', 'afii10044', 'afii10045', 'afii10046', 'afii10047',
        'afii10048', 'afii10049', 'afii10065', 'afii10066', 'afii10067',
        'afii10068', 'afii10069', 'afii10070', 'afii10072', 'afii10073',
        'afii10074', 'afii10075', 'afii10076', 'afii10077', 'afii10078',
        'afii10079', 'afii10080', 'afii10081', 'afii10082', 'afii10083',
        'afii10084', 'afii10085', 'afii10086', 'afii10087', 'afii10088',
        'afii10089', 'afii10090', 'afii10091', 'afii10092', 'afii10093',
        'afii10094', 'afii10095', 'afii10096', 'afii10097'
    )

    # Replace glyphs from code 128 to code 256 with cp1251 values
    for i in range(128, 256):
        cyrenc[i] = cp1251[i - 128]

    # Register newly created encoding
    pdfmetrics.registerEncoding(cyrenc)

    # Register type face
    pdfmetrics.registerTypeFace(cyrFace)

    # Register the font with adding '1251' to its name
    pdfmetrics.registerFont(pdfmetrics.Font(faceName + '1251', faceName, 'CP1251'))

    return faceName + '1251'  # def set_cyr_font
Exemplo n.º 4
0
    def font_start(self, name, ttf=None, afm=None, pfb=None):

        # True Type Fonts
        if ttf:
            font_path = os.path.join(self.font_dir, ttf)
            pdfmetrics.registerFont(TTFont(name, font_path))
            return

        # Type 1
        face = pdfmetrics.EmbeddedType1Face(afm, pfb)
        pdfmetrics.registerTypeFace(face) 
        font = pdfmetrics.Font(name, name, 'WinAnsiEncoding')
        pdfmetrics.registerFont(font) 
Exemplo n.º 5
0
def register_type1_font():
    """This function is a maintenence function that registers new Type 1 font for PDF use
    This only need be run on new installations and when installing new fonts. Does not need to be
    run every time a program starts up. This modifies the ReportLab installation."""

    # Define the location of the font to be registered
    folder = os.path.dirname(reportlab.__file__) + os.sep + "fonts"
    afmFile = os.path.join(folder, "DarkGardenMK.afm")
    pfbFile = os.path.join(folder, "DarkGardenMK.pfb")
    justFace = pdfmetrics.EmbeddedType1Face(afmFile, pfbFile)
    faceName = "DarkGardenMK"
    pdfmetrics.registerTypeFace(justFace)
    justFont = pdfmetrics.Font("DarkGardenMK", faceName, "WinAnsiEncoding")
    pdfmetrics.registerFont(justFont)
Exemplo n.º 6
0
    def import_pdf_font(self, base_name, face_name):
        if self.fonts.get(face_name, None) is None:
            afm = find(base_name + '.afm')
            pfb = find(base_name + '.pfb')

            try:
                face = pdfmetrics.EmbeddedType1Face(afm, pfb)

                pdfmetrics.registerTypeFace(face)
                font = pdfmetrics.Font(face_name, face_name, 'WinAnsiEncoding')
                pdfmetrics.registerFont(font)
            except:
                pass
        else:
            self.fonts[face_name] = True
Exemplo n.º 7
0
def registerFont0(sourceFile, name, path):
    "Register Type-1 font for future use, simple version."

    rl_config.warnOnMissingFontGlyphs = 0

    p = os.path.join(os.path.dirname(sourceFile), path)
    afmFiles = glob.glob(p + '.[aA][fF][mM]')
    pfbFiles = glob.glob(p + '.[pP][fF][bB]')
    assert len(afmFiles) == len(pfbFiles) == 1, FontFilesNotFoundError

    T1face = pdfmetrics.EmbeddedType1Face(afmFiles[0], pfbFiles[0])
    T1faceName = name
    pdfmetrics.registerTypeFace(T1face)
    T1font = pdfmetrics.Font(name, T1faceName, 'WinAnsiEncoding')
    pdfmetrics.registerFont(T1font)
Exemplo n.º 8
0
def installfont(fontname):
    """Registers a typeface and font based on the given name."""
    fontdir_afm = Path(CONFIG['fonts']['fontdir_afm'])
    fontdir_pfb = Path(CONFIG['fonts']['fontdir_pfb'])
    fontfile_stem = fontname
    afm = (fontdir_afm / fontfile_stem).with_suffix('.afm')
    pfb = (fontdir_pfb / fontfile_stem).with_suffix('.pfb')

    try:
        pdfmetrics.registerTypeFace(pdfmetrics.EmbeddedType1Face(afm, pfb))
        pdfmetrics.registerFont(
            pdfmetrics.Font(fontname, fontname, 'WinAnsiEncoding'))
    except AssertionError:
        raise FontFileNotFound(f'Cannot install font {fontname}. '
                               'Does its .afm and .pfb files exist?')
Exemplo n.º 9
0
def register_fonts():
    # Font name : file name
    # File name should be the same as internal font name
    fonts = {
        'HugoHandwriting': 'Hugohandwriting-Regular'
    }

    font_dir = Path.cwd() / 'tests' / 'data' / 'fonts'
    for font_name, font_file in fonts.items():
        font_path_afm = font_dir / (font_file + '.afm')
        font_path_pfb = font_dir / (font_file + '.pfb')

        face = pdfmetrics.EmbeddedType1Face(font_path_afm, font_path_pfb)
        pdfmetrics.registerTypeFace(face)

        font = pdfmetrics.Font(font_name, font_file, 'WinAnsiEncoding')
        pdfmetrics.registerFont(font)
Exemplo n.º 10
0
 def cyrillic(c, n):
     fname = 'font'
     faceName = 'TimesNewRomanPSMT'
     cyrFace = pdfmetrics.EmbeddedType1Face(fname + '.afm', fname + '.pfb')
     cyrEnc = pdfmetrics.Encoding('CP1251')
     cp1251 = (
         'afii10051', 'afii10052', 'quotesinglbase', 'afii10100',
         'quotedblbase', 'ellipsis', 'dagger', 'daggerdbl', 'Euro',
         'perthousand', 'afii10058', 'guilsinglleft', 'afii10059',
         'afii10061', 'afii10060', 'afii10145', 'afii10099', 'quoteleft',
         'quoteright', 'quotedblleft', 'quotedblright', 'bullet', 'endash',
         'emdash', 'tilde', 'trademark', 'afii10106', 'guilsinglright',
         'afii10107', 'afii10109', 'afii10108', 'afii10193', 'space',
         'afii10062', 'afii10110', 'afii10057', 'currency', 'afii10050',
         'brokenbar', 'section', 'afii10023', 'copyright', 'afii10053',
         'guillemotleft', 'logicalnot', 'hyphen', 'registered', 'afii10056',
         'degree', 'plusminus', 'afii10055', 'afii10103', 'afii10098',
         'mu1', 'paragraph', 'periodcentered', 'afii10071', 'afii61352',
         'afii10101', 'guillemotright', 'afii10105', 'afii10054',
         'afii10102', 'afii10104', 'afii10017', 'afii10018', 'afii10019',
         'afii10020', 'afii10021', 'afii10022', 'afii10024', 'afii10025',
         'afii10026', 'afii10027', 'afii10028', 'afii10029', 'afii10030',
         'afii10031', 'afii10032', 'afii10033', 'afii10034', 'afii10035',
         'afii10036', 'afii10037', 'afii10038', 'afii10039', 'afii10040',
         'afii10041', 'afii10042', 'afii10043', 'afii10044', 'afii10045',
         'afii10046', 'afii10047', 'afii10048', 'afii10049', 'afii10065',
         'afii10066', 'afii10067', 'afii10068', 'afii10069', 'afii10070',
         'afii10072', 'afii10073', 'afii10074', 'afii10075', 'afii10076',
         'afii10077', 'afii10078', 'afii10079', 'afii10080', 'afii10081',
         'afii10082', 'afii10083', 'afii10084', 'afii10085', 'afii10086',
         'afii10087', 'afii10088', 'afii10089', 'afii10090', 'afii10091',
         'afii10092', 'afii10093', 'afii10094', 'afii10095', 'afii10096',
         'afii10097')
     for i in range(128, 256):
         cyrEnc[i] = cp1251[i - 128]
     pdfmetrics.registerEncoding(cyrEnc)
     pdfmetrics.registerTypeFace(cyrFace)
     pdfmetrics.registerFont(
         pdfmetrics.Font(faceName + '1251', faceName, 'CP1251'))
     c.setFont(faceName + '1251', n)
Exemplo n.º 11
0
def registerFont(faceName, afm, pfb):
    """
    Helvetica BUT AS AFM

    The below section is NOT equal to::

        _baseFontName  ='Helvetica'
        _baseFontNameB ='Helvetica-Bold'
        _baseFontNameI ='Helvetica-Oblique'
        _baseFontNameBI='Helvetica-BoldOblique'

    we will mapp afm files from matplotlib with pfb files from reportlab

    this will give embedded Type1 Face Fonts

    """
    afm = os.path.join(__font_dir__, "".join(afm, ".afm"))
    pfb = os.path.join(__font_dir__, "".join(pfb, ".pfb"))

    face = pdfmetrics.EmbeddedType1Face(afm, pfb)
    pdfmetrics.registerTypeFace(face)
    font = pdfmetrics.Font(faceName, faceName, 'WinAnsiEncoding')
    pdfmetrics.registerFont(font)
Exemplo n.º 12
0
    def import_pdf_font(self, base_name, face_name):
        if self.fonts.get(face_name, None) is None:
            afm = find(base_name + '.afm')
            pfb = find(base_name + '.pfb')
            ttf = find(base_name + '.ttf')

            if afm:
                try:
                    face = pdfmetrics.EmbeddedType1Face(afm, pfb)

                    pdfmetrics.registerTypeFace(face)
                    font = pdfmetrics.Font(face_name, face_name,
                                           'WinAnsiEncoding')
                    pdfmetrics.registerFont(font)
                except:
                    pass
            elif ttf:
                pdfmetrics.registerFont(TTFont(face_name, ttf))
            else:
                raise Exception(
                    'Cannot find font %s (tried .afm, .pfb and .ttf)' %
                    base_name)
        else:
            self.fonts[face_name] = True
Exemplo n.º 13
0
 def process(self):
     args = self.getAttributeValues(valuesOnly=True)
     face = pdfmetrics.EmbeddedType1Face(*args)
     pdfmetrics.registerTypeFace(face)
Exemplo n.º 14
0
    def loadFont(self,
                 names,
                 src,
                 encoding="WinAnsiEncoding",
                 bold=0,
                 italic=0):

        # XXX Just works for local filenames!
        if names and src:

            file = src
            src = file.uri

            log.debug("Load font %r", src)

            if type(names) is types.ListType:
                fontAlias = names
            else:
                fontAlias = (x.lower().strip() for x in names.split(",") if x)

            # XXX Problems with unicode here
            fontAlias = [str(x) for x in fontAlias]

            fontName = fontAlias[0]
            parts = src.split(".")
            baseName, suffix = ".".join(parts[:-1]), parts[-1]
            suffix = suffix.lower()

            if suffix in ["ttc", "ttf"]:

                # determine full font name according to weight and style
                fullFontName = "%s_%d%d" % (fontName, bold, italic)

                # check if font has already been registered
                if fullFontName in self.fontList:
                    log.warn(
                        self.warning(
                            "Repeated font embed for %s, skip new embed ",
                            fullFontName))
                else:

                    # Register TTF font and special name
                    filename = file.getNamedFile()
                    pdfmetrics.registerFont(TTFont(fullFontName, filename))

                    # Add or replace missing styles
                    for bold in (0, 1):
                        for italic in (0, 1):
                            if ("%s_%d%d" %
                                (fontName, bold, italic)) not in self.fontList:
                                addMapping(fontName, bold, italic,
                                           fullFontName)

                    # Register "normal" name and the place holder for style
                    self.registerFont(fontName, fontAlias + [fullFontName])

            elif suffix in ("afm", "pfb"):

                if suffix == "afm":
                    afm = file.getNamedFile()
                    tfile = pisaFileObject(baseName + ".pfb")
                    pfb = tfile.getNamedFile()
                else:
                    pfb = file.getNamedFile()
                    tfile = pisaFileObject(baseName + ".afm")
                    afm = tfile.getNamedFile()

                # determine full font name according to weight and style
                fullFontName = "%s_%d%d" % (fontName, bold, italic)

                # check if font has already been registered
                if fullFontName in self.fontList:
                    log.warn(
                        self.warning(
                            "Repeated font embed for %s, skip new embed",
                            fontName))
                else:

                    # Include font
                    face = pdfmetrics.EmbeddedType1Face(afm, pfb)
                    fontNameOriginal = face.name
                    pdfmetrics.registerTypeFace(face)
                    # print fontName, fontNameOriginal, fullFontName
                    justFont = pdfmetrics.Font(fullFontName, fontNameOriginal,
                                               encoding)
                    pdfmetrics.registerFont(justFont)

                    # Add or replace missing styles
                    for bold in (0, 1):
                        for italic in (0, 1):
                            if ("%s_%d%d" %
                                (fontName, bold, italic)) not in self.fontList:
                                addMapping(fontName, bold, italic,
                                           fontNameOriginal)

                    # Register "normal" name and the place holder for style
                    self.registerFont(
                        fontName, fontAlias + [fullFontName, fontNameOriginal])
            else:
                log.warning(self.warning("wrong attributes for <pdf:font>"))
Exemplo n.º 15
0
def autoEmbed(fname):
    """Given a font name, does a best-effort of embedding
    said font and its variants.

    Returns a list of the font names it registered with ReportLab.

    """
    log.info("Trying to embed %s" % fname)
    fontList = []
    variants = []
    f = findFont(fname)
    if f:  # We have this font located
        if f[0].lower().endswith(".afm"):  # Type 1 font
            family = families[f[2]]

            # Register the whole family of faces
            faces = [
                pdfmetrics.EmbeddedType1Face(*fonts[fn.lower()][:2]) for fn in family
            ]
            for face in faces:
                pdfmetrics.registerTypeFace(face)

            for face, name in zip(faces, family):
                fontList.append(name)
                font = pdfmetrics.Font(face, name, "WinAnsiEncoding")
                log.info("Registering font: %s from %s" % (name, face.getFontFiles()))
                pdfmetrics.registerFont(font)

            # Map the variants
            regular, italic, bold, bolditalic = family
            for n in fname, regular:
                addMapping(n, 0, 0, regular)
                addMapping(n, 0, 1, italic)
                addMapping(n, 1, 0, bold)
                addMapping(n, 1, 1, bolditalic)
            log.info("Embedding as %s" % fontList)
            return fontList
        else:  # A TTF font
            variants = [fonts[x.lower()][0] for x in families[f[2]]]
    if not variants:  # Try fc-match
        variants = findTTFont(fname)
    # It is a TT Font and we found it using fc-match (or found *something*)
    if variants:
        for variant in variants:
            vname = os.path.basename(variant)[:-4]
            try:
                if vname not in pdfmetrics._fonts:
                    _font = TTFont(vname, variant)
                    log.info("Registering font: %s from %s" % (vname, variant))
                    pdfmetrics.registerFont(_font)
            except TTFError:
                log.error("Error registering font: %s from %s" % (vname, variant))
            else:
                fontList.append(vname)
        regular, bold, italic, bolditalic = [
            os.path.basename(variant)[:-4] for variant in variants
        ]
        addMapping(regular, 0, 0, regular)
        addMapping(regular, 0, 1, italic)
        addMapping(regular, 1, 0, bold)
        addMapping(regular, 1, 1, bolditalic)
        log.info("Embedding via findTTFont as %s" % fontList)
    return fontList
Exemplo n.º 16
0
def getExamples():
    """Returns all the example flowable objects"""
    styleSheet = getSampleStyleSheet()

    story = []

    #make a style with indents and spacing
    sty = ParagraphStyle('obvious', None)
    sty.leftIndent = 18
    sty.rightIndent = 18
    sty.firstLineIndent = 18
    sty.spaceBefore = 6
    sty.spaceAfter = 6
    story.append(
        Paragraph(
            """Now for some demo stuff - we need some on this page,
        even before we explain the concepts fully""", styleSheet['BodyText']))
    p = Paragraph(
        """
        Platypus is all about fitting objects into frames on the page.  You
        are looking at a fairly simple Platypus paragraph in Debug mode.
        It has some gridlines drawn around it to show the left and right indents,
        and the space before and after, all of which are attributes set in
        the style sheet.  To be specific, this paragraph has left and
        right indents of 18 points, a first line indent of 36 points,
        and 6 points of space before and after itself.  A paragraph
        object fills the width of the enclosing frame, as you would expect.""",
        sty)

    p.debug = 1  #show me the borders
    story.append(p)

    story.append(
        Paragraph(
            """Same but with justification 1.5 extra leading and green text.""",
            styleSheet['BodyText']))
    p = Paragraph(
        """
        <para align=justify leading="+1.5" fg=green><font color=red>Platypus</font> is all about fitting objects into frames on the page.  You
        are looking at a fairly simple Platypus paragraph in Debug mode.
        It has some gridlines drawn around it to show the left and right indents,
        and the space before and after, all of which are attributes set in
        the style sheet.  To be specific, this paragraph has left and
        right indents of 18 points, a first line indent of 36 points,
        and 6 points of space before and after itself.  A paragraph
        object fills the width of the enclosing frame, as you would expect.</para>""",
        sty)

    p.debug = 1  #show me the borders
    story.append(p)

    story.append(
        platypus.XBox(4 * inch, 0.75 * inch,
                      'This is a box with a fixed size'))

    story.append(
        Paragraph(
            """
        All of this is being drawn within a text frame which was defined
        on the page.  This frame is in 'debug' mode so you can see the border,
        and also see the margins which it reserves.  A frame does not have
        to have margins, but they have been set to 6 points each to create
        a little space around the contents.
        """, styleSheet['BodyText']))

    story.append(FrameBreak())

    #######################################################################
    #     Examples Page 2
    #######################################################################

    story.append(
        Paragraph(
            """
        Here's the base class for Flowable...
        """, styleSheet['Italic']))

    code = '''class Flowable:
        """Abstract base class for things to be drawn.  Key concepts:
    1. It knows its size
    2. It draws in its own coordinate system (this requires the
        base API to provide a translate() function.
        """
    def __init__(self):
        self.width = 0
        self.height = 0
        self.wrapped = 0

    def drawOn(self, canvas, x, y):
        "Tell it to draw itself on the canvas.  Do not override"
        self.canv = canvas
        self.canv.saveState()
        self.canv.translate(x, y)

        self.draw()   #this is the bit you overload

        self.canv.restoreState()
        del self.canv

    def wrap(self, availWidth, availHeight):
        """This will be called by the enclosing frame before objects
        are asked their size, drawn or whatever.  It returns the
        size actually used."""
        return (self.width, self.height)
    '''

    story.append(Preformatted(code, styleSheet['Code'], dedent=4))
    story.append(FrameBreak())
    #######################################################################
    #     Examples Page 3
    #######################################################################

    story.append(
        Paragraph("Here are some examples of the remaining objects above.",
                  styleSheet['Italic']))

    story.append(
        Paragraph("This is a bullet point",
                  styleSheet['Bullet'],
                  bulletText='O'))
    story.append(
        Paragraph("Another bullet point", styleSheet['Bullet'],
                  bulletText='O'))

    story.append(
        Paragraph(
            """Here is a Table, which takes all kinds of formatting options...""",
            styleSheet['Italic']))
    story.append(platypus.Spacer(0, 12))

    g = platypus.Table(
        (('', 'North', 'South', 'East', 'West'),
         ('Quarter 1', 100, 200, 300, 400), ('Quarter 2', 100, 200, 300, 400),
         ('Total', 200, 400, 600, 800)), (72, 36, 36, 36, 36),
        (24, 16, 16, 18))
    style = platypus.TableStyle([
        ('ALIGN', (1, 1), (-1, -1), 'RIGHT'),
        ('ALIGN', (0, 0), (-1, 0), 'CENTRE'),
        ('GRID', (0, 0), (-1, -1), 0.25, colors.black),
        ('LINEBELOW', (0, 0), (-1, 0), 2, colors.black),
        ('LINEBELOW', (1, -1), (-1, -1), 2, (0.5, 0.5, 0.5)),
        ('TEXTCOLOR', (0, 1), (0, -1), colors.black),
        ('BACKGROUND', (0, 0), (-1, 0), (0, 0.7, 0.7))
    ])
    g.setStyle(style)
    story.append(g)
    story.append(FrameBreak())

    #######################################################################
    #     Examples Page 4 - custom fonts
    #######################################################################
    # custom font with LettError-Robot font
    import reportlab.rl_config
    reportlab.rl_config.warnOnMissingFontGlyphs = 0

    from reportlab.pdfbase import pdfmetrics
    fontDir = os.path.join(_RL_DIR, 'fonts')
    face = pdfmetrics.EmbeddedType1Face(
        os.path.join(fontDir, 'DarkGardenMK.afm'),
        os.path.join(fontDir, 'DarkGardenMK.pfb'))
    faceName = face.name  # should be 'DarkGardenMK'
    pdfmetrics.registerTypeFace(face)
    font = pdfmetrics.Font(faceName, faceName, 'WinAnsiEncoding')
    pdfmetrics.registerFont(font)

    # put it inside a paragraph.
    story.append(
        Paragraph(
            """This is an ordinary paragraph, which happens to contain
        text in an embedded font:
        <font name="DarkGardenMK">DarkGardenMK</font>.
        Now for the real challenge...""", styleSheet['Normal']))

    styRobot = ParagraphStyle('Robot', styleSheet['Normal'])
    styRobot.fontSize = 16
    styRobot.leading = 20
    styRobot.fontName = 'DarkGardenMK'

    story.append(
        Paragraph("This whole paragraph is 16-point DarkGardenMK.", styRobot))
    story.append(FrameBreak())

    if _GIF:
        story.append(
            Paragraph(
                "Here is an Image flowable obtained from a string filename.",
                styleSheet['Italic']))
        story.append(platypus.Image(_GIF))
        story.append(
            Paragraph(
                "Here is an Image flowable obtained from a utf8 filename.",
                styleSheet['Italic']))
        #story.append(platypus.Image(fileName2FSEnc(_GIF)))
        story.append(
            Paragraph(
                "Here is an Image flowable obtained from a string file url.",
                styleSheet['Italic']))
        story.append(platypus.Image(getFurl(_GIF)))
        story.append(
            Paragraph("Here is an Image flowable obtained from an open file.",
                      styleSheet['Italic']))
        story.append(platypus.Image(open_for_read(_GIF, 'b')))
        story.append(FrameBreak())
        try:
            img = platypus.Image(
                'http://www.reportlab.com/rsrc/encryption.gif')
            story.append(
                Paragraph(
                    "Here is an Image flowable obtained from a string http url.",
                    styleSheet['Italic']))
            story.append(img)
        except:
            story.append(
                Paragraph(
                    "The image could not be obtained from a string http url.",
                    styleSheet['Italic']))
        story.append(FrameBreak())

    if _JPG:
        img = platypus.Image(_JPG)
        story.append(
            Paragraph(
                "Here is an JPEG Image flowable obtained from a filename.",
                styleSheet['Italic']))
        story.append(img)
        story.append(
            Paragraph(
                "Here is an JPEG Image flowable obtained from an open file.",
                styleSheet['Italic']))
        img = platypus.Image(open_for_read(_JPG, 'b'))
        story.append(img)
        story.append(FrameBreak())

    return story
                     fontSize=size))

    d.add(String(130, 120, 'Hello World',
                 fontName='Courier',
                 fontSize=36))

    d.add(String(150, 160, 'Hello World',
                 fontName='DarkGardenMK',
                 fontSize=36))
""")

from reportlab.pdfbase import pdfmetrics
from reportlab import rl_config
rl_config.warnOnMissingFontGlyphs = 0
afmFile, pfbFile = getJustFontPaths()
T1face = pdfmetrics.EmbeddedType1Face(afmFile, pfbFile)
T1faceName = 'DarkGardenMK'
pdfmetrics.registerTypeFace(T1face)
T1font = pdfmetrics.Font(T1faceName, T1faceName, 'WinAnsiEncoding')
pdfmetrics.registerFont(T1font)

d = Drawing(400, 200)
for size in range(12, 36, 4):
    d.add(
        String(10 + size * 2,
               10 + size * 2,
               'Hello World',
               fontName='Times-Roman',
               fontSize=size))

d.add(String(130, 120, 'Hello World', fontName='Courier', fontSize=36))
Exemplo n.º 18
0
    def __init__(self, flist, font_path=None, style_path=None, def_dpi=300):
        log.info('Using stylesheets: %s' % ','.join(flist))
        # find base path
        if hasattr(sys, 'frozen'):
            self.PATH = abspath(dirname(sys.executable))
        else:
            self.PATH = abspath(dirname(__file__))

        # flist is a list of stylesheet filenames.
        # They will be loaded and merged in order.
        # but the two default stylesheets will always
        # be loaded first
        flist = [
            join(self.PATH, 'styles', 'styles.style'),
            join(self.PATH, 'styles', 'default.style')
        ] + flist

        self.def_dpi = def_dpi
        if font_path is None:
            font_path = []
        font_path += ['.', os.path.join(self.PATH, 'fonts')]
        self.FontSearchPath = list(map(os.path.expanduser, font_path))

        if style_path is None:
            style_path = []
        style_path += [
            '.', os.path.join(self.PATH, 'styles'), '~/.rst2pdf/styles'
        ]
        self.StyleSearchPath = list(map(os.path.expanduser, style_path))

        # Remove duplicates but preserve order. Not very efficient, but these are short lists
        self.FontSearchPath = [x for (i,x) in enumerate(self.FontSearchPath) if self.FontSearchPath.index(x) == i]
        self.StyleSearchPath = [x for (i,x) in enumerate(self.StyleSearchPath) if self.StyleSearchPath.index(x) == i]

        log.info('FontPath:%s' % self.FontSearchPath)
        log.info('StylePath:%s' % self.StyleSearchPath)

        findfonts.flist = self.FontSearchPath
        # Page width, height
        self.pw = 0
        self.ph = 0

        # Page size [w,h]
        self.ps = None

        # Margins (top,bottom,left,right,gutter)
        self.tm = 0
        self.bm = 0
        self.lm = 0
        self.rm = 0
        self.gm = 0

        # text width
        self.tw = 0

        # Default emsize, later it will be the fontSize of the base style
        self.emsize = 10

        self.languages = []

        ssdata = self.readSheets(flist)

        # Get pageSetup data from all stylessheets in order:
        self.ps = pagesizes.A4
        self.page = {}
        for data, ssname in ssdata:
            page = data.get('pageSetup', {})
            if page:
                self.page.update(page)
                pgs = page.get('size', None)
                if pgs:  # A standard size
                    pgs = pgs.upper()
                    if pgs in pagesizes.__dict__:
                        self.ps = list(pagesizes.__dict__[pgs])
                        self.psname = pgs
                        if 'width' in self.page:
                            del(self.page['width'])
                        if 'height' in self.page:
                            del(self.page['height'])
                    elif pgs.endswith('-LANDSCAPE'):
                        self.psname = pgs.split('-')[0]
                        self.ps = list(pagesizes.landscape(pagesizes.__dict__[self.psname]))
                        if 'width' in self.page:
                            del(self.page['width'])
                        if 'height' in self.page:
                            del(self.page['height'])
                    else:
                        log.critical('Unknown page size %s in stylesheet %s' %
                                     (page['size'], ssname))
                        continue
                else:  # A custom size
                    if 'size'in self.page:
                        del(self.page['size'])
                    # The sizes are expressed in some unit.
                    # For example, 2cm is 2 centimeters, and we need
                    # to do 2*cm (cm comes from reportlab.lib.units)
                    if 'width' in page:
                        self.ps[0] = self.adjustUnits(page['width'])
                    if 'height' in page:
                        self.ps[1] = self.adjustUnits(page['height'])
                self.pw, self.ph = self.ps
                if 'margin-left' in page:
                    self.lm = self.adjustUnits(page['margin-left'])
                if 'margin-right' in page:
                    self.rm = self.adjustUnits(page['margin-right'])
                if 'margin-top' in page:
                    self.tm = self.adjustUnits(page['margin-top'])
                if 'margin-bottom' in page:
                    self.bm = self.adjustUnits(page['margin-bottom'])
                if 'margin-gutter' in page:
                    self.gm = self.adjustUnits(page['margin-gutter'])
                if 'spacing-header' in page:
                    self.ts = self.adjustUnits(page['spacing-header'])
                if 'spacing-footer' in page:
                    self.bs = self.adjustUnits(page['spacing-footer'])
                if 'firstTemplate' in page:
                    self.firstTemplate = page['firstTemplate']

                # tw is the text width.
                # We need it to calculate header-footer height
                # and compress literal blocks.
                self.tw = self.pw - self.lm - self.rm - self.gm

        # Get page templates from all stylesheets
        self.pageTemplates = {}
        for data, ssname in ssdata:
            templates = data.get('pageTemplates', {})
            # templates is a dictionary of pageTemplates
            for key in templates:
                template = templates[key]
                # template is a dict.
                # template[´frames'] is a list of frames
                if key in self.pageTemplates:
                    self.pageTemplates[key].update(template)
                else:
                    self.pageTemplates[key] = template

        # Get font aliases from all stylesheets in order
        self.fontsAlias = {}
        for data, ssname in ssdata:
            self.fontsAlias.update(data.get('fontsAlias', {}))

        embedded_fontnames = []
        self.embedded = []
        # Embed all fonts indicated in all stylesheets
        for data, ssname in ssdata:
            embedded = data.get('embeddedFonts', [])

            for font in embedded:
                try:
                    # Just a font name, try to embed it
                    if isinstance(font, six.string_types):
                        # See if we can find the font
                        fname, pos = findfonts.guessFont(font)
                        if font in embedded_fontnames:
                            pass
                        else:
                            fontList = findfonts.autoEmbed(font)
                            if fontList:
                                embedded_fontnames.append(font)
                        if not fontList:
                            if (fname, pos) in embedded_fontnames:
                                fontList = None
                            else:
                                fontList = findfonts.autoEmbed(fname)
                        if fontList is not None:
                            self.embedded += fontList
                            # Maybe the font we got is not called
                            # the same as the one we gave
                            # so check that out
                            suff = ["", "-Oblique", "-Bold", "-BoldOblique"]
                            if not fontList[0].startswith(font):
                                # We need to create font aliases, and use them
                                for fname, aliasname in zip(
                                        fontList,
                                        [font + suffix for suffix in suff]):
                                    self.fontsAlias[aliasname] = fname
                        continue

                    # Each "font" is a list of four files, which will be
                    # used for regular / bold / italic / bold+italic
                    # versions of the font.
                    # If your font doesn't have one of them, just repeat
                    # the regular font.

                    # Example, using the Tuffy font from
                    # http://tulrich.com/fonts/
                    # "embeddedFonts" : [
                    #                    ["Tuffy.ttf",
                    #                     "Tuffy_Bold.ttf",
                    #                     "Tuffy_Italic.ttf",
                    #                     "Tuffy_Bold_Italic.ttf"]
                    #                   ],

                    # The fonts will be registered with the file name,
                    # minus the extension.

                    if font[0].lower().endswith('.ttf'):  # A True Type font
                        for variant in font:
                            location = self.findFont(variant)
                            pdfmetrics.registerFont(
                                TTFont(str(variant.split('.')[0]), location))
                            log.info('Registering font: %s from %s' % (str(
                                variant.split('.')[0]), location))
                            self.embedded.append(str(variant.split('.')[0]))

                        # And map them all together
                        regular, bold, italic, bolditalic = [
                            variant.split('.')[0] for variant in font]
                        addMapping(regular, 0, 0, regular)
                        addMapping(regular, 0, 1, italic)
                        addMapping(regular, 1, 0, bold)
                        addMapping(regular, 1, 1, bolditalic)
                    else:  # A Type 1 font
                        # For type 1 fonts we require
                        # [FontName,regular,italic,bold,bolditalic]
                        # where each variant is a (pfbfile,afmfile) pair.
                        # For example, for the URW palladio from TeX:
                        # ["Palatino",("uplr8a.pfb","uplr8a.afm"),
                        #             ("uplri8a.pfb","uplri8a.afm"),
                        #             ("uplb8a.pfb","uplb8a.afm"),
                        #             ("uplbi8a.pfb","uplbi8a.afm")]
                        regular = pdfmetrics.EmbeddedType1Face(*font[1])
                        italic = pdfmetrics.EmbeddedType1Face(*font[2])
                        bold = pdfmetrics.EmbeddedType1Face(*font[3])
                        bolditalic = pdfmetrics.EmbeddedType1Face(*font[4])

                except Exception as e:
                    try:
                        if isinstance(font, list):
                            fname = font[0]
                        else:
                            fname = font
                        log.error("Error processing font %s: %s",
                                  os.path.splitext(fname)[0], str(e))
                        log.error("Registering %s as Helvetica alias", fname)
                        self.fontsAlias[fname] = 'Helvetica'
                    except Exception as e:
                        log.critical("Error processing font %s: %s", fname,
                                     str(e))
                        continue

        # Go though all styles in all stylesheets and find all fontNames.
        # Then decide what to do with them
        for data, ssname in ssdata:
            for [skey, style] in self.stylepairs(data):
                for key in style:
                    if key == 'fontName' or key.endswith('FontName'):
                        # It's an alias, replace it
                        if style[key] in self.fontsAlias:
                            style[key] = self.fontsAlias[style[key]]
                        # Embedded already, nothing to do
                        if style[key] in self.embedded:
                            continue
                        # Standard font, nothing to do
                        if style[key] in (
                                    "Courier",
                                    "Courier-Bold",
                                    "Courier-BoldOblique",
                                    "Courier-Oblique",
                                    "Helvetica",
                                    "Helvetica-Bold",
                                    "Helvetica-BoldOblique",
                                    "Helvetica-Oblique",
                                    "Symbol",
                                    "Times-Bold",
                                    "Times-BoldItalic",
                                    "Times-Italic",
                                    "Times-Roman",
                                    "ZapfDingbats"):
                            continue
                        # Now we need to do something
                        # See if we can find the font
                        fname, pos = findfonts.guessFont(style[key])

                        if style[key] in embedded_fontnames:
                            pass
                        else:
                            fontList = findfonts.autoEmbed(style[key])
                            if fontList:
                                embedded_fontnames.append(style[key])
                        if not fontList:
                            if (fname, pos) in embedded_fontnames:
                                fontList = None
                            else:
                                fontList = findfonts.autoEmbed(fname)
                            if fontList:
                                embedded_fontnames.append((fname, pos))
                        if fontList:
                            self.embedded += fontList
                            # Maybe the font we got is not called
                            # the same as the one we gave so check that out
                            suff = ["", "-Bold", "-Oblique", "-BoldOblique"]
                            if not fontList[0].startswith(style[key]):
                                # We need to create font aliases, and use them
                                basefname = style[key].split('-')[0]
                                for fname, aliasname in zip(
                                        fontList,
                                        [basefname + suffix for suffix in suff]):
                                    self.fontsAlias[aliasname] = fname
                                style[key] = self.fontsAlias[basefname +
                                                             suff[pos]]
                        else:
                            log.error("Unknown font: \"%s\","
                                      "replacing with Helvetica", style[key])
                            style[key] = "Helvetica"

        # Get styles from all stylesheets in order
        self.stylesheet = {}
        self.styles = []
        self.linkColor = 'navy'
        # FIXME: linkColor should probably not be a global
        #        style, and tocColor should probably not
        #        be a special case, but for now I'm going
        #        with the flow...
        self.tocColor = None
        for data, ssname in ssdata:
            self.linkColor = data.get('linkColor') or self.linkColor
            self.tocColor = data.get('tocColor') or self.tocColor
            for [skey, style] in self.stylepairs(data):
                sdict = {}
                # FIXME: this is done completely backwards
                for key in style:
                    # Handle color references by name
                    if key == 'color' or key.endswith('Color') and style[key]:
                        style[key] = formatColor(style[key])
                    elif key == 'commands':
                        style[key] = validateCommands(style[key])

                    # Handle alignment constants
                    elif key == 'alignment':
                        style[key] = dict(TA_LEFT=0,
                                          LEFT=0,
                                          TA_CENTER=1,
                                          CENTER=1,
                                          TA_CENTRE=1,
                                          CENTRE=1,
                                          TA_RIGHT=2,
                                          RIGHT=2,
                                          TA_JUSTIFY=4,
                                          JUSTIFY=4,
                                          DECIMAL=8, )[style[key].upper()]

                    elif key == 'language':
                        if not style[key] in self.languages:
                            self.languages.append(style[key])

                    sdict[key] = style[key]
                    sdict['name'] = skey
                # If the style already exists, update it
                if skey in self.stylesheet:
                    self.stylesheet[skey].update(sdict)
                else:  # New style
                    self.stylesheet[skey] = sdict
                    self.styles.append(sdict)

        # If the stylesheet has a style name docutils won't reach
        # make a copy with a sanitized name.
        # This may make name collisions possible but that should be
        # rare (who would have custom_name and custom-name in the
        # same stylesheet? ;-)
        # Issue 339

        styles2 = []
        for s in self.styles:
            if not re.match("^[a-z](-?[a-z0-9]+)*$", s['name']):
                s2 = copy(s)
                s2['name'] = docutils.nodes.make_id(s['name'])
                log.warning(
                    '%s is an invalid docutils class name, adding alias %s' %
                    (s['name'], s2['name']))
                styles2.append(s2)
        self.styles.extend(styles2)

        # And create  reportlabs stylesheet
        self.StyleSheet = StyleSheet1()

        dirty = True
        while dirty:
            dirty = False
            for s in self.styles:
                if s['name'] in self.StyleSheet:
                    continue
                try:
                    if 'parent' in s:
                        if s['parent'] is None:
                            if s['name'] != 'base':
                                s['parent'] = self.StyleSheet['base']
                            else:
                                del(s['parent'])
                        else:
                            s['parent'] = self.StyleSheet[s['parent']]
                    else:
                        if s['name'] != 'base':
                            s['parent'] = self.StyleSheet['base']
                except KeyError:
                    dirty = True
                    continue

                # If the style has no bulletFontName but it has a fontName, set it
                if ('bulletFontName' not in s) and ('fontName' in s):
                    s['bulletFontName'] = s['fontName']

                hasFS = True
                # Adjust fontsize units
                if 'fontSize' not in s:
                    s['fontSize'] = s['parent'].fontSize
                    s['trueFontSize'] = None
                    hasFS = False
                elif 'parent' in s:
                    # This means you can set the fontSize to
                    # "2cm" or to "150%" which will be calculated
                    # relative to the parent style
                    s['fontSize'] = self.adjustUnits(s['fontSize'],
                                                    s['parent'].fontSize)
                    s['trueFontSize'] = s['fontSize']
                else:
                    # If s has no parent, it's base, which has
                    # an explicit point size by default and %
                    # makes no sense, but guess it as % of 10pt
                    s['fontSize'] = self.adjustUnits(s['fontSize'], 10)

                # If the leading is not set, but the size is, set it
                if 'leading' not in s and hasFS:
                    s['leading'] = 1.2*s['fontSize']

                # If the bullet font size is not set, set it as fontSize
                if ('bulletFontSize' not in s) and ('fontSize' in s):
                    s['bulletFontSize'] = s['fontSize']

                # If the borderPadding is a list and wordaxe <=0.3.2,
                # convert it to an integer. Workaround for Issue
                if 'borderPadding' in s and (
                    ((HAS_WORDAXE and wordaxe_version <= 'wordaxe 0.3.2')
                    or reportlab.Version < "2.3")
                        and isinstance(s['borderPadding'], list)):
                    log.warning(
                        'Using a borderPadding list in '
                        'style %s with wordaxe <= 0.3.2 or Reportlab < 2.3. That is not '
                        'supported, so it will probably look wrong' % s['name'])
                    s['borderPadding'] = s['borderPadding'][0]
                if 'spaceBefore' in s:
                    if isinstance(s['spaceBefore'], str) and s['spaceBefore'].startswith('-'):
                        log.warning('A negative spaceBefore is the same as 0')
                    s['spaceBefore'] = self.adjustUnits(s['spaceBefore'])
                if 'spaceAfter' in s:
                    if isinstance(s['spaceAfter'], str) and s['spaceAfter'].startswith('-'):
                        log.warning('A negative spaceAfter is the same as 0')
                    s['spaceAfter'] = self.adjustUnits(s['spaceAfter'])

                self.StyleSheet.add(ParagraphStyle(**s))

        self.emsize = self['base'].fontSize
        # Make stdFont the basefont, for Issue 65
        reportlab.rl_config.canvas_basefontname = self['base'].fontName
        # Make stdFont the default font for table cell styles (Issue 65)
        reportlab.platypus.tables.CellStyle.fontname = self['base'].fontName
Exemplo n.º 19
0
    def loadFont(self,
                 names,
                 src,
                 encoding="WinAnsiEncoding",
                 bold=0,
                 italic=0):

        if names and src:
            if type(names) is types.ListType:
                fontAlias = names
            else:
                fontAlias = [x.lower().strip() for x in names.split(",") if x]

            # XXX Problems with unicode here
            fontAlias = [str(x) for x in fontAlias]
            src = str(src)

            fontName = fontAlias[0]
            parts = src.split(".")
            baseName, suffix = ".".join(parts[:-1]), parts[-1]
            suffix = suffix.lower()

            try:

                if suffix == "ttf":

                    # determine full font name according to weight and style
                    fullFontName = "%s_%d%d" % (fontName, bold, italic)

                    # check if font has already been registered
                    if fullFontName in self.fontList:
                        log.warn(
                            self.warning(
                                "Repeated font embed for %s, skip new embed ",
                                fullFontName))
                    else:

                        # Register TTF font and special name
                        pdfmetrics.registerFont(TTFont(fullFontName, src))

                        # Add or replace missing styles
                        for bold in (0, 1):
                            for italic in (0, 1):
                                if ("%s_%d%d" % (fontName, bold,
                                                 italic)) not in self.fontList:
                                    addMapping(fontName, bold, italic,
                                               fullFontName)

                        # Register "normal" name and the place holder for style
                        self.registerFont(fontName, fontAlias + [fullFontName])

                elif suffix in ("afm", "pfb"):

                    afm = baseName + ".afm"
                    pfb = baseName + ".pfb"

                    # determine full font name according to weight and style
                    fullFontName = "%s_%d%d" % (fontName, bold, italic)

                    #fontNameOriginal = ""
                    #for line in open(afm).readlines()[:-1]:
                    #    if line[:16] == 'StartCharMetrics':
                    #        self.error("Font name not found")
                    #    if line[:8] == 'FontName':
                    #        fontNameOriginal = line[9:].strip()
                    #        break

                    # check if font has already been registered
                    if fullFontName in self.fontList:
                        log.warn(
                            self.warning(
                                "Repeated font embed for %s, skip new embed",
                                fontName))
                    else:

                        # Include font
                        face = pdfmetrics.EmbeddedType1Face(afm, pfb)
                        fontNameOriginal = face.name
                        pdfmetrics.registerTypeFace(face)
                        # print fontName, fontNameOriginal, fullFontName
                        justFont = pdfmetrics.Font(fullFontName,
                                                   fontNameOriginal, encoding)
                        pdfmetrics.registerFont(justFont)

                        # Add or replace missing styles
                        for bold in (0, 1):
                            for italic in (0, 1):
                                if ("%s_%d%d" % (fontName, bold,
                                                 italic)) not in self.fontList:
                                    addMapping(fontName, bold, italic,
                                               fontNameOriginal)

                        # Register "normal" name and the place holder for style
                        self.registerFont(
                            fontName,
                            fontAlias + [fullFontName, fontNameOriginal])

                        #import pprint
                        #pprint.pprint(self.fontList)

                else:
                    log.warning(
                        self.warning("wrong attributes for <pdf:font>"))

            except Exception, e:
                log.warn(self.warning("Loading font '%s'", fontName),
                         exc_info=1)
Exemplo n.º 20
0
def autoEmbed(fname):
    """Given a font name, does a best-effort of embedding
    said font and its variants.

    Returns a list of the font names it registered with ReportLab.

    """
    log.info('Trying to embed %s' % fname)
    fontList = []
    f = findFont(fname)
    if f:  # It's a Type 1 font, and we have it
        family = families[f[2]]

        # Register the whole family of faces
        faces = [pdfmetrics.EmbeddedType1Face(*fonts[fn][:2]) for fn in family]
        for face in faces:
            pdfmetrics.registerTypeFace(face)

        for face, name in zip(faces, family):
            fontList.append(name)
            font = pdfmetrics.Font(face, name, "WinAnsiEncoding")
            log.info('Registering font: %s from %s'%\
                        (face,name))
            pdfmetrics.registerFont(font)

        # Map the variants
        regular, italic, bold, bolditalic = family
        addMapping(fname, 0, 0, regular)
        addMapping(fname, 0, 1, italic)
        addMapping(fname, 1, 0, bold)
        addMapping(fname, 1, 1, bolditalic)
        addMapping(regular, 0, 0, regular)
        addMapping(regular, 0, 1, italic)
        addMapping(regular, 1, 0, bold)
        addMapping(regular, 1, 1, bolditalic)
        log.info('Embedding as %s' % fontList)
        return fontList

    variants = findTTFont(fname)
    # It is a TT Font and we found it using fc-match (or found *something*)
    if variants:
        for variant in variants:
            vname = os.path.basename(variant)[:-4]
            try:
                if vname not in pdfmetrics._fonts:
                    _font = TTFont(vname, variant, validate=1)
                    log.info('Registering font: %s from %s'%\
                            (vname,variant))
                    pdfmetrics.registerFont(_font)
            except TTFError:
                log.error('Error registering font: %s from %s' %
                          (vname, variant))
            else:
                fontList.append(vname)
        regular, bold, italic, bolditalic = [
            os.path.basename(variant)[:-4] for variant in variants
        ]
        addMapping(regular, 0, 0, regular)
        addMapping(regular, 0, 1, italic)
        addMapping(regular, 1, 0, bold)
        addMapping(regular, 1, 1, bolditalic)
        log.info('Embedding via findTTFont as %s' % fontList)
    return fontList
Exemplo n.º 21
0
from reportlab.pdfgen import canvas
from reportlab.pdfbase import pdfmetrics

# Create a new canvas for cyrillic.pdf file
c = canvas.Canvas('cyrillic.pdf')

# fname - the font file name without extension
fname = 'a010013l'

# faceName - view a010013l.AFM file as a plain text and look at
# row beginning with 'FontName' word (it's usually the fourth row).
# The word after 'FontName' is the faceName ('URWGothicL-Book' in this case).
faceName = 'URWGothicL-Book'

# Define new Type 1 font
cyrFace = pdfmetrics.EmbeddedType1Face(fname + '.afm', fname + '.pfb')

# Create a new encoding called 'CP1251'
cyrenc = pdfmetrics.Encoding('CP1251')

# Fill in the tuple with Unicode glyphs in accordance with cp1251 (win1251)
# encoding
cp1251 = ('afii10051', 'afii10052', 'quotesinglbase', 'afii10100',
          'quotedblbase', 'ellipsis', 'dagger', 'daggerdbl', 'Euro',
          'perthousand', 'afii10058', 'guilsinglleft', 'afii10059',
          'afii10061', 'afii10060', 'afii10145', 'afii10099', 'quoteleft',
          'quoteright', 'quotedblleft', 'quotedblright', 'bullet', 'endash',
          'emdash', 'tilde', 'trademark', 'afii10106', 'guilsinglright',
          'afii10107', 'afii10109', 'afii10108', 'afii10193', 'space',
          'afii10062', 'afii10110', 'afii10057', 'currency', 'afii10050',
          'brokenbar', 'section', 'afii10023', 'copyright', 'afii10053',
Exemplo n.º 22
0
def __registerFont__(fontname, afmFilename, pfbFilename):
    justFace = pdfmetrics.EmbeddedType1Face(afmFilename, pfbFilename)
    pdfmetrics.registerTypeFace(justFace)
    justFont = pdfmetrics.Font(fontname, fontname, 'WinAnsiEncoding')
    pdfmetrics.registerFont(justFont)
Exemplo n.º 23
0
    def test0(self):
        """Make documents with embedded fonts.

        Just vam Rossum has kindly donated a font which we may use
        for testing purposes.  You need to contact him at [email protected]
        if you want to use it for real."""

        #LettError fonts should always be there.  The others are voluntary.

        ok = 1

        c = Canvas(outputfile('test_pdfbase_fontembed.pdf'))
        c.setPageCompression(0)
        c.setFont('Helvetica', 12)
        c.drawString(
            100, 700,
            'This is Helvetica.  The text below should be different fonts...')

        if os.path.isfile('GDB_____.AFM') and os.path.isfile('GDB_____.PFB'):
            # a normal text font
            garaFace = pdfmetrics.EmbeddedType1Face('GDB_____.AFM',
                                                    'GDB_____.PFB')
            faceName = 'AGaramond-Bold'  # pulled from AFM file
            pdfmetrics.registerTypeFace(garaFace)

            garaFont = pdfmetrics.Font('MyGaramondBold', faceName,
                                       'WinAnsiEncoding')
            pdfmetrics.registerFont(garaFont)

            c.setFont('AGaramond-Bold', 12)
            c.drawString(100, 650, 'This should be in AGaramond-Bold')

        if os.path.isfile('CR______.AFM') and os.path.isfile('CR______.PFB'):

            # one with a custom encoding
            cartaFace = pdfmetrics.EmbeddedType1Face('CR______.AFM',
                                                     'CR______.PFB')
            faceName = 'Carta'  # pulled from AFM file
            pdfmetrics.registerTypeFace(cartaFace)

            cartaFont = pdfmetrics.Font('Carta', 'Carta', 'CartaEncoding')
            pdfmetrics.registerFont(cartaFont)

            text = 'This should be in Carta, a map symbol font:'
            c.setFont('Helvetica', 12)
            c.drawString(100, 600, text)
            w = c.stringWidth(text, 'Helvetica', 12)

            c.setFont('Carta', 12)
            c.drawString(100 + w, 600, ' Hello World')

        # LettError sample - creates on demand, we hope
        y = 550
        ##        dgmkFace = pdfmetrics.EmbeddedType1Face('DarkGardenMK.afm','DarkGardenMK.PFB')
        ##
        ##        faceName = 'DarkGardenMK'  # pulled from AFM file
        ##        pdfmetrics.registerTypeFace(dgmkFace)
        ##
        ##        dgmkFont = pdfmetrics.Font('DarkGardenMK', faceName, 'WinAnsiEncoding')
        ##        pdfmetrics.registerFont(dgmk)

        c.setFont('DarkGardenMK', 12)
        c.drawString(100, y, 'This should be in DarkGardenMK')

        def testNamedFont(canv, fontName):
            canv.showPage()
            makeWidthTestForAllGlyphs(canv, fontName, outlining=0)

        testNamedFont(c, 'DarkGardenMK')

        c.save()
Exemplo n.º 24
0
    def __init__(self, flist, font_path=None, style_path=None, def_dpi=300):
        log.info('Using stylesheets: %s' % ','.join(flist))
        # find base path
        if hasattr(sys, 'frozen'):
            self.PATH = abspath(dirname(sys.executable))
        else:
            self.PATH = abspath(dirname(__file__))

        # flist is a list of stylesheet filenames.
        # They will be loaded and merged in order.
        # but the two default stylesheets will always
        # be loaded first
        flist = [join(self.PATH, 'styles', 'styles.style'),
                join(self.PATH, 'styles', 'default.style')] + flist

        self.def_dpi=def_dpi
        if font_path is None:
            font_path=[]
        font_path+=['.', os.path.join(self.PATH, 'fonts')]
        self.FontSearchPath = map(os.path.expanduser, font_path)

        if style_path is None:
            style_path=[]
        style_path+=['.', os.path.join(self.PATH, 'styles'),
                      '~/.rst2pdf/styles']
        self.StyleSearchPath = map(os.path.expanduser, style_path)
        self.FontSearchPath=list(set(self.FontSearchPath))
        self.StyleSearchPath=list(set(self.StyleSearchPath))

        log.info('FontPath:%s'%self.FontSearchPath)
        log.info('StylePath:%s'%self.StyleSearchPath)

        findfonts.flist = self.FontSearchPath
        # Page width, height
        self.pw = 0
        self.ph = 0

        # Page size [w,h]
        self.ps = None

        # Margins (top,bottom,left,right,gutter)
        self.tm = 0
        self.bm = 0
        self.lm = 0
        self.rm = 0
        self.gm = 0

        #text width
        self.tw = 0

        # Default emsize, later it will be the fontSize of the base style
        self.emsize=10

        self.languages = []

        ssdata = self.readSheets(flist)

        # Get pageSetup data from all stylessheets in order:
        self.ps = pagesizes.A4
        self.page={}
        for data, ssname in ssdata:
            page = data.get('pageSetup', {})
            if page:
                self.page.update(page)
                pgs=page.get('size', None)
                if pgs: # A standard size
                    pgs=pgs.upper()
                    if pgs in pagesizes.__dict__:
                        self.ps = list(pagesizes.__dict__[pgs])
                        self.psname = pgs
                        if 'width' in self.page: del(self.page['width'])
                        if 'height' in self.page: del(self.page['height'])
                    elif pgs.endswith('-LANDSCAPE'):
                        self.psname = pgs.split('-')[0]
                        self.ps = list(pagesizes.landscape(pagesizes.__dict__[self.psname]))
                        if 'width' in self.page: del(self.page['width'])
                        if 'height' in self.page: del(self.page['height'])
                    else:
                        log.critical('Unknown page size %s in stylesheet %s'%\
                            (page['size'], ssname))
                        continue
                else: #A custom size
                    if 'size'in self.page:
                        del(self.page['size'])
                    # The sizes are expressed in some unit.
                    # For example, 2cm is 2 centimeters, and we need
                    # to do 2*cm (cm comes from reportlab.lib.units)
                    if 'width' in page:
                        self.ps[0] = self.adjustUnits(page['width'])
                    if 'height' in page:
                        self.ps[1] = self.adjustUnits(page['height'])
                self.pw, self.ph = self.ps
                if 'margin-left' in page:
                    self.lm = self.adjustUnits(page['margin-left'])
                if 'margin-right' in page:
                    self.rm = self.adjustUnits(page['margin-right'])
                if 'margin-top' in page:
                    self.tm = self.adjustUnits(page['margin-top'])
                if 'margin-bottom' in page:
                    self.bm = self.adjustUnits(page['margin-bottom'])
                if 'margin-gutter' in page:
                    self.gm = self.adjustUnits(page['margin-gutter'])
                if 'spacing-header' in page:
                    self.ts = self.adjustUnits(page['spacing-header'])
                if 'spacing-footer' in page:
                    self.bs = self.adjustUnits(page['spacing-footer'])
                if 'firstTemplate' in page:
                    self.firstTemplate = page['firstTemplate']

                # tw is the text width.
                # We need it to calculate header-footer height
                # and compress literal blocks.
                self.tw = self.pw - self.lm - self.rm - self.gm

        # Get page templates from all stylesheets
        self.pageTemplates = {}
        for data, ssname in ssdata:
            templates = data.get('pageTemplates', {})
            # templates is a dictionary of pageTemplates
            for key in templates:
                template = templates[key]
                # template is a dict.
                # template[´frames'] is a list of frames
                if key in self.pageTemplates:
                    self.pageTemplates[key].update(template)
                else:
                    self.pageTemplates[key] = template

        # Get font aliases from all stylesheets in order
        self.fontsAlias = {}
        for data, ssname in ssdata:
            self.fontsAlias.update(data.get('fontsAlias', {}))

        embedded_fontnames = []
        self.embedded = []
        # Embed all fonts indicated in all stylesheets
        for data, ssname in ssdata:
            embedded = data.get('embeddedFonts', [])

            for font in embedded:
                try:
                    # Just a font name, try to embed it
                    if isinstance(font, unicode):
                        # See if we can find the font
                        fname, pos = findfonts.guessFont(font)
                        if font in embedded_fontnames:
                            pass
                        else:
                            fontList = findfonts.autoEmbed(font)
                            if fontList:
                                embedded_fontnames.append(font)
                        if not fontList:
                            if (fname, pos) in embedded_fontnames:
                                fontList = None
                            else:
                                fontList = findfonts.autoEmbed(fname)
                        if fontList is not None:
                            self.embedded += fontList
                            # Maybe the font we got is not called
                            # the same as the one we gave
                            # so check that out
                            suff = ["", "-Oblique", "-Bold", "-BoldOblique"]
                            if not fontList[0].startswith(font):
                                # We need to create font aliases, and use them
                                for fname, aliasname in zip(
                                        fontList,
                                        [font + suffix for suffix in suff]):
                                    self.fontsAlias[aliasname] = fname
                        continue

                    # Each "font" is a list of four files, which will be
                    # used for regular / bold / italic / bold+italic
                    # versions of the font.
                    # If your font doesn't have one of them, just repeat
                    # the regular font.

                    # Example, using the Tuffy font from
                    # http://tulrich.com/fonts/
                    # "embeddedFonts" : [
                    #                    ["Tuffy.ttf",
                    #                     "Tuffy_Bold.ttf",
                    #                     "Tuffy_Italic.ttf",
                    #                     "Tuffy_Bold_Italic.ttf"]
                    #                   ],

                    # The fonts will be registered with the file name,
                    # minus the extension.

                    if font[0].lower().endswith('.ttf'): # A True Type font
                        for variant in font:
                            location=self.findFont(variant)
                            pdfmetrics.registerFont(
                                TTFont(str(variant.split('.')[0]),
                                location))
                            log.info('Registering font: %s from %s'%\
                                (str(variant.split('.')[0]),location))
                            self.embedded.append(str(variant.split('.')[0]))

                        # And map them all together
                        regular, bold, italic, bolditalic = [
                            variant.split('.')[0] for variant in font]
                        addMapping(regular, 0, 0, regular)
                        addMapping(regular, 0, 1, italic)
                        addMapping(regular, 1, 0, bold)
                        addMapping(regular, 1, 1, bolditalic)
                    else: # A Type 1 font
                        # For type 1 fonts we require
                        # [FontName,regular,italic,bold,bolditalic]
                        # where each variant is a (pfbfile,afmfile) pair.
                        # For example, for the URW palladio from TeX:
                        # ["Palatino",("uplr8a.pfb","uplr8a.afm"),
                        #             ("uplri8a.pfb","uplri8a.afm"),
                        #             ("uplb8a.pfb","uplb8a.afm"),
                        #             ("uplbi8a.pfb","uplbi8a.afm")]
                        faceName = font[0]
                        regular = pdfmetrics.EmbeddedType1Face(*font[1])
                        italic = pdfmetrics.EmbeddedType1Face(*font[2])
                        bold = pdfmetrics.EmbeddedType1Face(*font[3])
                        bolditalic = pdfmetrics.EmbeddedType1Face(*font[4])

                except Exception, e:
                    try:
                        if isinstance(font, list):
                            fname = font[0]
                        else:
                            fname = font
                        log.error("Error processing font %s: %s",
                            os.path.splitext(fname)[0], str(e))
                        log.error("Registering %s as Helvetica alias", fname)
                        self.fontsAlias[fname] = 'Helvetica'
                    except Exception, e:
                        log.critical("Error processing font %s: %s",
                            fname, str(e))
                        continue
Exemplo n.º 25
0
import os
from reportlab.pdfbase import pdfmetrics, pdfdoc

for afm in os.listdir('.'):
    if not afm.endswith('.afm'):
        continue

    title = afm[:-4]
    pfb = title + '.pfb'

    if not os.path.exists(pfb):
        print "%s doesn't exist!" % pfb
        continue

    face = pdfmetrics.EmbeddedType1Face(afm, pfb)
    if face.name != title:
        os.rename(afm, face.name + '.afm')
        os.rename(pfb, face.name + '.pfb')
Exemplo n.º 26
0
                        ]
                        addMapping(regular, 0, 0, regular)
                        addMapping(regular, 0, 1, italic)
                        addMapping(regular, 1, 0, bold)
                        addMapping(regular, 1, 1, bolditalic)
                    else:  # A Type 1 font
                        # For type 1 fonts we require
                        # [FontName,regular,italic,bold,bolditalic]
                        # where each variant is a (pfbfile,afmfile) pair.
                        # For example, for the URW palladio from TeX:
                        # ["Palatino",("uplr8a.pfb","uplr8a.afm"),
                        #             ("uplri8a.pfb","uplri8a.afm"),
                        #             ("uplb8a.pfb","uplb8a.afm"),
                        #             ("uplbi8a.pfb","uplbi8a.afm")]
                        faceName = font[0]
                        regular = pdfmetrics.EmbeddedType1Face(*font[1])
                        italic = pdfmetrics.EmbeddedType1Face(*font[2])
                        bold = pdfmetrics.EmbeddedType1Face(*font[3])
                        bolditalic = pdfmetrics.EmbeddedType1Face(*font[4])

                except Exception, e:
                    try:
                        if isinstance(font, list):
                            fname = font[0]
                        else:
                            fname = font
                        log.error("Error processing font %s: %s",
                                  os.path.splitext(fname)[0], str(e))
                        log.error("Registering %s as Helvetica alias", fname)
                        self.fontsAlias[fname] = 'Helvetica'
                    except Exception, e: