12

I am having an issue with Arabic Font Ligatures showing discrepancy between ConTeXt and XeLateX, when using the same font namely Scheherazade. The issue is not present when using XeLateX but only appears in ConTeXt.

Here is my original question Reference Question, the solution to that question was provided by Paolo Brasolin

The issue is with all words which contain the letters " الا "

Here is the MWE:

\enableregime[utf]

\definefontfeature
   [arabic]
   [mode=node,language=dflt,script=arab,
    init=yes,medi=yes,fina=yes,isol=yes,
    liga=yes,dlig=yes,rlig=yes,clig=yes,
    mark=yes,mkmk=yes,kern=yes,curs=yes]

\starttypescript [serif] [arabic]
 \definefontsynonym [Arabic-Regular] [file:Scheherazade-Regular.ttf] [features=arabic]
 \definefontsynonym [Arabic-Bold]    [file:Scheherazade-Bold.ttf]    [features=arabic]
\stoptypescript

\starttypescript [serif] [arabic] [name]
 \usetypescript[serif][fallback]
 \definefontsynonym [Serif]     [Arabic-Regular] [features=arabic]
 \definefontsynonym [SerifBold] [Arabic-Bold]    [features=arabic]
\stoptypescript

\starttypescript [Arabic]
  \definetypeface [Arabic] [rm] [serif] [arabic] [default] 
\stoptypescript 

\def\ArabicGlobalDir {\pagedir TRT\bodydir TRT\pardir TRT\textdir TRT}
\def\ArabicParDir    {\textdir TRT\pardir TRT}
\def\ArabicTextDir   {\textdir TRT}

\define\setarabic
  {\ArabicGlobalDir%
   \usetypescript[Arabic]%
   \setupbodyfont[Arabic,20pt]}

\definestartstop
  [arabicpar]
  [commands=\Arabic\ArabicParDir]

\define[1]\RT
  {{\Arabic\ArabicTextDir#1}}

\mainlanguage[arabic]

\pagedir TRT
\bodydir TRT
\pardir TRT
\textdir TRT

\setuppagenumbering[alternative=doublesided]

\setuppapersize[A4]

\setuplayout[
  grid=min, 
  backspace=50mm, width=130mm,
  topspace=33mm, height=210mm,
  header=0mm, footer=0mm,
  ]

\showgrid

\setupbodyfont[Arabic,24pt]
\setupinterlinespace[line=42pt]
\setupheads[number=no]
\setuphead[chapter][style=\bfd,before=,after=\blank,alternative=middle,grid=both]
\setuphead[section][style=\bfc,before=\blank,after=,grid=both]

\starttext
\chapter{كِتَاب الطَّهَارَةِ}
اَلْمِيَاهُ ثَلَاثَةٌ\\
اَلْأَوَّلُ: طَهُورٌ وَهُوَ اَلْبَاقِي عَلَى خِلْقَتِهِ وَمِنْهُ مَكْرُوهٌ كَمُتَغَيِّرٍ بِغَيْرِ مُمَازِجٍ وَمُحَرَّمٌ لَا يَرْفَعُ اَلْحَدَثَ وَيُزِيلُ اَلْخَبَثَ وَهُوَ اَلْمَغْصُوب وَغَيْرُ بِئْرِ النَّاقَةِ مِنْ ثَمُودَ .\\
اَلثَّانِي: طَاهِرٌ لَا يَرْفَعُ اَلْحَدَثَ وَلَا يُزِيلُ اَلْخَبَثَ وَهُوَ اَلْمُتَغَيِّرُ بِمُمَازِجٍ طَاهِر وَمِنْهُ يَسِيرٌ مُسْتَعْمَلٌ فِي رَفْعِ حَدَثٍ .\\
اَلثَّالِثُ: نَجِسٌ يَحْرُمُ اِسْتِعْمَالُهُ مُطْلَقًا وَهُوَ مَا تَغَيَّرَ بِنَجَاسَةٍ فِي غَيْرِ مَحِلِّ تَطْهِيرٍ أَوْ لَاقَاهَا فِي غَيْرِهِ وَهُوَ يَسِيرٌ وَالْجَارِي كَالرَّاكِدِ وَالْكَثِيرُ قُلَّتَانِ وَهُمَا مِائَةُ رِطْلٍ وَسَبْعَةُ أَرْطَالٍ وَسُبْعُ رِطْلٍ بِالدِّمَشْقِيِّ وَالْيَسِيرُ مَا دُونَهُمَ .
\section{طَهَارَةُ اَلْآنِيَةِ}
كُلُّ إِنَاءٍ طَاهِرٍ يُبَاحُ اِتِّخَاذُهُ وَاسْتِعْمَالُهُ إِلَّا أَنْ يَكُونَ ذَهَبًا أَوْ فِضَّةً أَوْ مُضَبَّبًا بِأَحَدِهِمَا لَكِنْ تُبَاحُ ضَبَّةٌ يَسِيرَةٌ مِنْ فِضَّةٍ لِحَاجَةٍ وَمَا لَمْ تُعْلَمْ نَجَاسَتُهُ مِنْ آنِيَةِ كُفَّارٍ وَثِيَابُهُمْ طَاهِرَةٌ وَلَا يَطْهُرُ جِلْدُ مَيِّتَةٍ بِدِبَاغٍ وَكُلُّ أَجْزَائِهَا نَجِسَةٌ إِلَّا شَعْرًا وَنَحْوَهُ وَالْمُنْفَصِلُ مِنْ حَيٍّ كَمَيْتَتِهِ .
\section{اَلِاسْتِنْجَاءُ وَالِاسْتِجْمَارُ}
اَلِاسْتِنْجَاءُ وَاجِبٌ مِنْ كُلِّ خَارِجٍ إِلَّا اَلرِّيحَ وَالطَّاهِرَ وَغَيْرَ اَلْمُلَوَّث وَسُنَّ عِنْدَ دُخُولِ خَلَاءٍ قَوْلُ : بِسْمِ اَللَّهِ اَللَّهُمَّ إِنِّي أَعُوذُ بِكَ مِنْ اَلْخُبُثِ وَالْخَبَائِثِ وَبَعْدَ خُرُوجٍ مِنْهُ : غُفْرَانَكَ، اَلْحَمْدُ لِلَّهِ اَلَّذِي أَذْهَبَ عَنِّي اَلْأَذَى وَعَافَانِي.\\
\stoptext

Here are the screenshots with the ligature issue highlighted in red.

As you can notice in the 2nd section title, if we remove the diacritical mark before the letter " ل " , then it shows the correct ligatures. But when we place a diacritic mark before " ل ", the issue appears.

Screenshot

Does anyone have any experience dealing with these types of issues.

  • 1
    I'd be minded to compare LuaLaTeX and ConTeXt: both use a Lua-based font shaper rather than HarfBuzz, which is what is used by XeTeX. – Joseph Wright Jan 3 '16 at 9:32
  • 1
    This question has nothing to do with XeLaTeX. A more appropriate title would be ConTeXt missing arabic ligature because of diacritic. The essence of the problem is you have alif+lem+sukun+alif and the result is missing the mandatory ligature between the last two letters, so it's typeset with the usual joins. This does not happen without sukun. Probably the solution is to define a new font feature having the correct glyph substitution for the three characters in a lookup table, as shown here. – Paolo Brasolin Jan 3 '16 at 18:57
  • @Mico thats correct, it was a typo. Corrected it. – Ibn Saeed Jan 7 '16 at 6:56
  • I do not face this problem when using the accepted answer's code from the reference question. I think the font has been fixed? – Khalid Hussain Nov 10 '16 at 19:07
10
+150

Ideally, one could fix the problem using an OpenType feature file loaded at runtime through a ConTeXt typescript. In practice, that's not (yet) possible; as Hans Hagen told me

the new font loaders doesn't support fea files (i have a basic parser but it's not included as i'm still not sure if it should be .. fea files assume stable fonts and so)

This means that you'll have to patch the font directly. I'll explain how to do it using FontForge.

Writing the patch

First of all, you might want to study the OpenType Feature File Specification and The OpenType Cookbook.

Then you have to look at the insides of Scheherazade and notice that the lam-alef ligature is not done by substituting a single glyph to a pair, but replacing each one with the correct half-ligature, depending on context, form and applied diacritics.

After doing all that you are ready to write the patch feature file. Well, I did it for you. Here is saed.fea:

# feature for default language and arabic script
languagesystem arab dflt;

# ========================================================== GLYPHS CLASSES ====

# ----------------------------------------------------------------------- ALEF -

# final alef
@alef.fina = [
  uni0622.fina uni0622.fina.small
  uni0623.fina uni0625.fina uni0627.fina
  uni0672.fina uni0673.fina uni0675.fina
  uni0671.fina uni0773.fina uni0774.fina] ;

# alef-half of ligature with final/medial alef and initial lam
@alef.fina.postLamIni = [
  uni0622.fina.postLamIni uni0622.fina.postLamIni.small
  uni0623.fina.postLamIni uni0625.fina.postLamIni uni0627.fina.postLamIni
  uni0672.fina.postLamIni uni0673.fina.postLamIni uni0675.fina.postLamIni
  uni0671.fina.postLamIni uni0773.fina.postLamIni uni0774.fina.postLamIni] ;

# alef-half of ligature with final/medial alef and medial lam
@alef.fina.postLamMed = [
  uni0622.fina.postLamMed uni0622.fina.postLamMed.small
  uni0623.fina.postLamMed uni0625.fina.postLamMed uni0627.fina.postLamMed
  uni0672.fina.postLamMed uni0673.fina.postLamMed uni0675.fina.postLamMed
  uni0671.fina.postLamMed uni0773.fina.postLamMed uni0774.fina.postLamMed] ;

# ----------------------------------------------------------------------- LAM -

# initial lam
@lam.init = [
  uni0644.init
  uni06B5.init uni06B6.init uni06B7.init
  uni06B8.init uni076A.init uni08A6.init
] ;

# lam-half of ligature with final/medial alef and initial lam
@lam.init.preAlef  = [
  uni0644.init.preAlef
  uni06B5.init.preAlef uni06B6.init.preAlef uni06B7.init.preAlef
  uni06B8.init.preAlef uni076A.init.preAlef uni08A6.init.preAlef
] ;

# medial lam
@lam.medi = [
  uni0644.medi
  uni06B5.medi uni06B6.medi uni06B7.medi
  uni06B8.medi uni076A.medi uni08A6.medi
] ;

# lam-halv of ligature with final/medial alef and medial lam
@lam.medi.preAlef  = [
  uni0644.medi.preAlef
  uni06B5.medi.preAlef uni06B6.medi.preAlef uni06B7.medi.preAlef
  uni06B8.medi.preAlef uni076A.medi.preAlef uni08A6.medi.preAlef
] ;

# ======================================================== LIGATING LOOKUPS ====

# substitute final/medial alef with corresponding half-ligature to initial lam
lookup ALEF.POSTLAMINI {
  sub @alef.fina by @alef.fina.postLamIni ;
} ALEF.POSTLAMINI ;

# substitute final/medial alef with corresponding half-ligature to medial lam
lookup ALEF.POSTLAMMED {
  sub @alef.fina by @alef.fina.postLamMed ;
} ALEF.POSTLAMMED ;

# substitute initial/medial lam with corresponding half-ligature to alef
lookup LEM.PREALEF {
  sub @lam.init by @lam.init.preAlef ;
  sub @lam.medi by @lam.medi.preAlef ;
} LEM.PREALEF ;

# ============================================================ SAED FEATURE ====

# bundle together ligating lookups
lookup SAEDLIG {
  sub @lam.init' lookup LEM.PREALEF uni0652' @alef.fina' lookup ALEF.POSTLAMINI ;
  sub @lam.medi' lookup LEM.PREALEF uni0652' @alef.fina' lookup ALEF.POSTLAMMED ;
} SAEDLIG ;

# position correction for sukun
lookup SAEDPOS {
  pos @lam.init.preAlef uni0652' <100 220 0 0> @alef.fina.postLamIni;
  pos @lam.medi.preAlef uni0652' <150  40 0 0> @alef.fina.postLamMed;
} SAEDPOS ;

# define saed feature
feature saed {
  lookup SAEDLIG ;
  lookup SAEDPOS ;
} saed ;

The code is fairly commented so I won't go through the details. Observations:

  • Since this patch is applied after the other tables (diacritics, ligatures) I can directly substitute the contextual forms; it's a bit easier this way.
  • All possible variations of diacritics that this font allows are taken account for.
  • I adjusted the positions of the sukun differently for initial and medial lam. However I didn't make corrections for the case of multiple upwards diacritict on the lam: they will collide with the sukun. You can write the corrections if you need them.
  • The patch is bundled into a feature named saed that you can turn on and off. Cool!

Applying the patch

If you want to use the GUI of FontForge, the buttons are

File > Open
File > Merge Feature Info
File > Generate Fonts

Me, I'm allergic to clicking so I threw the font files into the same directory of the feature file and ran this pretty self-explanatory script (saed-patch.pe)

Open("Scheherazade-Regular.ttf")
MergeFeature("saed.fea")
Generate("Scheherazade-Regular-Saed.ttf")
Close()
Open("Scheherazade-Bold.ttf")
MergeFeature("saed.fea")
Generate("Scheherazade-Bold-Saed.ttf")
Close()

using the commandline

fontforge -script saed-patch.pe

Testing the font

Great! You have the patched font. Let's test the regular weight.

Here is a minimal typescript, type-scheherazade.tex:

\definefontfeature
   [arabic]
   [mode=node,language=dflt,script=arab,
    init=yes,medi=yes,fina=yes,isol=yes,
    liga=yes,dlig=yes,rlig=yes,clig=yes,
    mark=yes,mkmk=yes,kern=yes,curs=yes,
    saed=yes]

\starttypescript [serif] [arabic]
 \definefontsynonym [Arabic-Regular] [file:Scheherazade-Regular-Saed.ttf] [features=arabic]
\stoptypescript

\starttypescript [serif] [arabic] [name]
 \definefontsynonym [Serif]     [Arabic-Regular] [features=arabic]
\stoptypescript

\starttypescript [Scheherazade]
  \definetypeface [Scheherazade] [rm] [serif] [arabic] [default] 
\stoptypescript 

Note I enabled the saed feature I defined!

A minimal test document

\usetypescriptfile[type-scheherazade]
\usetypescript[Scheherazade]
\pagedir TRT \bodydir TRT \pardir TRT \textdir TRT
\setupbodyfont[Scheherazade,60pt]
\starttext
لْا ~ لْاـ ~ ـلْا ~ ـلْاـ

لْآ ~ لْآـ ~ ـلْآ ~ ـلْآـ
\stoptext

compiles to

ugliest sukun

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.