def put_char_vertical(font_size: int, rot: int, cdpt: str, pen_l: Tuple[int, int], canvas_text: np.ndarray, canvas_border: np.ndarray, border_size: int) :
	pen = pen_l.copy()
	
	is_pun = _is_punctuation(cdpt)
	cdpt, rot_degree = CJK_Compatibility_Forms_translate(cdpt, 1)
	slot = get_char_glyph(cdpt, font_size, 1)
	bitmap = slot.bitmap
	if bitmap.rows * bitmap.width == 0 or len(bitmap.buffer) != bitmap.rows * bitmap.width :
		char_offset_y = slot.metrics.vertBearingY >> 6
		return char_offset_y
	char_offset_y = slot.metrics.vertAdvance >> 6
	bitmap_char = np.array(bitmap.buffer, dtype = np.uint8).reshape((bitmap.rows,bitmap.width))
	pen[0] += slot.metrics.vertBearingX >> 6
	pen[1] += slot.metrics.vertBearingY >> 6
	canvas_text[pen[1]:pen[1]+bitmap.rows, pen[0]:pen[0]+bitmap.width] = bitmap_char
	#print(pen_l, pen, slot.metrics.vertBearingX >> 6, bitmap.width)
	#border
	if border_size > 0 :
		pen_border = (pen[0] - border_size, pen[1] - border_size)
		#slot_border = 
		glyph_border = get_char_border(cdpt, font_size, 1)
		stroker = freetype.Stroker()
		stroker.set(64 * max(int(0.07 * font_size), 1), freetype.FT_STROKER_LINEJOIN_ROUND, freetype.FT_STROKER_LINEJOIN_ROUND, 0)
		glyph_border.stroke(stroker, destroy=True)
		blyph = glyph_border.to_bitmap(freetype.FT_RENDER_MODE_NORMAL, freetype.Vector(0,0), True)
		bitmap_b = blyph.bitmap
		bitmap_border = np.array(bitmap_b.buffer, dtype = np.uint8).reshape(bitmap_b.rows,bitmap_b.width)
		canvas_border[pen_border[1]:pen_border[1]+bitmap_b.rows, pen_border[0]:pen_border[0]+bitmap_b.width] = cv2.add(canvas_border[pen_border[1]:pen_border[1]+bitmap_b.rows, pen_border[0]:pen_border[0]+bitmap_b.width], bitmap_border)
	return char_offset_y
    def _draw_string(cls, img, x_pos, y_pos, cur_pen, cur_char, color):
        '''
        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
        '''

        prev_char = 0
        pen = freetype.Vector()
        pen.x = x_pos << 6  # div 64
        pen.y = y_pos << 6

        image = copy.deepcopy(img)

        kerning = cls._face.get_kerning(prev_char, cur_char)
        pen.x += kerning.x
        slot = cls._face.glyph
        bitmap = slot.bitmap

        cur_pen.x = pen.x
        cur_pen.y = pen.y - slot.bitmap_top * 64
        image = cls._draw_ft_bitmap(image, bitmap, cur_pen, color)

        pen.x += slot.advance.x

        return image
Esempio n. 3
0
 def _write_glyph(self, glyph):
     blyph = glyph.to_bitmap(freetype.FT_RENDER_MODE_NORMAL,
                             freetype.Vector(0, 0))
     self.char.set_bitmap_geom(
         (blyph.left, -blyph.top, blyph.bitmap.width, blyph.bitmap.rows))
     bitmap = blyph.bitmap
     return FT2Bitmap(bitmap).to_pil_image()
Esempio n. 4
0
    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, matrix_random=True):
        '''
        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
        '''
        prev_char = 0
        pen = freetype.Vector()
        pen.x = x_pos << 6  # div 64
        pen.y = y_pos << 6

        hscale = 1.0
        if matrix_random:
            h2s = random.uniform(0, 0.4)
            h4s = random.uniform(1.0, 1.15)
            matrix = freetype.Matrix(int(hscale)*0x10000, int(h2s*0x10000),\
                                     int(0.0*0x10000), int(h4s*0x10000))
        else:
            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
Esempio n. 6
0
    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
Esempio n. 7
0
 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 string_2_bitmap(self, img, x_pos, y_pos, text, color):
        '''
        将字符串绘制为图片
        :param x_pos: text绘制的x起始坐标
        :param y_pos: text绘制的y起始坐标
        :param text:  text的unicode编码
        :param color: text的RGB颜色编码
        :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) * 0x10000L, int(0.2 * 0x10000L), int(0.0 * 0x10000L),
            int(1.1 * 0x10000L))
        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
Esempio n. 9
0
    def __fontString(self, img, x_pos, y_pos, text, color, sep=None):
        prev_char = 0
        pen = freetype.Vector()
        pen.x = x_pos << 6
        pen.y = y_pos << 6

        cur_pen = freetype.Vector()
        pen_translate = freetype.Vector()

        for cur_char in text:

            # 获取文本图像
            if self.__vector == True:
                self.__face.load_char(cur_char, 6)
            else:
                self.__face.load_char(
                    cur_char, freetype.FT_LOAD_MONOCHROME
                    | freetype.FT_LOAD_TARGET_MONO | freetype.FT_LOAD_RENDER)

            kerning = self.__face.get_kerning(prev_char, cur_char)
            slot = self.__face.glyph

            cur_pen.x = pen.x + kerning.x + self.__spc * 64  # 调整字符间距
            cur_pen.y = pen.y - slot.bitmap_top * 64

            self.__fontImage(img, slot.bitmap, cur_pen, color, sep)

            pen.x = cur_pen.x + slot.advance.x
            prev_char = cur_char

        width, height = self.__font_crop(img)

        # 图像裁剪和反转
        reimage = np.zeros([height, width], np.uint8)
        for h in range(height):
            for w in range(width):
                reimage[h, w] = img[height - h, w]

        return reimage
Esempio n. 10
0
    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
Esempio n. 11
0
    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)
Esempio n. 12
0
    def draw_text(self, image, pos, text, text_size, text_color):
        """
            draw chinese(or not) text with ttf
            :param image:     image(numpy.ndarray) to draw text
            :param pos:       where to draw text
            :param text:      the context, for chinese should be unicode type
            :param text_size: text size
            :param text_color:text color
            :return:          image
        """
        self._face.set_char_size(text_size * 64)
        metrics = self._face.size
        ascender = metrics.ascender / 64.0
        ypos = int(ascender)
        # descender = metrics.descender/64.0
        # height = metrics.height/64.0
        # linegap = height - ascender + descender

        x_pos = pos[0] + 2  # pos[0]和pos[1]均为0,
        y_pos = pos[1] + 8  #  + ypos       # 加上上行高度,

        pen = ft.Vector()
        pen.x = x_pos << 6  # 像素长度x_pos乘以64转化为26.6格式的值
        pen.y = y_pos << 6

        # hscale = 1.0
        # matrix = ft.Matrix(int(hscale) * 0x10000, int(0.2 * 0x10000), int(0.0 * 0x10000), int(1.1 * 0x10000))
        # prev_char = 0
        # cur_pen = ft.Vector()
        # pen_translate = ft.Vector()

        image = np.copy(image)
        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
            # cur_pen.x = pen.x
            # cur_pen.y = pen.y\
            # - self._face.glyph.bitmap_top * 64
            # self.draw_ft_bitmap(image, self._face.glyph.bitmap, cur_pen, text_color)
            self.draw_ft_bitmap(image, self._face.glyph.bitmap, pen,
                                text_color)
            pen.x += self._face.glyph.advance.x
            # prev_char = cur_char

        return image
Esempio n. 13
0
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
Esempio n. 14
0
def main(stroke=0):
    """executable entry."""
    face = ft.Face('./WenQuanYiMicroHei.ttf')
    face.set_char_size(48 * 64)
    if stroke == 0:
        flags = ft.FT_LOAD_DEFAULT
    else:
        flags = ft.FT_LOAD_DEFAULT | ft.FT_LOAD_NO_BITMAP
    face.load_char('心', flags)
    slot = face.glyph
    glyph = slot.get_glyph()

    if stroke > 0:
        stroker = ft.Stroker()
        stroker.set(64, ft.FT_STROKER_LINECAP_ROUND,
                    ft.FT_STROKER_LINEJOIN_ROUND, 0)
        glyph.stroke(stroker, True)

    blyph = glyph.to_bitmap(ft.FT_RENDER_MODE_NORMAL, ft.Vector(0, 0), True)
    bitmap = blyph.bitmap
    width, rows, pitch = bitmap.width, bitmap.rows, bitmap.pitch

    print({
        'width': slot.metrics.width >> 6,
        'height': slot.metrics.height >> 6,
        'horiBearingX': slot.metrics.horiBearingX >> 6,
        'horiBearingY': slot.metrics.horiBearingY >> 6,
        'horiAdvance': slot.metrics.horiAdvance >> 6,
        'bitmapWidth': bitmap.width,
        'bitmapHeight': bitmap.rows
    })
    img = Image.new("L", (width, rows), "black")
    pixels = img.load()

    for y in range(img.size[1]):
        offset = y * pitch
        for x in range(img.size[0]):
            pixels[x, y] = 255 - bitmap.buffer[offset + x]

    img.show()
Esempio n. 15
0
 def get_full_binary(self):
     try:
         with open(self.cache_file, 'rb') as f:
             return f.read()
     except OSError:
         tex_array = []
         for enum, my_char in enumerate(self.face.get_chars()):
             if self.outline:
                 self.face.load_glyph(
                     my_char[1], freetype.FT_LOAD_FLAGS['FT_LOAD_DEFAULT']
                     | freetype.FT_LOAD_FLAGS['FT_LOAD_NO_BITMAP'])
                 glyph = self.face.glyph.get_glyph()
                 stroker = freetype.Stroker()
                 stroker.set(
                     int(self.outline_thickness), freetype.
                     FT_STROKER_LINECAPS['FT_STROKER_LINECAP_ROUND'],
                     freetype.
                     FT_STROKER_LINEJOINS['FT_STROKER_LINEJOIN_ROUND'], 0)
                 glyph.stroke(stroker, True)
                 bitmap = glyph.to_bitmap(
                     freetype.FT_RENDER_MODES['FT_RENDER_MODE_NORMAL'],
                     freetype.Vector(0, 0), True).bitmap
             else:
                 self.face.load_glyph(my_char[1])
                 bitmap = self.face.glyph.bitmap
             if enum % MAGIC_NUMBER == 0:
                 for i in range(self.line_height):
                     tex_array.append([])
                     for j in range(self.line_height * MAGIC_NUMBER):
                         tex_array[-1].append(bytes([0, 0, 0, 0]))
             start_i = (enum // MAGIC_NUMBER) * self.line_height
             start_j = (enum % MAGIC_NUMBER) * self.line_height
             for i in range(bitmap.width):
                 for j in range(bitmap.rows):
                     tex_array[start_i + j][start_j + i] = bytes(
                         4 * [bitmap.buffer[j * bitmap.width + i]])
         full_binary = b''.join(i for row in tex_array for i in row)
         with open(self.cache_file, 'wb') as f:
             f.write(full_binary)
         return full_binary
Esempio n. 16
0
    def draw_text(self, image, pos, text, text_size, color):
        self.face.set_char_size(text_size * 64)

        pen = ft.Vector()
        pen.x = pos[0]
        pen.y = pos[1] + 10  #

        img = np.copy(image)  # image只是个空的模板,每次返回的是image的含有内容的副本
        for cur_char in text:
            self.face.load_char(cur_char)
            bitmap = self.face.glyph.bitmap

            for row in range(
                    bitmap.rows):  # 画布矩阵img和bitmap.buffer中的图像都是位于第四象限的图像
                for col in range(bitmap.width):  # 即上边界为x轴,左边界为y轴
                    if bitmap.buffer[row * bitmap.width + col] != 0:
                        img[pen.y + row][pen.x + col][0] = color[0]
                        img[pen.y + row][pen.x + col][1] = color[1]
                        img[pen.y + row][pen.x + col][2] = color[2]

            pen.x += self.face.glyph.advance.x >> 6  # 转化为像素值,每复制完一个字符的像素便向前推进一段距离
            # pen.x += 4 # 手动调节字符间距
            print(pen.x)
        return img
Esempio n. 17
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
            # ??? 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)
def create_text(text, font_info, fill=True, stroke=False, stroke_radius=0):

    face = font_info['font_face']
    height = font_info['height']
    baseline = font_info['baseline']
    height += stroke_radius * 2

    slot = face.glyph

    # First pass to compute bbox
    width = 0
    width2 = 0
    previous = 0
    for c in text:
        face.load_char(c)
        bitmap = slot.bitmap
        kerning = face.get_kerning(previous, c)
        width2 = width + bitmap.width + (kerning.x >> 6)
        width += (slot.advance.x >> 6) + (kerning.x >> 6)
        previous = c

    width = max(width, width2)
    width += 1

    width += stroke_radius * 2
    Z = np.zeros((height, width), dtype=np.int)

    # Second pass for actual rendering
    if fill:
        x, y = stroke_radius, 0
        previous = 0
        for c in text:
            face.load_char(c)
            bitmap = slot.bitmap
            top = slot.bitmap_top
            #left = slot.bitmap_left
            w, h = bitmap.width, bitmap.rows
            y = height - baseline - top - stroke_radius
            kerning = face.get_kerning(previous, c)
            x += (kerning.x >> 6)
            #print((c,x,y,w,h))
            Z[y:y + h, x:x + w] += np.array(bitmap.buffer,
                                            dtype='ubyte').reshape(h, w)
            x += (slot.advance.x >> 6)
            previous = c

    if stroke:

        x, y = 0, 0
        previous = 0
        for c in text:
            face.load_char(
                c, freetype.FT_LOAD_DEFAULT | freetype.FT_LOAD_NO_BITMAP)
            slot = face.glyph
            glyph = slot.get_glyph()
            stroker = freetype.Stroker()
            stroker.set(64 * stroke_radius, freetype.FT_STROKER_LINECAP_ROUND,
                        freetype.FT_STROKER_LINEJOIN_ROUND, 0)
            glyph.stroke(stroker, True)
            blyph = glyph.to_bitmap(freetype.FT_RENDER_MODE_NORMAL,
                                    freetype.Vector(0, 0), True)
            bitmap = blyph.bitmap

            #top = slot.bitmap_top
            #left = slot.bitmap_left
            #print(blyph.top)
            top = blyph.top
            w, h = bitmap.width, bitmap.rows
            y = height - baseline - top - stroke_radius
            kerning = face.get_kerning(previous, c)
            x += (kerning.x >> 6)
            #print((c,x,y,w,h))
            Z[y:y + h, x:x + w] += np.array(bitmap.buffer,
                                            dtype='ubyte').reshape(h, w)
            x += (slot.advance.x >> 6)
            previous = c

    Z = np.minimum(Z, 255)

    return Z