Code:
/ 4.0 / 4.0 / DEVDIV_TFS / Dev10 / Releases / RTMRel / wpf / src / Core / CSharp / MS / Internal / FontFace / FontDriver.cs / 1305600 / FontDriver.cs
using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Globalization; using System.IO; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Security.Permissions; using System.Security; using System.Text; using System.Windows; using System.Windows.Markup; // for XmlLanguage using System.Windows.Media; using MS.Internal; using MS.Internal.PresentationCore; using MS.Utility; using MS.Internal.FontCache; // Since we disable PreSharp warnings in this file, we first need to disable warnings about unknown message numbers and unknown pragmas. #pragma warning disable 1634, 1691 namespace MS.Internal.FontFace { ////// Font technology. /// internal enum FontTechnology { // this enum need to be kept in order of preference that we want to use with duplicate font face, // highest value will win in case of duplicate PostscriptOpenType, TrueType, TrueTypeCollection } internal class TrueTypeFontDriver { #region Font constants, structures and enumerations private struct DirectoryEntry { internal TrueTypeTags tag; internal CheckedPointer pointer; } private enum TrueTypeTags : int { CharToIndexMap = 0x636d6170, /* 'cmap' */ ControlValue = 0x63767420, /* 'cvt ' */ BitmapData = 0x45424454, /* 'EBDT' */ BitmapLocation = 0x45424c43, /* 'EBLC' */ BitmapScale = 0x45425343, /* 'EBSC' */ Editor0 = 0x65647430, /* 'edt0' */ Editor1 = 0x65647431, /* 'edt1' */ Encryption = 0x63727970, /* 'cryp' */ FontHeader = 0x68656164, /* 'head' */ FontProgram = 0x6670676d, /* 'fpgm' */ GridfitAndScanProc = 0x67617370, /* 'gasp' */ GlyphDirectory = 0x67646972, /* 'gdir' */ GlyphData = 0x676c7966, /* 'glyf' */ HoriDeviceMetrics = 0x68646d78, /* 'hdmx' */ HoriHeader = 0x68686561, /* 'hhea' */ HorizontalMetrics = 0x686d7478, /* 'hmtx' */ IndexToLoc = 0x6c6f6361, /* 'loca' */ Kerning = 0x6b65726e, /* 'kern' */ LinearThreshold = 0x4c545348, /* 'LTSH' */ MaxProfile = 0x6d617870, /* 'maxp' */ NamingTable = 0x6e616d65, /* 'name' */ OS_2 = 0x4f532f32, /* 'OS/2' */ Postscript = 0x706f7374, /* 'post' */ PreProgram = 0x70726570, /* 'prep' */ VertDeviceMetrics = 0x56444d58, /* 'VDMX' */ VertHeader = 0x76686561, /* 'vhea' */ VerticalMetrics = 0x766d7478, /* 'vmtx' */ PCLT = 0x50434C54, /* 'PCLT' */ TTO_GSUB = 0x47535542, /* 'GSUB' */ TTO_GPOS = 0x47504F53, /* 'GPOS' */ TTO_GDEF = 0x47444546, /* 'GDEF' */ TTO_BASE = 0x42415345, /* 'BASE' */ TTO_JSTF = 0x4A535446, /* 'JSTF' */ OTTO = 0x4f54544f, // Adobe OpenType 'OTTO' TTC_TTCF = 0x74746366 // 'ttcf' } #endregion #region Byte, Short, Long etc. accesss to CheckedPointers ////// The follwoing APIs extract OpenType variable types from OpenType font /// files. OpenType variables are stored big-endian, and the type are named /// as follows: /// Byte - signed 8 bit /// UShort - unsigned 16 bit /// Short - signed 16 bit /// ULong - unsigned 32 bit /// Long - signed 32 bit /// ////// Critical: Calls into probe which is critical and also has unsafe code blocks /// TreatAsSafe: This code is Ok to expose /// [SecurityCritical,SecurityTreatAsSafe] private static ushort ReadOpenTypeUShort(CheckedPointer pointer) { unsafe { byte * readBuffer = (byte *)pointer.Probe(0, 2); ushort result = (ushort)((readBuffer[0] << 8) + readBuffer[1]); return result; } } ////// Critical: Calls into probe which is critical and also has unsafe code blocks /// TreatAsSafe: This code IS Ok to expose /// [SecurityCritical,SecurityTreatAsSafe] private static int ReadOpenTypeLong(CheckedPointer pointer) { unsafe { byte * readBuffer = (byte *)pointer.Probe(0, 4); int result = (int)((((((readBuffer[0] << 8) + readBuffer[1]) << 8) + readBuffer[2]) << 8) + readBuffer[3]); return result; } } #endregion Byte, Short, Long etc. accesss to CheckedPointers #region Constructor and general helpers ////// Critical: constructs data for a checked pointer. /// [SecurityCritical] internal TrueTypeFontDriver(UnmanagedMemoryStream unmanagedMemoryStream, Uri sourceUri) { _sourceUri = sourceUri; _unmanagedMemoryStream = unmanagedMemoryStream; _fileStream = new CheckedPointer(unmanagedMemoryStream); try { CheckedPointer seekPosition = _fileStream; TrueTypeTags typeTag = (TrueTypeTags)ReadOpenTypeLong(seekPosition); seekPosition += 4; if (typeTag == TrueTypeTags.TTC_TTCF) { // this is a TTC file, we need to decode the ttc header _technology = FontTechnology.TrueTypeCollection; seekPosition += 4; // skip version _numFaces = ReadOpenTypeLong(seekPosition); } else if (typeTag == TrueTypeTags.OTTO) { _technology = FontTechnology.PostscriptOpenType; _numFaces = 1; } else { _technology = FontTechnology.TrueType; _numFaces = 1; } } catch (ArgumentOutOfRangeException e) { // convert exceptions from CheckedPointer to FileFormatException throw new FileFormatException(SourceUri, e); } } internal void SetFace(int faceIndex) { if (_technology == FontTechnology.TrueTypeCollection) { if (faceIndex < 0 || faceIndex >= _numFaces) throw new ArgumentOutOfRangeException("faceIndex"); } else { if (faceIndex != 0) throw new ArgumentOutOfRangeException("faceIndex", SR.Get(SRID.FaceIndexValidOnlyForTTC)); } try { CheckedPointer seekPosition = _fileStream + 4; if (_technology == FontTechnology.TrueTypeCollection) { // this is a TTC file, we need to decode the ttc header // skip version, num faces, OffsetTable array seekPosition += (4 + 4 + 4 * faceIndex); _directoryOffset = ReadOpenTypeLong(seekPosition); seekPosition = _fileStream + (_directoryOffset + 4); // 4 means that we skip the version number } _faceIndex = faceIndex; int numTables = ReadOpenTypeUShort(seekPosition); seekPosition += 2; // quick check for malformed fonts, see if numTables is too large // file size should be >= sizeof(offset table) + numTables * (sizeof(directory entry) + minimum table size (4)) long minimumFileSize = (4 + 2 + 2 + 2 + 2) + numTables * (4 + 4 + 4 + 4 + 4); if (_fileStream.Size < minimumFileSize) { throw new FileFormatException(SourceUri); } _tableDirectory = new DirectoryEntry[numTables]; // skip searchRange, entrySelector and rangeShift seekPosition += 6; // I can't use foreach here because C# disallows modifying the current value for (int i = 0; i < _tableDirectory.Length; ++i) { _tableDirectory[i].tag = (TrueTypeTags)ReadOpenTypeLong(seekPosition); seekPosition += 8; // skip checksum int offset = ReadOpenTypeLong(seekPosition); seekPosition += 4; int length = ReadOpenTypeLong(seekPosition); seekPosition += 4; _tableDirectory[i].pointer = _fileStream.CheckedProbe(offset, length); } } catch (ArgumentOutOfRangeException e) { // convert exceptions from CheckedPointer to FileFormatException throw new FileFormatException(SourceUri, e); } } #endregion #region Public methods and properties internal int NumFaces { get { return _numFaces; } } private Uri SourceUri { get { return _sourceUri; } } ////// Create font subset that includes glyphs in the input collection. /// ////// TreatAsSafe: This API could be public in terms of security as it demands unmanaged code /// Critical: Does an elevation by calling TrueTypeSubsetter which we are treating as equivalent to /// unsafe native methods /// [SecurityCritical, SecurityTreatAsSafe] internal byte[] ComputeFontSubset(ICollectionglyphs) { SecurityHelper.DemandUnmanagedCode(); int fileSize = _fileStream.Size; unsafe { void* fontData = _fileStream.Probe(0, fileSize); // Since we currently don't have a way to subset CFF fonts, just return a copy of the font. if (_technology == FontTechnology.PostscriptOpenType) { byte[] fontCopy = new byte[fileSize]; Marshal.Copy((IntPtr)fontData, fontCopy, 0, fileSize); return fontCopy; } ushort[] glyphArray; if (glyphs == null || glyphs.Count == 0) glyphArray = null; else { glyphArray = new ushort[glyphs.Count]; glyphs.CopyTo(glyphArray, 0); } return TrueTypeSubsetter.ComputeSubset(fontData, fileSize, SourceUri, _directoryOffset, glyphArray); } } #endregion Public methods and properties #region Fields // file-specific state private CheckedPointer _fileStream; private UnmanagedMemoryStream _unmanagedMemoryStream; private Uri _sourceUri; private int _numFaces; private FontTechnology _technology; // face-specific state private int _faceIndex; private int _directoryOffset; // table directory offset for TTC, 0 for TTF private DirectoryEntry[] _tableDirectory; #endregion } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. // Copyright (c) Microsoft Corporation. All rights reserved. using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Globalization; using System.IO; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Security.Permissions; using System.Security; using System.Text; using System.Windows; using System.Windows.Markup; // for XmlLanguage using System.Windows.Media; using MS.Internal; using MS.Internal.PresentationCore; using MS.Utility; using MS.Internal.FontCache; // Since we disable PreSharp warnings in this file, we first need to disable warnings about unknown message numbers and unknown pragmas. #pragma warning disable 1634, 1691 namespace MS.Internal.FontFace { /// /// Font technology. /// internal enum FontTechnology { // this enum need to be kept in order of preference that we want to use with duplicate font face, // highest value will win in case of duplicate PostscriptOpenType, TrueType, TrueTypeCollection } internal class TrueTypeFontDriver { #region Font constants, structures and enumerations private struct DirectoryEntry { internal TrueTypeTags tag; internal CheckedPointer pointer; } private enum TrueTypeTags : int { CharToIndexMap = 0x636d6170, /* 'cmap' */ ControlValue = 0x63767420, /* 'cvt ' */ BitmapData = 0x45424454, /* 'EBDT' */ BitmapLocation = 0x45424c43, /* 'EBLC' */ BitmapScale = 0x45425343, /* 'EBSC' */ Editor0 = 0x65647430, /* 'edt0' */ Editor1 = 0x65647431, /* 'edt1' */ Encryption = 0x63727970, /* 'cryp' */ FontHeader = 0x68656164, /* 'head' */ FontProgram = 0x6670676d, /* 'fpgm' */ GridfitAndScanProc = 0x67617370, /* 'gasp' */ GlyphDirectory = 0x67646972, /* 'gdir' */ GlyphData = 0x676c7966, /* 'glyf' */ HoriDeviceMetrics = 0x68646d78, /* 'hdmx' */ HoriHeader = 0x68686561, /* 'hhea' */ HorizontalMetrics = 0x686d7478, /* 'hmtx' */ IndexToLoc = 0x6c6f6361, /* 'loca' */ Kerning = 0x6b65726e, /* 'kern' */ LinearThreshold = 0x4c545348, /* 'LTSH' */ MaxProfile = 0x6d617870, /* 'maxp' */ NamingTable = 0x6e616d65, /* 'name' */ OS_2 = 0x4f532f32, /* 'OS/2' */ Postscript = 0x706f7374, /* 'post' */ PreProgram = 0x70726570, /* 'prep' */ VertDeviceMetrics = 0x56444d58, /* 'VDMX' */ VertHeader = 0x76686561, /* 'vhea' */ VerticalMetrics = 0x766d7478, /* 'vmtx' */ PCLT = 0x50434C54, /* 'PCLT' */ TTO_GSUB = 0x47535542, /* 'GSUB' */ TTO_GPOS = 0x47504F53, /* 'GPOS' */ TTO_GDEF = 0x47444546, /* 'GDEF' */ TTO_BASE = 0x42415345, /* 'BASE' */ TTO_JSTF = 0x4A535446, /* 'JSTF' */ OTTO = 0x4f54544f, // Adobe OpenType 'OTTO' TTC_TTCF = 0x74746366 // 'ttcf' } #endregion #region Byte, Short, Long etc. accesss to CheckedPointers ////// The follwoing APIs extract OpenType variable types from OpenType font /// files. OpenType variables are stored big-endian, and the type are named /// as follows: /// Byte - signed 8 bit /// UShort - unsigned 16 bit /// Short - signed 16 bit /// ULong - unsigned 32 bit /// Long - signed 32 bit /// ////// Critical: Calls into probe which is critical and also has unsafe code blocks /// TreatAsSafe: This code is Ok to expose /// [SecurityCritical,SecurityTreatAsSafe] private static ushort ReadOpenTypeUShort(CheckedPointer pointer) { unsafe { byte * readBuffer = (byte *)pointer.Probe(0, 2); ushort result = (ushort)((readBuffer[0] << 8) + readBuffer[1]); return result; } } ////// Critical: Calls into probe which is critical and also has unsafe code blocks /// TreatAsSafe: This code IS Ok to expose /// [SecurityCritical,SecurityTreatAsSafe] private static int ReadOpenTypeLong(CheckedPointer pointer) { unsafe { byte * readBuffer = (byte *)pointer.Probe(0, 4); int result = (int)((((((readBuffer[0] << 8) + readBuffer[1]) << 8) + readBuffer[2]) << 8) + readBuffer[3]); return result; } } #endregion Byte, Short, Long etc. accesss to CheckedPointers #region Constructor and general helpers ////// Critical: constructs data for a checked pointer. /// [SecurityCritical] internal TrueTypeFontDriver(UnmanagedMemoryStream unmanagedMemoryStream, Uri sourceUri) { _sourceUri = sourceUri; _unmanagedMemoryStream = unmanagedMemoryStream; _fileStream = new CheckedPointer(unmanagedMemoryStream); try { CheckedPointer seekPosition = _fileStream; TrueTypeTags typeTag = (TrueTypeTags)ReadOpenTypeLong(seekPosition); seekPosition += 4; if (typeTag == TrueTypeTags.TTC_TTCF) { // this is a TTC file, we need to decode the ttc header _technology = FontTechnology.TrueTypeCollection; seekPosition += 4; // skip version _numFaces = ReadOpenTypeLong(seekPosition); } else if (typeTag == TrueTypeTags.OTTO) { _technology = FontTechnology.PostscriptOpenType; _numFaces = 1; } else { _technology = FontTechnology.TrueType; _numFaces = 1; } } catch (ArgumentOutOfRangeException e) { // convert exceptions from CheckedPointer to FileFormatException throw new FileFormatException(SourceUri, e); } } internal void SetFace(int faceIndex) { if (_technology == FontTechnology.TrueTypeCollection) { if (faceIndex < 0 || faceIndex >= _numFaces) throw new ArgumentOutOfRangeException("faceIndex"); } else { if (faceIndex != 0) throw new ArgumentOutOfRangeException("faceIndex", SR.Get(SRID.FaceIndexValidOnlyForTTC)); } try { CheckedPointer seekPosition = _fileStream + 4; if (_technology == FontTechnology.TrueTypeCollection) { // this is a TTC file, we need to decode the ttc header // skip version, num faces, OffsetTable array seekPosition += (4 + 4 + 4 * faceIndex); _directoryOffset = ReadOpenTypeLong(seekPosition); seekPosition = _fileStream + (_directoryOffset + 4); // 4 means that we skip the version number } _faceIndex = faceIndex; int numTables = ReadOpenTypeUShort(seekPosition); seekPosition += 2; // quick check for malformed fonts, see if numTables is too large // file size should be >= sizeof(offset table) + numTables * (sizeof(directory entry) + minimum table size (4)) long minimumFileSize = (4 + 2 + 2 + 2 + 2) + numTables * (4 + 4 + 4 + 4 + 4); if (_fileStream.Size < minimumFileSize) { throw new FileFormatException(SourceUri); } _tableDirectory = new DirectoryEntry[numTables]; // skip searchRange, entrySelector and rangeShift seekPosition += 6; // I can't use foreach here because C# disallows modifying the current value for (int i = 0; i < _tableDirectory.Length; ++i) { _tableDirectory[i].tag = (TrueTypeTags)ReadOpenTypeLong(seekPosition); seekPosition += 8; // skip checksum int offset = ReadOpenTypeLong(seekPosition); seekPosition += 4; int length = ReadOpenTypeLong(seekPosition); seekPosition += 4; _tableDirectory[i].pointer = _fileStream.CheckedProbe(offset, length); } } catch (ArgumentOutOfRangeException e) { // convert exceptions from CheckedPointer to FileFormatException throw new FileFormatException(SourceUri, e); } } #endregion #region Public methods and properties internal int NumFaces { get { return _numFaces; } } private Uri SourceUri { get { return _sourceUri; } } ////// Create font subset that includes glyphs in the input collection. /// ////// TreatAsSafe: This API could be public in terms of security as it demands unmanaged code /// Critical: Does an elevation by calling TrueTypeSubsetter which we are treating as equivalent to /// unsafe native methods /// [SecurityCritical, SecurityTreatAsSafe] internal byte[] ComputeFontSubset(ICollectionglyphs) { SecurityHelper.DemandUnmanagedCode(); int fileSize = _fileStream.Size; unsafe { void* fontData = _fileStream.Probe(0, fileSize); // Since we currently don't have a way to subset CFF fonts, just return a copy of the font. if (_technology == FontTechnology.PostscriptOpenType) { byte[] fontCopy = new byte[fileSize]; Marshal.Copy((IntPtr)fontData, fontCopy, 0, fileSize); return fontCopy; } ushort[] glyphArray; if (glyphs == null || glyphs.Count == 0) glyphArray = null; else { glyphArray = new ushort[glyphs.Count]; glyphs.CopyTo(glyphArray, 0); } return TrueTypeSubsetter.ComputeSubset(fontData, fileSize, SourceUri, _directoryOffset, glyphArray); } } #endregion Public methods and properties #region Fields // file-specific state private CheckedPointer _fileStream; private UnmanagedMemoryStream _unmanagedMemoryStream; private Uri _sourceUri; private int _numFaces; private FontTechnology _technology; // face-specific state private int _faceIndex; private int _directoryOffset; // table directory offset for TTC, 0 for TTF private DirectoryEntry[] _tableDirectory; #endregion } } // 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
- bidPrivateBase.cs
- PasswordDeriveBytes.cs
- ConfigXmlSignificantWhitespace.cs
- FloaterParagraph.cs
- DbXmlEnabledProviderManifest.cs
- XmlUtil.cs
- ConvertersCollection.cs
- TypedDatasetGenerator.cs
- ProfileElement.cs
- HostedHttpContext.cs
- CodeSnippetTypeMember.cs
- XPathNodeIterator.cs
- BStrWrapper.cs
- StrokeNodeEnumerator.cs
- InputReport.cs
- IProvider.cs
- RegexBoyerMoore.cs
- ControlParameter.cs
- _NegoState.cs
- SevenBitStream.cs
- DbgCompiler.cs
- AssociationType.cs
- GridViewRowPresenter.cs
- _SpnDictionary.cs
- UnsafeCollabNativeMethods.cs
- InputLangChangeRequestEvent.cs
- WeakHashtable.cs
- rsa.cs
- XmlNodeWriter.cs
- Graph.cs
- EntitySqlQueryCacheEntry.cs
- FileSystemEventArgs.cs
- XmlSerializerNamespaces.cs
- HybridDictionary.cs
- Popup.cs
- SemanticTag.cs
- WinFormsUtils.cs
- ReflectionServiceProvider.cs
- WebPartMenuStyle.cs
- _ContextAwareResult.cs
- SqlConnectionFactory.cs
- EventItfInfo.cs
- PageAdapter.cs
- InvariantComparer.cs
- BasicExpandProvider.cs
- PrintEvent.cs
- WindowsBrush.cs
- JsonFormatWriterGenerator.cs
- DependencyObjectType.cs
- FirewallWrapper.cs
- OutputChannel.cs
- KnownColorTable.cs
- ForEachAction.cs
- XmlArrayAttribute.cs
- AuthenticationServiceManager.cs
- DataGridPageChangedEventArgs.cs
- MessageContractExporter.cs
- AggregateNode.cs
- DocumentPageViewAutomationPeer.cs
- Timeline.cs
- ItemCheckEvent.cs
- VisemeEventArgs.cs
- Maps.cs
- SettingsProviderCollection.cs
- DataGridTablesFactory.cs
- CroppedBitmap.cs
- ParameterCollection.cs
- Point3DCollection.cs
- XmlEncodedRawTextWriter.cs
- NegotiateStream.cs
- ObjectManager.cs
- NestPullup.cs
- CalendarModeChangedEventArgs.cs
- WinCategoryAttribute.cs
- DataBoundControlAdapter.cs
- WeakKeyDictionary.cs
- embossbitmapeffect.cs
- SqlConnection.cs
- PowerStatus.cs
- ReadContentAsBinaryHelper.cs
- WsdlInspector.cs
- EnvironmentPermission.cs
- ControlParameter.cs
- WebPartMinimizeVerb.cs
- MemberBinding.cs
- XmlCharCheckingReader.cs
- XPathQilFactory.cs
- DesigntimeLicenseContext.cs
- ApplicationException.cs
- FlowDocumentScrollViewer.cs
- XmlTypeAttribute.cs
- TreeViewEvent.cs
- FloaterBaseParaClient.cs
- CellIdBoolean.cs
- RegisteredScript.cs
- WorkflowRuntimeBehavior.cs
- DetailsViewDeletedEventArgs.cs
- PropagationProtocolsTracing.cs
- ModuleBuilder.cs
- XhtmlBasicImageAdapter.cs