예제 #1
0
    def apply(self, info, glyph, startx, starty, size, maxsize, glyphimage, previmage):
        factor = self.factor
        face = info.face
        flags = ft.LOAD_RENDER | ft.LOAD_TARGET_MONO
        
        face.set_char_size( width=0, height=(info.size*factor)*64, hres=info.dpi, vres=info.dpi )
        face.load_char( glyph.unicode, flags )

        bitmap = fu.make_array_from_bitmap(face.glyph.contents.bitmap) * 255
        
        metrics = face.glyph.contents.metrics
        bearingY = (metrics.horiBearingY >> 6) + info.internalpadding[1]*factor + info.extrapadding[1]*factor
        
        # Due to the down scaling, we need to make sure that the bitmap start at the correct pixels
        offset_y = bearingY - glyph.bearingY * factor
        
        bitmap = fu.pad_bitmap(bitmap, info.extrapadding[0]*factor, info.extrapadding[1]*factor - offset_y, info.extrapadding[2]*factor, info.extrapadding[3]*factor + offset_y, 0, debug=glyph.unicode=='r')
        
        # TODO: Work out how to eliminate this issue
        e = np.empty( bitmap.shape, bitmap.dtype, order='F' )
        e[:, :] = bitmap
        bitmap = e
        
        i = utils.calculate_sedt(bitmap, self.size)
        #i = bitmap
        
        while factor > 1:
            i = utils.half_size(i)
            factor /= 2
        
        i = i.astype(np.float64) / 255.0
        
        a = np.zeros_like(i)
        a[i > 0] = 1.0
        
        return np.dstack( (i, i, i, a) )
예제 #2
0
def render(options, info, face):
    
    found = False
    for charmap in face.charmaps:
        found = found or charmap.encoding == ft.ENCODING_UNICODE
    if not found:
        logging.warning("The font %s doesn't seem to support unicode!? Continuing anyway")
    
    if options.writetext:
        info.letters = [c for c in info.letters if unichr(c) in options.writetext]

    logging.debug("Rendering %d characters" % len(info.letters))

    # find out the needed extra padding on each side of each glyph
    info.extrapadding = _get_extra_padding(info)
    
    info.face = face

    flags = ft.LOAD_RENDER
        
    antialias = getattr(info, 'antialias', 'normal')
    if antialias == 'none':
        flags |= ft.LOAD_TARGET_MONO
    elif antialias == 'light':
        flags |= ft.LOAD_TARGET_LIGHT
    elif antialias == 'normal':
        flags |= ft.LOAD_TARGET_NORMAL

    logging.debug("RENDERING %s", unicode([g.unicode for g in info.glyphs]))
    
    assert len(info.glyphs) > 0, "No glyphs to process!"
    
    # since the layers might set this, we set it back
    face.set_char_size( width=0, height=info.size * 64, hres=info.dpi, vres=info.dpi )
    
    for glyph in info.glyphs:

        face.load_char( glyph.unicode, flags )

        if face.glyph.contents.bitmap.rows:
            glyph.bitmap = fu.make_array_from_bitmap(face.glyph.contents.bitmap)
            shape = glyph.bitmap.shape

            glyph.bitmap = fu.pad_bitmap(glyph.bitmap, info.extrapadding[0], info.extrapadding[1], info.extrapadding[2], info.extrapadding[3], 0.0)

            if info.useadvanceaswidth:
                # Pad the bitmap with the bearing width on each side
                # This is useful for file formats that doesn't carry all the glyph info into it
                padleft = glyph.bearingX
                padright = glyph.advance - shape[0] - padleft
                glyph.bitmap = fu.pad_bitmap(glyph.bitmap, 0, 0, padright, 0, 0.0)

            if antialias != 'none':
                glyph.bitmap /= 255.0

        else:
            logging.debug("char missing bitmap %X '%s'" % (glyph.utf8, glyph.unicode) )

    # Apply all layers on all the tiny bitmaps
    _apply_layers(info)
    
    max_bearing_y = 0 # the maximum extent above the baseline
    min_bearing_y = 0 # the maximum extent below the baseline
    max_width = 0

    # calculate the height/width, since the layers may increased/decreased the size
    max_width = 0
    max_height = 0
    for glyph in info.glyphs:
        if glyph.bitmap is None:
            continue
        # find the highest char
        max_bearing_y = max(max_bearing_y, glyph.bearingY)
        # find the lowest char
        min_bearing_y = min(min_bearing_y, glyph.bearingY - glyph.bitmap.shape[1])
        
        max_width = max(max_width, glyph.bitmap.shape[0])
        max_height = max(max_height, glyph.bitmap.shape[1])

    info.max_height = max(max_height, info.ascender - info.descender)
    info.max_width = max_width