Code:
/ Dotnetfx_Win7_3.5.1 / Dotnetfx_Win7_3.5.1 / 3.5.1 / DEVDIV / depot / DevDiv / releases / Orcas / NetFXw7 / wpf / src / Core / CSharp / MS / Internal / Shaping / CompositeFontFamily.cs / 1 / CompositeFontFamily.cs
//------------------------------------------------------------------------ // // Microsoft Windows Client Platform // Copyright (C) Microsoft Corporation, 2002 // // File: CompositeFontFamily.cs // // Contents: Composite font family // // Created: 5-25-2003 Worachai Chaoweeraprasit (wchao) // //----------------------------------------------------------------------- using System; using System.Globalization; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Security; using System.Windows; using System.Windows.Markup; // for XmlLanguage using System.Windows.Media; using System.Windows.Media.TextFormatting; using MS.Internal.FontCache; using MS.Internal.FontFace; using MS.Internal.TextFormatting; using FontFamily = System.Windows.Media.FontFamily; using SR=MS.Internal.PresentationCore.SR; using SRID=MS.Internal.PresentationCore.SRID; namespace MS.Internal.Shaping { ////// Composite font family /// internal sealed class CompositeFontFamily : IFontFamily { private CompositeFontInfo _fontInfo; private IFontFamily _firstFontFamily; #region Constructors ////// Construct a default composite font family /// internal CompositeFontFamily() : this(new CompositeFontInfo()) {} ////// Construct a composite font family from composite font info /// internal CompositeFontFamily(CompositeFontInfo fontInfo) { _fontInfo = fontInfo; } ////// Construct a composite font family with a single target family name /// internal CompositeFontFamily( string friendlyName ) : this( friendlyName, null // firstFontFamily ) {} ////// Construct a composite font family with a single target family name /// after the first font family in the target family is known /// ////// Critical - as this accesses _firstFontFamily which is marked critical. /// Safe - as this doesn't expose it. /// [SecurityCritical, SecurityTreatAsSafe] internal CompositeFontFamily( string friendlyName, IFontFamily firstFontFamily ) : this() { FamilyMaps.Add( new FontFamilyMap( 0, FontFamilyMap.LastUnicodeScalar, null, // any language friendlyName, 1 // scaleInEm ) ); _firstFontFamily = firstFontFamily; } #endregion #region IFontFamily properties ////// Font family name table indexed by culture /// IDictionaryIFontFamily.Names { get { return _fontInfo.FamilyNames; } } /// /// Distance from character cell top to English baseline relative to em size. /// public double Baseline { get { if(_fontInfo.Baseline == 0) { _fontInfo.Baseline = GetFirstFontFamily().Baseline; } return _fontInfo.Baseline; } } public void SetBaseline(double value) { _fontInfo.Baseline = value; } ////// Recommended baseline-to-baseline distance for text in this font. /// public double LineSpacing { get { if (_fontInfo.LineSpacing == 0) { _fontInfo.LineSpacing = GetFirstFontFamily().LineSpacing; } return _fontInfo.LineSpacing; } } public void SetLineSpacing(double value) { _fontInfo.LineSpacing = value; } ////// Get typeface metrics of the specified typeface /// ITypefaceMetrics IFontFamily.GetTypefaceMetrics( FontStyle style, FontWeight weight, FontStretch stretch ) { if (_fontInfo.FamilyTypefaces == null && _fontInfo.FamilyMaps.Count == 1 && _fontInfo.FamilyMaps[0].IsSimpleFamilyMap) { // Typical e.g. "MyFont, sans-serif" return GetFirstFontFamily().GetTypefaceMetrics(style, weight, stretch); } return FindTypefaceMetrics(style, weight, stretch); } ////// Look up device font for the typeface. /// IDeviceFont IFontFamily.GetDeviceFont(FontStyle style, FontWeight weight, FontStretch stretch) { FamilyTypeface bestFace = FindExactFamilyTypeface(style, weight, stretch); if (bestFace != null && bestFace.DeviceFontName != null) return bestFace; else return null; } ////// Get family name correspondent to the first n-characters of the specified character string /// bool IFontFamily.GetMapTargetFamilyNameAndScale( CharacterBufferRange unicodeString, CultureInfo culture, CultureInfo digitCulture, double defaultSizeInEm, out int cchAdvance, out string targetFamilyName, out double scaleInEm ) { Invariant.Assert(unicodeString.CharacterBuffer != null && unicodeString.Length > 0); Invariant.Assert(culture != null); // Get the family map. This will find the first family map that matches // the specified culture, an ancestor neutral culture, or "any" culture. FontFamilyMap familyMap = GetTargetFamilyMap( unicodeString, culture, digitCulture, out cchAdvance ); // Return the values for the matching FontFamilyMap. If there is none this is // FontFamilyMap.Default which has Target == null and Scale == 1.0. targetFamilyName = familyMap.Target; scaleInEm = familyMap.Scale; return true; } ICollectionIFontFamily.GetTypefaces(FontFamilyIdentifier familyIdentifier) { throw new NotImplementedException(); } #endregion #region collections exposed by FontFamily internal LanguageSpecificStringDictionary FamilyNames { get { return _fontInfo.FamilyNames; } } internal FamilyTypefaceCollection FamilyTypefaces { get { return _fontInfo.GetFamilyTypefaceList(); } } internal FontFamilyMapCollection FamilyMaps { get { return _fontInfo.FamilyMaps; } } #endregion private FontFamilyMap GetTargetFamilyMap( CharacterBufferRange unicodeString, CultureInfo culture, CultureInfo digitCulture, out int cchAdvance ) { DigitMap digitMap = new DigitMap(digitCulture); ushort[] familyMaps = _fontInfo.GetFamilyMapsOfLanguage(XmlLanguage.GetLanguage(culture.IetfLanguageTag)); int sizeofChar = 0; int ch = 0; // skip all the leading joinder characters. They need to be shaped with the // surrounding strong characters. cchAdvance = Classification.AdvanceWhile(unicodeString, ItemClass.JoinerClass); if (cchAdvance >= unicodeString.Length) { // It is rare that the run only contains joiner characters. // If it really happens, just map them to the initial family map. return _fontInfo.GetFamilyMapOfChar( familyMaps, Classification.UnicodeScalar(unicodeString, out sizeofChar) ); } // // If the run starts with combining marks, we will not be able to find base characters for them // within the run. These combining marks will be mapped to their best fonts as normal characters. // ch = Classification.UnicodeScalar( new CharacterBufferRange(unicodeString, cchAdvance, unicodeString.Length - cchAdvance), out sizeofChar ); bool hasBaseChar = !Classification.IsCombining(ch); ch = digitMap[ch]; FontFamilyMap familyMap = _fontInfo.GetFamilyMapOfChar(familyMaps, ch); Invariant.Assert(familyMap != null); for (cchAdvance += sizeofChar; cchAdvance < unicodeString.Length; cchAdvance += sizeofChar) { ch = Classification.UnicodeScalar( new CharacterBufferRange(unicodeString, cchAdvance, unicodeString.Length - cchAdvance), out sizeofChar ); if (Classification.IsJoiner(ch)) continue; // continue to advance if current char is a joiner if (!Classification.IsCombining(ch)) { hasBaseChar = true; } else if (hasBaseChar) { continue; // continue to advance for combining mark with base char } ch = digitMap[ch]; if (_fontInfo.GetFamilyMapOfChar(familyMaps, ch) != familyMap) break; } return familyMap; } /// /// Get the first font family of the first target family name /// private IFontFamily GetFirstFontFamily() { if(_firstFontFamily == null) { if (_fontInfo.FamilyMaps.Count != 0) { _firstFontFamily = FontFamily.FindFontFamilyFromFriendlyNameList(_fontInfo.FamilyMaps[0].Target); } else { _firstFontFamily = FontFamily.LookupFontFamily(FontFamily.NullFontFamilyCanonicalName); } Invariant.Assert(_firstFontFamily != null); } return _firstFontFamily; } private ITypefaceMetrics FindTypefaceMetrics( FontStyle style, FontWeight weight, FontStretch stretch ) { FamilyTypeface bestFace = FindNearestFamilyTypeface(style, weight, stretch); if (bestFace == null) return new CompositeTypefaceMetrics(); else return bestFace; } ////// Find the face closest to the specified style, weight and stretch. /// Returns null if there is no matching face. /// private FamilyTypeface FindNearestFamilyTypeface( FontStyle style, FontWeight weight, FontStretch stretch ) { if (_fontInfo.FamilyTypefaces == null || _fontInfo.FamilyTypefaces.Count == 0) { return null; } FamilyTypeface bestFace = (FamilyTypeface)_fontInfo.FamilyTypefaces[0]; MatchingStyle bestMatch = new MatchingStyle(bestFace.Style, bestFace.Weight, bestFace.Stretch); MatchingStyle target = new MatchingStyle(style, weight, stretch); for (int i = 1; i < _fontInfo.FamilyTypefaces.Count; i++) { FamilyTypeface currentFace = (FamilyTypeface)_fontInfo.FamilyTypefaces[i]; MatchingStyle currentMatch = new MatchingStyle(currentFace.Style, currentFace.Weight, currentFace.Stretch); if (MatchingStyle.IsBetterMatch(target, bestMatch, ref currentMatch)) { bestFace = currentFace; bestMatch = currentMatch; } } return bestFace; } ////// Find the face exactly matching the specified style, weight and stretch. /// Returns null if there is no matching face. /// private FamilyTypeface FindExactFamilyTypeface( FontStyle style, FontWeight weight, FontStretch stretch ) { if (_fontInfo.FamilyTypefaces == null || _fontInfo.FamilyTypefaces.Count == 0) { return null; } MatchingStyle target = new MatchingStyle(style, weight, stretch); foreach (FamilyTypeface currentFace in _fontInfo.FamilyTypefaces) { MatchingStyle currentMatch = new MatchingStyle(currentFace.Style, currentFace.Weight, currentFace.Stretch); if (currentMatch == target) { return currentFace; } } return 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, 2002 // // File: CompositeFontFamily.cs // // Contents: Composite font family // // Created: 5-25-2003 Worachai Chaoweeraprasit (wchao) // //----------------------------------------------------------------------- using System; using System.Globalization; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Security; using System.Windows; using System.Windows.Markup; // for XmlLanguage using System.Windows.Media; using System.Windows.Media.TextFormatting; using MS.Internal.FontCache; using MS.Internal.FontFace; using MS.Internal.TextFormatting; using FontFamily = System.Windows.Media.FontFamily; using SR=MS.Internal.PresentationCore.SR; using SRID=MS.Internal.PresentationCore.SRID; namespace MS.Internal.Shaping { ////// Composite font family /// internal sealed class CompositeFontFamily : IFontFamily { private CompositeFontInfo _fontInfo; private IFontFamily _firstFontFamily; #region Constructors ////// Construct a default composite font family /// internal CompositeFontFamily() : this(new CompositeFontInfo()) {} ////// Construct a composite font family from composite font info /// internal CompositeFontFamily(CompositeFontInfo fontInfo) { _fontInfo = fontInfo; } ////// Construct a composite font family with a single target family name /// internal CompositeFontFamily( string friendlyName ) : this( friendlyName, null // firstFontFamily ) {} ////// Construct a composite font family with a single target family name /// after the first font family in the target family is known /// ////// Critical - as this accesses _firstFontFamily which is marked critical. /// Safe - as this doesn't expose it. /// [SecurityCritical, SecurityTreatAsSafe] internal CompositeFontFamily( string friendlyName, IFontFamily firstFontFamily ) : this() { FamilyMaps.Add( new FontFamilyMap( 0, FontFamilyMap.LastUnicodeScalar, null, // any language friendlyName, 1 // scaleInEm ) ); _firstFontFamily = firstFontFamily; } #endregion #region IFontFamily properties ////// Font family name table indexed by culture /// IDictionaryIFontFamily.Names { get { return _fontInfo.FamilyNames; } } /// /// Distance from character cell top to English baseline relative to em size. /// public double Baseline { get { if(_fontInfo.Baseline == 0) { _fontInfo.Baseline = GetFirstFontFamily().Baseline; } return _fontInfo.Baseline; } } public void SetBaseline(double value) { _fontInfo.Baseline = value; } ////// Recommended baseline-to-baseline distance for text in this font. /// public double LineSpacing { get { if (_fontInfo.LineSpacing == 0) { _fontInfo.LineSpacing = GetFirstFontFamily().LineSpacing; } return _fontInfo.LineSpacing; } } public void SetLineSpacing(double value) { _fontInfo.LineSpacing = value; } ////// Get typeface metrics of the specified typeface /// ITypefaceMetrics IFontFamily.GetTypefaceMetrics( FontStyle style, FontWeight weight, FontStretch stretch ) { if (_fontInfo.FamilyTypefaces == null && _fontInfo.FamilyMaps.Count == 1 && _fontInfo.FamilyMaps[0].IsSimpleFamilyMap) { // Typical e.g. "MyFont, sans-serif" return GetFirstFontFamily().GetTypefaceMetrics(style, weight, stretch); } return FindTypefaceMetrics(style, weight, stretch); } ////// Look up device font for the typeface. /// IDeviceFont IFontFamily.GetDeviceFont(FontStyle style, FontWeight weight, FontStretch stretch) { FamilyTypeface bestFace = FindExactFamilyTypeface(style, weight, stretch); if (bestFace != null && bestFace.DeviceFontName != null) return bestFace; else return null; } ////// Get family name correspondent to the first n-characters of the specified character string /// bool IFontFamily.GetMapTargetFamilyNameAndScale( CharacterBufferRange unicodeString, CultureInfo culture, CultureInfo digitCulture, double defaultSizeInEm, out int cchAdvance, out string targetFamilyName, out double scaleInEm ) { Invariant.Assert(unicodeString.CharacterBuffer != null && unicodeString.Length > 0); Invariant.Assert(culture != null); // Get the family map. This will find the first family map that matches // the specified culture, an ancestor neutral culture, or "any" culture. FontFamilyMap familyMap = GetTargetFamilyMap( unicodeString, culture, digitCulture, out cchAdvance ); // Return the values for the matching FontFamilyMap. If there is none this is // FontFamilyMap.Default which has Target == null and Scale == 1.0. targetFamilyName = familyMap.Target; scaleInEm = familyMap.Scale; return true; } ICollectionIFontFamily.GetTypefaces(FontFamilyIdentifier familyIdentifier) { throw new NotImplementedException(); } #endregion #region collections exposed by FontFamily internal LanguageSpecificStringDictionary FamilyNames { get { return _fontInfo.FamilyNames; } } internal FamilyTypefaceCollection FamilyTypefaces { get { return _fontInfo.GetFamilyTypefaceList(); } } internal FontFamilyMapCollection FamilyMaps { get { return _fontInfo.FamilyMaps; } } #endregion private FontFamilyMap GetTargetFamilyMap( CharacterBufferRange unicodeString, CultureInfo culture, CultureInfo digitCulture, out int cchAdvance ) { DigitMap digitMap = new DigitMap(digitCulture); ushort[] familyMaps = _fontInfo.GetFamilyMapsOfLanguage(XmlLanguage.GetLanguage(culture.IetfLanguageTag)); int sizeofChar = 0; int ch = 0; // skip all the leading joinder characters. They need to be shaped with the // surrounding strong characters. cchAdvance = Classification.AdvanceWhile(unicodeString, ItemClass.JoinerClass); if (cchAdvance >= unicodeString.Length) { // It is rare that the run only contains joiner characters. // If it really happens, just map them to the initial family map. return _fontInfo.GetFamilyMapOfChar( familyMaps, Classification.UnicodeScalar(unicodeString, out sizeofChar) ); } // // If the run starts with combining marks, we will not be able to find base characters for them // within the run. These combining marks will be mapped to their best fonts as normal characters. // ch = Classification.UnicodeScalar( new CharacterBufferRange(unicodeString, cchAdvance, unicodeString.Length - cchAdvance), out sizeofChar ); bool hasBaseChar = !Classification.IsCombining(ch); ch = digitMap[ch]; FontFamilyMap familyMap = _fontInfo.GetFamilyMapOfChar(familyMaps, ch); Invariant.Assert(familyMap != null); for (cchAdvance += sizeofChar; cchAdvance < unicodeString.Length; cchAdvance += sizeofChar) { ch = Classification.UnicodeScalar( new CharacterBufferRange(unicodeString, cchAdvance, unicodeString.Length - cchAdvance), out sizeofChar ); if (Classification.IsJoiner(ch)) continue; // continue to advance if current char is a joiner if (!Classification.IsCombining(ch)) { hasBaseChar = true; } else if (hasBaseChar) { continue; // continue to advance for combining mark with base char } ch = digitMap[ch]; if (_fontInfo.GetFamilyMapOfChar(familyMaps, ch) != familyMap) break; } return familyMap; } /// /// Get the first font family of the first target family name /// private IFontFamily GetFirstFontFamily() { if(_firstFontFamily == null) { if (_fontInfo.FamilyMaps.Count != 0) { _firstFontFamily = FontFamily.FindFontFamilyFromFriendlyNameList(_fontInfo.FamilyMaps[0].Target); } else { _firstFontFamily = FontFamily.LookupFontFamily(FontFamily.NullFontFamilyCanonicalName); } Invariant.Assert(_firstFontFamily != null); } return _firstFontFamily; } private ITypefaceMetrics FindTypefaceMetrics( FontStyle style, FontWeight weight, FontStretch stretch ) { FamilyTypeface bestFace = FindNearestFamilyTypeface(style, weight, stretch); if (bestFace == null) return new CompositeTypefaceMetrics(); else return bestFace; } ////// Find the face closest to the specified style, weight and stretch. /// Returns null if there is no matching face. /// private FamilyTypeface FindNearestFamilyTypeface( FontStyle style, FontWeight weight, FontStretch stretch ) { if (_fontInfo.FamilyTypefaces == null || _fontInfo.FamilyTypefaces.Count == 0) { return null; } FamilyTypeface bestFace = (FamilyTypeface)_fontInfo.FamilyTypefaces[0]; MatchingStyle bestMatch = new MatchingStyle(bestFace.Style, bestFace.Weight, bestFace.Stretch); MatchingStyle target = new MatchingStyle(style, weight, stretch); for (int i = 1; i < _fontInfo.FamilyTypefaces.Count; i++) { FamilyTypeface currentFace = (FamilyTypeface)_fontInfo.FamilyTypefaces[i]; MatchingStyle currentMatch = new MatchingStyle(currentFace.Style, currentFace.Weight, currentFace.Stretch); if (MatchingStyle.IsBetterMatch(target, bestMatch, ref currentMatch)) { bestFace = currentFace; bestMatch = currentMatch; } } return bestFace; } ////// Find the face exactly matching the specified style, weight and stretch. /// Returns null if there is no matching face. /// private FamilyTypeface FindExactFamilyTypeface( FontStyle style, FontWeight weight, FontStretch stretch ) { if (_fontInfo.FamilyTypefaces == null || _fontInfo.FamilyTypefaces.Count == 0) { return null; } MatchingStyle target = new MatchingStyle(style, weight, stretch); foreach (FamilyTypeface currentFace in _fontInfo.FamilyTypefaces) { MatchingStyle currentMatch = new MatchingStyle(currentFace.Style, currentFace.Weight, currentFace.Stretch); if (currentMatch == target) { return currentFace; } } return 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
- RegisteredExpandoAttribute.cs
- GenericXmlSecurityToken.cs
- TextTreeInsertElementUndoUnit.cs
- StructuralCache.cs
- SupportsEventValidationAttribute.cs
- DrawItemEvent.cs
- BamlVersionHeader.cs
- recordstatefactory.cs
- ThumbButtonInfo.cs
- XamlStackWriter.cs
- TogglePatternIdentifiers.cs
- OdbcParameterCollection.cs
- PromptStyle.cs
- HostedNamedPipeTransportManager.cs
- WebBaseEventKeyComparer.cs
- ItemsChangedEventArgs.cs
- StringStorage.cs
- CaseKeyBox.xaml.cs
- OleDbCommandBuilder.cs
- PermissionToken.cs
- NullableDoubleMinMaxAggregationOperator.cs
- PropertyBuilder.cs
- LambdaCompiler.Binary.cs
- DesignerDataTable.cs
- ProfileProvider.cs
- PrivateUnsafeNativeCompoundFileMethods.cs
- MatrixTransform3D.cs
- StateMachine.cs
- __ConsoleStream.cs
- LayoutDump.cs
- ObjectFactoryCodeDomTreeGenerator.cs
- GridViewHeaderRowPresenterAutomationPeer.cs
- BaseCollection.cs
- XmlILConstructAnalyzer.cs
- ToolboxItem.cs
- MapPathBasedVirtualPathProvider.cs
- MessageHeaderDescription.cs
- BmpBitmapDecoder.cs
- QueryStringParameter.cs
- StorageAssociationSetMapping.cs
- MulticastNotSupportedException.cs
- OpCellTreeNode.cs
- BamlLocalizer.cs
- InstanceOwner.cs
- EditorZone.cs
- WebEventTraceProvider.cs
- TypeConverterHelper.cs
- LabelLiteral.cs
- MetadataArtifactLoaderCompositeResource.cs
- ResXFileRef.cs
- DataGridViewTextBoxCell.cs
- DrawingVisual.cs
- Fx.cs
- XmlSchemaSequence.cs
- Pts.cs
- AttachedPropertyMethodSelector.cs
- ImageEditor.cs
- DataTableReaderListener.cs
- Table.cs
- ObjectListComponentEditor.cs
- XpsFilter.cs
- ProgressiveCrcCalculatingStream.cs
- PropertyGeneratedEventArgs.cs
- OleDbPermission.cs
- OdbcPermission.cs
- PropertyPathWorker.cs
- MouseGesture.cs
- Region.cs
- ErrorWrapper.cs
- ElementFactory.cs
- OpenTypeLayout.cs
- SqlDataSourceStatusEventArgs.cs
- DateTimeConstantAttribute.cs
- ApplicationFileCodeDomTreeGenerator.cs
- nulltextnavigator.cs
- CodeEntryPointMethod.cs
- Trigger.cs
- SamlAuthenticationClaimResource.cs
- SortedSetDebugView.cs
- JsonUriDataContract.cs
- DesignerGenericWebPart.cs
- ItemsControlAutomationPeer.cs
- HuffModule.cs
- ObjectConverter.cs
- PageSettings.cs
- TitleStyle.cs
- ImageCodecInfo.cs
- IisTraceListener.cs
- Block.cs
- VsPropertyGrid.cs
- ScrollBarAutomationPeer.cs
- SafeViewOfFileHandle.cs
- IgnoreFileBuildProvider.cs
- StateMachineSubscription.cs
- EntityCommandCompilationException.cs
- ElementNotEnabledException.cs
- GridViewSortEventArgs.cs
- AsyncDataRequest.cs
- BuildProviderCollection.cs
- StaticFileHandler.cs