Skip to content
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

Open
yanone opened this issue Sep 9, 2022 · 50 comments
Open

Add KSHD (Kashida) axis #77

yanone opened this issue Sep 9, 2022 · 50 comments
Labels
--new-axis New variable axis definition

Comments

@yanone
Copy link
Contributor

yanone commented Sep 9, 2022

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):

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.

Bildschirmfoto 2022-09-09 um 11 10 29

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.

Bildschirmfoto 2022-09-09 um 11 36 34

@moyogo
Copy link

moyogo commented Sep 9, 2022

@yanone There seems to be overlap with the GEXT (Glyph Extension) axis proposal and jmsole/gext-demos.

@i14h
Copy link

i14h commented Sep 12, 2022

@aminabedi68 FYI

@chrissimpkins chrissimpkins added the --new-axis New variable axis definition label Sep 21, 2022
@chrissimpkins
Copy link
Member

@khaledhosny @Gue3bara

@khaledhosny
Copy link

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.

@yanone
Copy link
Contributor Author

yanone commented Nov 2, 2022

@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.

@aminabedi68
Copy link

(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.

@yanone
Copy link
Contributor Author

yanone commented Nov 3, 2022

@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

@davelab6
Copy link
Member

davelab6 commented Nov 3, 2022

@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?

@aminabedi68
Copy link

@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.

@dberlow
Copy link

dberlow commented Nov 4, 2022

@davelab6 you want to register something like an XRAK axis by EOY, or do you want me to respond by then?

@bateni
Copy link

bateni commented Nov 7, 2022

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:

  1. Letter spacing (though not as heavily as in Latin),
  2. Tatweels of different widths between letters (as in Amin's font),
  3. Elongating certain letters (as in Yanone's commercial font), or
  4. Changing letter shapes completely to achieve desired width (see the attached pictures below, taken from this doc).

al-hamd
la-fi
yaktumoon
wal-azab

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.

@davelab6
Copy link
Member

@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.

@davelab6
Copy link
Member

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.

@simoncozens
Copy link
Contributor

@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.

@davelab6
Copy link
Member

@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
Copy link

behdad commented Sep 21, 2023

@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

@dberlow
Copy link

dberlow commented Sep 22, 2023

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?

@behdad
Copy link

behdad commented Sep 22, 2023

Maybe like the wdth axis as percentage of default?

@yanone
Copy link
Contributor Author

yanone commented Sep 22, 2023

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.

Bildschirmfoto 2023-09-22 um 11 47 55

@khaledhosny
Copy link

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.

@yanone
Copy link
Contributor Author

yanone commented Sep 22, 2023

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.

@davelab6
Copy link
Member

@graphicore 's https://github.com/graphicore/varla-varfo might be relevant to this

@graphicore
Copy link

@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.

@davelab6
Copy link
Member

@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.

@behdad
Copy link

behdad commented Apr 12, 2024

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.

@davelab6
Copy link
Member

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?

@yanone
Copy link
Contributor Author

yanone commented Apr 13, 2024

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.

@yanone
Copy link
Contributor Author

yanone commented Apr 13, 2024

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.

@khaledhosny
Copy link

@asibahi

@behdad
Copy link

behdad commented Apr 13, 2024

The more I think about this, the more it sounds like the jstf we introduced in HarfBuzz.

@behdad
Copy link

behdad commented Apr 13, 2024

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 wdth axis. The fragment shaper doesn't care about those. But the line shaper can make use of unified values when you have different fonts on the same line.

@davelab6
Copy link
Member

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:

Screenshot 2024-04-12 at 3 39 09 PM Screenshot 2024-04-12 at 3 39 07 PM Screenshot 2024-04-12 at 3 39 03 PM

I also came across https://www.khtt.net/en/page/1821/the-big-kashida-secret which categorizes the different kinds of kashidas

@asibahi
Copy link

asibahi commented Apr 18, 2024

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.

@behdad
Copy link

behdad commented Apr 18, 2024

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.

@khaledhosny
Copy link

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):
https://web.archive.org/web/20030719183154/http://www.microsoft.com/middleeast/msdn/JustifyingText-CSS.aspx
(this is the “secret” that Khtt.net link above talks about)

@khaledhosny
Copy link

Another paper with a proposed algorithm using only glyph alternates: http://dx.doi.org/10.3998/3336451.0013.105

@yanone
Copy link
Contributor Author

yanone commented May 24, 2024

@aminabedi68

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).
Additionally, you may consider a KSHD axis that exclusively modulates the Kashida character.

@behdad
Copy link

behdad commented May 24, 2024

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.

That sounds unnecessary to me.

@aminabedi68
Copy link

aminabedi68 commented May 24, 2024

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).

@davelab6
Copy link
Member

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.

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.

@behdad
Copy link

behdad commented May 24, 2024

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.

@dberlow
Copy link

dberlow commented May 26, 2024 via email

@vv-monsalve
Copy link
Contributor

chatted on a call about yesterday was offering both options, a 'per mille' absolute font unit values range axes, and a 'per centage' relative range axis.

These would be the axes definitions for each of these options:

XEXT Horizontal Extension

# XEXT
tag: "XEXT"
display_name: "Vertical Extension"
min_value: 0
default_value: 0
max_value: 100
precision: 0
fallback {
  name: "Default"
  value: 0
}
fallback_only: false
description: "The axis elongate glyph parts in the X dimension, such as the"
  " initial or terminal strokes, swashes, or connections. This is a relative axis,"
  " starting at 0% and going to the typeface's individual maximum"
  " extent at 100%."

This axis would follow the current use of Estedad font. Thus, after the implementation of this axis, the font could be shipped as it is now.


KSHD Kashida

# KSHD 
tag: "KSHD"
display_name: "Kashida"
min_value: 50
default_value: 200
max_value: 2000
precision: 0
fallback {
  name: "Default"
  value: 0
}
fallback_only: false
description: "This is a parametric axis starting for varying the extension 
  " of the Kashid glyph in the X dimension."

Such an axis would operate directly over a Kashida glyph in UPM units, making it an Arabic-specific parametric axis that can be used in precise justification calculations. The min, default, and max values above are drafted using a hypothetical case in which the Kashida's default width is 200 units and could extend up to 2000 UPM.

Any font that implements this axis should use a Kashida glyph and be compressed or expanded in em units.

@vv-monsalve
Copy link
Contributor

@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 XEXT in charge of elongating the strokes in standard glyphs, and KSHD to govern that particular glyph on a UPM scale to work with the justification algorithms.

@davelab6
Copy link
Member

Percent axes should default to zero, not 100.

@behdad
Copy link

behdad commented May 28, 2024

Percent axes should default to zero, not 100.

Humm?

@davelab6
Copy link
Member

MS made a nightmare start for variation in typography when they defined wdth as a % of itself

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."

image

@yanone
Copy link
Contributor Author

yanone commented May 29, 2024

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 min_value and default_value value of KSHD to be 200 each. There is no reason a Kashida should shrink from its default width. It should start at a low default value and only grow from there, never shrink.

If need be, the axis definition can be widened later into both directions. A max_value of 2000 is reasonable for now, but my own (commercial) font has a max extension of 5000, and there is no theoretical limit. Typographers play with the Kashida freely (see below), and while most fonts have a static Kashida character that's a straight line that simply gets multiplied (or stretched on decomposed outlines in Illustrator), a growing number of fonts implement dynamic Kashidas that follow a stroke curvature (see my example above), and those will have some limit. 2000 is a good start.

298510109_6031842716842925_6707232015763747599_n

@behdad
Copy link

behdad commented May 29, 2024

There is no reason a Kashida should shrink from its default width.

The smallest width is not necessarily the most desirable form.

@vv-monsalve
Copy link
Contributor

vv-monsalve commented May 29, 2024

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
--new-axis New variable axis definition
Projects
None yet
Development

No branches or pull requests