Code:
/ Net / Net / 3.5.50727.3053 / DEVDIV / depot / DevDiv / releases / Orcas / SP / wpf / src / Core / CSharp / MS / Internal / FontFace / PhysicalFontFamily.cs / 1 / PhysicalFontFamily.cs
//---------------------------------------------------------------------------- // //// Copyright (C) Microsoft Corporation. All rights reserved. // // // // Description: The PhysicalFontFamily class // // History: // 03/04/2004 : mleonov - Created a new file for PhysicalFontFamily. It was in FontCollection.cs before. // //--------------------------------------------------------------------------- using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Globalization; using System.Security; using System.Security.Permissions; using System.Text; using System.Windows; using System.Windows.Markup; using System.Windows.Media; using System.Windows.Media.TextFormatting; using MS.Internal; using MS.Internal.FontCache; using MS.Internal.TextFormatting; namespace MS.Internal.FontFace { ////// PhysicalFontFamily class represents a font family obtained from a collection of OpenType files. /// internal sealed class PhysicalFontFamily : IFontFamily { internal PhysicalFontFamily(CachedFontFamily cachedFamily) { Invariant.Assert(!cachedFamily.IsNull); _cachedFamily = cachedFamily; } ////// Get typeface metrics of the specified typeface /// ITypefaceMetrics IFontFamily.GetTypefaceMetrics( FontStyle style, FontWeight weight, FontStretch stretch ) { return GetGlyphTypeface(style, weight, stretch); } ////// Look up device font for the typeface. /// IDeviceFont IFontFamily.GetDeviceFont(FontStyle style, FontWeight weight, FontStretch stretch) { return null; } ////// Indexer that indexes the underlying family name table via CultureInfo /// ///IDictionary IFontFamily.Names { get { return _cachedFamily.Names; } } /// /// Get the matching glyph typeface of a specified style /// /// font style /// font weight /// font stretch ///matching font face ////// Critical - as this returns GlyphTypeface created from internal constructor /// which exposes windows font information. /// Safe - as this doesn't allow you to create a GlyphTypeface object for a specific /// font and thus won't allow you to figure what fonts might be installed on /// the machine. /// [SecurityCritical, SecurityTreatAsSafe] internal GlyphTypeface GetGlyphTypeface( FontStyle style, FontWeight weight, FontStretch stretch ) { MatchingStyle targetStyle = new MatchingStyle(style, weight, stretch); MatchingStyle bestMatch = new MatchingStyle(); CachedFontFace bestMatchFontFace = CachedFontFace.Null; foreach (CachedFontFace fontFace in _cachedFamily) { MatchingStyle current = fontFace.MatchingStyle; if ( MatchingStyle.IsBetterMatch( targetStyle, bestMatch, ref current ) || bestMatchFontFace.IsNull) { bestMatchFontFace = fontFace; bestMatch = current; } } Debug.Assert(!bestMatchFontFace.IsNull); return bestMatchFontFace.CreateGlyphTypeface(); } ////// Get the matching typeface for the specified target style that also supports /// glyph mapping of the specified character string. /// /// font style /// font weight /// font stretch /// character string /// culture used for digit substitution or null /// number of characters with valid glyph mapped /// offset to the character mapping to a valid glyph ///matching typeface ////// Critical - as this returns GlyphTypeface created from internal constructor /// which exposes windows font information. /// Safe - as this doesn't allow you to create a GlyphTypeface object for a specific /// font and thus won't allow you to figure what fonts might be installed on /// the machine. /// [SecurityCritical, SecurityTreatAsSafe] internal GlyphTypeface MapGlyphTypeface( FontStyle style, FontWeight weight, FontStretch stretch, CharacterBufferRange charString, CultureInfo digitCulture, ref int advance, ref int nextValid ) { int smallestInvalid = charString.Length; // Add all the cached font faces to a priority queue. MatchingStyle targetStyle = new MatchingStyle(style, weight, stretch); PriorityQueuequeue = new PriorityQueue ( _cachedFamily.NumberOfFaces, new MatchingFaceComparer(targetStyle)); foreach (CachedFontFace face in _cachedFamily) { queue.Push(new MatchingFace(face, targetStyle)); } // Remember the best style match. GlyphTypeface bestStyleTypeface = null; // Iterate in priority order. for (; queue.Count != 0; queue.Pop()) { GlyphTypeface typeface = queue.Top.FontFace.CreateGlyphTypeface(); int invalid = 0; int valid = MapCharacters(typeface, charString, digitCulture, ref invalid); if (valid > 0) { if (smallestInvalid > 0 && smallestInvalid < valid) { // advance only to smallestInvalid because there's a better match after that advance = smallestInvalid; nextValid = 0; } else { advance = valid; nextValid = invalid; } return typeface; } else { if (invalid < smallestInvalid) { // keep track of the current shortest length of invalid characters, smallestInvalid = invalid; } if (bestStyleTypeface == null) { bestStyleTypeface = typeface; } } } // no face can map the specified character string, // fall back to the closest style match advance = 0; nextValid = smallestInvalid; Debug.Assert(bestStyleTypeface != null); return bestStyleTypeface; } /// /// Element type for priority queue used by MapGlyphTypeface. /// private struct MatchingFace { internal MatchingFace(CachedFontFace face, MatchingStyle targetStyle) { _face = face; _style = face.MatchingStyle; } internal CachedFontFace FontFace { get { return _face; } } internal MatchingStyle MatchingStyle { get { return _style; } } private CachedFontFace _face; private MatchingStyle _style; } ////// Comparer for priority queue used by MapGlyphTypeface. /// private class MatchingFaceComparer : IComparer{ internal MatchingFaceComparer(MatchingStyle targetStyle) { _targetStyle = targetStyle; } int IComparer .Compare(MatchingFace a, MatchingFace b) { return a.MatchingStyle.IsBetterMatch(_targetStyle, b.MatchingStyle) ? -1 : 1; } private MatchingStyle _targetStyle; } /// /// Map character supported by the typeface /// ////// Combining mark is considered part of the character that may be supported /// thru precomposed form or OpenType glyph substitution table. /// private int MapCharacters( GlyphTypeface typeface, CharacterBufferRange unicodeString, CultureInfo digitCulture, ref int nextValid ) { IDictionarycmap = typeface.CharacterToGlyphMap; DigitMap digitMap = new DigitMap(digitCulture); int sizeofChar = 0; int advance; // skip all the leading joiner characters. They need to be shaped with the // surrounding strong characters. advance = Classification.AdvanceWhile(unicodeString, ItemClass.JoinerClass); if (advance >= unicodeString.Length) { // It is rare that the run only contains joiner characters. // If it really happens, just return. return advance; } // // If the run starts with combining marks, we will not be able to find base characters for them // within the run. These combining marks will be mapped to their best fonts as normal characters. // bool hasBaseChar = false; // Determine how many characters we can advance, i.e., find the first invalid character. for (; advance < unicodeString.Length; advance += sizeofChar) { // Get the character and apply digit substitution, if any. int originalChar = Classification.UnicodeScalar( new CharacterBufferRange(unicodeString, advance, unicodeString.Length - advance), out sizeofChar ); if (Classification.IsJoiner(originalChar)) continue; if (!Classification.IsCombining(originalChar)) { hasBaseChar = true; } else if (hasBaseChar) { // continue to advance for combining mark with base char continue; } int ch = digitMap[originalChar]; if (cmap.ContainsKey(ch)) continue; // If ch is a substituted character, can we substitute a different character instead? if (ch != originalChar) { ch = DigitMap.GetFallbackCharacter(ch); if (ch != 0 && cmap.ContainsKey(ch)) continue; } // If we fall through to here it's invalid. break; } // UnicodeScalar won't return a sizeofChar that exceeds the string length. Debug.Assert(advance <= unicodeString.Length); // Find the next valid character. if (advance < unicodeString.Length) { // UnicodeScalar won't return a sizeofChar that exceeds the string length. Debug.Assert(advance + sizeofChar <= unicodeString.Length); for (nextValid = advance + sizeofChar; nextValid < unicodeString.Length; nextValid += sizeofChar) { // Get the character. int originalChar = Classification.UnicodeScalar( new CharacterBufferRange(unicodeString, nextValid, unicodeString.Length - nextValid), out sizeofChar ); // Apply digit substitution, if any. int ch = digitMap[originalChar]; // // Combining mark should always be shaped by the same font as the base char. // If the physical font is invalid for the base char, it should also be invalid for the // following combining mark so that both characters will go onto the same fallback font. // - When the fallback font is physical font, the font will be valid for both characters // if and only if it is valid for the base char. Otherwise, it will be invalid for both. // - When the fallback font is composite font, it maps the combining mark to the same font // as the base char such that they will eventually be resolved to the same physical font. // That means FamilyMap for the combining mark is not used when it follows a base char. // // The same goes for joiner. Note that "hasBaseChar" here indicates if there is an invalid base // char in front. if (Classification.IsJoiner(ch) || (hasBaseChar && Classification.IsCombining(ch)) ) continue; // If we have a glyph it's valid. if (cmap.ContainsKey(ch)) break; // If ch is a substituted character, can we substitute a different character instead? if (ch != originalChar) { ch = DigitMap.GetFallbackCharacter(ch); if (ch != 0 && cmap.ContainsKey(ch)) break; } } } return advance; } /// /// Distance from character cell top to English baseline relative to em size. /// double IFontFamily.Baseline { get { unsafe { return _cachedFamily.Baseline; } } } ////// Recommended baseline-to-baseline distance for text in this font /// double IFontFamily.LineSpacing { get { unsafe { return _cachedFamily.LineSpacing; } } } ICollectionIFontFamily.GetTypefaces(FontFamilyIdentifier familyIdentifier) { return new TypefaceCollection(new FontFamily(familyIdentifier), _cachedFamily); } /// /// Get family name correspondent to the first n-characters of the specified character string /// bool IFontFamily.GetMapTargetFamilyNameAndScale( CharacterBufferRange unicodeString, CultureInfo culture, CultureInfo digitCulture, double defaultSizeInEm, out int cchAdvance, out string targetFamilyName, out double scaleInEm ) { cchAdvance = unicodeString.Length; targetFamilyName = null; scaleInEm = defaultSizeInEm; return false; } private CachedFontFamily _cachedFamily; } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. // Copyright (c) Microsoft Corporation. All rights reserved. //---------------------------------------------------------------------------- // //// Copyright (C) Microsoft Corporation. All rights reserved. // // // // Description: The PhysicalFontFamily class // // History: // 03/04/2004 : mleonov - Created a new file for PhysicalFontFamily. It was in FontCollection.cs before. // //--------------------------------------------------------------------------- using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Globalization; using System.Security; using System.Security.Permissions; using System.Text; using System.Windows; using System.Windows.Markup; using System.Windows.Media; using System.Windows.Media.TextFormatting; using MS.Internal; using MS.Internal.FontCache; using MS.Internal.TextFormatting; namespace MS.Internal.FontFace { ////// PhysicalFontFamily class represents a font family obtained from a collection of OpenType files. /// internal sealed class PhysicalFontFamily : IFontFamily { internal PhysicalFontFamily(CachedFontFamily cachedFamily) { Invariant.Assert(!cachedFamily.IsNull); _cachedFamily = cachedFamily; } ////// Get typeface metrics of the specified typeface /// ITypefaceMetrics IFontFamily.GetTypefaceMetrics( FontStyle style, FontWeight weight, FontStretch stretch ) { return GetGlyphTypeface(style, weight, stretch); } ////// Look up device font for the typeface. /// IDeviceFont IFontFamily.GetDeviceFont(FontStyle style, FontWeight weight, FontStretch stretch) { return null; } ////// Indexer that indexes the underlying family name table via CultureInfo /// ///IDictionary IFontFamily.Names { get { return _cachedFamily.Names; } } /// /// Get the matching glyph typeface of a specified style /// /// font style /// font weight /// font stretch ///matching font face ////// Critical - as this returns GlyphTypeface created from internal constructor /// which exposes windows font information. /// Safe - as this doesn't allow you to create a GlyphTypeface object for a specific /// font and thus won't allow you to figure what fonts might be installed on /// the machine. /// [SecurityCritical, SecurityTreatAsSafe] internal GlyphTypeface GetGlyphTypeface( FontStyle style, FontWeight weight, FontStretch stretch ) { MatchingStyle targetStyle = new MatchingStyle(style, weight, stretch); MatchingStyle bestMatch = new MatchingStyle(); CachedFontFace bestMatchFontFace = CachedFontFace.Null; foreach (CachedFontFace fontFace in _cachedFamily) { MatchingStyle current = fontFace.MatchingStyle; if ( MatchingStyle.IsBetterMatch( targetStyle, bestMatch, ref current ) || bestMatchFontFace.IsNull) { bestMatchFontFace = fontFace; bestMatch = current; } } Debug.Assert(!bestMatchFontFace.IsNull); return bestMatchFontFace.CreateGlyphTypeface(); } ////// Get the matching typeface for the specified target style that also supports /// glyph mapping of the specified character string. /// /// font style /// font weight /// font stretch /// character string /// culture used for digit substitution or null /// number of characters with valid glyph mapped /// offset to the character mapping to a valid glyph ///matching typeface ////// Critical - as this returns GlyphTypeface created from internal constructor /// which exposes windows font information. /// Safe - as this doesn't allow you to create a GlyphTypeface object for a specific /// font and thus won't allow you to figure what fonts might be installed on /// the machine. /// [SecurityCritical, SecurityTreatAsSafe] internal GlyphTypeface MapGlyphTypeface( FontStyle style, FontWeight weight, FontStretch stretch, CharacterBufferRange charString, CultureInfo digitCulture, ref int advance, ref int nextValid ) { int smallestInvalid = charString.Length; // Add all the cached font faces to a priority queue. MatchingStyle targetStyle = new MatchingStyle(style, weight, stretch); PriorityQueuequeue = new PriorityQueue ( _cachedFamily.NumberOfFaces, new MatchingFaceComparer(targetStyle)); foreach (CachedFontFace face in _cachedFamily) { queue.Push(new MatchingFace(face, targetStyle)); } // Remember the best style match. GlyphTypeface bestStyleTypeface = null; // Iterate in priority order. for (; queue.Count != 0; queue.Pop()) { GlyphTypeface typeface = queue.Top.FontFace.CreateGlyphTypeface(); int invalid = 0; int valid = MapCharacters(typeface, charString, digitCulture, ref invalid); if (valid > 0) { if (smallestInvalid > 0 && smallestInvalid < valid) { // advance only to smallestInvalid because there's a better match after that advance = smallestInvalid; nextValid = 0; } else { advance = valid; nextValid = invalid; } return typeface; } else { if (invalid < smallestInvalid) { // keep track of the current shortest length of invalid characters, smallestInvalid = invalid; } if (bestStyleTypeface == null) { bestStyleTypeface = typeface; } } } // no face can map the specified character string, // fall back to the closest style match advance = 0; nextValid = smallestInvalid; Debug.Assert(bestStyleTypeface != null); return bestStyleTypeface; } /// /// Element type for priority queue used by MapGlyphTypeface. /// private struct MatchingFace { internal MatchingFace(CachedFontFace face, MatchingStyle targetStyle) { _face = face; _style = face.MatchingStyle; } internal CachedFontFace FontFace { get { return _face; } } internal MatchingStyle MatchingStyle { get { return _style; } } private CachedFontFace _face; private MatchingStyle _style; } ////// Comparer for priority queue used by MapGlyphTypeface. /// private class MatchingFaceComparer : IComparer{ internal MatchingFaceComparer(MatchingStyle targetStyle) { _targetStyle = targetStyle; } int IComparer .Compare(MatchingFace a, MatchingFace b) { return a.MatchingStyle.IsBetterMatch(_targetStyle, b.MatchingStyle) ? -1 : 1; } private MatchingStyle _targetStyle; } /// /// Map character supported by the typeface /// ////// Combining mark is considered part of the character that may be supported /// thru precomposed form or OpenType glyph substitution table. /// private int MapCharacters( GlyphTypeface typeface, CharacterBufferRange unicodeString, CultureInfo digitCulture, ref int nextValid ) { IDictionarycmap = typeface.CharacterToGlyphMap; DigitMap digitMap = new DigitMap(digitCulture); int sizeofChar = 0; int advance; // skip all the leading joiner characters. They need to be shaped with the // surrounding strong characters. advance = Classification.AdvanceWhile(unicodeString, ItemClass.JoinerClass); if (advance >= unicodeString.Length) { // It is rare that the run only contains joiner characters. // If it really happens, just return. return advance; } // // If the run starts with combining marks, we will not be able to find base characters for them // within the run. These combining marks will be mapped to their best fonts as normal characters. // bool hasBaseChar = false; // Determine how many characters we can advance, i.e., find the first invalid character. for (; advance < unicodeString.Length; advance += sizeofChar) { // Get the character and apply digit substitution, if any. int originalChar = Classification.UnicodeScalar( new CharacterBufferRange(unicodeString, advance, unicodeString.Length - advance), out sizeofChar ); if (Classification.IsJoiner(originalChar)) continue; if (!Classification.IsCombining(originalChar)) { hasBaseChar = true; } else if (hasBaseChar) { // continue to advance for combining mark with base char continue; } int ch = digitMap[originalChar]; if (cmap.ContainsKey(ch)) continue; // If ch is a substituted character, can we substitute a different character instead? if (ch != originalChar) { ch = DigitMap.GetFallbackCharacter(ch); if (ch != 0 && cmap.ContainsKey(ch)) continue; } // If we fall through to here it's invalid. break; } // UnicodeScalar won't return a sizeofChar that exceeds the string length. Debug.Assert(advance <= unicodeString.Length); // Find the next valid character. if (advance < unicodeString.Length) { // UnicodeScalar won't return a sizeofChar that exceeds the string length. Debug.Assert(advance + sizeofChar <= unicodeString.Length); for (nextValid = advance + sizeofChar; nextValid < unicodeString.Length; nextValid += sizeofChar) { // Get the character. int originalChar = Classification.UnicodeScalar( new CharacterBufferRange(unicodeString, nextValid, unicodeString.Length - nextValid), out sizeofChar ); // Apply digit substitution, if any. int ch = digitMap[originalChar]; // // Combining mark should always be shaped by the same font as the base char. // If the physical font is invalid for the base char, it should also be invalid for the // following combining mark so that both characters will go onto the same fallback font. // - When the fallback font is physical font, the font will be valid for both characters // if and only if it is valid for the base char. Otherwise, it will be invalid for both. // - When the fallback font is composite font, it maps the combining mark to the same font // as the base char such that they will eventually be resolved to the same physical font. // That means FamilyMap for the combining mark is not used when it follows a base char. // // The same goes for joiner. Note that "hasBaseChar" here indicates if there is an invalid base // char in front. if (Classification.IsJoiner(ch) || (hasBaseChar && Classification.IsCombining(ch)) ) continue; // If we have a glyph it's valid. if (cmap.ContainsKey(ch)) break; // If ch is a substituted character, can we substitute a different character instead? if (ch != originalChar) { ch = DigitMap.GetFallbackCharacter(ch); if (ch != 0 && cmap.ContainsKey(ch)) break; } } } return advance; } /// /// Distance from character cell top to English baseline relative to em size. /// double IFontFamily.Baseline { get { unsafe { return _cachedFamily.Baseline; } } } ////// Recommended baseline-to-baseline distance for text in this font /// double IFontFamily.LineSpacing { get { unsafe { return _cachedFamily.LineSpacing; } } } ICollectionIFontFamily.GetTypefaces(FontFamilyIdentifier familyIdentifier) { return new TypefaceCollection(new FontFamily(familyIdentifier), _cachedFamily); } /// /// Get family name correspondent to the first n-characters of the specified character string /// bool IFontFamily.GetMapTargetFamilyNameAndScale( CharacterBufferRange unicodeString, CultureInfo culture, CultureInfo digitCulture, double defaultSizeInEm, out int cchAdvance, out string targetFamilyName, out double scaleInEm ) { cchAdvance = unicodeString.Length; targetFamilyName = null; scaleInEm = defaultSizeInEm; return false; } private CachedFontFamily _cachedFamily; } } // 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
- BitmapEffectInput.cs
- BitmapEffectDrawingContextState.cs
- CompiledXpathExpr.cs
- SamlAuthorityBinding.cs
- WindowsPrincipal.cs
- IndicCharClassifier.cs
- DataObjectFieldAttribute.cs
- RequestCacheValidator.cs
- NonVisualControlAttribute.cs
- BitmapEffectState.cs
- EllipseGeometry.cs
- InternalControlCollection.cs
- SystemInfo.cs
- WorkflowItemPresenter.cs
- SiteMapDataSourceView.cs
- Popup.cs
- InfoCardProofToken.cs
- TokenBasedSet.cs
- StateManagedCollection.cs
- DynamicValueConverter.cs
- Soap.cs
- ConnectionManagementElement.cs
- DatagridviewDisplayedBandsData.cs
- AssemblyCache.cs
- SecurityDocument.cs
- SafeBitVector32.cs
- XamlGridLengthSerializer.cs
- Identity.cs
- ScriptControl.cs
- Stylesheet.cs
- Char.cs
- OleDbParameter.cs
- Merger.cs
- AudioSignalProblemOccurredEventArgs.cs
- TextBoxRenderer.cs
- ClientBuildManagerCallback.cs
- AppearanceEditorPart.cs
- TypedDataSetSchemaImporterExtension.cs
- BuiltInExpr.cs
- GorillaCodec.cs
- InputLanguageManager.cs
- PrincipalPermission.cs
- ImportCatalogPart.cs
- VectorAnimationBase.cs
- TextServicesManager.cs
- XmlNamespaceDeclarationsAttribute.cs
- HtmlInputHidden.cs
- XmlSchemaChoice.cs
- TimeoutConverter.cs
- Rect.cs
- MetadataHelper.cs
- CompressedStack.cs
- DebugController.cs
- BamlLocalizableResource.cs
- AvTraceFormat.cs
- DataListCommandEventArgs.cs
- SqlMethodAttribute.cs
- FirstMatchCodeGroup.cs
- HtmlTitle.cs
- BuilderInfo.cs
- KnownBoxes.cs
- TextRangeBase.cs
- EncryptedData.cs
- GestureRecognizer.cs
- EtwTrace.cs
- DbExpressionVisitor_TResultType.cs
- Effect.cs
- AbandonedMutexException.cs
- PageThemeParser.cs
- MatrixKeyFrameCollection.cs
- SQLInt32Storage.cs
- LoopExpression.cs
- infer.cs
- ProcessHostMapPath.cs
- ArraySubsetEnumerator.cs
- PolyLineSegment.cs
- CorrelationManager.cs
- AppSettingsReader.cs
- TraceHandlerErrorFormatter.cs
- _NestedSingleAsyncResult.cs
- OdbcConnection.cs
- WindowsPrincipal.cs
- ColorMatrix.cs
- Attributes.cs
- ScaleTransform3D.cs
- StartUpEventArgs.cs
- WeakReference.cs
- ProviderUtil.cs
- ConfigurationSettings.cs
- XmlCountingReader.cs
- BindingList.cs
- RadioButtonStandardAdapter.cs
- QueryCacheManager.cs
- ToolStripDropTargetManager.cs
- LinqDataSourceDisposeEventArgs.cs
- ViewValidator.cs
- URLIdentityPermission.cs
- ScrollViewerAutomationPeer.cs
- WindowsNonControl.cs
- ProvidersHelper.cs