Esempio n. 1
0
    def __init__(self, filename, size, atlas):

        self.filename = filename
        self.atlas = atlas
        self.size = size
        self.glyphs = {}
        face = freetype.Face(self.filename)
        face.set_char_size(int(size * 64))
        metrics = face.size
        self.ascender = metrics.ascender / 64.0
        self.descender = metrics.descender / 64.0
        self.height = metrics.height / 64.0
        self.linegap = (self.height - self.ascender + self.descender)

        freetype.set_lcd_filter(freetype.FT_LCD_FILTER_LIGHT)
Esempio n. 2
0
    def __init__(self, filename, atlas):

        self._hires_size = 256
        self._lowres_size = 48
        self._padding = 0.125

        self.filename = filename
        self.atlas = atlas

        self.glyphs = {}
        face = freetype.Face(self.filename)
        face.set_char_size(self._lowres_size * 64)
        metrics = face.size
        self.ascender = metrics.ascender / 64.0
        self.descender = metrics.descender / 64.0
        self.height = metrics.height / 64.0
        self.linegap = (self.height - self.ascender + self.descender)
Esempio n. 3
0
    def load(self, charcodes=''):
        face = freetype.Face(self.filename)

        for charcode in charcodes:
            if charcode in self.glyphs.keys():
                continue

            data, offset, advance = self.load_glyph(face, charcode)

            h, w = data.shape
            region = self.atlas.allocate((h + 2, w + 2))
            if region is None:
                log.warn("Cannot store glyph '%c'" % charcode)
                continue
            x, y, _, _ = region
            x, y = x + 1, y + 1
            self.atlas[y:y + h, x:x + w] = data.reshape(h, w, 1)

            u0 = (x + 0.0) / float(self.atlas.width)
            v0 = (y + 0.0) / float(self.atlas.height)
            u1 = (x + w - 0.0) / float(self.atlas.width)
            v1 = (y + h - 0.0) / float(self.atlas.height)
            texcoords = (u0, v0, u1, v1)
            glyph = Glyph(charcode, data.shape, offset, advance, texcoords)
            self.glyphs[charcode] = glyph

            # Generate kerning (for reference size)
            face.set_char_size(self._lowres_size * 64)
            for g in self.glyphs.values():
                kerning = face.get_kerning(g.charcode,
                                           charcode,
                                           mode=freetype.FT_KERNING_UNFITTED)
                if kerning.x != 0:
                    glyph.kerning[g.charcode] = kerning.x / 64.0
                kerning = face.get_kerning(charcode,
                                           g.charcode,
                                           mode=freetype.FT_KERNING_UNFITTED)
                if kerning.x != 0:
                    g.kerning[charcode] = kerning.x / 64.0
Esempio n. 4
0
    def load(self, charcodes=''):
        '''
        Build glyphs corresponding to individual characters in charcodes.

        Parameters:
        -----------

        charcodes: [str | unicode]
            Set of characters to be represented
        '''
        face = freetype.Face(self.filename)
        pen = freetype.Vector(0, 0)
        hres = 100 * 72
        hscale = 1.0 / 100

        for charcode in charcodes:
            face.set_char_size(int(self.size * 64), 0, hres, 72)
            matrix = freetype.Matrix(int((hscale) * 0x10000),
                                     int((0.0) * 0x10000), int(
                                         (0.0) * 0x10000), int(
                                             (1.0) * 0x10000))
            face.set_transform(matrix, pen)
            if charcode in self.glyphs.keys():
                continue

            flags = freetype.FT_LOAD_RENDER | freetype.FT_LOAD_FORCE_AUTOHINT
            flags |= freetype.FT_LOAD_TARGET_LCD

            face.load_char(charcode, flags)
            bitmap = face.glyph.bitmap
            left = face.glyph.bitmap_left
            top = face.glyph.bitmap_top
            width = face.glyph.bitmap.width
            rows = face.glyph.bitmap.rows
            pitch = face.glyph.bitmap.pitch

            w = int(width // 3)
            h = rows
            # h+1,w+1 to have a black border
            region = self.atlas.allocate((h + 1, w + 1))
            if region is None:
                log.warn("Cannot store glyph '%c'" % charcode)
                continue

            x, y, _, _ = region
            # sould be y+h+1,x+w+1 but we skip the black border

            texture = self.atlas[y:y + h, x:x + w]
            data = []
            for i in range(rows):
                data.extend(bitmap.buffer[i * pitch:i * pitch + width])
            data = np.array(data, dtype=np.ubyte).reshape(h, w, 3)
            texture[...] = data

            # Build glyph
            size = w, h
            offset = left, top
            advance = face.glyph.advance.x, face.glyph.advance.y

            u0 = (x + 0.0) / float(self.atlas.width)
            v0 = (y + 0.0) / float(self.atlas.height)
            u1 = (x + w - 0.0) / float(self.atlas.width)
            v1 = (y + h - 0.0) / float(self.atlas.height)
            texcoords = (u0, v0, u1, v1)
            glyph = Glyph(charcode, size, offset, advance, texcoords)
            self.glyphs[charcode] = glyph

            # Generate kerning
            for g in self.glyphs.values():
                # 64 * 64 because of 26.6 encoding AND the transform matrix used
                # in texture_font_load_face (hres = 64)
                kerning = face.get_kerning(g.charcode,
                                           charcode,
                                           mode=freetype.FT_KERNING_UNFITTED)
                if kerning.x != 0:
                    glyph.kerning[g.charcode] = kerning.x / (64.0 * 64.0)
                kerning = face.get_kerning(charcode,
                                           g.charcode,
                                           mode=freetype.FT_KERNING_UNFITTED)
                if kerning.x != 0:
                    g.kerning[charcode] = kerning.x / (64.0 * 64.0)