Add KSHD (Kashida) axis
The two Farsi fonts Estedad (https://github.com/aminabedi68/Estedad) and Mikhak (https://github.com/aminabedi68/Mikhak) that I’m commissioned to onboard have a so-called Kashida axis (KSHD) that elongates the connections between connected letters.
Before I prepare descriptions, fallback names, and sensible start and end values for the axis, I want to discuss some observations:
1.
The experienced behaviour strongly reminds me of the Tracking axis that is currently undergoing registration (see https://github.com/googlefonts/axisregistry/issues/27). Now, obviously, the intended Kashida feature that elongates letter connections is different from adding tracking in the disconnected script sense (actual space between letters), but it’s hard to ignore that the usage leads to very similar results: The line length and "space" between letters grows. Therefore I want to ask whether a separate axis registration is necessary here.
Here’s Wikipedia on the Kasheeda (https://en.wikipedia.org/wiki/Kashida):
In contrast to white-space justification, which increases the length of a line of text by expanding spaces between words or individual letters, kasheeda creates justification by elongating characters at certain points. Kasheeda justification can be combined with white-space justification.`
This description actually sounds like it supports a separate Kashida axis that is different from adding tracking (white space).
2.
What confuses me is that the Kashida exists as distinct glyph (blue in the image) in every digital Arabic font, and at first I typed that glyph explicitly only to find that the elongations implemented in Estedad and Mikhak are not related to the Kashida glyph. The axis does elongate the glyph, but to make things worse, the rendering breaks (in Indesign) when a KSHD value greater than 100 is applied to just the Kashida glyph. It returns to normal once the KSHD feature is applied to the whole word. This is very unfortunate and probably a bug in Indesign (or maybe even expected behaviour of OpenType typography) more than a bug in the fonts, but I need to point out that the word Kashida has a very widely known, very distinct meaning in contemporary digital typography that may cause confusion with the present proposition of the Kashida axis for users.
Also, applying elongations to a whole word at once works against how the elongations are actually used in sensible Arabic typography.
Khtt.net on the issue (https://www.khtt.net/en/page/1821/the-big-kashida-secret):
First it looks for characters with the highest priority in each word, which means kashida-extensions will only been used in one position in each word. Not more.
The lowest line of Mikhak in the image shows the KSHD feature applied to only the last two letters without the manual insertion of the distinct Kashida glyph, which shows the intended selective behaviour, but the first instinct of contemporary Arabic typographers could be the insertion of the Kashida glyph rather than selectively applying the KSHD feature.
Added to that, selectively enabling a feature (or axis value) to parts of a text is significantly more complicated in CSS than in DTP applications. I haven’t tried yet, but I can only imagine the selective elongation through the KSHD axis implemented through a <span> tag along the lines of يانو<span class="kashida">نه</span>. Again, it could be more intuitive for users to insert the distinct Kashida glyph instead.
Now, the two present fonts indeed present the elongations visually identical to inserting the Kashida glyph, while other fonts such as the commercial multi-script font that I’m currently finalizing (see below) move the letter connections to be well below the baseline. In this example, applying a feature or axis value is the only way to achieve the intended behaviour, as inserting a Kashida glyph would definitely break the rendering here. To my knowledge, it’s not possible in OpenType to programmatically have the Kashida glyph removed and instead the feature turned on for this glyph sequence. I wish it would.
This example is not related to the two present fonts, but more elaborate Arabic elongation designs are very thinkable to get released on Google Fonts in the future, and therefore I must again call the name Kashida for this axis into question and ask whether a more general name (stupid example: Elongation or Swash Length) could work better for a wider range of fonts. (Personally I’m currently calling my axis Swash Width but I’m actually inclined to align the feature with whatever result we end up here, even though my typeface won’t get release on Google Fonts). And what even about connected scripts of other writing systems, be it script-style Latin or Devanagari, for example? Mongolian, that mimicks Arabic but certainly doesn’t have a feature called Kashida? I can definitely see some form of Elongation axis coming up in the future that would essentially be a duplicate of a Kashida axis.
@yanone There seems to be overlap with the GEXT (Glyph Extension) axis proposal and jmsole/gext-demos.
@aminabedi68 FYI
@khaledhosny @gue3bara
I think the proposed axis is more of a letter-spacing one, since letters are indiscriminately elongated (css-text-4 suggests this how cursive scripts should be letter-spaced, though I don’t think any browser supports this).
Proper kashida insertion, as used e.g. in justification, is contextual and needs weighted priorities. There exists several algorithms for deciding where to insert Kashida, and more thought is needed on the interaction between the application and the font.
I think the proposed axis should be folded into a general letter-spacing/tracking axis and specifying that cursive writing system can implement it this way.
@aminabedi68
We just internally discussed this axis proposal again, and found that the behaviour of both your fonts’ Kashida axis is actually almost identical to how the width axis would behave for Arabic fonts, or at least very close. (In reality, for a width axis, a little bit of outer space would probably be added).
So we could onboard the fonts now if you would accept this width axis idea. Otherwise we have a tracking and spacing axis coming up which could then be used instead, but these axes aren't ready yet. I'm not in the loop for how long they'll take, but they're happening.
Please let us know what you think. Thank you.
(sorry to response this late, i wrote something before but decide to not sent till hear all comments) thank you for this issue. i guess we all(almost) have the same idea about Arabic Kashida concept: expanding of connection in connected Arabic letters so why we just want calligraphic part of that? it could be as simple as a straight none-rule connection. i mean "a simple Kashida" is still a "Kashida" and if you talk to ordinary Arabic script people about what this is(in Estedad & Mikhak), most of them call it Kashida!
i used "some kind of" Kashida for my fonts, and this is not all we can do about Kashida in other fonts.(for example in a calligraphic traditional font, kashida axis could process the variation in a HOI interpolation...) i think you had to consider adding Kashida axis someday(because it's a huge concept for Arabic script), so please reconsider. i insist because i think it's totally make sense. thank you again.
@aminabedi68 What’s your opinion about the GEXT axis that @moyogo mentioned early on here?
It was proposed by an Arabic type designer for the sole purpose of accommodating Kashidas, while being open and compatible enough to accommodate similar expressions in other scripts, such as connected Latin script.
I'm just worried that we'll get stuck on this because the sentiment around here is that there are enough alternatives, already published or still in development, to an explicit Kashida axis that serve a very similar purpose but are not called Kashida. My understanding is that Google Fonts wants to avoid duplicate axes at all costs.
I'll forward your remark to the internal discussion, but still curious on your opinion on GEXT
@dberlow please could you queue up writing an explanation of why we expect to support this as an x transparency secondary parametric axis, before eoy?
@moyogo @yanone yes, it seems GEXT is containing Kashida concept(i'm not sure GEXT covers whole Kashida concept or not). in the other hand, GEXT points to the font(of all scripts) but Kashida points to the Arabic type. Arabic script people use and recognize Kashida with a clear definition in their type and calligraphy culture, so it's a right path to bring such concepts to their own digital life in variable fonts. an Arab calligraphy master probably don't know what is GEXT, but it's impossible he/she don't know what Kashida is, so using GEXT for Kashida may not be wrong but it has a hidden message of ignoring.
@davelab6 you want to register something like an XRAK axis by EOY, or do you want me to respond by then?
The nomenclature is unfortunately confusing. The unicode character U+0640 is officially called "Arabic tatweel" but it is sometimes unofficially referred to as 'kashida'. Arabic justification - when done properly! - uses multiple devices:
- Letter spacing (though not as heavily as in Latin),
- Tatweels of different widths between letters (as in Amin's font),
- Elongating certain letters (as in Yanone's commercial font), or
- Changing letter shapes completely to achieve desired width (see the attached pictures below, taken from this doc).

It would be excellent if all of this were implemented nicely and were easy to use. Absent such mechanisms (never mind in a universal and standard form), people use and implement tatweel in different ways.
As Khaled said, ideal justified Arabic typography should assign different weights to different letters and letter connections. It usually looks better if only one (or at most two) positions in a word use the tatweel glyph. The exception is perhaps when letter shapes change and it no longer seems like an artificial elongation. A good chunk of the logic should be pushed into the higher layer (in the browser, for instance) because it is very hard (if not impossible) to do a good job within OpenType.
I'm concerned that GEXT may be too hard to achieve (in OpenType), so it will remain an under-investigation proposal. What's the status? Is there a timeline for supporting it?
Amin's implementation is certainly not "tracking". It can be folded under some sort of "width" access, but since it's only adding tatweel between letters, "kashida" may not be a bad or confusing name for it.
Yanone mentions difficulty of turning the feature on and off for particular letters/words. That is correct, but perhaps a browser or some other typographic software can decide on the locations and let OpenType do its magic.
@dberlow and @simoncozens are working on "jstf" OpenType feature ideas, because as you say an axis by itself isn't a complete solution. I doubt GEXT or KSHD will be added to any Google Fonts family at least with those names. But the overall seeking of a solution is happening.
I will be away from work all of April, I'll be working with @dberlow when I get back on avar2 stuff, so I expect more might be published over the summer.
@dberlow and @simoncozens are working on "jstf" OpenType feature ideas, because as you say an axis by itself isn't a complete solution.
The outcome of our meeting was that it actually might be, if that axis did different things to different glyphs along different positions. @khaledhosny and Behdad are experimenting with a jstf axis with shaper support.
@behdad any updates?
@dberlow following the presentation by @khaledhosny and @Gue3bara today, please respond soon to how you think Kashidas should be integrated in to the Parametric Axes set of axes as defined in this repo
@behdad any updates?
There has been experimental hb_shape_justify() API in HarfBuzz for a while, as demo'ed in Paris.
https://docs.google.com/presentation/d/11bv9aC0l2lIesguiwtp0CDpKaiE6p5pMSZD3RvuUL9w/edit#slide=id.g212b1c0df88_7_26
My question on this axes is how to give it values on a range that is interoperable useful to a composition system that is choosing among the variations as would a calligrapher based on options available from the combination of opentype and variables.
So, first I'm curious as to what people think the longest possible kashida is?
Maybe like the wdth axis as percentage of default?
So, first I'm curious as to what people think the longest possible kashida is?
My WIP typeface has a Kashida width of 0 to 5000 font units (2500 units per glyph and they meet in the middle as usual).
I'm making sure in QA that the glyphs’ extended versions are exactly 2500 units wider than their contracted versions so that the font units can be used in precise justification calculations.
At least that's how I thought justification calculations would work: You know how wide a line is in font units and you know how wide your unextended line of text is in font units, so applying the justification is a relatively simple calculation of setting the axis value to the available space that’s left divided by the amount of kashida characters in the line.
Therefore, I propose to make the axis measure in font units, maybe normalized to a 1000 grid to enhance the UX across fonts with different UPMs.
Kashida application is usually done by analyzing the line, finding places where kashida is allowed and then inserting copies of the kashida glyph at these places enough to fill all the required space. The implementations I know don’t reshape the text after inserting the kashida glyphs, which is their biggest limitation since usually the glyphs before and after the kashida need to change shape to accommodate (sometimes only subtly, sometimes in more drastic ways)
How can such an algorithm be extended to use a variation axis?
Should it insert a kashida character at each allowed place in the original text, reshape, then apply variation until all space is filled? How it know how many kashida’s it needs to insert? What happens if inserting kashida and re-shaping made the text much wider than before that even with the axis at default coordinate the text no longer fits the line?
Or is it up to the font to codify where kashida should be inserted, and if so how would that be done?
I think we need to consider the justification algorithm before spec’ing the variation axis.
I don't want to impose myself too much here because a font-level jstf axis (or even table) is really not my area of expertise, but I want to outline how I intended to apply justification for my font:
I wanted to create a Python package that can automatically insert kashidas into a text. (Khaled has already pointed me to his previous work for LibreOffice but I haven't gotten around to successfully porting it to Python yet). Then possibly port it to Javascript, too.
Then I wanted to write a browser-based Javascript package that's essentially a typesetter that breaks text into lines, adds kashidas, then applies the KSHD axis (still called GEXT in my font).
This could be turned into a convenient Figma plugin, too.
My understanding of what should be applied where in a jstf axis (or even table) is very confused.
Should it insert a kashida character at each allowed place in the original text, reshape, then apply variation until all space is filled? How it know how many kashida’s it needs to insert? What happens if inserting kashida and re-shaping made the text much wider than before that even with the axis at default coordinate the text no longer fits the line?
... but because of these valid concerns I don't see how this whole issue can be solved at the font level, especially since the font doesn't know about the available line space, and won't be able to calculate an axis value because no WASM table. So this needs to be external anyway, right?
Preferences of where all to insert kashidas might even vary among typesetters. That’s why I thought this should all stay under the user’s control, at least controllable through a UI (web typesetter, Figma plugin), and axis variation applied externally by the typesetter algorithm and not by the font.
And kashida implementation varies between font designs, too. In my font, the kashida character gets removed after the glyphs left and right of it are shaped (the default instances have a GEXT value of 300 so that in normal text, kashidas are visible). With an axis value of 0, no width adjustments happen at all, leaving the entire remaining space to be applicable to the axis.
I think we need to consider the justification algorithm before spec’ing the variation axis.
My opinion: If the kashida axis is defined in font units, the whole typesetting algorithm doesn't matter because it can only happen outside of the font anyway. Each algorithm will know how many kashidas to insert and justify the text by calculating available space in font units and apply that value to the axis.
@graphicore 's https://github.com/graphicore/varla-varfo might be relevant to this
@graphicore 's https://github.com/graphicore/varla-varfo might be relevant to this
Then I wanted to write a browser-based Javascript package that's essentially a typesetter that breaks text into lines, adds kashidas, then applies the KSHD axis (still called GEXT in my font). This could be turned into a convenient Figma plugin, too.
I'm pretty sure it can be adapted to work rather easily, especially the part that breaks text into lines and makes them longer (or shorter) until they fit etc. It's rather slow, but it can be a proof of concept.
There are also ideas how to speed it up, i.e. shaping in memory with wasm-harfbuzz, but the current version is likely more complete for a while, e.g. it works with mixed type as well when bold or italics are used on a line (or a lot/any markup) and it uses the justification as done by the browser. A lot of those details in-memory shaping would have to implement itself.
@evanwadams and @vv-monsalve and just met and provisionally agreed a KSHD axis tag and Kashida Length name with a percentage unit, pending feedback from paragraph layout engineers :)
I believe the latest from @behdad is that he thinks a jstf feature isn't needed and "everything can be done with an axis". There was the ATypI 2023 Paris presentation with @khaledhosny 's example.
@yanone wrote,
Therefore, I propose to make the axis measure in font units, maybe normalized to a 1000 grid to enhance the UX across fonts with different UPMs.
Initially we discussed how we might expect this axis to be used by a justification algo for a very specific use-case of full justification paragraph layout, so the alternative range of a percentage is less useful, per-mille values are useful for users to see.
While Evan by default prefers a percentage for humans, and 100% is simply "the widest this font supports", this led me to consider a font with different Kashida lengths for different glyphs; say one glyph has a 100 UPM extension and another has a 200 UPM extension, then the design space layout needs to make that reflect correctly. This complicates things perhaps unnecessarily.
So @vv-monsalve proposed we hold this decision and seek comment from folks implementing paragraph layout :)
Also @yanone wrote,
This example is not related to the two present fonts, but more elaborate Arabic elongation designs are very thinkable to get released on Google Fonts in the future, and therefore I must again call the name Kashida for this axis into question and ask whether a more general name (stupid example: Elongation or Swash Length) could work better for a wider range of fonts. (Personally I’m currently calling my axis Swash Width but I’m actually inclined to align the feature with whatever result we end up here, even though my typeface won’t get release on Google Fonts). And what even about connected scripts of other writing systems, be it script-style Latin or Devanagari, for example? Mongolian, that mimicks Arabic but certainly doesn’t have a feature called Kashida? I can definitely see some form of Elongation axis coming up in the future that would essentially be a duplicate of a Kashida axis.
And @khaledhosny wrote,
I think the proposed axis should be folded into a general letter-spacing/tracking axis and specifying that cursive writing system can implement it this way.
@vv-monsalve argued that "Kashida" is a well known name for an element of the Arabic script, and I would say that a font with a Swash Width axis for Latin and a Kashida axis for Arabic in one font is useful to have split out into 2 axes to give independent control of the 2 different things easily. We have since registered a general letter-spacing/tracking axis exactly - see spacing.textproto - and similarly I expect we want to have independent control of full letter break in transparency and with the joins in kashidas.
A bikeshedding note. Kashida is a Persian word. Tatweel is the Arabic word for it. I suggest using the Arabic word since this is not limited to Persian.
Tatweel sounds good :) Do you think the unit matters at all for paragraph layout software? Will that always work the same whatever the units, and the units are only useful for end-users?
I'm happy with the name, but not the units, as has already been acknowledged, so I don't know what to say now.
With the axis using font units, I can program my own justification algorithm in JavaScript or Python: break text into lines, add kashida characters, measure each line's width, and then apply the axis value as a calculation of the remaining space per line divided by the number of kashida characters per line.
With percentage of each font's individual maximum extension, that's not possible.
I think all width-related adjustments should be counted in font units. You also don't apply tracking as a percentage of the font’s widest sidebearing.
@asibahi
The more I think about this, the more it sounds like the jstf we introduced in HarfBuzz.