def draw(font, text, size): print font, text, size face = ft.Face(font) face.set_char_size(size * 64, 0, FREETYPE_DPI, 0) slot = face.glyph #matrix = ft.Matrix() #matrix.xx = (int)( math.cos(0) * 0x10000L) #matrix.xy = (int)(-math.sin(0) * 0x10000L) #matrix.yx = (int)( math.sin(0) * 0x10000L) #matrix.yy = (int)( math.cos(0) * 0x10000L) pen = ft.Vector(0, 0) minx = 0 miny = 0 maxx = 0 maxy = 0 for i, c in enumerate(text): face.set_transform(ft.Matrix(), pen) face.load_char(c, ft.FT_LOAD_RENDER) bitmap = slot.bitmap _l = slot.bitmap_left _t = 0 - slot.bitmap_top minx = min(minx, _l) miny = min(miny, _t) maxx = max(maxx, _l + bitmap.width) maxy = max(maxy, _t + bitmap.rows) pen.x += slot.advance.x pen.y += slot.advance.y width = maxx - minx height = maxy - miny pen.x = (0 - minx) * 64 pen.y = (maxy) * 64 image = Image.new('RGBA', (width, height), (255, 255, 255, 0)) for i, c in enumerate(text): face.set_transform(ft.Matrix(), pen) face.load_char(c, ft.FT_LOAD_RENDER) draw_bitmap(image, slot.bitmap, slot.bitmap_left, height - slot.bitmap_top) pen.x += slot.advance.x pen.y += slot.advance.y return image
def _set_face_transfrom(self): face = self._font._face horizontal_scale = 100 resolution = self._resolution # dpi face.set_char_size(int(to_64th_point(self._size)), 0, horizontal_scale * resolution, resolution) # Matrix cooeficients are expressed in 16.16 fixed-point units. # 2**16 = 0x10000L = 65536 matrix = freetype.Matrix(2**16 / horizontal_scale, 0, 0, 2**16) # The vector coordinates are expressed in 1/64th of a pixel # (also known as 26.6 fixed-point numbers). delta = freetype.Vector(0, 0) face.set_transform(matrix, delta) freetype.set_lcd_filter(freetype.FT_LCD_FILTER_LIGHT)
def draw_string(self, img, x_pos, y_pos, text, color, gap=1): ''' draw string :param x_pos: text x-postion on img :param y_pos: text y-postion on img :param text: text (unicode) :param color: text color :return: image ''' if self.ttf == "data/font/times.ttf": gap = gap * 1.2 elif self.ttf == "data/font/msyhbd.ttf": gap = gap * 1 else: gap = gap prev_char = 0 pen = freetype.Vector() pen.x = x_pos << 6 # div 64 pen.y = y_pos << 6 hscale = 1.0 matrix = freetype.Matrix( int(hscale) * 0x10000, int(0.2 * 0x10000), int(0.0 * 0x10000), int(1.1 * 0x10000)) cur_pen = freetype.Vector() pen_translate = freetype.Vector() image = copy.deepcopy(img) for cur_char in text: self._face.set_transform(matrix, pen_translate) self._face.load_char(cur_char) kerning = self._face.get_kerning(prev_char, cur_char) pen.x += kerning.x slot = self._face.glyph bitmap = slot.bitmap cur_pen.x = pen.x cur_pen.y = pen.y - slot.bitmap_top * 64 self.draw_ft_bitmap(image, bitmap, cur_pen, color) pen.x += int(gap * slot.advance.x) prev_char = cur_char return image
def draw_string(self, img, x_pos, y_pos, text, color): ''' draw string :param xpos: text x-position on img :param ypos: text y-position on img :param text: text (unicode) :param color: text color :return: image ''' prev_char = 0 pen = freetype.Vector() pen.x = x_pos << 6 # div 64 pen.y = y_pos << 6 hscale = 1.0 matrix = freetype.Matrix(int((hscale) * 0x10000), int((0.2) * 0x10000), int((0.0) * 0x10000), int((1.1) * 0x10000)) cur_pen = freetype.Vector() pen_translate = freetype.Vector() image = copy.deepcopy(img) for cur_char in text: self._face.set_transform(matrix, pen_translate) self._face.load_char(cur_char) kerning = self._face.get_kerning(prev_char, cur_char) pen.x += kerning.x slot = self._face.glyph bitmap = slot.bitmap cur_pen.x = pen.x cur_pen.y = pen.y - slot.bitmap_top * 64 self.draw_ft_bitmap(image, bitmap, cur_pen, color) pen.x += slot.advance.x prev_char = cur_char return image
def draw_string(self, img, x_pos, y_pos, text, color): """ draw string :param img: ndarray :param x_pos: x coordinate :param y_pos: y coordinate :param text: text(str) :param color: text color :return: image """ prev_char = 0 pen = freetype.Vector() pen.x = x_pos << 6 pen.y = y_pos << 6 hscale = 1.0 matrix = freetype.Matrix( int(hscale) * 0x10000, int(0.2 * 0x10000), int(0.0 * 0x10000), int(1.1 * 0x10000)) cur_pen = freetype.Vector() pen_translate = freetype.Vector() image = copy.deepcopy(img) for cur_char in text: self._face.set_transform(matrix, pen_translate) self._face.load_char(cur_char) # kerning = self._face.get_kerning(prev_char, cur_char) pen.x = pen.x + 170 slot = self._face.glyph bitmap = slot.bitmap cur_pen.x = pen.x cur_pen.y = pen.y - slot.bitmap_top * 64 self.draw_ft_bitmap(image, bitmap, cur_pen, color) # cv2.imshow('image', image) # cv2.waitKey(0) pen.x += slot.advance.x prev_char = cur_char return image
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 # ??? why doesn't the linter find these? 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: print("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.shape[0]) v0 = (y + 0.0) / float(self.atlas.shape[1]) u1 = (x + w - 0.0) / float(self.atlas.shape[0]) v1 = (y + h - 0.0) / float(self.atlas.shape[1]) 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)