/// <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);
            }
        }
示例#2
0
            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);
            }
示例#3
0
        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);
        }
示例#5
0
            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);
            }
示例#6
0
        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);
        }