Пример #1
0
def setup_harfbuzz() -> Tuple[HarfBuzz.font_t, HarfBuzz.buffer_t]:
    """
    Finds a font for HarfBuzz to use, and creates a buffer
    
    Because this is wrapped with functools.lru_cache, the buffer returned
    may have text still in it, which means
    gi.repository.HarfBuzz.buffer_clear_contents()
    will need to be called on the buffer to return it to its empty state
    """
    font_file = get_font_file()
    font_blob = HarfBuzz.glib_blob_create(
        GLib.Bytes.new(font_file.read_bytes()))
    face = HarfBuzz.face_create(font_blob, 0)
    del font_blob
    font = HarfBuzz.font_create(face)
    upem = HarfBuzz.face_get_upem(face)
    del face
    HarfBuzz.font_set_scale(font, 100, 100)
    HarfBuzz.ot_font_set_funcs(font)
    buffer = HarfBuzz.buffer_create()
    # HarfBuzz.buffer_set_message_func(
    #    buffer,
    #    lambda *args: True,
    #    1,
    #    0,
    # )

    return (font, upem, buffer)
Пример #2
0
def runHB(direction, script, language, features, text, fontname, positions):
    font = getHbFont(fontname)
    buf = HarfBuzz.buffer_create()
    text = toUnicode(text)
    HarfBuzz.buffer_add_utf8(buf, text.encode('utf-8'), 0, -1)
    HarfBuzz.buffer_set_direction(buf, HarfBuzz.direction_from_string(toBytes(direction)))
    HarfBuzz.buffer_set_script(buf, HarfBuzz.script_from_string(toBytes(script)))
    if language:
        HarfBuzz.buffer_set_language(buf, HarfBuzz.language_from_string(toBytes(language)))

    if features:
        features = [HarfBuzz.feature_from_string(toBytes(fea))[1] for fea in features.split(',')]
    else:
        features = []
    HarfBuzz.shape(font, buf, features)

    info = HarfBuzz.buffer_get_glyph_infos(buf)
    ttfont = getTtFont(fontname)
    if positions:
        pos = HarfBuzz.buffer_get_glyph_positions(buf)
        glyphs = []
        for i, p in zip(info, pos):
            glyph = ttfont.getGlyphName(i.codepoint)
            if p.x_offset or p.y_offset:
                glyph += "@%d,%d" % (p.x_offset, p.y_offset)
            glyph += "+%d" % p.x_advance
            if p.y_advance:
                glyph += ",%d" % p.y_advance
            glyphs.append(glyph)
        out = "|".join(glyphs)
    else:
        out = "|".join([ttfont.getGlyphName(i.codepoint) for i in info])

    return "[%s]" % out
Пример #3
0
def runTest(tests, refs, fontname):
    failed = {}
    passed = []
    font = getHbFont(fontname)
    buf = HarfBuzz.buffer_create()
    ttfont = TTFont(fontname)
    for i, (text, ref) in enumerate(zip(tests, refs)):
        result = runHB(text, buf, font, ttfont)
        if ref == result:
            passed.append(i + 1)
        else:
            failed[i + 1] = (text, ref, result)

    return passed, failed
Пример #4
0
def runTest(tests, refs, fontname):
    failed = {}
    passed = []
    font = getHbFont(fontname)
    buf = HarfBuzz.buffer_create()
    ttfont = TTFont(fontname)
    for i, (text, ref) in enumerate(zip(tests, refs)):
        result = runHB(text, buf, font, ttfont)
        if ref == result:
            passed.append(i + 1)
        else:
            failed[i + 1] = (text, ref, result)

    return passed, failed
Пример #5
0
def shape(text, font):
    text = toUnicode(text)
    buf = HarfBuzz.buffer_create()

    HarfBuzz.buffer_add_utf8(buf, text.encode('utf-8'), 0, -1)
    HarfBuzz.buffer_set_direction(buf, HarfBuzz.direction_t.RTL)
    HarfBuzz.buffer_set_script(buf, HarfBuzz.script_t.ARABIC)
    HarfBuzz.buffer_set_language(buf, HarfBuzz.language_from_string("ar"))

    HarfBuzz.shape(font, buf, [HarfBuzz.feature_from_string("+ss01")[1]])

    glyphs = HarfBuzz.buffer_get_glyph_infos(buf)
    positions = HarfBuzz.buffer_get_glyph_positions(buf)

    return [(g.codepoint, p.x_advance, p.x_offset, p.y_offset) for g, p in zip(glyphs, positions)]
Пример #6
0
    def shape(self, text_="abvd", flag=False):
        text = text_
        # Need to create GLib.Bytes explicitly until this bug is fixed:
        # https://bugzilla.gnome.org/show_bug.cgi?id=729541

        buf = hb.buffer_create()

        # class Debugger(object):
        #     def message(self, buf, font, msg, data, _x_what_is_this):
        #         print(msg)
        #         return True
        # debugger = Debugger()
        # hb.buffer_set_message_func (buf, debugger.message, 1, 0)

        ##
        ## Add text to buffer
        ##
        #
        # See https://github.com/harfbuzz/harfbuzz/pull/271
        #
        if flag:
            # If you do not care about cluster values reflecting Python
            # string indices, then this is quickest way to add text to
            # buffer:
            #         void hb_buffer_add_utf8 (hb_buffer_t *buffer,
            #                     const char *text,
            #                     int text_length,
            #                     unsigned int item_offset,
            #                     int item_length);
            hb.buffer_add_utf8(buf, text.encode('utf-8'), 0, -1)
            # Otherwise, then following handles both narrow and wide
            # Python builds:
        elif sys.maxunicode == 0x10FFFF:
            hb.buffer_add_utf32(buf, array.array('I', text.encode('utf-32le')),
                                0, -1)
        else:
            hb.buffer_add_utf16(buf, array.array('H', text.encode('utf-16le')),
                                0, -1)

        hb.buffer_guess_segment_properties(buf)

        hb.shape(self.__font, buf, [])
        # del font

        infos = hb.buffer_get_glyph_infos(buf)
        # positions = hb.buffer_get_glyph_positions(buf)

        return [info.codepoint for info in infos]
Пример #7
0
def shape(text, font):
    text = toUnicode(text)
    buf = HarfBuzz.buffer_create()

    HarfBuzz.buffer_add_utf8(buf, text.encode('utf-8'), 0, -1)
    HarfBuzz.buffer_set_direction(buf, HarfBuzz.direction_t.RTL)
    HarfBuzz.buffer_set_script(buf, HarfBuzz.script_t.ARABIC)
    HarfBuzz.buffer_set_language(buf, HarfBuzz.language_from_string("ar"))

    HarfBuzz.shape(font, buf, [HarfBuzz.feature_from_string("+ss01")[1]])

    glyphs = HarfBuzz.buffer_get_glyph_infos(buf)
    positions = HarfBuzz.buffer_get_glyph_positions(buf)

    return [(g.codepoint, p.x_advance, p.x_offset, p.y_offset)
            for g, p in zip(glyphs, positions)]
Пример #8
0
def get_text_shape(text, font=None, weight=None, path=None, debug=False):
    if weight is not None:
        font = f'{font}:{weight}'
    if path is None:
        path = get_font_path(font)

    base, ext = os.path.splitext(path)
    ext = ext[1:]

    with open(path, 'rb') as fid:
        fontdata = fid.read()

    bdata = GLib.Bytes.new(fontdata)
    blob = hb.glib_blob_create(bdata)
    face = hb.face_create(blob, 0)

    font = hb.font_create(face)
    upem = hb.face_get_upem(face)
    hb.font_set_scale(font, upem, upem)
    # hb.font_set_ptem(font, font_size)

    if ext == 'woff':
        hb.ft_font_set_funcs(font)

    buf = hb.buffer_create()
    hb.buffer_add_utf8(buf, text.encode('utf-8'), 0, -1)

    hb.buffer_guess_segment_properties(buf)
    hb.shape(font, buf, [])
    infos = hb.buffer_get_glyph_infos(buf)
    positions = hb.buffer_get_glyph_positions(buf)
    extents = [hb.font_get_glyph_extents(font, i.codepoint) for i in infos]

    if debug:
        return font, infos, positions, extents

    norm = upem
    wh_extract = lambda ext: (ext.extents.width / norm, -ext.extents.height /
                              norm)

    cluster = [(i.codepoint, i.cluster) for i in infos]
    shapes = [wh_extract(e) for e in extents]
    deltas = [(p.x_advance / norm, p.y_advance / norm) for p in positions]
    offsets = [(p.x_offset / norm, p.y_offset / norm) for p in positions]

    return cluster, shapes, deltas, offsets
Пример #9
0
def main():
    font_file = barcode_wheel.get_font_file()
    font_blob = HarfBuzz.glib_blob_create(GLib.Bytes.new(font_file.read_bytes()))
    face = HarfBuzz.face_create(font_blob, 0)
    del font_blob
    font = HarfBuzz.font_create(face)
    upem = HarfBuzz.face_get_upem(face)
    del face
    HarfBuzz.font_set_scale(font, upem, upem)

    text = sys.argv[1]
    HarfBuzz.ot_font_set_funcs(font)

    buf = HarfBuzz.buffer_create()
    HarfBuzz.buffer_set_message_func(
        buf,
        # lambda *args: [print(x) for x in args] and True,
        lambda *args: True,
        1,
        0,
    )

    if False:
        HarfBuzz.buffer_add_utf8(buf, text.encode("utf-8"), 0, -1)
    elif sys.maxunicode == 0x10FFFF:
        HarfBuzz.buffer_add_utf32(
            buf, array.array("I", text.encode("utf-32"))[1:], 0, -1
        )
    else:
        HarfBuzz.buffer_add_utf16(
            buf, array.array("H", text.encode("utf-16"))[1:], 0, -1
        )

    HarfBuzz.buffer_guess_segment_properties(buf)
    HarfBuzz.shape(font, buf, [])
    del font

    infos = HarfBuzz.buffer_get_glyph_infos(buf)
    positions = HarfBuzz.buffer_get_glyph_positions(buf)

    for info, pos in zip(infos, positions):
        gid = info.codepoint
        cluster = info.cluster

        print(f"gid {gid} = {cluster} @ {pos.x_advance}, {pos.x_offset}+{pos.y_offset}")
Пример #10
0
fontdata = open(sys.argv[1], 'rb').read()
text = tounicode(sys.argv[2])
# Need to create GLib.Bytes explicitly until this bug is fixed:
# https://bugzilla.gnome.org/show_bug.cgi?id=729541
blob = hb.glib_blob_create(GLib.Bytes.new(fontdata))
face = hb.face_create(blob, 0)
del blob
font = hb.font_create(face)
upem = hb.face_get_upem(face)
del face
hb.font_set_scale(font, upem, upem)
#hb.ft_font_set_funcs (font)
hb.ot_font_set_funcs(font)

buf = hb.buffer_create()


class Debugger(object):
    def message(self, buf, font, msg, data, _x_what_is_this):
        print(msg)
        return True


debugger = Debugger()
hb.buffer_set_message_func(buf, debugger.message, 1, 0)

##
## Add text to buffer
##
#
Пример #11
0
fontdata = open (sys.argv[1], 'rb').read ()
text = tounicode(sys.argv[2])
# Need to create GLib.Bytes explicitly until this bug is fixed:
# https://bugzilla.gnome.org/show_bug.cgi?id=729541
blob = hb.glib_blob_create (GLib.Bytes.new (fontdata))
face = hb.face_create (blob, 0)
del blob
font = hb.font_create (face)
upem = hb.face_get_upem (face)
del face
hb.font_set_scale (font, upem, upem)
#hb.ft_font_set_funcs (font)
hb.ot_font_set_funcs (font)

buf = hb.buffer_create ()
class Debugger(object):
	def message (self, buf, font, msg, data, _x_what_is_this):
		print(msg)
		return True
debugger = Debugger()
hb.buffer_set_message_func (buf, debugger.message, 1, 0)

##
## Add text to buffer
##
#
# See https://github.com/harfbuzz/harfbuzz/pull/271
#
if False:
	# If you do not care about cluster values reflecting Python