def getGlyphInfos(self): result = [] # glyphIndexToNameMap = {} glyphToCharacterMap = self.getGlyphIndexToCharacterMap() if self.ftFont.has_glyph_names: for glyphIndex in self.getGlyphIndices(): glyphNameBuffer = ' ' * 256 error = freetype.FT_Get_Glyph_Name(self.ftFont._FT_Face, glyphIndex, glyphNameBuffer, len(glyphNameBuffer) - 1) if error: raise freetype.FT_Exception(error) glyphInfo = TFSMap() glyphInfo.glyphIndex = glyphIndex glyphInfo.glyphName = glyphNameBuffer.strip()[:-1] # print 'glyphName', glyphIndex, glyphName, len(glyphName) glyphInfo.characterCode = None if glyphIndex in glyphToCharacterMap: glyphInfo.characterCode = glyphToCharacterMap[glyphIndex] result.append(glyphInfo) else: for glyphIndex, characterCode in glyphToCharacterMap.items(): glyphInfo = TFSMap() glyphInfo.glyphIndex = glyphIndex glyphInfo.glyphName = getUnicodeCharacterName(characterCode) glyphInfo.characterCode = characterCode # glyphInfoMap[glyphIndex] = glyphInfo result.append(glyphInfo) return result
def getKerning(self, glyphIndex0, glyphIndex1): kerning = freetype.FT_Vector(0, 0) error = freetype.FT_Get_Kerning(self.ftFont._FT_Face, glyphIndex0, glyphIndex1, ft_enums.FT_KERNING_UNSCALED, freetype.byref(kerning)) if error: raise freetype.FT_Exception(error) return kerning.x
def get_glyph(self, stroke=None): glyph = self.face.glyph.get_glyph() if stroke is not None: stroke_width = int(stroke * 64 * self.font.hres / 330) stroker = ft.Stroker() stroker.set(stroke_width, ft.FT_STROKER_LINECAP_ROUND, ft.FT_STROKER_LINEJOIN_ROUND, 0) # StrokeBorder is not wrapped in freetype-py.Glyph... error = ft.FT_Glyph_StrokeBorder(ft.byref(glyph._FT_Glyph), stroker._FT_Stroker, 0, 0) if error: raise ft.FT_Exception(error) blyph = glyph.to_bitmap(ft.FT_RENDER_MODE_NORMAL, ft.Vector(0,0)) blyph.glyph = glyph # keep a reference, otherwise it blows up return blyph
def load_character(self, character): assert self.face is not None assert len(character) == 1 if character not in self.foreTextures: # load background glyph # the render option will lead to an outline glyph (not rendered) self.face.load_char(character, ft.FT_LOAD_FLAGS['FT_LOAD_DEFAULT']) backGlyph = ft.FT_Glyph() ft.FT_Get_Glyph(self.face.glyph._FT_GlyphSlot, ft.byref(backGlyph)) backGlyph = ft.Glyph(backGlyph) # add border to the glyph error = ft.FT_Glyph_StrokeBorder(ft.byref(backGlyph._FT_Glyph), self.stroker._FT_Stroker, False, False) if error: raise ft.FT_Exception(error) # the render option will lead to a rendered glyph backBitmapGlyph = backGlyph.to_bitmap( ft.FT_RENDER_MODES['FT_RENDER_MODE_NORMAL'], 0) backBitmap = backBitmapGlyph.bitmap backHeight, backWidth = backBitmap.rows, backBitmap.width backBitmap = np.array(backBitmap.buffer, dtype=np.uint8).reshape( (backHeight, backWidth)) backTexture = _create_text_texture(backBitmap) backSlot = CharacterSlot(backTexture, backBitmapGlyph) self.backTextures[character] = backSlot # load foreground glyph self.face.load_char(character, ft.FT_LOAD_FLAGS['FT_LOAD_RENDER']) foreBitmap = self.face.glyph.bitmap foreHeight, foreWidth = foreBitmap.rows, foreBitmap.width foreBitmap = np.array(foreBitmap.buffer, dtype=np.uint8).reshape( (foreHeight, foreWidth)) foreTexture = _create_text_texture(foreBitmap) foreSlot = CharacterSlot(foreTexture, self.face.glyph) self.foreTextures[character] = foreSlot
def processFont(self, filepath): # print # print 'filepath', filepath face = None try: if os.path.basename(filepath).lower().endswith('.otf'): print 'ignoring otf', os.path.basename(filepath) return face = freetype.Face(filepath) postscript_name = face.postscript_name if postscript_name in self.processedPostscriptNames: return # print '\t', 'postscript_name', postscript_name self.processedPostscriptNames.add(postscript_name) # print 'freetype.__dll__.FT_Get_Kerning', freetype.__dll__.FT_Get_Kerning, type(freetype.__dll__.FT_Get_Kerning) # freetype.FT_Get_Kerning = freetype.__dll__.FT_Get_Kerning # hasKerningTable = freetype.__dll__.FT_Get_Kerning(face._FT_Face) # print 'hasKerningTable', hasKerningTable, type(hasKerningTable) print 'postscript_name', postscript_name, os.path.basename( filepath), 'num_glyphs', face.num_glyphs glyphIndexToCharacterMap = {} # self.ftFont.select_charmap(ft_enums.FT_ENCODING_UNICODE) characterCode, glyphIndex = face.get_first_char() while glyphIndex > 0: glyphIndexToCharacterMap[glyphIndex] = characterCode characterCode, glyphIndex = face.get_next_char( characterCode, 0) units_per_EM = face.units_per_EM pairCount = 0 for glyphIndex0 in glyphIndexToCharacterMap: for glyphIndex1 in glyphIndexToCharacterMap: # for index0 in xrange(1, face.num_glyphs): # for index1 in xrange(1, face.num_glyphs): kerning = freetype.FT_Vector(0, 0) error = freetype.FT_Get_Kerning( face._FT_Face, glyphIndex0, glyphIndex1, # freetype.ft_enums.FT_KERNING_DEFAULT, freetype.ft_enums.FT_KERNING_UNSCALED, freetype.byref(kerning)) if error: raise freetype.FT_Exception(error) # return kerning # kerning = face.get_kerning(index0, index1, mode=freetype.ft_enums.FT_KERNING_UNSCALED) if kerning.x != 0: key = ( glyphIndexToCharacterMap[glyphIndex0], glyphIndexToCharacterMap[glyphIndex1], ) # print 'glyphIndex0, glyphIndex1', glyphIndex0, glyphIndex1, key self.kerningPairCountMap[ key] = self.kerningPairCountMap.get(key, 0) + 1 absEms = abs(kerning.x / float(units_per_EM)) self.kerningPairAbsEmsMap[ key] = self.kerningPairAbsEmsMap.get(key, 0) + absEms pairCount += 1 # print 'kerning', kerning, type(kerning), kerning.x, type(kerning.x) # print 'kerning', kerning, type(kerning), kerning.x, type(kerning.x), index0, index1 print '\t', 'pairCount', pairCount if pairCount > 0: self.nonEmptyPostscriptNames.add(postscript_name) # print '.' # print 'complete.' # import sys # sys.exit(0) # kerningPairCountMap # glyphs = [] # characterCode, glyphIndex = face.get_first_char(); ## while characterCode > 0 and glyphIndex > 0: # while glyphIndex > 0: # if characterCode > 0: # glyphs.append(characterCode) # characterCode, glyphIndex = face.get_next_char(characterCode, 0); # # for glyph in glyphs: # self.glyphCountMap[glyph] = 1 + self.glyphCountMap.get(glyph, 0) # # if len(glyphs) > 0: # self.nonEmptyPostscriptNames.add(postscript_name) # pass ## print 'glyphs', len(glyphs), glyphs[0], glyphs[-1] ## print 'characterCode', type(characterCode), characterCode # else: # print 'filepath', filepath # print 'no glyphs' # print 'characterCode, glyphIndex', characterCode, glyphIndex except Exception, e: print e.message