Code:
/ Dotnetfx_Win7_3.5.1 / Dotnetfx_Win7_3.5.1 / 3.5.1 / DEVDIV / depot / DevDiv / releases / Orcas / NetFXw7 / wpf / src / Core / CSharp / MS / Internal / Shaping / Substitution.cs / 1 / Substitution.cs
//+------------------------------------------------------------------------ // // Microsoft Windows Client Platform // Copyright (C) Microsoft Corporation, 2002 // // File: Sustitution.cs // // Contents: OpentTypeLayout substitution classes // // contact: sergeym // // History: 2002-03-23 Created (sergeym) // //----------------------------------------------------------------------- using System.Diagnostics; using System.Security; using System.Security.Permissions; using System; using System.IO; namespace MS.Internal.Shaping { // [SecurityCritical(SecurityCriticalScope.Everything)] internal struct SingleSubstitutionSubtable { private const int offsetFormat = 0; private const int offsetCoverage = 2; private const int offsetFormat1DeltaGlyphId = 4; private const int offsetFormat2GlyphCount = 4; private const int offsetFormat2SubstitutehArray = 6; private const int sizeFormat2SubstituteSize = 2; private ushort Format(FontTable Table) { return Table.GetUShort(offset + offsetFormat); } private CoverageTable Coverage(FontTable Table) { return new CoverageTable(offset+Table.GetUShort(offset + offsetCoverage)); } private short Format1DeltaGlyphId(FontTable Table) { Invariant.Assert(Format(Table)==1); return Table.GetShort(offset + offsetFormat1DeltaGlyphId); } // Not used. This value should be equal to glyph count in Coverage. // Keeping it for future reference //private ushort Foramt2GlyphCount(FontTable Table) //{ // Debug.Assert(Format(Table)==2); // return Table.GetUShort(offset + offsetFormat2GlyphCount); //} private ushort Format2SubstituteGlyphId(FontTable Table,ushort Index) { Invariant.Assert(Format(Table)==2); return Table.GetUShort(offset + offsetFormat2SubstitutehArray + Index * sizeFormat2SubstituteSize); } public bool Apply( FontTable Table, GlyphInfoList GlyphInfo, // List of GlyphInfo structs int FirstGlyph, // where to apply it out int NextGlyph // Next glyph to process ) { Invariant.Assert(FirstGlyph >= 0); NextGlyph = FirstGlyph + 1; //In case we don't match; ushort GlyphId = GlyphInfo.Glyphs[FirstGlyph]; int CoverageIndex = Coverage(Table).GetGlyphIndex(Table,GlyphId); if (CoverageIndex == -1) return false; switch(Format(Table)) { case 1: GlyphInfo.Glyphs[FirstGlyph] = (ushort)(GlyphId + Format1DeltaGlyphId(Table)); GlyphInfo.GlyphFlags[FirstGlyph] = (ushort)(GlyphFlags.Unresolved | GlyphFlags.Substituted); NextGlyph = FirstGlyph + 1; return true; case 2: GlyphInfo.Glyphs[FirstGlyph] = Format2SubstituteGlyphId(Table,(ushort)CoverageIndex); GlyphInfo.GlyphFlags[FirstGlyph] = (ushort)(GlyphFlags.Unresolved | GlyphFlags.Substituted); NextGlyph = FirstGlyph + 1; return true; default: NextGlyph = FirstGlyph+1; return false; } } public bool IsLookupCovered( FontTable table, uint[] glyphBits, ushort minGlyphId, ushort maxGlyphId) { return Coverage(table).IsAnyGlyphCovered(table, glyphBits, minGlyphId, maxGlyphId ); } public CoverageTable GetPrimaryCoverage(FontTable table) { return Coverage(table); } public SingleSubstitutionSubtable(int Offset) { offset = Offset; } private int offset; } ////// Critical - Everything in this struct is considered critical /// because they either operate on raw font table bits or unsafe pointers. /// [SecurityCritical(SecurityCriticalScope.Everything)] internal struct LigatureSubstitutionSubtable { private const int offsetFormat = 0; private const int offsetCoverage = 2; private const int offsetLigatureSetCount = 4; private const int offsetLigatureSetArray = 6; private const int sizeLigatureSet = 2; private ushort Format(FontTable Table) { return Table.GetUShort(offset + offsetFormat); } private CoverageTable Coverage(FontTable Table) { return new CoverageTable(offset + Table.GetUShort(offset + offsetCoverage)); } private ushort LigatureSetCount(FontTable Table) { return Table.GetUShort(offset + offsetLigatureSetCount); } private LigatureSetTable LigatureSet(FontTable Table, ushort Index) { return new LigatureSetTable(offset+Table.GetUShort(offset+ offsetLigatureSetArray + Index * sizeLigatureSet)); } #region Ligature Substitution subtable private structures ////// Critical - Everything in this struct is considered critical /// because they either operate on raw font table bits or unsafe pointers. /// [SecurityCritical(SecurityCriticalScope.Everything)] private struct LigatureSetTable { private const int offsetLigatureCount = 0; private const int offsetLigatureArray = 2; private const int sizeLigatureOffset = 2; public ushort LigatureCount(FontTable Table) { return Table.GetUShort(offset + offsetLigatureCount); } public LigatureTable Ligature(FontTable Table, ushort Index) { return new LigatureTable(offset + Table.GetUShort(offset + offsetLigatureArray + Index * sizeLigatureOffset)); } public LigatureSetTable(int Offset) { offset = Offset; } private int offset; } ////// Critical - Everything in this struct is considered critical /// because they either operate on raw font table bits or unsafe pointers. /// [SecurityCritical(SecurityCriticalScope.Everything)] private struct LigatureTable { private const int offsetLigatureGlyph = 0; private const int offsetComponentCount = 2; private const int offsetComponentArray = 4; private const int sizeComponent = 2; public ushort LigatureGlyph(FontTable Table) { return Table.GetUShort(offset + offsetLigatureGlyph); } public ushort ComponentCount(FontTable Table) { return Table.GetUShort(offset + offsetComponentCount); } public ushort Component(FontTable Table, ushort Index) { //LigaTable includes comps from 1 to N. So, (Index-1) return Table.GetUShort(offset + offsetComponentArray + (Index-1) * sizeComponent); } public LigatureTable(int Offset) { offset = Offset; } private int offset; } #endregion public unsafe bool Apply( IOpenTypeFont Font, FontTable Table, int CharCount, UshortList Charmap, // Character to glyph map GlyphInfoList GlyphInfo, // List of GlyphInfo ushort LookupFlags, // Lookup flags for glyph lookups int FirstGlyph, // where to apply it int AfterLastGlyph, // how long is a context we can use out int NextGlyph // Next glyph to process ) { Invariant.Assert(FirstGlyph>=0); Invariant.Assert(AfterLastGlyph<=GlyphInfo.Length); NextGlyph = FirstGlyph + 1; //In case we don't match; if (Format(Table) != 1) return false; // Unknown format int glyphCount=GlyphInfo.Length; ushort glyphId = GlyphInfo.Glyphs[FirstGlyph]; int CoverageIndex = Coverage(Table).GetGlyphIndex(Table,glyphId); if (CoverageIndex==-1) return false; int curGlyph; ushort ligatureGlyph=0; bool match = false; ushort compCount=0; LigatureSetTable ligatureSet = LigatureSet(Table,(ushort)CoverageIndex); ushort ligaCount = ligatureSet.LigatureCount(Table); for(ushort liga=0; liga=AfterLastGlyph) break; if (GlyphInfo.Glyphs[curGlyph]!=ligature.Component(Table,comp)) break; } if (comp==compCount) //liga matched { match=true; ligatureGlyph = ligature.LigatureGlyph(Table); break; //Liga found } } //If no ligature found, match will remain false after last iteration if (match) { //Fix character and glyph Mapping //PERF: localize ligature character range //Calculate Ligature CharCount int totalLigaCharCount=0; int firstLigaChar=int.MaxValue; curGlyph=FirstGlyph; for(ushort comp=0;comp 0) { for(int glyph=prevGlyph+1; glyph 1) //do fixing only if have glyphs in between { for(int curChar=0; curChar prevGlyph && curCharmap 1) { GlyphInfo.Remove(GlyphInfo.Length-compCount+1,compCount-1); } NextGlyph=prevGlyph-(compCount-1)+1; } return match; } public bool IsLookupCovered( FontTable table, uint[] glyphBits, ushort minGlyphId, ushort maxGlyphId) { if (!Coverage(table).IsAnyGlyphCovered(table, glyphBits, minGlyphId, maxGlyphId ) ) return false; ushort ligatureSetCount = LigatureSetCount(table); for(ushort setIndex = 0; setIndex < ligatureSetCount; setIndex++) { LigatureSetTable ligatureSet = LigatureSet(table, setIndex); ushort ligaCount = ligatureSet.LigatureCount(table); for (ushort liga = 0; liga < ligaCount; liga++) { LigatureTable ligature = ligatureSet.Ligature(table, liga); ushort compCount = ligature.ComponentCount(table); bool ligatureIsComplex = true; for(ushort compIndex = 1; compIndex < compCount; compIndex++) { ushort glyphId = ligature.Component(table,compIndex); if (glyphId > maxGlyphId || glyphId < minGlyphId || (glyphBits[glyphId >> 5] & (1 << (glyphId % 32))) == 0 ) { ligatureIsComplex = false; break; } } if (ligatureIsComplex) return true; } } return false; } public CoverageTable GetPrimaryCoverage(FontTable table) { return Coverage(table); } public LigatureSubstitutionSubtable(int Offset) { offset = Offset; } private int offset; } /// /// Critical - Everything in this struct is considered critical /// because they either operate on raw font table bits or unsafe pointers. /// [SecurityCritical(SecurityCriticalScope.Everything)] internal struct MultipleSubstitutionSequenceTable { private const int offsetGlyphCount = 0; private const int offsetGlyphArray = 2; private const int sizeGlyphId = 2; public ushort GlyphCount(FontTable Table) { return Table.GetUShort(offset + offsetGlyphCount); } public ushort Glyph(FontTable Table, ushort index) { return Table.GetUShort(offset + offsetGlyphArray + index * sizeGlyphId); } public MultipleSubstitutionSequenceTable(int Offset) { offset = Offset; } private int offset; } ////// Critical - Everything in this struct is considered critical /// because they either operate on raw font table bits or unsafe pointers. /// [SecurityCritical(SecurityCriticalScope.Everything)] internal struct MultipleSubstitutionSubtable { private const int offsetFormat = 0; private const int offsetCoverage = 2; private const int offsetSequenceCount = 4; private const int offsetSequenceArray = 6; private const int sizeSequenceOffset = 2; private ushort Format(FontTable Table) { return Table.GetUShort(offset + offsetFormat); } private CoverageTable Coverage(FontTable Table) { return new CoverageTable(offset + Table.GetUShort(offset + offsetCoverage)); } // Not used. This value should be equal to glyph count in Coverage. // Keeping it for future reference //private ushort SequenceCount(FontTable Table) //{ // return Table.GetUShort(offset + offsetSequenceCount); //} private MultipleSubstitutionSequenceTable Sequence(FontTable Table, int Index) { return new MultipleSubstitutionSequenceTable( offset + Table.GetUShort(offset + offsetSequenceArray + Index * sizeSequenceOffset) ); } public unsafe bool Apply( IOpenTypeFont Font, FontTable Table, int CharCount, UshortList Charmap, // Character to glyph map GlyphInfoList GlyphInfo, // List of GlyphInfo ushort LookupFlags, // Lookup flags for glyph lookups int FirstGlyph, // where to apply it int AfterLastGlyph, // how long is a context we can use out int NextGlyph // Next glyph to process ) { NextGlyph = FirstGlyph + 1; // in case we don't match if (Format(Table) != 1) return false; //unknown format int oldGlyphCount=GlyphInfo.Length; ushort glyphId = GlyphInfo.Glyphs[FirstGlyph]; int coverageIndex = Coverage(Table).GetGlyphIndex(Table,glyphId); if (coverageIndex==-1) return false; MultipleSubstitutionSequenceTable sequence = Sequence(Table,coverageIndex); ushort sequenceLength = sequence.GlyphCount(Table); int lengthDelta = sequenceLength - 1; if (sequenceLength==0) { // This is illegal, because mapping will be broken - // corresponding char will be lost. Just leave it as it is. // (char will be attached to the following glyph). GlyphInfo.Remove(FirstGlyph,1); } else { ushort firstChar = GlyphInfo.FirstChars[FirstGlyph]; ushort ligatureCount = GlyphInfo.LigatureCounts[FirstGlyph]; if (lengthDelta > 0) { GlyphInfo.Insert(FirstGlyph,lengthDelta); } //put glyphs in place for(ushort gl=0; glbase and marks decomposition // for(int ch=0;ch FirstGlyph) Charmap[ch] = (ushort)(Charmap[ch]+lengthDelta); } NextGlyph = FirstGlyph + lengthDelta + 1; return true; } public bool IsLookupCovered( FontTable table, uint[] glyphBits, ushort minGlyphId, ushort maxGlyphId) { return Coverage(table).IsAnyGlyphCovered(table, glyphBits, minGlyphId, maxGlyphId ); } public CoverageTable GetPrimaryCoverage(FontTable table) { return Coverage(table); } public MultipleSubstitutionSubtable(int Offset) { offset = Offset; } private int offset; } /// /// Critical - Everything in this struct is considered critical /// because they either operate on raw font table bits or unsafe pointers. /// [SecurityCritical(SecurityCriticalScope.Everything)] struct AlternateSubstitutionSubtable { private const int offsetFormat = 0; private const int offsetCoverage = 2; private const int offsetAlternateSetCount = 4; private const int offsetAlternateSets = 6; private const int sizeAlternateSetOffset = 2; private const ushort InvalidAlternateGlyph = 0xFFFF; public ushort Format(FontTable Table) { return Table.GetUShort(offset + offsetFormat); } private CoverageTable Coverage(FontTable Table) { return new CoverageTable(offset + Table.GetUShort(offset + offsetCoverage)); } // Not used. This value should be equal to glyph count in Coverage. // Keeping it for future reference //private ushort AlternateSetCount(FontTable Table) //{ // return Table.GetUShort(offset + offsetAlternateSetCount); //} private AlternateSetTable AlternateSet(FontTable Table, int index) { return new AlternateSetTable(offset + Table.GetUShort(offset + offsetAlternateSets + index * sizeAlternateSetOffset) ); } ////// Critical - Everything in this struct is considered critical /// because they either operate on raw font table bits or unsafe pointers. /// [SecurityCritical(SecurityCriticalScope.Everything)] private struct AlternateSetTable { private const int offsetGlyphCount = 0; private const int offsetGlyphs = 2; private const int sizeGlyph = 2; public ushort GlyphCount(FontTable Table) { return Table.GetUShort(offset + offsetGlyphCount); } public ushort Alternate(FontTable Table, uint FeatureParam) { Invariant.Assert(FeatureParam > 0); // Parameter 0 means feautre is disabled. //Should be filtered out in GetNextEnabledGlyphRange // Off by one - alternate number 1 is stored under index 0 uint index = FeatureParam - 1; if (index >= GlyphCount(Table)) { return AlternateSubstitutionSubtable.InvalidAlternateGlyph; } return Table.GetUShort(offset + offsetGlyphs + (ushort)index*sizeGlyph); } public AlternateSetTable(int Offset) { offset = Offset; } private int offset; } public unsafe bool Apply( FontTable Table, GlyphInfoList GlyphInfo, // List of GlyphInfo uint FeatureParam, // For this lookup - index of glyph alternate int FirstGlyph, // where to apply it out int NextGlyph // Next glyph to process ) { NextGlyph = FirstGlyph + 1; // always move one glyph forward, // doesn't matter whether we matched context if (Format(Table) != 1) return false; //Unknown format int oldGlyphCount=GlyphInfo.Length; int coverageIndex = Coverage(Table). GetGlyphIndex(Table,GlyphInfo.Glyphs[FirstGlyph]); if (coverageIndex==-1) return false; AlternateSetTable alternateSet = AlternateSet(Table,coverageIndex); ushort alternateGlyph = alternateSet.Alternate(Table, FeatureParam); if (alternateGlyph != InvalidAlternateGlyph) { GlyphInfo.Glyphs[FirstGlyph] = alternateGlyph; GlyphInfo.GlyphFlags[FirstGlyph] = (ushort)(GlyphFlags.Unresolved | GlyphFlags.Substituted); return true; } return false; } public bool IsLookupCovered( FontTable table, uint[] glyphBits, ushort minGlyphId, ushort maxGlyphId) { return Coverage(table).IsAnyGlyphCovered(table, glyphBits, minGlyphId, maxGlyphId ); } public CoverageTable GetPrimaryCoverage(FontTable table) { return Coverage(table); } public AlternateSubstitutionSubtable(int Offset) { offset = Offset; } private int offset; } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. // Copyright (c) Microsoft Corporation. All rights reserved. //+------------------------------------------------------------------------ // // Microsoft Windows Client Platform // Copyright (C) Microsoft Corporation, 2002 // // File: Sustitution.cs // // Contents: OpentTypeLayout substitution classes // // contact: sergeym // // History: 2002-03-23 Created (sergeym) // //----------------------------------------------------------------------- using System.Diagnostics; using System.Security; using System.Security.Permissions; using System; using System.IO; namespace MS.Internal.Shaping { // [SecurityCritical(SecurityCriticalScope.Everything)] internal struct SingleSubstitutionSubtable { private const int offsetFormat = 0; private const int offsetCoverage = 2; private const int offsetFormat1DeltaGlyphId = 4; private const int offsetFormat2GlyphCount = 4; private const int offsetFormat2SubstitutehArray = 6; private const int sizeFormat2SubstituteSize = 2; private ushort Format(FontTable Table) { return Table.GetUShort(offset + offsetFormat); } private CoverageTable Coverage(FontTable Table) { return new CoverageTable(offset+Table.GetUShort(offset + offsetCoverage)); } private short Format1DeltaGlyphId(FontTable Table) { Invariant.Assert(Format(Table)==1); return Table.GetShort(offset + offsetFormat1DeltaGlyphId); } // Not used. This value should be equal to glyph count in Coverage. // Keeping it for future reference //private ushort Foramt2GlyphCount(FontTable Table) //{ // Debug.Assert(Format(Table)==2); // return Table.GetUShort(offset + offsetFormat2GlyphCount); //} private ushort Format2SubstituteGlyphId(FontTable Table,ushort Index) { Invariant.Assert(Format(Table)==2); return Table.GetUShort(offset + offsetFormat2SubstitutehArray + Index * sizeFormat2SubstituteSize); } public bool Apply( FontTable Table, GlyphInfoList GlyphInfo, // List of GlyphInfo structs int FirstGlyph, // where to apply it out int NextGlyph // Next glyph to process ) { Invariant.Assert(FirstGlyph >= 0); NextGlyph = FirstGlyph + 1; //In case we don't match; ushort GlyphId = GlyphInfo.Glyphs[FirstGlyph]; int CoverageIndex = Coverage(Table).GetGlyphIndex(Table,GlyphId); if (CoverageIndex == -1) return false; switch(Format(Table)) { case 1: GlyphInfo.Glyphs[FirstGlyph] = (ushort)(GlyphId + Format1DeltaGlyphId(Table)); GlyphInfo.GlyphFlags[FirstGlyph] = (ushort)(GlyphFlags.Unresolved | GlyphFlags.Substituted); NextGlyph = FirstGlyph + 1; return true; case 2: GlyphInfo.Glyphs[FirstGlyph] = Format2SubstituteGlyphId(Table,(ushort)CoverageIndex); GlyphInfo.GlyphFlags[FirstGlyph] = (ushort)(GlyphFlags.Unresolved | GlyphFlags.Substituted); NextGlyph = FirstGlyph + 1; return true; default: NextGlyph = FirstGlyph+1; return false; } } public bool IsLookupCovered( FontTable table, uint[] glyphBits, ushort minGlyphId, ushort maxGlyphId) { return Coverage(table).IsAnyGlyphCovered(table, glyphBits, minGlyphId, maxGlyphId ); } public CoverageTable GetPrimaryCoverage(FontTable table) { return Coverage(table); } public SingleSubstitutionSubtable(int Offset) { offset = Offset; } private int offset; } ////// Critical - Everything in this struct is considered critical /// because they either operate on raw font table bits or unsafe pointers. /// [SecurityCritical(SecurityCriticalScope.Everything)] internal struct LigatureSubstitutionSubtable { private const int offsetFormat = 0; private const int offsetCoverage = 2; private const int offsetLigatureSetCount = 4; private const int offsetLigatureSetArray = 6; private const int sizeLigatureSet = 2; private ushort Format(FontTable Table) { return Table.GetUShort(offset + offsetFormat); } private CoverageTable Coverage(FontTable Table) { return new CoverageTable(offset + Table.GetUShort(offset + offsetCoverage)); } private ushort LigatureSetCount(FontTable Table) { return Table.GetUShort(offset + offsetLigatureSetCount); } private LigatureSetTable LigatureSet(FontTable Table, ushort Index) { return new LigatureSetTable(offset+Table.GetUShort(offset+ offsetLigatureSetArray + Index * sizeLigatureSet)); } #region Ligature Substitution subtable private structures ////// Critical - Everything in this struct is considered critical /// because they either operate on raw font table bits or unsafe pointers. /// [SecurityCritical(SecurityCriticalScope.Everything)] private struct LigatureSetTable { private const int offsetLigatureCount = 0; private const int offsetLigatureArray = 2; private const int sizeLigatureOffset = 2; public ushort LigatureCount(FontTable Table) { return Table.GetUShort(offset + offsetLigatureCount); } public LigatureTable Ligature(FontTable Table, ushort Index) { return new LigatureTable(offset + Table.GetUShort(offset + offsetLigatureArray + Index * sizeLigatureOffset)); } public LigatureSetTable(int Offset) { offset = Offset; } private int offset; } ////// Critical - Everything in this struct is considered critical /// because they either operate on raw font table bits or unsafe pointers. /// [SecurityCritical(SecurityCriticalScope.Everything)] private struct LigatureTable { private const int offsetLigatureGlyph = 0; private const int offsetComponentCount = 2; private const int offsetComponentArray = 4; private const int sizeComponent = 2; public ushort LigatureGlyph(FontTable Table) { return Table.GetUShort(offset + offsetLigatureGlyph); } public ushort ComponentCount(FontTable Table) { return Table.GetUShort(offset + offsetComponentCount); } public ushort Component(FontTable Table, ushort Index) { //LigaTable includes comps from 1 to N. So, (Index-1) return Table.GetUShort(offset + offsetComponentArray + (Index-1) * sizeComponent); } public LigatureTable(int Offset) { offset = Offset; } private int offset; } #endregion public unsafe bool Apply( IOpenTypeFont Font, FontTable Table, int CharCount, UshortList Charmap, // Character to glyph map GlyphInfoList GlyphInfo, // List of GlyphInfo ushort LookupFlags, // Lookup flags for glyph lookups int FirstGlyph, // where to apply it int AfterLastGlyph, // how long is a context we can use out int NextGlyph // Next glyph to process ) { Invariant.Assert(FirstGlyph>=0); Invariant.Assert(AfterLastGlyph<=GlyphInfo.Length); NextGlyph = FirstGlyph + 1; //In case we don't match; if (Format(Table) != 1) return false; // Unknown format int glyphCount=GlyphInfo.Length; ushort glyphId = GlyphInfo.Glyphs[FirstGlyph]; int CoverageIndex = Coverage(Table).GetGlyphIndex(Table,glyphId); if (CoverageIndex==-1) return false; int curGlyph; ushort ligatureGlyph=0; bool match = false; ushort compCount=0; LigatureSetTable ligatureSet = LigatureSet(Table,(ushort)CoverageIndex); ushort ligaCount = ligatureSet.LigatureCount(Table); for(ushort liga=0; liga=AfterLastGlyph) break; if (GlyphInfo.Glyphs[curGlyph]!=ligature.Component(Table,comp)) break; } if (comp==compCount) //liga matched { match=true; ligatureGlyph = ligature.LigatureGlyph(Table); break; //Liga found } } //If no ligature found, match will remain false after last iteration if (match) { //Fix character and glyph Mapping //PERF: localize ligature character range //Calculate Ligature CharCount int totalLigaCharCount=0; int firstLigaChar=int.MaxValue; curGlyph=FirstGlyph; for(ushort comp=0;comp 0) { for(int glyph=prevGlyph+1; glyph 1) //do fixing only if have glyphs in between { for(int curChar=0; curChar prevGlyph && curCharmap 1) { GlyphInfo.Remove(GlyphInfo.Length-compCount+1,compCount-1); } NextGlyph=prevGlyph-(compCount-1)+1; } return match; } public bool IsLookupCovered( FontTable table, uint[] glyphBits, ushort minGlyphId, ushort maxGlyphId) { if (!Coverage(table).IsAnyGlyphCovered(table, glyphBits, minGlyphId, maxGlyphId ) ) return false; ushort ligatureSetCount = LigatureSetCount(table); for(ushort setIndex = 0; setIndex < ligatureSetCount; setIndex++) { LigatureSetTable ligatureSet = LigatureSet(table, setIndex); ushort ligaCount = ligatureSet.LigatureCount(table); for (ushort liga = 0; liga < ligaCount; liga++) { LigatureTable ligature = ligatureSet.Ligature(table, liga); ushort compCount = ligature.ComponentCount(table); bool ligatureIsComplex = true; for(ushort compIndex = 1; compIndex < compCount; compIndex++) { ushort glyphId = ligature.Component(table,compIndex); if (glyphId > maxGlyphId || glyphId < minGlyphId || (glyphBits[glyphId >> 5] & (1 << (glyphId % 32))) == 0 ) { ligatureIsComplex = false; break; } } if (ligatureIsComplex) return true; } } return false; } public CoverageTable GetPrimaryCoverage(FontTable table) { return Coverage(table); } public LigatureSubstitutionSubtable(int Offset) { offset = Offset; } private int offset; } /// /// Critical - Everything in this struct is considered critical /// because they either operate on raw font table bits or unsafe pointers. /// [SecurityCritical(SecurityCriticalScope.Everything)] internal struct MultipleSubstitutionSequenceTable { private const int offsetGlyphCount = 0; private const int offsetGlyphArray = 2; private const int sizeGlyphId = 2; public ushort GlyphCount(FontTable Table) { return Table.GetUShort(offset + offsetGlyphCount); } public ushort Glyph(FontTable Table, ushort index) { return Table.GetUShort(offset + offsetGlyphArray + index * sizeGlyphId); } public MultipleSubstitutionSequenceTable(int Offset) { offset = Offset; } private int offset; } ////// Critical - Everything in this struct is considered critical /// because they either operate on raw font table bits or unsafe pointers. /// [SecurityCritical(SecurityCriticalScope.Everything)] internal struct MultipleSubstitutionSubtable { private const int offsetFormat = 0; private const int offsetCoverage = 2; private const int offsetSequenceCount = 4; private const int offsetSequenceArray = 6; private const int sizeSequenceOffset = 2; private ushort Format(FontTable Table) { return Table.GetUShort(offset + offsetFormat); } private CoverageTable Coverage(FontTable Table) { return new CoverageTable(offset + Table.GetUShort(offset + offsetCoverage)); } // Not used. This value should be equal to glyph count in Coverage. // Keeping it for future reference //private ushort SequenceCount(FontTable Table) //{ // return Table.GetUShort(offset + offsetSequenceCount); //} private MultipleSubstitutionSequenceTable Sequence(FontTable Table, int Index) { return new MultipleSubstitutionSequenceTable( offset + Table.GetUShort(offset + offsetSequenceArray + Index * sizeSequenceOffset) ); } public unsafe bool Apply( IOpenTypeFont Font, FontTable Table, int CharCount, UshortList Charmap, // Character to glyph map GlyphInfoList GlyphInfo, // List of GlyphInfo ushort LookupFlags, // Lookup flags for glyph lookups int FirstGlyph, // where to apply it int AfterLastGlyph, // how long is a context we can use out int NextGlyph // Next glyph to process ) { NextGlyph = FirstGlyph + 1; // in case we don't match if (Format(Table) != 1) return false; //unknown format int oldGlyphCount=GlyphInfo.Length; ushort glyphId = GlyphInfo.Glyphs[FirstGlyph]; int coverageIndex = Coverage(Table).GetGlyphIndex(Table,glyphId); if (coverageIndex==-1) return false; MultipleSubstitutionSequenceTable sequence = Sequence(Table,coverageIndex); ushort sequenceLength = sequence.GlyphCount(Table); int lengthDelta = sequenceLength - 1; if (sequenceLength==0) { // This is illegal, because mapping will be broken - // corresponding char will be lost. Just leave it as it is. // (char will be attached to the following glyph). GlyphInfo.Remove(FirstGlyph,1); } else { ushort firstChar = GlyphInfo.FirstChars[FirstGlyph]; ushort ligatureCount = GlyphInfo.LigatureCounts[FirstGlyph]; if (lengthDelta > 0) { GlyphInfo.Insert(FirstGlyph,lengthDelta); } //put glyphs in place for(ushort gl=0; glbase and marks decomposition // for(int ch=0;ch FirstGlyph) Charmap[ch] = (ushort)(Charmap[ch]+lengthDelta); } NextGlyph = FirstGlyph + lengthDelta + 1; return true; } public bool IsLookupCovered( FontTable table, uint[] glyphBits, ushort minGlyphId, ushort maxGlyphId) { return Coverage(table).IsAnyGlyphCovered(table, glyphBits, minGlyphId, maxGlyphId ); } public CoverageTable GetPrimaryCoverage(FontTable table) { return Coverage(table); } public MultipleSubstitutionSubtable(int Offset) { offset = Offset; } private int offset; } /// /// Critical - Everything in this struct is considered critical /// because they either operate on raw font table bits or unsafe pointers. /// [SecurityCritical(SecurityCriticalScope.Everything)] struct AlternateSubstitutionSubtable { private const int offsetFormat = 0; private const int offsetCoverage = 2; private const int offsetAlternateSetCount = 4; private const int offsetAlternateSets = 6; private const int sizeAlternateSetOffset = 2; private const ushort InvalidAlternateGlyph = 0xFFFF; public ushort Format(FontTable Table) { return Table.GetUShort(offset + offsetFormat); } private CoverageTable Coverage(FontTable Table) { return new CoverageTable(offset + Table.GetUShort(offset + offsetCoverage)); } // Not used. This value should be equal to glyph count in Coverage. // Keeping it for future reference //private ushort AlternateSetCount(FontTable Table) //{ // return Table.GetUShort(offset + offsetAlternateSetCount); //} private AlternateSetTable AlternateSet(FontTable Table, int index) { return new AlternateSetTable(offset + Table.GetUShort(offset + offsetAlternateSets + index * sizeAlternateSetOffset) ); } ////// Critical - Everything in this struct is considered critical /// because they either operate on raw font table bits or unsafe pointers. /// [SecurityCritical(SecurityCriticalScope.Everything)] private struct AlternateSetTable { private const int offsetGlyphCount = 0; private const int offsetGlyphs = 2; private const int sizeGlyph = 2; public ushort GlyphCount(FontTable Table) { return Table.GetUShort(offset + offsetGlyphCount); } public ushort Alternate(FontTable Table, uint FeatureParam) { Invariant.Assert(FeatureParam > 0); // Parameter 0 means feautre is disabled. //Should be filtered out in GetNextEnabledGlyphRange // Off by one - alternate number 1 is stored under index 0 uint index = FeatureParam - 1; if (index >= GlyphCount(Table)) { return AlternateSubstitutionSubtable.InvalidAlternateGlyph; } return Table.GetUShort(offset + offsetGlyphs + (ushort)index*sizeGlyph); } public AlternateSetTable(int Offset) { offset = Offset; } private int offset; } public unsafe bool Apply( FontTable Table, GlyphInfoList GlyphInfo, // List of GlyphInfo uint FeatureParam, // For this lookup - index of glyph alternate int FirstGlyph, // where to apply it out int NextGlyph // Next glyph to process ) { NextGlyph = FirstGlyph + 1; // always move one glyph forward, // doesn't matter whether we matched context if (Format(Table) != 1) return false; //Unknown format int oldGlyphCount=GlyphInfo.Length; int coverageIndex = Coverage(Table). GetGlyphIndex(Table,GlyphInfo.Glyphs[FirstGlyph]); if (coverageIndex==-1) return false; AlternateSetTable alternateSet = AlternateSet(Table,coverageIndex); ushort alternateGlyph = alternateSet.Alternate(Table, FeatureParam); if (alternateGlyph != InvalidAlternateGlyph) { GlyphInfo.Glyphs[FirstGlyph] = alternateGlyph; GlyphInfo.GlyphFlags[FirstGlyph] = (ushort)(GlyphFlags.Unresolved | GlyphFlags.Substituted); return true; } return false; } public bool IsLookupCovered( FontTable table, uint[] glyphBits, ushort minGlyphId, ushort maxGlyphId) { return Coverage(table).IsAnyGlyphCovered(table, glyphBits, minGlyphId, maxGlyphId ); } public CoverageTable GetPrimaryCoverage(FontTable table) { return Coverage(table); } public AlternateSubstitutionSubtable(int Offset) { offset = Offset; } private int offset; } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. // Copyright (c) Microsoft Corporation. All rights reserved.
Link Menu

This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- RoleGroupCollection.cs
- SEHException.cs
- AncillaryOps.cs
- MachineKeySection.cs
- documentsequencetextview.cs
- EntityTransaction.cs
- UserControl.cs
- CapiSafeHandles.cs
- TabletCollection.cs
- WebPart.cs
- XmlAnyAttributeAttribute.cs
- Scheduling.cs
- LogicalTreeHelper.cs
- SafeBitVector32.cs
- EdmItemError.cs
- SourceElementsCollection.cs
- GreenMethods.cs
- IPEndPointCollection.cs
- RuntimeHelpers.cs
- QilBinary.cs
- ErrorTolerantObjectWriter.cs
- TemplateLookupAction.cs
- Effect.cs
- BinaryHeap.cs
- RadioButton.cs
- XmlIterators.cs
- Image.cs
- diagnosticsswitches.cs
- Latin1Encoding.cs
- XPathMessageFilterElementCollection.cs
- ObjectConverter.cs
- SubtreeProcessor.cs
- Error.cs
- PartialArray.cs
- CultureInfo.cs
- SafeTimerHandle.cs
- WindowsPen.cs
- SerializationException.cs
- ReferenceSchema.cs
- Debugger.cs
- WhitespaceRuleReader.cs
- NativeBuffer.cs
- GetRecipientListRequest.cs
- DecimalAnimationBase.cs
- WebPartConnectionsEventArgs.cs
- AlternationConverter.cs
- PenLineCapValidation.cs
- CompilerLocalReference.cs
- TextSpanModifier.cs
- _FixedSizeReader.cs
- HttpWebResponse.cs
- SHA1.cs
- XmlComment.cs
- EditModeSwitchButton.cs
- SchemaNotation.cs
- UdpConstants.cs
- ExtensionSurface.cs
- ChangeDirector.cs
- Profiler.cs
- DateTimeUtil.cs
- DataRecordObjectView.cs
- WebPartManagerInternals.cs
- RegistryExceptionHelper.cs
- ReflectionUtil.cs
- AssociationType.cs
- Container.cs
- FutureFactory.cs
- ExpressionTable.cs
- TextChange.cs
- LicenseException.cs
- CssClassPropertyAttribute.cs
- ConnectionInterfaceCollection.cs
- SettingsPropertyCollection.cs
- CriticalHandle.cs
- DoubleLink.cs
- ToolboxDataAttribute.cs
- XmlSchemaInclude.cs
- SamlSecurityTokenAuthenticator.cs
- UpdatePanelTriggerCollection.cs
- AggregateNode.cs
- MemoryFailPoint.cs
- DispatcherHooks.cs
- CodeIterationStatement.cs
- ProvidersHelper.cs
- EnumValAlphaComparer.cs
- unsafenativemethodsother.cs
- ToolStripOverflowButton.cs
- QilXmlWriter.cs
- FacetDescriptionElement.cs
- EventHandlersStore.cs
- TextEffect.cs
- LicenseContext.cs
- ListViewSelectEventArgs.cs
- UpdateTranslator.cs
- HttpVersion.cs
- MobileSysDescriptionAttribute.cs
- TextRunTypographyProperties.cs
- DataGridViewSelectedColumnCollection.cs
- WeakRefEnumerator.cs
- ProxyElement.cs