Beispiel #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)
Beispiel #2
0
def buildCompatChars(sfd, ttf):
    zwj = u'\u200D'
    ranges = (
        (0xfb50, 0xfbb1),
        (0xfbd3, 0xfd3d),
        (0xfd50, 0xfdf9),
        (0xfdfc, 0xfdfc),
        (0xfe70, 0xfefc),
    )

    with open(ttf, "rb") as f:
        data = f.read()
        blob = HarfBuzz.glib_blob_create(GLib.Bytes.new(data))
        face = HarfBuzz.face_create(blob, 0)
        hbfont = HarfBuzz.font_create(face)
        upem = HarfBuzz.face_get_upem(face)
        HarfBuzz.font_set_scale(hbfont, upem, upem)
        HarfBuzz.ot_font_set_funcs(hbfont)

    ttfont = TTFont(ttf)

    for r in ranges:
        for c in range(r[0], r[1] + 1):
            dec = ucd.decomposition(unichr(c)).split()
            if dec:
                keyword = dec[0]
                text = u''

                for i in dec[1:]:
                    text += unichr(int(str(i), 16))

                if keyword == '<initial>':
                    text = text + zwj
                elif keyword == '<final>':
                    text = zwj + text
                elif keyword == '<medial>':
                    text = zwj + text + zwj

                components = shape(text, hbfont)
                if components:
                    glyph = sfd.createChar(c)
                    glyph.clear()
                    glyph.color = 0xff0000  # red color
                    x = 0
                    for component in components:
                        gid = component[0]
                        name = ttfont.getGlyphName(gid)
                        x_advance = component[1]
                        x_offset = component[2]
                        y_offset = component[3]

                        matrix = psMat.translate(x + x_offset, y_offset)

                        # ignore blank glyphs, e.g. space or ZWJ
                        if sfd[name].foreground or sfd[name].references:
                            glyph.addReference(name, matrix)

                        x += x_advance

                    glyph.width = x
def buildCompatChars(sfd, ttf):
    zwj = u'\u200D'
    ranges = (
            (0xfb50, 0xfbb1),
            (0xfbd3, 0xfd3d),
            (0xfd50, 0xfdf9),
            (0xfdfc, 0xfdfc),
            (0xfe70, 0xfefc),
            )

    with open(ttf, "rb") as f:
        data = f.read()
        blob = HarfBuzz.glib_blob_create(GLib.Bytes.new(data))
        face = HarfBuzz.face_create(blob, 0)
        hbfont = HarfBuzz.font_create(face)
        upem = HarfBuzz.face_get_upem(face)
        HarfBuzz.font_set_scale(hbfont, upem, upem)
        HarfBuzz.ot_font_set_funcs(hbfont)

    ttfont = TTFont(ttf)

    for r in ranges:
        for c in range(r[0], r[1]+1):
            dec = ucd.decomposition(unichr(c)).split()
            if dec:
                keyword = dec[0]
                text = u''

                for i in dec[1:]:
                    text += unichr(int(str(i),16))

                if keyword == '<initial>':
                    text = text + zwj
                elif keyword == '<final>':
                    text = zwj + text
                elif keyword == '<medial>':
                    text = zwj + text + zwj

                components = shape(text, hbfont)
                if components:
                    glyph = sfd.createChar(c)
                    glyph.clear()
                    glyph.color = 0xff0000 # red color
                    x = 0
                    for component in components:
                        gid = component[0]
                        name = ttfont.getGlyphName(gid)
                        x_advance = component[1]
                        x_offset = component[2]
                        y_offset = component[3]

                        matrix = psMat.translate(x + x_offset, y_offset)

                        # ignore blank glyphs, e.g. space or ZWJ
                        if sfd[name].foreground or sfd[name].references:
                            glyph.addReference(name, matrix)

                        x += x_advance

                    glyph.width = x
Beispiel #4
0
def getHbFont(fontname):
    font = open(fontname, "rb")
    data = font.read()
    font.close()
    blob = HarfBuzz.glib_blob_create(GLib.Bytes.new(data))
    face = HarfBuzz.face_create(blob, 0)
    font = HarfBuzz.font_create(face)
    upem = HarfBuzz.face_get_upem(face)
    HarfBuzz.font_set_scale(font, upem, upem)
    HarfBuzz.ot_font_set_funcs(font)

    return font
Beispiel #5
0
def getHbFont(fontname):
    font = open(fontname, "rb")
    data = font.read()
    font.close()
    blob = HarfBuzz.glib_blob_create(GLib.Bytes.new(data))
    face = HarfBuzz.face_create(blob, 0)
    font = HarfBuzz.font_create(face)
    upem = HarfBuzz.face_get_upem(face)
    HarfBuzz.font_set_scale(font, upem, upem)
    HarfBuzz.ot_font_set_funcs(font)

    return font
Beispiel #6
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 #7
0
def get_ot_font(path, overwrite=False):
    if path not in _ot_type_registry or overwrite:
        # check if is sfd or binary
        fontname, ext = os.path.splitext(path)
        if ext == '.sfd':
            print('Warning: implicit OTF build triggered')
            os.system('fontforge -script IO/sfd2otf.pe ' + path)
            filepath = fontname + '.otf'
        else:
            filepath = path
        print('\033[92mLoading font\033[0m      :', filepath)
        HB_face = _hb_face_from_path(filepath)
        HB_font = hb.font_create(HB_face)
        upem = hb.face_get_upem(HB_face)
        hb.font_set_scale(HB_font, upem, upem)
        hb.ot_font_set_funcs(HB_font)

        CR_face = fontloader.create_cairo_font_face_for_file(filepath)
        _ot_type_registry[path] = upem, HB_face, HB_font, CR_face

    return _ot_type_registry[path]
Beispiel #8
0
def get_ot_font(path, overwrite=False):
    if path not in _ot_type_registry or overwrite:
        # check if is sfd or binary
        fontname, ext = os.path.splitext(path)
        if ext == '.sfd':
            print('Warning: implicit OTF build triggered')
            os.system('fontforge -script IO/sfd2otf.pe ' + path)
            filepath = fontname + '.otf'
        else:
            filepath = path
        print('\033[92mLoading font\033[0m      :', filepath)
        HB_face = _hb_face_from_path(filepath)
        HB_font = hb.font_create(HB_face)
        upem = hb.face_get_upem(HB_face)
        hb.font_set_scale(HB_font, upem, upem)
        hb.ot_font_set_funcs(HB_font)

        CR_face = fontloader.create_cairo_font_face_for_file(filepath)
        _ot_type_registry[path] = upem, HB_face, HB_font, CR_face
        
    return _ot_type_registry[path]
Beispiel #9
0
    def __init__(self, font_path):
        try:
            assert os.path.isfile(font_path)
            font_file = open(font_path, "br")
            fontdata = font_file.read()

            blob = hb.glib_blob_create(GLib.Bytes.new(fontdata))

            del fontdata

            face = hb.face_create(blob, 0)
            del blob
            self.__font = hb.font_create(face)
            upem = hb.face_get_upem(face)

            del face
            font_file.close()

            hb.font_set_scale(self.__font, upem, upem)
            #hb.ft_font_set_funcs (font)
            hb.ot_font_set_funcs(self.__font)
        except Exception:
            print(font_path)
Beispiel #10
0
        return s


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
Beispiel #11
0
	else:
		return s

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
#