/// <summary>Checks if given glyph line at the given position matches given rule.</summary> /// <returns> /// either index which corresponds to the last glyph of the matching context inside the glyph line if context matches, /// or -1 if context doesn't match. /// </returns> protected internal virtual int CheckIfContextMatch(GlyphLine line, ContextualSubstRule rule) { int j; OpenTableLookup.GlyphIndexer gidx = new OpenTableLookup.GlyphIndexer(); gidx.line = line; gidx.idx = line.idx; //Note, that starting index shall be 1 for (j = 1; j < rule.GetContextLength(); ++j) { gidx.NextGlyph(openReader, lookupFlag); if (gidx.glyph == null || !rule.IsGlyphMatchesInput(gidx.glyph.GetCode(), j)) { break; } } bool isMatch = j == rule.GetContextLength(); if (isMatch) { return(gidx.idx); } else { return(-1); } }
public override bool TransformOne(GlyphLine line) { if (line.idx >= line.end || line.idx < line.start) { return(false); } bool changed = false; Glyph g1 = line.Get(line.idx); IDictionary <int, GposLookupType2.PairValueFormat> m = gposMap.Get(g1.GetCode()); if (m != null) { OpenTableLookup.GlyphIndexer gi = new OpenTableLookup.GlyphIndexer(); gi.line = line; gi.idx = line.idx; gi.NextGlyph(openReader, lookupFlag); if (gi.glyph != null) { GposLookupType2.PairValueFormat pv = m.Get(gi.glyph.GetCode()); if (pv != null) { Glyph g2 = gi.glyph; line.Set(line.idx, new Glyph(g1, 0, 0, pv.first.XAdvance, pv.first.YAdvance, 0)); line.Set(gi.idx, new Glyph(g2, 0, 0, pv.second.XAdvance, pv.second.YAdvance, 0)); line.idx = gi.idx; changed = true; } } } return(changed); }
public virtual void SubstituteManyToOne(OpenTypeFontTableReader tableReader, int lookupFlag, int rightPartLen , int substitutionGlyphIndex) { OpenTableLookup.GlyphIndexer gidx = new OpenTableLookup.GlyphIndexer(); gidx.line = this; gidx.idx = idx; StringBuilder chars = new StringBuilder(); Glyph currentGlyph = glyphs[idx]; if (currentGlyph.GetChars() != null) { chars.Append(currentGlyph.GetChars()); } else { if (currentGlyph.HasValidUnicode()) { chars.Append(iText.IO.Util.TextUtil.ConvertFromUtf32(currentGlyph.GetUnicode())); } } for (int j = 0; j < rightPartLen; ++j) { gidx.NextGlyph(tableReader, lookupFlag); currentGlyph = glyphs[gidx.idx]; if (currentGlyph.GetChars() != null) { chars.Append(currentGlyph.GetChars()); } else { if (currentGlyph.HasValidUnicode()) { chars.Append(iText.IO.Util.TextUtil.ConvertFromUtf32(currentGlyph.GetUnicode())); } } RemoveGlyph(gidx.idx--); } char[] newChars = new char[chars.Length]; chars.GetChars(0, chars.Length, newChars, 0); Glyph newGlyph = tableReader.GetGlyph(substitutionGlyphIndex); newGlyph.SetChars(newChars); glyphs[idx] = newGlyph; end -= rightPartLen; }
public override bool TransformOne(GlyphLine line) { //TODO > if (line.idx >= line.end) { return(false); } bool changed = false; Glyph g = line.Get(line.idx); bool match = false; if (ligatures.ContainsKey(g.GetCode()) && !openReader.IsSkip(g.GetCode(), lookupFlag)) { OpenTableLookup.GlyphIndexer gidx = new OpenTableLookup.GlyphIndexer(); gidx.line = line; IList <int[]> ligs = ligatures.Get(g.GetCode()); foreach (int[] lig in ligs) { match = true; gidx.idx = line.idx; for (int j = 1; j < lig.Length; ++j) { gidx.NextGlyph(openReader, lookupFlag); if (gidx.glyph == null || gidx.glyph.GetCode() != lig[j]) { match = false; break; } } if (match) { line.SubstituteManyToOne(openReader, lookupFlag, lig.Length - 1, lig[0]); break; } } } if (match) { changed = true; } line.idx++; return(changed); }
public override bool TransformOne(GlyphLine line) { if (line.idx >= line.end || line.idx < line.start) { return(false); } Glyph g1 = line.Get(line.idx); if (!coverageSet.Contains(g1.GetCode())) { return(false); } int c1 = classDef1.GetOtfClass(g1.GetCode()); GposLookupType2.PairValueFormat[] pvs = posSubs.Get(c1); if (pvs == null) { return(false); } OpenTableLookup.GlyphIndexer gi = new OpenTableLookup.GlyphIndexer(); gi.line = line; gi.idx = line.idx; gi.NextGlyph(openReader, lookupFlag); if (gi.glyph == null) { return(false); } Glyph g2 = gi.glyph; int c2 = classDef2.GetOtfClass(g2.GetCode()); if (c2 >= pvs.Length) { return(false); } GposLookupType2.PairValueFormat pv = pvs[c2]; line.Set(line.idx, new Glyph(g1, 0, 0, pv.first.XAdvance, pv.first.YAdvance, 0)); line.Set(gi.idx, new Glyph(g2, 0, 0, pv.second.XAdvance, pv.second.YAdvance, 0)); line.idx = gi.idx; return(true); }
public override bool TransformOne(GlyphLine line) { bool changed = false; int oldLineStart = line.start; int oldLineEnd = line.end; int initialLineIndex = line.idx; foreach (ContextualSubTable subTable in subTables) { ContextualSubstRule contextRule = subTable.GetMatchingContextRule(line); if (contextRule == null) { continue; } int lineEndBeforeSubstitutions = line.end; SubstLookupRecord[] substLookupRecords = contextRule.GetSubstLookupRecords(); OpenTableLookup.GlyphIndexer gidx = new OpenTableLookup.GlyphIndexer(); gidx.line = line; foreach (SubstLookupRecord substRecord in substLookupRecords) { // There could be some skipped glyphs inside the context sequence, therefore currently GlyphIndexer and // nextGlyph method are used to get to the glyph at "substRecord.sequenceIndex" index gidx.idx = initialLineIndex; for (int i = 0; i < substRecord.sequenceIndex; ++i) { gidx.NextGlyph(openReader, lookupFlag); } line.idx = gidx.idx; OpenTableLookup lookupTable = openReader.GetLookupTable(substRecord.lookupListIndex); changed = lookupTable.TransformOne(line) || changed; } line.idx = line.end; line.start = oldLineStart; int lenDelta = lineEndBeforeSubstitutions - line.end; line.end = oldLineEnd - lenDelta; return(changed); } ++line.idx; return(changed); }