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
- COM2Properties.cs
- TextTrailingWordEllipsis.cs
- ErrorProvider.cs
- PeerInputChannel.cs
- HttpCachePolicyWrapper.cs
- CapiSafeHandles.cs
- EncryptedPackage.cs
- FormsAuthenticationUserCollection.cs
- SafeRightsManagementEnvironmentHandle.cs
- ImpersonationContext.cs
- DataRowCollection.cs
- DateTimeFormatInfo.cs
- OleDbDataAdapter.cs
- TableRow.cs
- HandoffBehavior.cs
- UnknownBitmapDecoder.cs
- RunClient.cs
- VisualBrush.cs
- XPathEmptyIterator.cs
- GridViewDeletedEventArgs.cs
- ClientSettings.cs
- DefaultPropertyAttribute.cs
- TaskForm.cs
- XmlSubtreeReader.cs
- VisualTreeHelper.cs
- RenderingBiasValidation.cs
- HttpRequest.cs
- ObjectSecurity.cs
- Pkcs9Attribute.cs
- PageBreakRecord.cs
- ListBoxChrome.cs
- XmlHierarchyData.cs
- FilteredAttributeCollection.cs
- SecureEnvironment.cs
- PingReply.cs
- SamlAuthenticationStatement.cs
- TextTreeDeleteContentUndoUnit.cs
- XsltLibrary.cs
- Int64Animation.cs
- PageCodeDomTreeGenerator.cs
- FactorySettingsElement.cs
- SchemaCollectionCompiler.cs
- EventOpcode.cs
- BindingBase.cs
- LayoutTable.cs
- unsafenativemethodstextservices.cs
- IISMapPath.cs
- DataGridViewComboBoxColumn.cs
- ControlIdConverter.cs
- basenumberconverter.cs
- VScrollBar.cs
- NamespaceInfo.cs
- OleDbWrapper.cs
- PathSegment.cs
- ISAPIRuntime.cs
- DesignerSerializationOptionsAttribute.cs
- ExcCanonicalXml.cs
- ConnectionPoint.cs
- Mapping.cs
- SystemException.cs
- MimeWriter.cs
- ByteRangeDownloader.cs
- WebPartPersonalization.cs
- Viewport3DAutomationPeer.cs
- Compiler.cs
- SqlDelegatedTransaction.cs
- PhysicalAddress.cs
- TypeDelegator.cs
- RightsManagementEncryptedStream.cs
- ToolStripRendererSwitcher.cs
- QilStrConcatenator.cs
- XmlSchemaExporter.cs
- AppSettingsExpressionBuilder.cs
- ImageButton.cs
- PathFigure.cs
- TextCompositionManager.cs
- AuthenticationSection.cs
- PageThemeParser.cs
- DrawingVisual.cs
- XPathDocument.cs
- TypedTableHandler.cs
- X509Certificate2.cs
- BrowserCapabilitiesFactory.cs
- ReaderWriterLockWrapper.cs
- ToolboxSnapDragDropEventArgs.cs
- PrintDialog.cs
- ChtmlCalendarAdapter.cs
- DataGridViewAccessibleObject.cs
- DtdParser.cs
- ipaddressinformationcollection.cs
- PropertyGridView.cs
- HostingPreferredMapPath.cs
- KeyManager.cs
- ValidateNames.cs
- CmsInterop.cs
- RegistryKey.cs
- XmlElementAttributes.cs
- HeaderCollection.cs
- NavigatorOutput.cs
- ModelTypeConverter.cs