Code:
/ Dotnetfx_Win7_3.5.1 / Dotnetfx_Win7_3.5.1 / 3.5.1 / DEVDIV / depot / DevDiv / releases / Orcas / NetFXw7 / 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
- ComAwareEventInfo.cs
- ImmComposition.cs
- ReadOnlyMetadataCollection.cs
- PeerTransportSecurityElement.cs
- peersecurityelement.cs
- FolderBrowserDialog.cs
- MailWebEventProvider.cs
- AsyncParams.cs
- NumberFormatter.cs
- TransformCollection.cs
- ConstrainedDataObject.cs
- WebFormDesignerActionService.cs
- OdbcParameterCollection.cs
- WebPartVerbCollection.cs
- WebServiceBindingAttribute.cs
- StatusBarPanelClickEvent.cs
- Transform3D.cs
- ThreadAbortException.cs
- CircleHotSpot.cs
- ResXFileRef.cs
- DecimalStorage.cs
- namescope.cs
- DatePicker.cs
- RectangleConverter.cs
- SHA256Managed.cs
- webproxy.cs
- SecuritySessionFilter.cs
- ByteFacetDescriptionElement.cs
- VarRefManager.cs
- ClockController.cs
- EventLogPermission.cs
- StrokeNode.cs
- RuntimeEnvironment.cs
- ShapeTypeface.cs
- DataGridViewImageColumn.cs
- SendParametersContent.cs
- DbProviderFactoriesConfigurationHandler.cs
- DocumentAutomationPeer.cs
- Set.cs
- Hashtable.cs
- EntityDataSourceMemberPath.cs
- MergablePropertyAttribute.cs
- ProfileParameter.cs
- AsymmetricSignatureDeformatter.cs
- OleDbMetaDataFactory.cs
- TableColumn.cs
- FormViewModeEventArgs.cs
- MatrixValueSerializer.cs
- ScopedKnownTypes.cs
- ItemsChangedEventArgs.cs
- DataGridViewTextBoxEditingControl.cs
- NumberFunctions.cs
- BaseProcessor.cs
- Metadata.cs
- TraceSection.cs
- ImageMap.cs
- TableItemStyle.cs
- HebrewCalendar.cs
- LookupNode.cs
- InvalidDataException.cs
- StringBuilder.cs
- SymbolType.cs
- PreviewKeyDownEventArgs.cs
- IDispatchConstantAttribute.cs
- WorkflowApplicationTerminatedException.cs
- ErrorHandler.cs
- ExtendedTransformFactory.cs
- AssemblyCollection.cs
- SiteMapNodeItem.cs
- DataPointer.cs
- TextTreeRootTextBlock.cs
- FormViewDeletedEventArgs.cs
- TextBoxBase.cs
- FormsAuthenticationCredentials.cs
- MaskedTextBoxDesigner.cs
- EditorAttribute.cs
- PointAnimationUsingPath.cs
- DataGridAddNewRow.cs
- EnumUnknown.cs
- StringUtil.cs
- GC.cs
- ModuleConfigurationInfo.cs
- Intellisense.cs
- ForwardPositionQuery.cs
- EngineSite.cs
- ParameterCollection.cs
- Synchronization.cs
- WindowVisualStateTracker.cs
- QilUnary.cs
- IISUnsafeMethods.cs
- JulianCalendar.cs
- KoreanCalendar.cs
- OleDbSchemaGuid.cs
- ApplicationCommands.cs
- DirectoryNotFoundException.cs
- SQLInt16Storage.cs
- SchemaSetCompiler.cs
- XPathAncestorIterator.cs
- XmlSchemaInferenceException.cs
- TraceXPathNavigator.cs