编写补丁

编写补丁

我遇到了阿拉伯字体连字问题,在使用同一种字体 Scheherazade 时,ConTeXt 和 XeLateX 之间出现了差异。使用 XeLateX 时不存在此问题,但仅出现在 ConTeXt 中。

这是我原来的问题参考问题,这个问题的解决方案是由保罗·布拉索林

问题包含以下所有单词字母“ الا ”

以下是 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

以下是连字符问题的屏幕截图,其中用红色突出显示。

尽你所能注意第二部分标题,如果我们删除字母“ل”前的变音符号,那么它会显示正确的连字。但是当我们在“ل”前放置变音符号时,问题就出现了。

截屏

有没有人有处理此类问题的经验。

答案1

理想情况下,可以使用在运行时通过 ConTeXt 打字稿加载的 OpenType 功能文件来修复此问题。实际上,这还不可能;因为汉斯·哈根告诉我

新的字体加载器不支持 fea 文件(我有一个基本的解析器但它不包含在内因为我仍然不确定它是否应该包括在内.. fea 文件假设稳定的字体等等)

这意味着你必须直接修补字体。我将解释如何使用FontForge

编写补丁

首先,你可能想研究OpenType 特征文件规范OpenType 手册

然后你必须看看山鲁佐德并注意到 lam-alef 连字符是不是通过将单个字形替换为一对字形来实现,但根据上下文、形式和应用的变音符号,用正确的半连字符替换每个字形。

完成所有操作后,您就可以编写补丁功能文件了。好吧,我帮您完成了。下面是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 ;

代码注释得很清楚,所以我就不赘述了。观察:

  • 由于此补丁是在其他表(变音符号、连字)之后应用的,因此我可以直接替换上下文形式;这样会更容易一些。
  • 此字体允许的所有可能的变音符号变化均被考虑在内。
  • 我对首音和中间音 lam 的 sukun 位置进行了不同的调整。但是,我没有针对 lam 上多个向上变音符号的情况进行更正:它们会与 sukun 发生冲突。如果需要,您可以写下更正。
  • 该补丁捆绑在一个名为的功能中saed,您可以打开和关闭它。太棒了!

应用补丁

如果你想使用 FontForge 的 GUI,按钮是

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

我对点击过敏,所以我将字体文件放入功能文件的同一目录中,并运行这个非常不言自明的脚本(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()

使用命令行

fontforge -script saed-patch.pe

测试字体

太棒了!您已修复字体。让我们测试一下常规粗细。

这是一个最简单的打字稿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 

注意我启用了saed我定义的功能!

最小测试文档

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

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

编译为

最丑的 sukun

相关内容