From c38380464d29c4502c98d996236ccf890392fe86 Mon Sep 17 00:00:00 2001 From: eunhhu Date: Mon, 28 Sep 2026 12:48:45 +0100 Subject: Shape text as HarfBuzz does, from a symbol file, checked against HarfBuzz The build tool compiles a font's shaping plans the way HarfBuzz's planner does (features, stages, masks, lookups per script and direction) and carries them with the font's character map, advances and GDEF, GSUB and GPOS tables in a section of the symbol file (VEGASYM4); glyphs shaping reaches become symbols of their own. A small engine ports HarfBuzz 10's default, Arabic and Hebrew shaping step for step and reads the tables in place, every read bounds-checked. The build refuses a file whose shaping differs from HarfBuzz's on random runs: DejaVu Sans agrees on 600,000 runs in six scripts both ways, and every installed font the tool accepts agrees too, at 1.05-1.18 times HarfBuzz's time. --- Makefile | 23 ++++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-) (limited to 'Makefile') diff --git a/Makefile b/Makefile index 29bbc27..119e116 100644 --- a/Makefile +++ b/Makefile @@ -39,24 +39,37 @@ $(BUILD)/vega-surface.so: $(SURFACES) surfaces/vega.h symbols/symbols.c symbols/ -fdata-sections -DVEGA_SURFACE -I$(PURE)/core -I$(PURE)/serve -Isymbols $(SURFACES) symbols/symbols.c \ $(LDFLAGS) -Wl,--gc-sections -lm $(LDLIBS) -o $@ -# Building symbol files reads fonts through FreeType; reading them does not. +# Building symbol files reads fonts through FreeType, and compiles and checks +# their shaping with HarfBuzz; reading them needs neither. FREETYPE_CFLAGS ?= $(shell pkg-config --cflags freetype2) FREETYPE_LIBS ?= $(shell pkg-config --libs freetype2) +HARFBUZZ_CFLAGS ?= $(shell pkg-config --cflags harfbuzz) +HARFBUZZ_LIBS ?= $(shell pkg-config --libs harfbuzz) # Drawing them on the GPU takes OpenGL ES 3.1 through EGL. GL_LIBS ?= $(shell pkg-config --libs egl glesv2) SYMBOLS = symbols/symbols.c symbols/symbols-gl.c -$(BUILD)/vega-symbols: symbols/symbols-tool.c $(SYMBOLS) symbols/symbols.h symbols/symbols-gl.h | $(BUILD) - $(CC) $(CPPFLAGS) $(CFLAGS) $(FREETYPE_CFLAGS) symbols/symbols-tool.c $(SYMBOLS) $(LDFLAGS) \ - $(FREETYPE_LIBS) $(GL_LIBS) -lm $(LDLIBS) -o $@ +SHAPE = text/shape.c text/unicode-data.c +$(BUILD)/vega-symbols: symbols/symbols-tool.c $(SYMBOLS) symbols/symbols.h symbols/symbols-gl.h $(SHAPE) text/shape-build.c \ + text/shape.h text/shape-build.h text/text.h | $(BUILD) + $(CC) $(CPPFLAGS) $(CFLAGS) $(FREETYPE_CFLAGS) $(HARFBUZZ_CFLAGS) -Itext symbols/symbols-tool.c $(SYMBOLS) $(SHAPE) \ + text/shape-build.c $(LDFLAGS) $(FREETYPE_LIBS) $(HARFBUZZ_LIBS) $(GL_LIBS) -lm $(LDLIBS) -o $@ TEXT = text/bidi.c text/normalize.c text/unicode-data.c $(BUILD)/test-text: text/test-text.c $(TEXT) text/text.h | $(BUILD) $(CC) $(CPPFLAGS) $(CFLAGS) -Itext text/test-text.c $(TEXT) $(LDFLAGS) $(LDLIBS) -o $@ -# Unicode's conformance tests, where the UCD is installed (Debian: unicode-data). +# Unicode's conformance tests, where the UCD is installed (Debian: unicode-data); +# and shaping, where DejaVu Sans is: the build refuses a file whose shaping +# differs from HarfBuzz's on random runs of Latin, Greek, Cyrillic, Hebrew, +# Arabic and Common text, both ways. UCD ?= /usr/share/unicode +SHAPED_FONT ?= /usr/share/fonts/truetype/dejavu/DejaVuSans.ttf +SHAPED_CODES = 0x20-0x7e,0xa0-0x24f,0x300-0x36f,0x370-0x3ff,0x400-0x4ff,0x591-0x5f4,0x600-0x6ff,0x2000-0x206f check: $(BUILD)/vega $(BUILD)/vega-symbols $(BUILD)/vega-surface.so $(BUILD)/test-text if [ -f $(UCD)/BidiTest.txt ]; then $(BUILD)/test-text $(UCD); else echo "no UCD at $(UCD): text tests skipped"; fi + if [ -f $(SHAPED_FONT) ]; then $(BUILD)/vega-symbols build --font $(SHAPED_FONT) --codes $(SHAPED_CODES) \ + --shape Latn,Grek,Cyrl,Hebr,Arab,Zyyy --runs 5000 -o $(BUILD)/shaped.vsym; \ + else echo "no $(SHAPED_FONT): shaping tests skipped"; fi $(MAKE) -C $(AUP) build/aup $(MAKE) -C $(PURE) build/pure-serve python3 tests/check.py --vega $(BUILD)/vega --symbols $(BUILD)/vega-symbols --aup $(AUP)/build/aup --serve $(PURE)/build/pure-serve -- cgit v1.2.3