@@ -203,6 +203,94 @@ function ligatureSubstitutionFormat1(contextParams, subtable) {
203203 return null ;
204204}
205205
206+ /**
207+ * Handle context substitution - format 1
208+ * @param {ContextParams } contextParams context params to lookup
209+ */
210+ function contextSubstitutionFormat1 ( contextParams , subtable ) {
211+ let glyphId = contextParams . current ;
212+ let ligSetIndex = lookupCoverage ( glyphId , subtable . coverage ) ;
213+ if ( ligSetIndex === - 1 )
214+ return null ;
215+ for ( const ruleSet of subtable . ruleSets ) {
216+ for ( const rule of ruleSet ) {
217+ let matched = true ;
218+ for ( let i = 0 ; i < rule . input . length ; i ++ ) {
219+ if ( contextParams . lookahead [ i ] !== rule . input [ i ] ) {
220+ matched = false ;
221+ break ;
222+ }
223+ }
224+ if ( matched ) {
225+ let substitutions = [ ] ;
226+ substitutions . push ( glyphId ) ;
227+ for ( let i = 0 ; i < rule . input . length ; i ++ ) {
228+ substitutions . push ( rule . input [ i ] ) ;
229+ }
230+ const parser = ( substitutions , lookupRecord ) => {
231+ const { lookupListIndex, sequenceIndex} = lookupRecord ;
232+ const { subtables} = this . getLookupByIndex ( lookupListIndex ) ;
233+ for ( const subtable of subtables ) {
234+ let ligSetIndex = lookupCoverage ( substitutions [ sequenceIndex ] , subtable . coverage ) ;
235+ if ( ligSetIndex !== - 1 ) {
236+ substitutions [ sequenceIndex ] = subtable . deltaGlyphId ;
237+ }
238+ }
239+ } ;
240+
241+ for ( let i = 0 ; i < rule . lookupRecords . length ; i ++ ) {
242+ const lookupRecord = rule . lookupRecords [ i ] ;
243+ parser ( substitutions , lookupRecord ) ;
244+ }
245+
246+ return substitutions ;
247+ }
248+ }
249+ }
250+ return null ;
251+ }
252+
253+ /**
254+ * Handle context substitution - format 3
255+ * @param {ContextParams } contextParams context params to lookup
256+ */
257+ function contextSubstitutionFormat3 ( contextParams , subtable ) {
258+ let substitutions = [ ] ;
259+
260+ for ( let i = 0 ; i < subtable . coverages . length ; i ++ ) {
261+ const lookupRecord = subtable . lookupRecords [ i ] ;
262+ const coverage = subtable . coverages [ i ] ;
263+
264+ let glyphIndex = contextParams . context [ contextParams . index + lookupRecord . sequenceIndex ] ;
265+ let ligSetIndex = lookupCoverage ( glyphIndex , coverage ) ;
266+ if ( ligSetIndex === - 1 ) {
267+ return null ;
268+ }
269+ let lookUp = this . font . tables . gsub . lookups [ lookupRecord . lookupListIndex ] ;
270+ for ( let i = 0 ; i < lookUp . subtables . length ; i ++ ) {
271+ let subtable = lookUp . subtables [ i ] ;
272+ let ligSetIndex = lookupCoverage ( glyphIndex , subtable . coverage ) ;
273+ if ( ligSetIndex === - 1 )
274+ return null ;
275+ switch ( lookUp . lookupType ) {
276+ case 1 :{
277+ let ligature = subtable . substitute [ ligSetIndex ] ;
278+ substitutions . push ( ligature ) ;
279+ break ;
280+ }
281+ case 2 :{
282+ let ligatureSet = subtable . sequences [ ligSetIndex ] ;
283+ substitutions . push ( ligatureSet ) ;
284+ break ;
285+ }
286+ default :
287+ break ;
288+ }
289+ }
290+ }
291+ return substitutions ;
292+ }
293+
206294/**
207295 * Handle decomposition substitution - format 1
208296 * @param {number } glyphIndex glyph index
@@ -327,8 +415,17 @@ FeatureQuery.prototype.getLookupMethod = function(lookupTable, subtable) {
327415 return glyphIndex => decompositionSubstitutionFormat1 . apply (
328416 this , [ glyphIndex , subtable ]
329417 ) ;
418+ case '51' :
419+ return contextParams => contextSubstitutionFormat1 . apply (
420+ this , [ contextParams , subtable ]
421+ ) ;
422+ case '53' :
423+ return contextParams => contextSubstitutionFormat3 . apply (
424+ this , [ contextParams , subtable ]
425+ ) ;
330426 default :
331427 throw new Error (
428+ `substitutionType : ${ substitutionType } ` +
332429 `lookupType: ${ lookupTable . lookupType } - ` +
333430 `substFormat: ${ subtable . substFormat } ` +
334431 'is not yet supported'
@@ -435,6 +532,17 @@ FeatureQuery.prototype.lookupFeature = function (query) {
435532 } ) ) ;
436533 }
437534 break ;
535+ case '51' :
536+ case '53' :
537+ substitution = lookup ( contextParams ) ;
538+ if ( Array . isArray ( substitution ) && substitution . length ) {
539+ substitutions . splice ( currentIndex , 1 , new SubstitutionAction ( {
540+ id : parseInt ( substType ) ,
541+ tag : query . tag ,
542+ substitution
543+ } ) ) ;
544+ }
545+ break ;
438546 }
439547 contextParams = new ContextParams ( substitutions , currentIndex ) ;
440548 if ( Array . isArray ( substitution ) && ! substitution . length ) continue ;
0 commit comments