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
- StateMachineWorkflowInstance.cs
- MultiPageTextView.cs
- CodeTypeParameter.cs
- SettingsPropertyIsReadOnlyException.cs
- AmbientValueAttribute.cs
- DatatypeImplementation.cs
- HtmlInputButton.cs
- PropagationProtocolsTracing.cs
- SapiInterop.cs
- KnownTypesHelper.cs
- DescendentsWalker.cs
- RemoveStoryboard.cs
- StylusPointPropertyId.cs
- ReferenceEqualityComparer.cs
- MachineKeyConverter.cs
- StyleXamlTreeBuilder.cs
- TableAdapterManagerMethodGenerator.cs
- CheckBoxBaseAdapter.cs
- ServiceContractListItemList.cs
- Decimal.cs
- Set.cs
- SqlInfoMessageEvent.cs
- ImpersonateTokenRef.cs
- activationcontext.cs
- Polygon.cs
- IntranetCredentialPolicy.cs
- FirstQueryOperator.cs
- TextPointer.cs
- ActivityInstanceMap.cs
- GcSettings.cs
- TagPrefixCollection.cs
- SizeIndependentAnimationStorage.cs
- WindowsStatusBar.cs
- BufferModesCollection.cs
- WebContext.cs
- HttpChannelHelpers.cs
- ConfigurationStrings.cs
- CompModSwitches.cs
- ImageListUtils.cs
- RangeContentEnumerator.cs
- GeometryCollection.cs
- Update.cs
- webbrowsersite.cs
- TextServicesHost.cs
- RemotingSurrogateSelector.cs
- BreakRecordTable.cs
- InteropDesigner.xaml.cs
- NavigationProgressEventArgs.cs
- MetadataItem_Static.cs
- BamlMapTable.cs
- SecurityBindingElement.cs
- ListControlBoundActionList.cs
- EntityKeyElement.cs
- PrivilegedConfigurationManager.cs
- MemberRelationshipService.cs
- ControlParameter.cs
- ScrollChrome.cs
- PieceDirectory.cs
- Validator.cs
- Model3DGroup.cs
- OpacityConverter.cs
- SimpleRecyclingCache.cs
- WebPartTransformerCollection.cs
- InvalidOperationException.cs
- Command.cs
- sqlmetadatafactory.cs
- GeometryDrawing.cs
- ProxyGenerationError.cs
- NameValueConfigurationElement.cs
- TextRenderer.cs
- ReadOnlyTernaryTree.cs
- Part.cs
- ErrorTableItemStyle.cs
- InputLanguageEventArgs.cs
- InputEventArgs.cs
- CancellationToken.cs
- NativeMethods.cs
- AsymmetricAlgorithm.cs
- ItemContainerGenerator.cs
- GenericAuthenticationEventArgs.cs
- OneOfElement.cs
- DetailsViewPagerRow.cs
- ClientTarget.cs
- XNodeSchemaApplier.cs
- MoveSizeWinEventHandler.cs
- SingleKeyFrameCollection.cs
- updatecommandorderer.cs
- CultureInfoConverter.cs
- JoinCqlBlock.cs
- EntityObject.cs
- BigIntegerStorage.cs
- odbcmetadatafactory.cs
- UnsafeNativeMethods.cs
- SmtpNetworkElement.cs
- WebPartTransformerAttribute.cs
- XsltConvert.cs
- NotifyIcon.cs
- DetailsViewUpdatedEventArgs.cs
- HandlerBase.cs
- ClonableStack.cs