Code:
/ Net / Net / 3.5.50727.3053 / DEVDIV / depot / DevDiv / releases / Orcas / SP / wpf / src / Core / CSharp / System / Windows / Media / Typeface.cs / 1 / Typeface.cs
//------------------------------------------------------------------------ // // Microsoft Windows Client Platform // Copyright (C) Microsoft Corporation // // File: Typeface.cs // // Contents: Typeface // // Created: 5-25-2003 Worachai Chaoweeraprasit (wchao) // //----------------------------------------------------------------------- using System; using System.Globalization; using System.Security.Permissions; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Security; using System.Windows; using System.Windows.Media.TextFormatting; using System.Runtime.InteropServices; using System.ComponentModel; using MS.Internal; using MS.Internal.FontFace; using MS.Internal.FontCache; using MS.Internal.Shaping; using MS.Internal.TextFormatting; namespace System.Windows.Media { ////// A Typeface is a combination of family, weight, style and stretch: /// public class Typeface { private FontFamily _fontFamily; // these _style, _weight and _stretch are only used for storing what was passed into the constructor. // Since FontFamily may change these values when it includes a style name implicitly, private FontStyle _style; private FontWeight _weight; private FontStretch _stretch; private FontFamily _fallbackFontFamily; // Cached canonical values of the typeface. private CachedTypeface _cachedTypeface; ////// Construct a typeface /// /// font typeface name public Typeface( string typefaceName ) // assume face name is family name until we get face name resolved properly. : this( new FontFamily(typefaceName), FontStyles.Normal, FontWeights.Normal, FontStretches.Normal ) {} ////// Construct a typeface /// /// Font family /// Font style /// Boldness of font /// Width of characters public Typeface( FontFamily fontFamily, FontStyle style, FontWeight weight, FontStretch stretch ) : this( fontFamily, style, weight, stretch, FontFamily.FontFamilyGlobalUI ) {} ////// Construct a typeface /// /// Font family /// Font style /// Boldness of font /// Width of characters /// fallback font family public Typeface( FontFamily fontFamily, FontStyle style, FontWeight weight, FontStretch stretch, FontFamily fallbackFontFamily ) { if(fontFamily == null) { throw new ArgumentNullException("fontFamily"); } _fontFamily = fontFamily; _style = style; _weight = weight; _stretch = stretch; _fallbackFontFamily = fallbackFontFamily; } ////// Font family /// public FontFamily FontFamily { get { return _fontFamily; } } ////// Font weight (light, bold, etc.) /// public FontWeight Weight { get { return _weight; } } ////// Font style (italic, oblique) /// public FontStyle Style { get { return _style; } } ////// Font Stretch (narrow, wide, etc.) /// public FontStretch Stretch { get { return _stretch; } } ////// Returns true if FontStyle.Oblique is algorithmically simulated by /// slanting glyphs. Returns false otherwise. /// public bool IsObliqueSimulated { get { return (CachedTypeface.TypefaceMetrics.StyleSimulations & StyleSimulations.ItalicSimulation) != 0; } } ////// Returns true if FontStyle.Bold is algorithmically simulated by /// thickening glyphs. Returns false otherwise. /// public bool IsBoldSimulated { get { return (CachedTypeface.TypefaceMetrics.StyleSimulations & StyleSimulations.BoldSimulation) != 0; } } ////// Obtain a glyph typeface that corresponds to the Typeface object constructed from an OpenType font family. /// If the Typeface was constructed from a composite font family, returns null. /// /// GlyphTypeface object that corresponds to this Typeface, or null if the Typeface /// was constructed from a composite font. ///Whether glyphTypeface is not null. public bool TryGetGlyphTypeface(out GlyphTypeface glyphTypeface) { glyphTypeface = CachedTypeface.TypefaceMetrics as GlyphTypeface; return glyphTypeface != null; } ////// Fallback font family /// internal FontFamily FallbackFontFamily { get { return _fallbackFontFamily; } } ////// (Western) x-height relative to em size. /// public double XHeight { get { return CachedTypeface.TypefaceMetrics.XHeight; } } ////// Distance from baseline to top of English ----, relative to em size. /// public double CapsHeight { get { return CachedTypeface.TypefaceMetrics.CapsHeight; } } ////// Distance from baseline to underline position /// public double UnderlinePosition { get { return CachedTypeface.TypefaceMetrics.UnderlinePosition; } } ////// Underline thickness /// public double UnderlineThickness { get { return CachedTypeface.TypefaceMetrics.UnderlineThickness; } } ////// Distance from baseline to strike-through position /// public double StrikethroughPosition { get { return CachedTypeface.TypefaceMetrics.StrikethroughPosition; } } ////// strike-through thickness /// public double StrikethroughThickness { get { return CachedTypeface.TypefaceMetrics.StrikethroughThickness; } } ////// Collection of culture-dependant face names. /// public LanguageSpecificStringDictionary FaceNames { get { return new LanguageSpecificStringDictionary(CachedTypeface.TypefaceMetrics.AdjustedFaceNames); } } ////// Distance from character cell top to English baseline relative to em size. /// internal double Baseline { get { return CachedTypeface.FirstFontFamily.Baseline; } } ////// Baseline to baseline distance relative to em size /// internal double LineSpacing { get { return CachedTypeface.FirstFontFamily.LineSpacing; } } ////// Flag indicating if the typeface is of symbol type /// internal bool Symbol { get { return CachedTypeface.TypefaceMetrics.Symbol; } } internal bool NullFont { get { return CachedTypeface.NullFont; } } // Tries to get a GlyphTypeface based on the Typeface properties. The // return value can be null. However, if CheckFastPathNominalGlyphs // returns true, then one can expect this function to return a valid // GlyphTypeface that maps all the specified text. internal GlyphTypeface TryGetGlyphTypeface() { return CachedTypeface.TypefaceMetrics as GlyphTypeface; } internal FontStyle CanonicalStyle { get { return CachedTypeface.CanonicalStyle; } } internal FontWeight CanonicalWeight { get { return CachedTypeface.CanonicalWeight; } } internal FontStretch CanonicalStretch { get { return CachedTypeface.CanonicalStretch; } } ////// Scan through specified character string checking for valid character /// nominal glyph. /// /// character buffer range /// height of Em /// maximum width allowed /// do not stop arbitrarily in the middle of a word /// digits require complex shaping /// CultureInfo of the text /// number of character fit in given width ///whether the specified string can be optimized by nominal glyph lookup internal bool CheckFastPathNominalGlyphs( CharacterBufferRange charBufferRange, double emSize, double widthMax, bool keepAWord, bool numberSubstitution, CultureInfo cultureInfo, out int stringLengthFit ) { stringLengthFit = 0; if (CachedTypeface.NullFont) return false; GlyphTypeface glyphTypeface = TryGetGlyphTypeface(); if (glyphTypeface == null) return false; stringLengthFit = 0; IDictionarycmap = glyphTypeface.CharacterToGlyphMap; double totalWidth = 0; int i = 0; ushort blankGlyph = glyphTypeface.BlankGlyphIndex; ushort glyph = blankGlyph; ushort charFlagsMask = numberSubstitution ? (ushort)(CharacterAttributeFlags.CharacterComplex | CharacterAttributeFlags.CharacterDigit) : (ushort)CharacterAttributeFlags.CharacterComplex; ushort charFlags = 0; ushort charFastTextCheck = (ushort)(CharacterAttributeFlags.CharacterFastText | CharacterAttributeFlags.CharacterIdeo); bool symbolTypeface = glyphTypeface.Symbol; if (symbolTypeface) { // we don't care what code points are present if it's a non-Unicode font such as Symbol or Wingdings; // the code points don't have any standardized meanings, and we always want to bypass shaping charFlagsMask = 0; } if(keepAWord) { do { char ch = charBufferRange[i++]; int charClass = (int)Classification.GetUnicodeClassUTF16(ch); charFlags = Classification.CharAttributeOf(charClass).Flags; charFastTextCheck &= charFlags; cmap.TryGetValue(ch, out glyph); totalWidth += emSize * glyphTypeface.GetAdvanceWidth(glyph); } while( i < charBufferRange.Length && ((charFlags & charFlagsMask) == 0) && (glyph != 0 || symbolTypeface) && glyph != blankGlyph ); // i is now at a character immediately following a leading blank } while( i < charBufferRange.Length && totalWidth <= widthMax && ((charFlags & charFlagsMask) == 0) && (glyph != 0 || symbolTypeface) ) { char ch = charBufferRange[i++]; int charClass = (int)Classification.GetUnicodeClassUTF16(ch); charFlags = Classification.CharAttributeOf(charClass).Flags; charFastTextCheck &= charFlags; cmap.TryGetValue(ch, out glyph); totalWidth += emSize * glyphTypeface.GetAdvanceWidth(glyph); } if (symbolTypeface) { // always optimize for non-Unicode font as we don't support shaping or typographic features; // we also don't fall back from non-Unicode fonts so we don't care if there are missing glyphs stringLengthFit = i; return true; } if (glyph == 0) { // character is not supported by the font return false; } if ((charFlags & charFlagsMask) != 0) { // complex character encountered, exclude it Debug.Assert(i > 0); if(--i <= 0) { // first char is complex, fail the call return false; } } stringLengthFit = i; TypographyAvailabilities typography = glyphTypeface.FontFaceLayoutInfo.TypographyAvailabilities; if ((charFastTextCheck & (byte) CharacterAttributeFlags.CharacterFastText) != 0) { // all input code points are Fast Text if ((typography & ( TypographyAvailabilities.FastTextTypographyAvailable | TypographyAvailabilities.FastTextMajorLanguageLocalizedFormAvailable ) ) != 0 ) { // Considered too risky to optimize. It is either because the font // has required features or the font has 'locl' lookup for major languages. return false; } else if ((typography & TypographyAvailabilities.FastTextExtraLanguageLocalizedFormAvailable) != 0) { // The font has 'locl' lookup for FastText code points for non major languages. // Check whether the input is major langauge. If it is, we are still good to optimize. return MajorLanguages.Contains(cultureInfo); } else { // No FastText flags are present, safe to optimize return true; } } else if ((charFastTextCheck & (byte) CharacterAttributeFlags.CharacterIdeo) != 0) { // The input are all ideographs, check the IdeoTypographyAvailable bit. It is safe if // the bit is not set. return ((typography & TypographyAvailabilities.IdeoTypographyAvailable) == 0); } else { // for all the rest of the cases, just check whether there is any required typography // present at all. If none exists, it is optimizable. We might under-optimize here but // it will be non-major languages. return ((typography & TypographyAvailabilities.Available) == 0); } } /// /// Lookup characters nominal glyphs and width /// /// character buffer range /// height of Em /// scaling factor from real to ideal unit /// glyph nominal advances in ideal units /// total width in ideal units ///true for success ///This function is only used in fast path, and can only be called /// if CheckFastPathNominalGlyphs has previously returned true. internal void GetCharacterNominalWidthsAndIdealWidth( CharacterBufferRange charBufferRange, double emSize, double toIdeal, out int[] nominalWidths, out int idealWidth ) { // This function should only be called if CheckFastPathNominalGlyphs has // returned true so we can assume the ITypefaceMetrics is a GlyphTypeface. GlyphTypeface glyphTypeface = TryGetGlyphTypeface(); Invariant.Assert(glyphTypeface != null); IDictionarycmap = glyphTypeface.CharacterToGlyphMap; nominalWidths = new int[charBufferRange.Length]; idealWidth = 0; for (int i = 0; i < charBufferRange.Length; i++) { ushort glyphIndex; cmap.TryGetValue(charBufferRange[i], out glyphIndex); double advance = emSize * glyphTypeface.GetAdvanceWidth(glyphIndex); nominalWidths[i] = (int) Math.Round(advance * toIdeal); idealWidth += nominalWidths[i]; } } /// /// Create correspondent hash code for the object /// ///object hash code public override int GetHashCode() { int hash = _fontFamily.GetHashCode(); if (_fallbackFontFamily != null) hash = HashFn.HashMultiply(hash) + _fallbackFontFamily.GetHashCode(); hash = HashFn.HashMultiply(hash) + _style.GetHashCode(); hash = HashFn.HashMultiply(hash) + _weight.GetHashCode(); hash = HashFn.HashMultiply(hash) + _stretch.GetHashCode(); return HashFn.HashScramble(hash); } ////// Equality check /// public override bool Equals(object o) { Typeface t = o as Typeface; if(t == null) return false; return _style == t._style && _weight == t._weight && _stretch == t._stretch && _fontFamily.Equals(t._fontFamily) && CompareFallbackFontFamily(t._fallbackFontFamily); } internal bool CompareFallbackFontFamily(FontFamily fallbackFontFamily) { if (fallbackFontFamily == null || _fallbackFontFamily == null) return fallbackFontFamily == _fallbackFontFamily; return _fallbackFontFamily.Equals(fallbackFontFamily); } //---------------------------------------- // Private method //---------------------------------------- private CachedTypeface CachedTypeface { get { if (_cachedTypeface == null) { CachedTypeface cachedTypeface = TypefaceMetricsCache.ReadonlyLookup(this) as CachedTypeface; if (cachedTypeface == null) { cachedTypeface = ConstructCachedTypeface(); TypefaceMetricsCache.Add(this, cachedTypeface); } // For thread-safety, set the _cachedTypeface field only after we have a fully // initialized CachedTypeface object. _cachedTypeface = cachedTypeface; } return _cachedTypeface; } } private CachedTypeface ConstructCachedTypeface() { FontStyle canonicalStyle = _style; FontWeight canonicalWeight = _weight; FontStretch canonicalStretch = _stretch; // // We always call FontFamily.FindFirstFontFamilyAndFace() method to resolve the // canonical styles since the implied styles in FontFamily name will override // the given styles in the Typeface. But we don't always use the IFontFamily // instance returned from this method because an equal instance might already be // cached. // FontFamily sourceFontFamily = FontFamily; IFontFamily firstFontFamily = sourceFontFamily.FindFirstFontFamilyAndFace( ref canonicalStyle, ref canonicalWeight, ref canonicalStretch ); if (firstFontFamily == null) { if (FallbackFontFamily != null) { sourceFontFamily = FallbackFontFamily; firstFontFamily = sourceFontFamily.FindFirstFontFamilyAndFace( ref canonicalStyle, ref canonicalWeight, ref canonicalStretch ); } if (firstFontFamily == null) { sourceFontFamily = null; firstFontFamily = FontFamily.LookupFontFamily(FontFamily.NullFontFamilyCanonicalName); } } // If it's a named font, map all occurrences of the same name to one cached IFontFamily. if (sourceFontFamily != null && sourceFontFamily.Source != null) { // We lookup in the cache to see if there is cached IFontFamily instance of the source FontFamily. Otherwise, // this IFontFamily value is added to the TypefaceMetrics cache. IFontFamily cachedValue = TypefaceMetricsCache.ReadonlyLookup(sourceFontFamily.FamilyIdentifier) as IFontFamily; if (cachedValue != null) { firstFontFamily = cachedValue; } else { TypefaceMetricsCache.Add(sourceFontFamily.FamilyIdentifier, firstFontFamily); } } ITypefaceMetrics typefaceMetrics = firstFontFamily.GetTypefaceMetrics(canonicalStyle, canonicalWeight, canonicalStretch); return new CachedTypeface( canonicalStyle, canonicalWeight, canonicalStretch, firstFontFamily, typefaceMetrics, sourceFontFamily == null ); } } } // 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 // // File: Typeface.cs // // Contents: Typeface // // Created: 5-25-2003 Worachai Chaoweeraprasit (wchao) // //----------------------------------------------------------------------- using System; using System.Globalization; using System.Security.Permissions; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Security; using System.Windows; using System.Windows.Media.TextFormatting; using System.Runtime.InteropServices; using System.ComponentModel; using MS.Internal; using MS.Internal.FontFace; using MS.Internal.FontCache; using MS.Internal.Shaping; using MS.Internal.TextFormatting; namespace System.Windows.Media { ////// A Typeface is a combination of family, weight, style and stretch: /// public class Typeface { private FontFamily _fontFamily; // these _style, _weight and _stretch are only used for storing what was passed into the constructor. // Since FontFamily may change these values when it includes a style name implicitly, private FontStyle _style; private FontWeight _weight; private FontStretch _stretch; private FontFamily _fallbackFontFamily; // Cached canonical values of the typeface. private CachedTypeface _cachedTypeface; ////// Construct a typeface /// /// font typeface name public Typeface( string typefaceName ) // assume face name is family name until we get face name resolved properly. : this( new FontFamily(typefaceName), FontStyles.Normal, FontWeights.Normal, FontStretches.Normal ) {} ////// Construct a typeface /// /// Font family /// Font style /// Boldness of font /// Width of characters public Typeface( FontFamily fontFamily, FontStyle style, FontWeight weight, FontStretch stretch ) : this( fontFamily, style, weight, stretch, FontFamily.FontFamilyGlobalUI ) {} ////// Construct a typeface /// /// Font family /// Font style /// Boldness of font /// Width of characters /// fallback font family public Typeface( FontFamily fontFamily, FontStyle style, FontWeight weight, FontStretch stretch, FontFamily fallbackFontFamily ) { if(fontFamily == null) { throw new ArgumentNullException("fontFamily"); } _fontFamily = fontFamily; _style = style; _weight = weight; _stretch = stretch; _fallbackFontFamily = fallbackFontFamily; } ////// Font family /// public FontFamily FontFamily { get { return _fontFamily; } } ////// Font weight (light, bold, etc.) /// public FontWeight Weight { get { return _weight; } } ////// Font style (italic, oblique) /// public FontStyle Style { get { return _style; } } ////// Font Stretch (narrow, wide, etc.) /// public FontStretch Stretch { get { return _stretch; } } ////// Returns true if FontStyle.Oblique is algorithmically simulated by /// slanting glyphs. Returns false otherwise. /// public bool IsObliqueSimulated { get { return (CachedTypeface.TypefaceMetrics.StyleSimulations & StyleSimulations.ItalicSimulation) != 0; } } ////// Returns true if FontStyle.Bold is algorithmically simulated by /// thickening glyphs. Returns false otherwise. /// public bool IsBoldSimulated { get { return (CachedTypeface.TypefaceMetrics.StyleSimulations & StyleSimulations.BoldSimulation) != 0; } } ////// Obtain a glyph typeface that corresponds to the Typeface object constructed from an OpenType font family. /// If the Typeface was constructed from a composite font family, returns null. /// /// GlyphTypeface object that corresponds to this Typeface, or null if the Typeface /// was constructed from a composite font. ///Whether glyphTypeface is not null. public bool TryGetGlyphTypeface(out GlyphTypeface glyphTypeface) { glyphTypeface = CachedTypeface.TypefaceMetrics as GlyphTypeface; return glyphTypeface != null; } ////// Fallback font family /// internal FontFamily FallbackFontFamily { get { return _fallbackFontFamily; } } ////// (Western) x-height relative to em size. /// public double XHeight { get { return CachedTypeface.TypefaceMetrics.XHeight; } } ////// Distance from baseline to top of English ----, relative to em size. /// public double CapsHeight { get { return CachedTypeface.TypefaceMetrics.CapsHeight; } } ////// Distance from baseline to underline position /// public double UnderlinePosition { get { return CachedTypeface.TypefaceMetrics.UnderlinePosition; } } ////// Underline thickness /// public double UnderlineThickness { get { return CachedTypeface.TypefaceMetrics.UnderlineThickness; } } ////// Distance from baseline to strike-through position /// public double StrikethroughPosition { get { return CachedTypeface.TypefaceMetrics.StrikethroughPosition; } } ////// strike-through thickness /// public double StrikethroughThickness { get { return CachedTypeface.TypefaceMetrics.StrikethroughThickness; } } ////// Collection of culture-dependant face names. /// public LanguageSpecificStringDictionary FaceNames { get { return new LanguageSpecificStringDictionary(CachedTypeface.TypefaceMetrics.AdjustedFaceNames); } } ////// Distance from character cell top to English baseline relative to em size. /// internal double Baseline { get { return CachedTypeface.FirstFontFamily.Baseline; } } ////// Baseline to baseline distance relative to em size /// internal double LineSpacing { get { return CachedTypeface.FirstFontFamily.LineSpacing; } } ////// Flag indicating if the typeface is of symbol type /// internal bool Symbol { get { return CachedTypeface.TypefaceMetrics.Symbol; } } internal bool NullFont { get { return CachedTypeface.NullFont; } } // Tries to get a GlyphTypeface based on the Typeface properties. The // return value can be null. However, if CheckFastPathNominalGlyphs // returns true, then one can expect this function to return a valid // GlyphTypeface that maps all the specified text. internal GlyphTypeface TryGetGlyphTypeface() { return CachedTypeface.TypefaceMetrics as GlyphTypeface; } internal FontStyle CanonicalStyle { get { return CachedTypeface.CanonicalStyle; } } internal FontWeight CanonicalWeight { get { return CachedTypeface.CanonicalWeight; } } internal FontStretch CanonicalStretch { get { return CachedTypeface.CanonicalStretch; } } ////// Scan through specified character string checking for valid character /// nominal glyph. /// /// character buffer range /// height of Em /// maximum width allowed /// do not stop arbitrarily in the middle of a word /// digits require complex shaping /// CultureInfo of the text /// number of character fit in given width ///whether the specified string can be optimized by nominal glyph lookup internal bool CheckFastPathNominalGlyphs( CharacterBufferRange charBufferRange, double emSize, double widthMax, bool keepAWord, bool numberSubstitution, CultureInfo cultureInfo, out int stringLengthFit ) { stringLengthFit = 0; if (CachedTypeface.NullFont) return false; GlyphTypeface glyphTypeface = TryGetGlyphTypeface(); if (glyphTypeface == null) return false; stringLengthFit = 0; IDictionarycmap = glyphTypeface.CharacterToGlyphMap; double totalWidth = 0; int i = 0; ushort blankGlyph = glyphTypeface.BlankGlyphIndex; ushort glyph = blankGlyph; ushort charFlagsMask = numberSubstitution ? (ushort)(CharacterAttributeFlags.CharacterComplex | CharacterAttributeFlags.CharacterDigit) : (ushort)CharacterAttributeFlags.CharacterComplex; ushort charFlags = 0; ushort charFastTextCheck = (ushort)(CharacterAttributeFlags.CharacterFastText | CharacterAttributeFlags.CharacterIdeo); bool symbolTypeface = glyphTypeface.Symbol; if (symbolTypeface) { // we don't care what code points are present if it's a non-Unicode font such as Symbol or Wingdings; // the code points don't have any standardized meanings, and we always want to bypass shaping charFlagsMask = 0; } if(keepAWord) { do { char ch = charBufferRange[i++]; int charClass = (int)Classification.GetUnicodeClassUTF16(ch); charFlags = Classification.CharAttributeOf(charClass).Flags; charFastTextCheck &= charFlags; cmap.TryGetValue(ch, out glyph); totalWidth += emSize * glyphTypeface.GetAdvanceWidth(glyph); } while( i < charBufferRange.Length && ((charFlags & charFlagsMask) == 0) && (glyph != 0 || symbolTypeface) && glyph != blankGlyph ); // i is now at a character immediately following a leading blank } while( i < charBufferRange.Length && totalWidth <= widthMax && ((charFlags & charFlagsMask) == 0) && (glyph != 0 || symbolTypeface) ) { char ch = charBufferRange[i++]; int charClass = (int)Classification.GetUnicodeClassUTF16(ch); charFlags = Classification.CharAttributeOf(charClass).Flags; charFastTextCheck &= charFlags; cmap.TryGetValue(ch, out glyph); totalWidth += emSize * glyphTypeface.GetAdvanceWidth(glyph); } if (symbolTypeface) { // always optimize for non-Unicode font as we don't support shaping or typographic features; // we also don't fall back from non-Unicode fonts so we don't care if there are missing glyphs stringLengthFit = i; return true; } if (glyph == 0) { // character is not supported by the font return false; } if ((charFlags & charFlagsMask) != 0) { // complex character encountered, exclude it Debug.Assert(i > 0); if(--i <= 0) { // first char is complex, fail the call return false; } } stringLengthFit = i; TypographyAvailabilities typography = glyphTypeface.FontFaceLayoutInfo.TypographyAvailabilities; if ((charFastTextCheck & (byte) CharacterAttributeFlags.CharacterFastText) != 0) { // all input code points are Fast Text if ((typography & ( TypographyAvailabilities.FastTextTypographyAvailable | TypographyAvailabilities.FastTextMajorLanguageLocalizedFormAvailable ) ) != 0 ) { // Considered too risky to optimize. It is either because the font // has required features or the font has 'locl' lookup for major languages. return false; } else if ((typography & TypographyAvailabilities.FastTextExtraLanguageLocalizedFormAvailable) != 0) { // The font has 'locl' lookup for FastText code points for non major languages. // Check whether the input is major langauge. If it is, we are still good to optimize. return MajorLanguages.Contains(cultureInfo); } else { // No FastText flags are present, safe to optimize return true; } } else if ((charFastTextCheck & (byte) CharacterAttributeFlags.CharacterIdeo) != 0) { // The input are all ideographs, check the IdeoTypographyAvailable bit. It is safe if // the bit is not set. return ((typography & TypographyAvailabilities.IdeoTypographyAvailable) == 0); } else { // for all the rest of the cases, just check whether there is any required typography // present at all. If none exists, it is optimizable. We might under-optimize here but // it will be non-major languages. return ((typography & TypographyAvailabilities.Available) == 0); } } /// /// Lookup characters nominal glyphs and width /// /// character buffer range /// height of Em /// scaling factor from real to ideal unit /// glyph nominal advances in ideal units /// total width in ideal units ///true for success ///This function is only used in fast path, and can only be called /// if CheckFastPathNominalGlyphs has previously returned true. internal void GetCharacterNominalWidthsAndIdealWidth( CharacterBufferRange charBufferRange, double emSize, double toIdeal, out int[] nominalWidths, out int idealWidth ) { // This function should only be called if CheckFastPathNominalGlyphs has // returned true so we can assume the ITypefaceMetrics is a GlyphTypeface. GlyphTypeface glyphTypeface = TryGetGlyphTypeface(); Invariant.Assert(glyphTypeface != null); IDictionarycmap = glyphTypeface.CharacterToGlyphMap; nominalWidths = new int[charBufferRange.Length]; idealWidth = 0; for (int i = 0; i < charBufferRange.Length; i++) { ushort glyphIndex; cmap.TryGetValue(charBufferRange[i], out glyphIndex); double advance = emSize * glyphTypeface.GetAdvanceWidth(glyphIndex); nominalWidths[i] = (int) Math.Round(advance * toIdeal); idealWidth += nominalWidths[i]; } } /// /// Create correspondent hash code for the object /// ///object hash code public override int GetHashCode() { int hash = _fontFamily.GetHashCode(); if (_fallbackFontFamily != null) hash = HashFn.HashMultiply(hash) + _fallbackFontFamily.GetHashCode(); hash = HashFn.HashMultiply(hash) + _style.GetHashCode(); hash = HashFn.HashMultiply(hash) + _weight.GetHashCode(); hash = HashFn.HashMultiply(hash) + _stretch.GetHashCode(); return HashFn.HashScramble(hash); } ////// Equality check /// public override bool Equals(object o) { Typeface t = o as Typeface; if(t == null) return false; return _style == t._style && _weight == t._weight && _stretch == t._stretch && _fontFamily.Equals(t._fontFamily) && CompareFallbackFontFamily(t._fallbackFontFamily); } internal bool CompareFallbackFontFamily(FontFamily fallbackFontFamily) { if (fallbackFontFamily == null || _fallbackFontFamily == null) return fallbackFontFamily == _fallbackFontFamily; return _fallbackFontFamily.Equals(fallbackFontFamily); } //---------------------------------------- // Private method //---------------------------------------- private CachedTypeface CachedTypeface { get { if (_cachedTypeface == null) { CachedTypeface cachedTypeface = TypefaceMetricsCache.ReadonlyLookup(this) as CachedTypeface; if (cachedTypeface == null) { cachedTypeface = ConstructCachedTypeface(); TypefaceMetricsCache.Add(this, cachedTypeface); } // For thread-safety, set the _cachedTypeface field only after we have a fully // initialized CachedTypeface object. _cachedTypeface = cachedTypeface; } return _cachedTypeface; } } private CachedTypeface ConstructCachedTypeface() { FontStyle canonicalStyle = _style; FontWeight canonicalWeight = _weight; FontStretch canonicalStretch = _stretch; // // We always call FontFamily.FindFirstFontFamilyAndFace() method to resolve the // canonical styles since the implied styles in FontFamily name will override // the given styles in the Typeface. But we don't always use the IFontFamily // instance returned from this method because an equal instance might already be // cached. // FontFamily sourceFontFamily = FontFamily; IFontFamily firstFontFamily = sourceFontFamily.FindFirstFontFamilyAndFace( ref canonicalStyle, ref canonicalWeight, ref canonicalStretch ); if (firstFontFamily == null) { if (FallbackFontFamily != null) { sourceFontFamily = FallbackFontFamily; firstFontFamily = sourceFontFamily.FindFirstFontFamilyAndFace( ref canonicalStyle, ref canonicalWeight, ref canonicalStretch ); } if (firstFontFamily == null) { sourceFontFamily = null; firstFontFamily = FontFamily.LookupFontFamily(FontFamily.NullFontFamilyCanonicalName); } } // If it's a named font, map all occurrences of the same name to one cached IFontFamily. if (sourceFontFamily != null && sourceFontFamily.Source != null) { // We lookup in the cache to see if there is cached IFontFamily instance of the source FontFamily. Otherwise, // this IFontFamily value is added to the TypefaceMetrics cache. IFontFamily cachedValue = TypefaceMetricsCache.ReadonlyLookup(sourceFontFamily.FamilyIdentifier) as IFontFamily; if (cachedValue != null) { firstFontFamily = cachedValue; } else { TypefaceMetricsCache.Add(sourceFontFamily.FamilyIdentifier, firstFontFamily); } } ITypefaceMetrics typefaceMetrics = firstFontFamily.GetTypefaceMetrics(canonicalStyle, canonicalWeight, canonicalStretch); return new CachedTypeface( canonicalStyle, canonicalWeight, canonicalStretch, firstFontFamily, typefaceMetrics, sourceFontFamily == null ); } } } // 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
- TemplateBindingExpression.cs
- ADConnectionHelper.cs
- FamilyTypeface.cs
- DataGridHelper.cs
- ToolboxItemImageConverter.cs
- ComponentChangingEvent.cs
- WindowsStartMenu.cs
- AnnotationStore.cs
- EmptyWithCancelationCheckWorkItem.cs
- ProcessHostServerConfig.cs
- XmlAnyAttributeAttribute.cs
- ObservableCollection.cs
- SecurityManager.cs
- ApplicationCommands.cs
- HtmlContainerControl.cs
- DbConnectionHelper.cs
- AppDomainManager.cs
- Repeater.cs
- objectresult_tresulttype.cs
- PointAnimationUsingPath.cs
- MethodAccessException.cs
- AttributeEmitter.cs
- MoveSizeWinEventHandler.cs
- RIPEMD160.cs
- TextDocumentView.cs
- ContainerSelectorGlyph.cs
- SerializationEventsCache.cs
- SendOperation.cs
- Main.cs
- Brush.cs
- Keywords.cs
- ReplacementText.cs
- XsltLoader.cs
- Options.cs
- CodeMethodInvokeExpression.cs
- EndEvent.cs
- SortedList.cs
- DataTableMapping.cs
- ErrorFormatter.cs
- CodeTypeReference.cs
- ResXResourceSet.cs
- DataGridViewAutoSizeModeEventArgs.cs
- EntityDataSourceReferenceGroup.cs
- NamedObject.cs
- Quad.cs
- BufferedWebEventProvider.cs
- RtType.cs
- MultitargetUtil.cs
- MediaPlayerState.cs
- AlignmentXValidation.cs
- TriState.cs
- TransformPattern.cs
- StubHelpers.cs
- SharedPersonalizationStateInfo.cs
- ClipboardProcessor.cs
- CodeCommentStatement.cs
- SByte.cs
- WebPartCloseVerb.cs
- DynamicUpdateCommand.cs
- FontFamily.cs
- TextTreeUndo.cs
- InputBindingCollection.cs
- ErrorRuntimeConfig.cs
- Italic.cs
- SystemWebSectionGroup.cs
- updatecommandorderer.cs
- WebHttpBindingCollectionElement.cs
- QuaternionValueSerializer.cs
- FillErrorEventArgs.cs
- FlowDocumentScrollViewer.cs
- WebControlAdapter.cs
- XmlMtomWriter.cs
- _FixedSizeReader.cs
- ObjectIDGenerator.cs
- ImageBrush.cs
- DateTimeOffset.cs
- ResourceDescriptionAttribute.cs
- MetadataItem_Static.cs
- MsmqProcessProtocolHandler.cs
- SoapHeaders.cs
- CodeAccessPermission.cs
- GeometryCollection.cs
- BamlLocalizer.cs
- FrameworkElementFactory.cs
- TdsParserSafeHandles.cs
- FontDifferentiator.cs
- InvalidFilterCriteriaException.cs
- SecurityException.cs
- MethodSet.cs
- ContentTextAutomationPeer.cs
- EdgeProfileValidation.cs
- SecurityUtils.cs
- PageSetupDialog.cs
- ProfilePropertySettingsCollection.cs
- CngProperty.cs
- LambdaCompiler.ControlFlow.cs
- XmlQueryOutput.cs
- columnmapkeybuilder.cs
- EventEntry.cs
- OracleRowUpdatedEventArgs.cs