fontbox/src/main/java/org/apache/fontbox/ttf/gsub/GsubWorkerForDevanagari.java [78:146]:
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    @Override
    public List<Integer> applyTransforms(List<Integer> originalGlyphIds)
    {
        List<Integer> intermediateGlyphsFromGsub = adjustRephPosition(originalGlyphIds);
        intermediateGlyphsFromGsub = repositionGlyphs(intermediateGlyphsFromGsub);
        for (String feature : FEATURES_IN_ORDER)
        {
            if (!gsubData.isFeatureSupported(feature))
            {
                if (feature.equals(RKRF_FEATURE) && gsubData.isFeatureSupported(VATU_FEATURE))
                {
                    // Create your own rkrf feature from vatu feature
                    intermediateGlyphsFromGsub = applyRKRFFeature(
                            gsubData.getFeature(VATU_FEATURE),
                            intermediateGlyphsFromGsub);
                }
                LOG.debug("the feature {} was not found", feature);
                continue;
            }

            LOG.debug("applying the feature {}", feature);
            ScriptFeature scriptFeature = gsubData.getFeature(feature);
            intermediateGlyphsFromGsub = applyGsubFeature(scriptFeature,
                    intermediateGlyphsFromGsub);
        }
        return Collections.unmodifiableList(intermediateGlyphsFromGsub);
    }

    private List<Integer> applyRKRFFeature(ScriptFeature rkrfGlyphsForSubstitution,
            List<Integer> originalGlyphIds)
    {
        Set<List<Integer>> rkrfGlyphIds = rkrfGlyphsForSubstitution.getAllGlyphIdsForSubstitution();
        if (rkrfGlyphIds.isEmpty())
        {
            LOG.debug("Glyph substitution list for {} is empty.", rkrfGlyphsForSubstitution.getName());
            return originalGlyphIds;
        }
        // Replace this with better implementation to get second GlyphId from rkrfGlyphIds
        int rkrfReplacement = 0;
        for (List<Integer> firstList : rkrfGlyphIds)
        {
            if (firstList.size() > 1)
            {
                rkrfReplacement = firstList.get(1);
                break;
            }
        }

        if (rkrfReplacement == 0)
        {
            LOG.debug("Cannot find rkrf candidate. The rkrfGlyphIds doesn't contain lists of two elements.");
            return originalGlyphIds;
        }

        List<Integer> rkrfList = new ArrayList<>(originalGlyphIds);
        for (int index = originalGlyphIds.size() - 1; index > 1; index--)
        {
            int raGlyph = originalGlyphIds.get(index);
            if (raGlyph == rephGlyphIds.get(0))
            {
                int viramaGlyph = originalGlyphIds.get(index - 1);
                if (viramaGlyph == rephGlyphIds.get(1))
                {
                    rkrfList.set(index - 1, rkrfReplacement);
                    rkrfList.remove(index);
                }
            }
        }
        return rkrfList;
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -



fontbox/src/main/java/org/apache/fontbox/ttf/gsub/GsubWorkerForGujarati.java [78:145]:
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    @Override
    public List<Integer> applyTransforms(List<Integer> originalGlyphIds)
    {
        List<Integer> intermediateGlyphsFromGsub = adjustRephPosition(originalGlyphIds);
        intermediateGlyphsFromGsub = repositionGlyphs(intermediateGlyphsFromGsub);
        for (String feature : FEATURES_IN_ORDER)
        {
            if (!gsubData.isFeatureSupported(feature))
            {
                if (feature.equals(RKRF_FEATURE) && gsubData.isFeatureSupported(VATU_FEATURE))
                {
                    // Create your own rkrf feature from vatu feature
                    intermediateGlyphsFromGsub = applyRKRFFeature(
                            gsubData.getFeature(VATU_FEATURE),
                            intermediateGlyphsFromGsub);
                }
                LOG.debug("the feature {} was not found", feature);
                continue;
            }
            LOG.debug("applying the feature {}", feature);
            ScriptFeature scriptFeature = gsubData.getFeature(feature);
            intermediateGlyphsFromGsub = applyGsubFeature(scriptFeature,
                    intermediateGlyphsFromGsub);
        }
        return Collections.unmodifiableList(intermediateGlyphsFromGsub);
    }

    private List<Integer> applyRKRFFeature(ScriptFeature rkrfGlyphsForSubstitution,
            List<Integer> originalGlyphIds)
    {
        Set<List<Integer>> rkrfGlyphIds = rkrfGlyphsForSubstitution.getAllGlyphIdsForSubstitution();
        if (rkrfGlyphIds.isEmpty())
        {
            LOG.debug("Glyph substitution list for {} is empty.", rkrfGlyphsForSubstitution.getName());
            return originalGlyphIds;
        }

        // Replace this with better implementation to get second GlyphId from rkrfGlyphIds
        int rkrfReplacement = 0;
        for (List<Integer> firstList : rkrfGlyphIds)
        {
            if (firstList.size() > 1)
            {
                rkrfReplacement = firstList.get(1);
                break;
            }
        }
        if (rkrfReplacement == 0)
        {
            LOG.debug("Cannot find rkrf candidate. The rkrfGlyphIds doesn't contain lists of two elements.");
            return originalGlyphIds;
        }

        List<Integer> rkrfList = new ArrayList<>(originalGlyphIds);
        for (int index = originalGlyphIds.size() - 1; index > 1; index--)
        {
            int raGlyph = originalGlyphIds.get(index);
            if (raGlyph == rephGlyphIds.get(0))
            {
                int viramaGlyph = originalGlyphIds.get(index - 1);
                if (viramaGlyph == rephGlyphIds.get(1))
                {
                    rkrfList.set(index - 1, rkrfReplacement);
                    rkrfList.remove(index);
                }
            }
        }
        return rkrfList;
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -



