com.itextpdf.io.font.otf.ChainingContextualTable Maven / Gradle / Ivy
/*
This file is part of the iText (R) project.
Copyright (c) 1998-2022 iText Group NV
Authors: iText Software.
This program is offered under a commercial and under the AGPL license.
For commercial licensing, contact us at https://itextpdf.com/sales. For AGPL licensing, see below.
AGPL licensing:
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see .
*/
package com.itextpdf.io.font.otf;
import java.util.List;
public abstract class ChainingContextualTable extends ContextualTable {
protected ChainingContextualTable(OpenTypeFontTableReader openReader, int lookupFlag) {
super(openReader, lookupFlag);
}
@Override
public T getMatchingContextRule(GlyphLine line) {
if (line.idx >= line.end) {
return null;
}
Glyph g = line.get(line.idx);
List rules = getSetOfRulesForStartGlyph(g.getCode());
for (T rule : rules) {
int lastGlyphIndex = checkIfContextMatch(line, rule);
if (lastGlyphIndex != -1
&& checkIfLookaheadContextMatch(line, rule, lastGlyphIndex)
&& checkIfBacktrackContextMatch(line, rule)) {
line.start = line.idx;
line.end = lastGlyphIndex + 1;
return rule;
}
}
return null;
}
/**
* Checks if given glyph line at the given position matches given rule.
*
* @param line glyph line to be checked
* @param rule rule to be compared with a given line
* @param startIdx glyph line position
* @return true if given glyph line at the given position matches given rule
*/
protected boolean checkIfLookaheadContextMatch(GlyphLine line, T rule, int startIdx) {
OpenTableLookup.GlyphIndexer gidx = new OpenTableLookup.GlyphIndexer();
gidx.line = line;
gidx.idx = startIdx;
for (int j = 0; j < rule.getLookaheadContextLength(); ++j) {
gidx.nextGlyph(openReader, lookupFlag);
if (gidx.glyph == null || !rule.isGlyphMatchesLookahead(gidx.glyph.getCode(), j)) {
return false;
}
}
return true;
}
/**
* Checks if given glyph line at the given position matches given rule.
*
* @param line glyph line to be checked
* @param rule rule to be compared with a given line
* @return true if given glyph line matches given rule
*/
protected boolean checkIfBacktrackContextMatch(GlyphLine line, T rule) {
OpenTableLookup.GlyphIndexer gidx = new OpenTableLookup.GlyphIndexer();
gidx.line = line;
gidx.idx = line.idx;
for (int j = 0; j < rule.getBacktrackContextLength(); ++j) {
gidx.previousGlyph(openReader, lookupFlag);
if (gidx.glyph == null || !rule.isGlyphMatchesBacktrack(gidx.glyph.getCode(), j)) {
return false;
}
}
return true;
}
}