diff --git a/docs/assets/fonts/Raqq.woff2 b/docs/assets/fonts/Raqq.woff2 index 862a848..79fd7c4 100644 Binary files a/docs/assets/fonts/Raqq.woff2 and b/docs/assets/fonts/Raqq.woff2 differ diff --git a/fonts/Raqq.ttf b/fonts/Raqq.ttf index 95f8d3d..77b93e7 100644 Binary files a/fonts/Raqq.ttf and b/fonts/Raqq.ttf differ diff --git a/fonts/Raqq.woff2 b/fonts/Raqq.woff2 index 862a848..79fd7c4 100644 Binary files a/fonts/Raqq.woff2 and b/fonts/Raqq.woff2 differ diff --git a/requirements-test.in b/requirements-test.in index 1bc041c..e54128a 100644 --- a/requirements-test.in +++ b/requirements-test.in @@ -1 +1 @@ -fontbakery[shaping,googlefonts] +fontbakery[shaping,googlefonts] @ git+https://github.com/fonttools/fontbakery@shaping-variations diff --git a/requirements-test.txt b/requirements-test.txt index 7ca4e83..355bfb1 100644 --- a/requirements-test.txt +++ b/requirements-test.txt @@ -52,8 +52,10 @@ filelock==3.13.1 # via youseedee font-v==2.1.0 # via fontbakery -fontbakery==0.10.8 - # via -r requirements-test.in +fontbakery @ git+https://github.com/fonttools/fontbakery@shaping-variations + # via + # -r requirements-test.in + # fontbakery fontfeatures==1.8.0 # via babelfont fonttools==4.47.0 diff --git a/scripts/update-shaping-test.py b/scripts/update-shaping-test.py index 78838c4..098630a 100644 --- a/scripts/update-shaping-test.py +++ b/scripts/update-shaping-test.py @@ -31,7 +31,7 @@ def parsefeatures(text): return features -def shape(font, text, direction, script, language, features): +def shape(font, text, direction, script, language, features, variations): buffer = hb.Buffer() buffer.add_str(text) buffer.direction = direction @@ -39,6 +39,10 @@ def shape(font, text, direction, script, language, features): if language: buffer.language = language + old_variations = font.get_var_coords_normalized() + if variations: + font.set_variations(variations) + hb.shape(font, buffer, features) output = [] @@ -52,6 +56,9 @@ def shape(font, text, direction, script, language, features): glyph += f",{pos.y_advance}" output.append(glyph) + if variations: + font.set_var_coords_normalized(old_variations) + return "|".join(output) @@ -66,6 +73,8 @@ def main(rags): test = {k: v for k, v in test.items() if v} if features := test.get("features"): test["features"] = parsefeatures(features) + if variations := test.get("variations"): + test["variations"] = parsefeatures(variations) test["expectation"] = shape( font, test.get("input"), @@ -73,6 +82,7 @@ def main(rags): test.get("script", "arab"), test.get("language"), test.get("features"), + test.get("variations"), ) tests.append(test) diff --git a/sources/Raqq.glyphspackage/fontinfo.plist b/sources/Raqq.glyphspackage/fontinfo.plist index 51251e6..48cd5f8 100644 --- a/sources/Raqq.glyphspackage/fontinfo.plist +++ b/sources/Raqq.glyphspackage/fontinfo.plist @@ -21,6 +21,7 @@ classes = ( code = "$[name LIKE \"*-ar\" && category == \"Letter\" && ! colorIndex == 0 && name != \"kashida-ar\" && name != \"hamza-ar\"] +lam-ar.short period threedots-ar zerowidthspace @@ -666,6 +667,8 @@ lookup short_lam { sub lam-ar.medi by lam-ar.medi.short; sub lam-ar.medi.round by lam-ar.medi.round.short; sub alef-ar.fina by alef-ar.fina.short; + sub lam-ar by lam-ar.short; + sub lam-ar.init by lam-ar.init.short; } short_lam; lookup yehbarree_baseline { @@ -712,6 +715,23 @@ lookup rlig_4 { @aftermeem' lookup rounded; ; } rlig_4; + +conditionset compact { + SPAC -100 -95; +} compact; + +variation rlig compact { + lookupflag IgnoreMarks; + + ignore + sub [alef-ar alef-ar.fina fehDotless_alef-ar] + [lam-ar lam-ar.init]' + [lam-ar.medi.short lam-ar.medi.round.short lam-ar.fina.short] + ; + sub [alef-ar alef-ar.fina fehDotless_alef-ar] + [lam-ar lam-ar.init]' lookup short_lam + ; +} rlig; "; name = misc; }, @@ -1581,7 +1601,9 @@ _c.hah.noon = -25; "seen-ar.medi.low" = -10; }; "fehDotless_alef-ar" = { +"@MMK_L_lam" = -8; "alef-ar" = -7; +"lam-ar.short" = -17; }; "hah-ar.init" = { "lam_alef-ar.fina" = -57; diff --git a/sources/Raqq.glyphspackage/glyphs/lam-ar.fina.short.glyph b/sources/Raqq.glyphspackage/glyphs/lam-ar.fina.short.glyph index ee8c82f..c437a32 100644 --- a/sources/Raqq.glyphspackage/glyphs/lam-ar.fina.short.glyph +++ b/sources/Raqq.glyphspackage/glyphs/lam-ar.fina.short.glyph @@ -37,55 +37,14 @@ scale = (5,5); layerId = m01; shapes = ( { -closed = 1; -nodes = ( -(175,-234,o), -(186,-222,o), -(186,-198,cs), -(186,-93,o), -(178,11,o), -(177,78,c), -(172,263,o), -(169,475,o), -(158,671,cs), -(157,694,o), -(143,700,o), -(133,681,cs), -(121,658,o), -(82,624,o), -(64,610,cs), -(49,597,o), -(55,584,o), -(56,574,cs), -(70,413,o), -(88,83,o), -(99,-166,c), -(119,-135,l), -(77,-145,o), -(40,-142,o), -(7,-131,cs), -(-1,-129,o), -(-11,-126,o), -(-17,-133,cs), -(-41,-162,o), -(-62,-192,o), -(-91,-211,cs), -(-104,-220,o), -(-109,-233,o), -(-96,-240,cs), -(-12,-283,o), -(91,-283,o), -(159,-243,cs) -); +alignment = -1; +ref = "lam-ar.short"; }, { -closed = 1; -nodes = ( -(190,0,l), -(190,110,l), -(118,110,l), -(118,0,l) -); +alignment = -1; +pos = (130,0); +ref = _p.lam; +scale = (0.6,1); } ); width = 178; diff --git a/sources/Raqq.glyphspackage/glyphs/lam-ar.init.hah1.glyph b/sources/Raqq.glyphspackage/glyphs/lam-ar.init.hah1.glyph index b679fd0..6baa374 100644 --- a/sources/Raqq.glyphspackage/glyphs/lam-ar.init.hah1.glyph +++ b/sources/Raqq.glyphspackage/glyphs/lam-ar.init.hah1.glyph @@ -33,30 +33,9 @@ scale = (5,5); layerId = m01; shapes = ( { -closed = 1; -nodes = ( -(18,115,l), -(92,117,o), -(127,123,o), -(123,231,cs), -(118,378,o), -(107,590,o), -(98,786,cs), -(97,809,o), -(83,815,o), -(73,796,cs), -(61,773,o), -(22,739,o), -(4,725,cs), -(-11,712,o), -(-5,699,o), -(-4,689,cs), -(6,528,o), -(16,354,o), -(18,225,c), -(-20,225,l), -(-20,115,l) -); +alignment = -1; +pos = (0,115); +ref = "lam-ar.init.short"; } ); width = 123; diff --git a/sources/Raqq.glyphspackage/glyphs/lam-ar.init.short.glyph b/sources/Raqq.glyphspackage/glyphs/lam-ar.init.short.glyph new file mode 100644 index 0000000..cd90745 --- /dev/null +++ b/sources/Raqq.glyphspackage/glyphs/lam-ar.init.short.glyph @@ -0,0 +1,66 @@ +{ +glyphname = "lam-ar.init.short"; +kernLeft = lam; +kernRight = lam; +layers = ( +{ +anchors = ( +{ +name = damma; +pos = (5,173); +}, +{ +name = exit; +}, +{ +name = fatha; +pos = (-54,520); +}, +{ +name = kasra; +pos = (123,-36); +} +); +backgroundImage = { +alpha = 80; +angle = -0.1; +imagePath = "images/MS-ADD-01116-000-00003.jpg"; +locked = 1; +pos = (-3157,-1867); +scale = (5,5); +}; +layerId = m01; +shapes = ( +{ +closed = 1; +nodes = ( +(18,0,l), +(92,2,o), +(127,8,o), +(123,116,cs), +(118,263,o), +(107,475,o), +(98,671,cs), +(97,694,o), +(83,700,o), +(73,681,cs), +(61,658,o), +(22,624,o), +(4,610,cs), +(-11,597,o), +(-5,584,o), +(-4,574,cs), +(6,413,o), +(16,239,o), +(18,110,c), +(-20,110,l), +(-20,0,l) +); +} +); +width = 123; +} +); +metricLeft = "=-20@0"; +metricRight = "=0"; +} diff --git a/sources/Raqq.glyphspackage/glyphs/lam-ar.short.glyph b/sources/Raqq.glyphspackage/glyphs/lam-ar.short.glyph new file mode 100644 index 0000000..63c7d08 --- /dev/null +++ b/sources/Raqq.glyphspackage/glyphs/lam-ar.short.glyph @@ -0,0 +1,78 @@ +{ +glyphname = "lam-ar.short"; +kernLeft = lam.fina; +layers = ( +{ +anchors = ( +{ +name = damma; +pos = (33,56); +}, +{ +name = fatha; +pos = (3,509); +}, +{ +name = kasra; +pos = (246,-135); +} +); +backgroundImage = { +alpha = 80; +angle = -0.2; +imagePath = "images/MS-ADD-01116-000-00005.jpg"; +locked = 1; +pos = (-4737,-1764); +scale = (5,5); +}; +layerId = m01; +shapes = ( +{ +closed = 1; +nodes = ( +(175,-234,o), +(186,-222,o), +(186,-198,cs), +(186,-93,o), +(178,11,o), +(177,78,c), +(172,263,o), +(169,475,o), +(158,671,cs), +(157,694,o), +(143,700,o), +(133,681,cs), +(121,658,o), +(82,624,o), +(64,610,cs), +(49,597,o), +(55,584,o), +(56,574,cs), +(70,413,o), +(88,83,o), +(99,-166,c), +(119,-135,l), +(77,-145,o), +(40,-142,o), +(7,-131,cs), +(-1,-129,o), +(-11,-126,o), +(-17,-133,cs), +(-41,-162,o), +(-62,-192,o), +(-91,-211,cs), +(-104,-220,o), +(-109,-233,o), +(-96,-240,cs), +(-12,-283,o), +(91,-283,o), +(159,-243,cs) +); +} +); +width = 186; +} +); +metricLeft = "=-100@-220"; +metricRight = "=0"; +} diff --git a/sources/Raqq.glyphspackage/order.plist b/sources/Raqq.glyphspackage/order.plist index 6032bf4..bbbb311 100644 --- a/sources/Raqq.glyphspackage/order.plist +++ b/sources/Raqq.glyphspackage/order.plist @@ -66,6 +66,7 @@ space, "kaf-ar.init", "kaf-ar.init.alt", "lam-ar", +"lam-ar.short", "lam-ar.fina", "lam-ar.fina.short", "lam-ar.medi", @@ -81,6 +82,7 @@ space, "lam-ar.init.hah1.alt", "lam-ar.init.hah2", "lam-ar.init.hah2.alt", +"lam-ar.init.short", "meem-ar", "meem-ar.fina", "meem-ar.fina.round", diff --git a/tests/shaping.csv b/tests/shaping.csv index 79dfcf1..94203eb 100644 --- a/tests/shaping.csv +++ b/tests/shaping.csv @@ -1,4 +1,4 @@ -input;direction;features;script;language +input;direction;features;script;language;variations آ أ ؤ @@ -546,6 +546,7 @@ input;direction;features;script;language جلح جنح جنى +حال حبا حبب حبر @@ -646,6 +647,7 @@ input;direction;features;script;language فها فهم فهو +قال قلم كسي كـا @@ -774,6 +776,8 @@ input;direction;features;script;language يمر يمن وقح لا +حال;;;;;SPAC=-100 +قال;;;;;SPAC=-100 بسي;;salt بشي;;salt بني;;salt @@ -942,6 +946,7 @@ input;direction;features;script;language ثثثا جججج جلحو +حالت ريحا سبإٍ سببا @@ -958,6 +963,7 @@ input;direction;features;script;language فبيا فلاُ فلِي +قالت قلنا كلمة لبشر @@ -1043,6 +1049,8 @@ input;direction;features;script;language يمما يممر يممو +حالت;;;;;SPAC=-100 +قالت;;;;;SPAC=-100 ببسي;;salt بسسي;;salt بصسي;;salt diff --git a/tests/shaping.json b/tests/shaping.json index 73087aa..c2d7cf8 100644 --- a/tests/shaping.json +++ b/tests/shaping.json @@ -2571,6 +2571,10 @@ "input": "جنى", "expectation": "alefMaksura-ar.fina.tooth=2+9|dotabove-ar.beh=1@-29,270+0|behDotless-ar.medi.round=1+108|dotbelow-ar=0@220,-112+0|_c.hah.beh=0+7|hah-ar.init=0+703" }, + { + "input": "حال", + "expectation": "lam-ar=2+186|alef-ar.fina=1@400,0+501|_c.hah.beh=0+7|hah-ar.init=0+703" + }, { "input": "حبا", "expectation": "alef-ar.fina=2+101|dotbelow-ar=1@9,-110+0|_c.seen.beh=1+0|behDotless-ar.medi=1+128|_c.hah.beh=0+7|hah-ar.init=0+703" @@ -2971,6 +2975,10 @@ "input": "فهو", "expectation": "waw-ar.fina.round=2+492|heh-ar.medi.round=1+323|dotabove-ar=0@-1,373+0|_c.feh.init.beh=0+174|fehDotless-ar.init=0@-114,0+220" }, + { + "input": "قال", + "expectation": "lam-ar=2+186|twodotsverticalabove-ar=0@523,402+0|fehDotless_alef-ar=0@400,0+960" + }, { "input": "قلم", "expectation": "meem-ar.fina.round=2+554|lam-ar.medi.round=1+95|twodotsverticalabove-ar=0@-31,381+0|_c.feh.init.beh=0+174|fehDotless-ar.init=0@-114,0+220" @@ -3483,6 +3491,20 @@ "input": "وقح لا", "expectation": "lam_alef-ar=4+542|space=3+400|hah-ar.fina=2+417|twodotsverticalabove-ar=1@-86,496+0|fehDotless-ar.init.hah=1@11,115+479|waw-ar=0@320,0+829" }, + { + "input": "حال", + "variations": { + "SPAC": -100 + }, + "expectation": "lam-ar.short=2+186|alef-ar.fina=1@20,0+121|_c.hah.beh=0+7|hah-ar.init=0+703" + }, + { + "input": "قال", + "variations": { + "SPAC": -100 + }, + "expectation": "lam-ar.short=2+186|twodotsverticalabove-ar=0@126,402+0|fehDotless_alef-ar=0@3,0+563" + }, { "input": "بسي", "features": { @@ -4320,6 +4342,10 @@ "input": "جلحو", "expectation": "waw-ar.fina.round=3+492|_c.ain.meem=2@-7,0+28|hah-ar.medi=2@-39,0+94|lam-ar.medi.hah1=1@0,7+125|dotbelow-ar=0@270,-10+0|_c.hah.beh=0@0,122+7|hah-ar.init=0@0,122+703" }, + { + "input": "حالت", + "expectation": "twodotsverticalabove-ar=3@803,264+0|behDotless-ar.fina=3+984|_c.seen.beh=2+0|lam-ar.init=2+123|alef-ar.fina=1@400,0+501|_c.hah.beh=0+7|hah-ar.init=0+703" + }, { "input": "ريحا", "expectation": "alef-ar.fina=3+101|_c.hah.beh=2+7|hah-ar.medi.alt=2+135|twodotsverticalbelow-ar=1@167,158+0|behDotless-ar.init.hah=1@63,5+572|reh-ar=0@400,0+850" @@ -4384,6 +4410,10 @@ "input": "فلِي", "expectation": "twodotsverticalbelow-ar=3@339,-334+0|alefMaksura-ar.fina=3+282|kasra-ar=1@48,-111+0|lam-ar.medi=1+125|dotabove-ar=0@-1,373+0|_c.feh.init.beh=0+174|fehDotless-ar.init=0@-114,0+220" }, + { + "input": "قالت", + "expectation": "twodotsverticalabove-ar=3@803,264+0|behDotless-ar.fina=3+984|_c.seen.beh=2+0|lam-ar.init=2+123|twodotsverticalabove-ar=0@515,402+0|fehDotless_alef-ar=0@392,0+952" + }, { "input": "قلنا", "expectation": "alef-ar.fina=3+101|dotabove-ar.beh=2@8,294+0|_c.seen.beh=2+0|behDotless-ar.medi=2+128|_c.seen.beh=1+0|lam-ar.medi=1+125|twodotsverticalabove-ar=0@-31,381+0|_c.feh.init.beh=0+174|fehDotless-ar.init=0@-114,0+220" @@ -4724,6 +4754,20 @@ "input": "يممو", "expectation": "waw-ar.fina.round=3+492|meem-ar.medi.round3=2+398|meem-ar.medi.round2=1+398|twodotsverticalbelow-ar=0@72,-73+0|behDotless-ar.init=0+130" }, + { + "input": "حالت", + "variations": { + "SPAC": -100 + }, + "expectation": "twodotsverticalabove-ar=3@803,264+0|behDotless-ar.fina=3+984|_c.seen.beh=2+0|lam-ar.init.short=2+123|alef-ar.fina=1@20,0+121|_c.hah.beh=0+7|hah-ar.init=0+703" + }, + { + "input": "قالت", + "variations": { + "SPAC": -100 + }, + "expectation": "twodotsverticalabove-ar=3@803,264+0|behDotless-ar.fina=3+984|_c.seen.beh=2+0|lam-ar.init.short=2+123|twodotsverticalabove-ar=0@135,402+0|fehDotless_alef-ar=0@12,0+572" + }, { "input": "ببسي", "features": {