-
Notifications
You must be signed in to change notification settings - Fork 11
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add KSHD (Kashida) axis #77
Comments
@yanone There seems to be overlap with the GEXT (Glyph Extension) axis proposal and jmsole/gext-demos. |
@aminabedi68 FYI |
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. |
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) 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...) |
@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 |
@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
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. |
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 |
There has been experimental |
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? |
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 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 My understanding of what should be applied where in a
... 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
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 |
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 I believe the latest from @behdad is that he thinks a @yanone wrote,
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,
And @khaledhosny wrote,
@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. |
The more I think about this, the more it sounds like the |
And yes, you have have priorities of which letters expand first. The downside is that the feature-variations don't work as well as we want them to. The units probably be similar to the |
I also noticed that English Wikipedia redirects https://en.wikipedia.org/wiki/Tatweel to https://en.wikipedia.org/wiki/Kashida and Kashida is the name I've heard most often. I chatted with @dberlow about this overall, and he suggested we should consider this part of the Parametric Axes system, so these can all go into programs with the same value system: users can use them together, across fonts and across programs, and typography is easier to program; no converting between per-mille and percents. X Transparency Kashida XTKA, or X Transparency Tatweel, XTTW. Theoretically, the maximum maximum kashida length is the longest line length in a paragraph. However, this is somewhat theoretical... Somewhat related, in traditional Latin text typography, if the last line is over 1/2 of the col width, and you use a finial, then you fill the col width with a fineal (or leave it alone), while if the last line is under 1/2 perhaps the finial goes to 3/4 of the col width. But with Arabic justification, unlike Latin, the kashida is used both as a finial and within the lines, and so it could be used also with a 'full' width axis, or a XTRA, full as in for every glyph. Also, there's no hyphenation in Arabic, so to do forward/backward full paragraph justification in Arabic, you're looking to shunt words at the start/end of lines to lines above/below. Mamoun had mentioned once in one of his typefaces that there are vertical extensions in Arabic that can be used similarly with line-height. And width is clearly wrong here, since the Latin width doesn't change: I also came across https://www.khtt.net/en/page/1821/the-big-kashida-secret which categorizes the different kinds of kashidas |
Hello I do not share you guys’ technical pedigree and expertise on the subject but I’m reading this as an interested observer. (Thanks Khaled for the ping). There seems to me two topics being discussed here, the correct/most suitable name for the feature in the original issue, and the matter of Arabic Justification. Regarding the first, since it’s pretty much uniform across all (applicable) glyphs, and evenly, the perhaps more apt name would be Glyph Extension, or GEXT. The proposed name would imply to me that it’s being applied selectively, as an aesthetic choice to make a certain word look better or to fit it in its space better. That’s to say, it is not something you apply everywhere all at once. And a small bikeshedding note here, the name “Tatweel” feels a bit too abstract for me, meaning simply elongation, stretching or, well, extension. ”Why are you stretching these file names how are you going to search for them later?”. “Kashida” , for me, is the concrete term for the specific ـ glyph, since I believe Microsoft Office uses that word in the settings. (Or at least used to back in the 90s?). Regarding justification, I believe that’s honestly best left to the font designer, by way of a JSTF variable axis or, in case of Mamdouh Sakkal, a bunch of stylistic sets With obviously a fallback (that fallback being inserting kashidas and adjusting spacing) in case the font designer wasn’t thorough enough. The JSTF variable is probably the cleanest solution all around. You can’t really choose a correct unit for it that’s suitable for all fonts. The extension might be uneven, like Behdad and Simon mentioned, with different glyphs doing different things at different intervals of the variable axis’ range. Any unit will be, by necessity, at best a useful approximation that you cannot depend on for exact math. You must reshape the line anyway. The only thing the typesetter can reasonably assume (or should be able to) is that the line’s width has a positive relationship with the axis. As in: the line width cannot decrease if the axis increases., and vice versa. May remain unchanged tho. For JSTF, I’d suggest an arbitrary scale from, say, -25 to 100. Where 0 is the neutral, basic state. 100 is maximum (reasonable?) elongation, and minus values are for when you would want to compress things a bit and maybe draw the Nun above the Aleph (as anyone handwriting Arabic would do). And if the font doesn’t shrink, just start from 0. finally , re features not applying to Latin characters: I don’t know why this should really matter. It’s an Arabic script font primarily. The Latin characters are simply an embedded fallback font. |
As for the name: TATWEEL is what Unicode uses. But that doesn't mean much. Any color the shed be... With avar2 it's also possible to expose the same mechanism as both a kashida axis and a JSTF axis. |
I agree with @asibahi, the proposed axis is uniformly stretching the glyphs, so it is not a kashida axis. A kashida axis would be selectively stretching glyphs (I think this can be done with feature variations, though I haven’t attempted it). Calling the proposed axis kashida axis closes the door for a more clever one in the future. I’d go with GEXT tag for the proposed axis. Much have been said about Arabic justification in this issue, so here is another paper that surveys the justification techniques and proposes more elaborate kashida insertion points: https://www.tug.org/tugboat/tb27-2/tb87benatia.pdf Here is also the algorithm that IE documents and few other applications (e.g. LibreOffice) implement (tatweel glyphs are inserted after shaping, which has the limitations Sakkal discussed, but recent LibreOffice versions use HarfBuzz to filter-out problematic insertion points to mitigate the issue): |
Another paper with a proposed algorithm using only glyph alternates: http://dx.doi.org/10.3998/3336451.0013.105 |
We had a meeting yesterday discussing the Kashida axis proposal with regards to your two fonts. Google Fonts is generally open to adding a KSHD axis under the name Kashida, to cater to the culture of letter elongations that are specific to the Arabic script. However, both of your fonts are not in line with the common user experience of Kashidas. Your KSHD axis modulates the width of all connected Arabic letters regardless of the presence of the dedicated Kashida character (ـ) in the typed text. Google Fonts expects a KSHD axis to exclusively modulate the width of the dedicated Kashida character (and possibly connected letters directly adjacent to the Kashida character depending on each font’s specific design). What your fonts are doing is what we would describe and implement as a HEXT (horizontal extension) axis, which also still requires registration (doesn't exist yet in GF’s axis registry). While it is my personal opinion that all width-related axes should be described in absolute font unit values (normalized to 1000upm) in line with how spacing and tracking is applied by users, the people responsible for the axis registry are more leaning towards a 0–100 percentage range regardless of the absolute amount of horizontal expansion of each font, in line with other existing axes. Regardless of the technical details, while we value the implementation of your designs, your fonts cannot be onboarded with a KSHD axis as-is. You may choose to convert the axis to a HEXT axis with 0–100 values (best wait until the axis is actually registered). |
That sounds unnecessary to me. |
respectfully i think we have not common feelings about the concept(or the usage of that...), and this conversation took a long time. i will remove the axis from both fonts (either in google fonts version or at all). |
What @evanwadams , @vv-monsalve , @chrissimpkins , @yanone and I chatted on a call about yesterday was offering both options, a 'per mille' absolute font unit values range axus, and a 'per centage' relative range axis. |
Since it's 'per mille', I don't see why some keep referring to it as font units. |
Percent is also inaccurate if the default is constrained to 100%.
This is because there is absolutely nothing to say the maximum range is equal to the minimum range and as Type developers do not measure when setting the actual % of change over the min and max, it’s it’s just wrong %s. So the default can be 300/1000 and the min 5/1000 and the max 500/1000 and the percents 50 and 150, instead of the numerically accurate %.
On top of that, all useful values in type are percent of em, not of the change of a single font style’s variation, or NO typographic past would even exist. All vertical measures are in parts of an em, as are tracking, kerning, and average glyph width in the OT format, in font units, and only font units can be converted to accurate % of the em. MS made a nightmare start for variation in typography when they defined wdth as a % of itself, wght by OT values and opsz with whatever scaling of the actual size a developer decided on. Having a value be either % of itself or % of em is totally unfriendly to People and Programs.
Unless someone out there can tell a me, and a program, how to detect which value it is, please do not make it any worse for programs or people.
Or, if people think this axis can be programmed to properly fit the variations of kashida with a % of the Kashida, to a typographic space, then Prove It Please.
Thanks.
|
These would be the axes definitions for each of these options:
|
@aminabedi68 After re-reading all the insights provided in this issue, the Estedad and Mikhak fonts could use a combination of these two axes. Leaving |
Percent axes should default to zero, not 100. |
Humm? |
Right: Percent axes should default to zero, not 100. Then the variation along such an axis starts from "no change" and goes along to "maximum change available." This is 'dumb' since it is "local" to the font, and dissociated from any other units. But for some people, "less is more." |
Following up on a question @vv-monsalve asked me separately, I analyzed the GF library in terms of typical Kashida width. The average width of the Kashida character is 190 units (normalized to 1000upm). For comparison, the average width of the space character is 263. All were measured on each font's default location only. Therefore, I propose a If need be, the axis definition can be widened later into both directions. A |
The smallest width is not necessarily the most desirable form. |
I indeed doubted whether the Kashidas could contract. After re-reading the entire issue, a couple of comments left that option open, which I considered for the above draft. However, the axes are registered by taking what the font introducing them is using as a base, and then trying to find a reasonable value for the maximum value. The values in the axis range can be increased if another font needs them in the future, but they can't be reduced. The registered axis default can be overridden on the family METADATA.pb file; it must not be modified in the axis registry. |
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 #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):
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 theKSHD
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):
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 theKSHD
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.
The text was updated successfully, but these errors were encountered: