Code:
/ 4.0 / 4.0 / untmp / DEVDIV_TFS / Dev10 / Releases / RTMRel / wpf / src / Core / CSharp / MS / Internal / Shaping / Substitution.cs / 1305600 / 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.
Link Menu
This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- TemplatePartAttribute.cs
- ObjectStorage.cs
- InternalSafeNativeMethods.cs
- SqlCacheDependencyDatabase.cs
- ErrorInfoXmlDocument.cs
- BaseCollection.cs
- GACMembershipCondition.cs
- ObjectComplexPropertyMapping.cs
- StyleTypedPropertyAttribute.cs
- XmlReader.cs
- MailWriter.cs
- LiteralLink.cs
- EditorPart.cs
- Type.cs
- DescendentsWalker.cs
- XPathAxisIterator.cs
- XmlSchemaAny.cs
- Exceptions.cs
- BadImageFormatException.cs
- LoggedException.cs
- WpfKnownMemberInvoker.cs
- BatchStream.cs
- XmlSchemaComplexContentExtension.cs
- UserNamePasswordValidator.cs
- MailAddressParser.cs
- ErrorFormatterPage.cs
- SqlConnectionString.cs
- TextComposition.cs
- TakeQueryOptionExpression.cs
- XmlTextEncoder.cs
- SmtpClient.cs
- BadImageFormatException.cs
- XmlCountingReader.cs
- followingquery.cs
- FixedTextBuilder.cs
- ObservableCollection.cs
- RequestQueue.cs
- BounceEase.cs
- PrintDialogException.cs
- OleDbRowUpdatingEvent.cs
- storepermissionattribute.cs
- XmlDataSourceView.cs
- SqlUdtInfo.cs
- WebPartCatalogCloseVerb.cs
- CharKeyFrameCollection.cs
- SizeConverter.cs
- EntityDataSourceSelectedEventArgs.cs
- LocatorBase.cs
- TemplateField.cs
- ButtonFlatAdapter.cs
- WpfKnownTypeInvoker.cs
- SafeReadContext.cs
- complextypematerializer.cs
- indexingfiltermarshaler.cs
- ObjectAnimationUsingKeyFrames.cs
- ClonableStack.cs
- ChtmlPageAdapter.cs
- Image.cs
- EFColumnProvider.cs
- SQLInt32.cs
- Dump.cs
- BamlLocalizabilityResolver.cs
- Emitter.cs
- CodeTypeReference.cs
- DataGridViewRowCancelEventArgs.cs
- X509CertificateRecipientClientCredential.cs
- MouseEvent.cs
- mactripleDES.cs
- Reference.cs
- ArrayList.cs
- CodeTypeParameterCollection.cs
- ValidationEventArgs.cs
- CfgSemanticTag.cs
- SafeRightsManagementHandle.cs
- base64Transforms.cs
- ActionItem.cs
- EventHandlingScope.cs
- ChildTable.cs
- DataGridSortCommandEventArgs.cs
- WindowProviderWrapper.cs
- DataSourceSelectArguments.cs
- DataBindingsDialog.cs
- IdentityNotMappedException.cs
- WebPartUtil.cs
- Parsers.cs
- SqlRecordBuffer.cs
- StructuredCompositeActivityDesigner.cs
- panel.cs
- RegularExpressionValidator.cs
- BinaryObjectReader.cs
- Typeface.cs
- PrintingPermissionAttribute.cs
- FileDialogPermission.cs
- TablePatternIdentifiers.cs
- RunWorkerCompletedEventArgs.cs
- CloudCollection.cs
- StreamWithDictionary.cs
- OdbcCommandBuilder.cs
- EpmSourceTree.cs
- ScriptResourceAttribute.cs