Beispiel #1
0
def glyph_metrics(string: str) -> Iterable[Metrics]:
    font, upem, buffer = setup_harfbuzz()
    HarfBuzz.buffer_clear_contents(buffer)

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

    # If this doesn't get run, the Python interpreter crashes
    HarfBuzz.buffer_guess_segment_properties(buffer)

    HarfBuzz.shape(font, buffer, [])
    codepoints = [
        info.codepoint for info in HarfBuzz.buffer_get_glyph_infos(buffer)
    ]
    positions = HarfBuzz.buffer_get_glyph_positions(buffer)

    for extents, pos in zip(glyphs_extents(font, codepoints), positions):
        yield Metrics(
            Positions(pos.x_advance, pos.y_advance, pos.x_offset,
                      pos.y_offset),
            extents,
            upem,
        )
Beispiel #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
Beispiel #3
0
def runHB(text, buf, font, ttfont):
    HarfBuzz.buffer_clear_contents(buf)
    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(b"ar"))

    HarfBuzz.shape(font, buf, [])

    info = HarfBuzz.buffer_get_glyph_infos(buf)
    out = "|".join([ttfont.getGlyphName(i.codepoint) for i in info])

    return "[%s]" % out
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)]
Beispiel #5
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]
Beispiel #6
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)]
Beispiel #7
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
Beispiel #8
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}")
Beispiel #9
0
def runHB(text, buf, font, ttfont):
    HarfBuzz.buffer_clear_contents(buf)
    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(b"ar"))

    HarfBuzz.shape(font, buf, [])

    info = HarfBuzz.buffer_get_glyph_infos(buf)
    positions = HarfBuzz.buffer_get_glyph_positions(buf)
    out = []
    for i, p in zip(info, positions):
        text = ""
        text += ttfont.getGlyphName(i.codepoint)
        text += " w=%d" % p.x_advance
        if p.x_offset:
            text += " x=%d" % p.x_offset
        if p.y_offset:
            text += " y=%d" % p.y_offset
        out.append(text)

    return "[%s]" % "|".join(out)
Beispiel #10
0
# See https://github.com/harfbuzz/harfbuzz/pull/271
#
if False:
    # If you do not care about cluster values reflecting Python
    # string indices, then this is quickest way to add text to
    # buffer:
    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-32')), 0, -1)
else:
    hb.buffer_add_utf16(buf, array.array('H', text.encode('utf-16')), 0, -1)

hb.buffer_guess_segment_properties(buf)

hb.shape(font, buf, [])
del font

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

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

    print("gid%d=%d@%d,%d+%d" % (gid, cluster, x_advance, x_offset, y_offset))
Beispiel #11
0
#
if False:
	# If you do not care about cluster values reflecting Python
	# string indices, then this is quickest way to add text to
	# buffer:
	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-32')), 0, -1)
else:
	hb.buffer_add_utf16 (buf, array.array('H', text.encode('utf-16')), 0, -1)


hb.buffer_guess_segment_properties (buf)

hb.shape (font, buf, [])
del font

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

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

	print("gid%d=%d@%d,%d+%d" % (gid, cluster, x_advance, x_offset, y_offset))