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) )
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