1/*
2 * (C) Copyright IBM Corp. 1998-2013 - All Rights Reserved
3 *
4 */
5
6#include "LETypes.h"
7#include "LEGlyphFilter.h"
8#include "OpenTypeTables.h"
9#include "GlyphSubstitutionTables.h"
10#include "LigatureSubstSubtables.h"
11#include "GlyphIterator.h"
12#include "LESwaps.h"
13
14U_NAMESPACE_BEGIN
15
16le_uint32 LigatureSubstitutionSubtable::process(const LETableReference &base, GlyphIterator *glyphIterator, LEErrorCode &success, const LEGlyphFilter *filter) const
17{
18    LEGlyphID glyph = glyphIterator->getCurrGlyphID();
19    le_int32 coverageIndex = getGlyphCoverage(base, glyph, success);
20
21    if (coverageIndex >= 0) {
22        Offset ligSetTableOffset = SWAPW(ligSetTableOffsetArray[coverageIndex]);
23        const LigatureSetTable *ligSetTable = (const LigatureSetTable *) ((char *) this + ligSetTableOffset);
24        le_uint16 ligCount = SWAPW(ligSetTable->ligatureCount);
25
26        for (le_uint16 lig = 0; lig < ligCount; lig += 1) {
27            Offset ligTableOffset = SWAPW(ligSetTable->ligatureTableOffsetArray[lig]);
28            const LigatureTable *ligTable = (const LigatureTable *) ((char *)ligSetTable + ligTableOffset);
29            le_uint16 compCount = SWAPW(ligTable->compCount) - 1;
30            le_int32 startPosition = glyphIterator->getCurrStreamPosition();
31            TTGlyphID ligGlyph = SWAPW(ligTable->ligGlyph);
32            le_uint16 comp;
33
34            for (comp = 0; comp < compCount; comp += 1) {
35                if (! glyphIterator->next()) {
36                    break;
37                }
38
39                if (LE_GET_GLYPH(glyphIterator->getCurrGlyphID()) != SWAPW(ligTable->componentArray[comp])) {
40                    break;
41                }
42            }
43
44            if (comp == compCount && (filter == NULL || filter->accept(LE_SET_GLYPH(glyph, ligGlyph)))) {
45                GlyphIterator tempIterator(*glyphIterator);
46                TTGlyphID deletedGlyph = tempIterator.ignoresMarks()? 0xFFFE : 0xFFFF;
47
48                while (comp > 0) {
49                    tempIterator.setCurrGlyphID(deletedGlyph);
50                    tempIterator.prev();
51
52                    comp -= 1;
53                }
54
55                tempIterator.setCurrGlyphID(ligGlyph);
56
57                return compCount + 1;
58            }
59
60            glyphIterator->setCurrStreamPosition(startPosition);
61        }
62
63    }
64
65    return 0;
66}
67
68U_NAMESPACE_END
69