Code:
/ 4.0 / 4.0 / DEVDIV_TFS / Dev10 / Releases / RTMRel / wpf / src / Core / CSharp / MS / Internal / FontFace / PhysicalFontFamily.cs / 1305600 / PhysicalFontFamily.cs
//----------------------------------------------------------------------------
//
//
// Copyright (C) Microsoft Corporation. All rights reserved.
//
//
//
// Description: The PhysicalFontFamily class
//
// History:
// 03/04/2004 : mleonov - Created a new file for PhysicalFontFamily. It was in FontCollection.cs before.
//
//---------------------------------------------------------------------------
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.Security;
using System.Security.Permissions;
using System.Text;
using System.Windows;
using System.Windows.Markup;
using System.Windows.Media;
using System.Windows.Media.TextFormatting;
using MS.Internal;
using MS.Internal.FontCache;
using MS.Internal.TextFormatting;
namespace MS.Internal.FontFace
{
///
/// PhysicalFontFamily class represents a font family obtained from a collection of OpenType files.
///
internal sealed class PhysicalFontFamily : IFontFamily
{
private Text.TextInterface.FontFamily _family;
private IDictionary _familyNames;
// _family.FamilyNames is of type LocalizedStrings which does not support editing (Adding, Replacing, and Clearing)
// IFontFamily.Names is passed to a LanguageSpecificStringDictionary which is exposed publicly and allows editing
// operations. Thus to convert from IDictionary to IDictionary we had
// 2 approaches:
// - Copying the elements into a new IDictionary
// - Implement a new class that wraps the IDictionary and allow
// editing operations
// The second approach will eventually copy elements into a new structure that allows editing when
// an editing operation is performed. Since this dictionary is not expected to hold a huge number of elements
// we chose to do the copying upfront and not lazily and hence use the first approach.
//
private static IDictionary ConvertDictionary(IDictionary dictionary)
{
Dictionary convertedDictionary = new Dictionary();
foreach (KeyValuePair pair in dictionary)
{
convertedDictionary.Add(XmlLanguage.GetLanguage(pair.Key.Name), pair.Value);
}
return convertedDictionary;
}
internal PhysicalFontFamily(Text.TextInterface.FontFamily family)
{
Invariant.Assert(family != null);
_family = family;
}
///
/// Get typeface metrics of the specified typeface
///
ITypefaceMetrics IFontFamily.GetTypefaceMetrics(
FontStyle style,
FontWeight weight,
FontStretch stretch
)
{
return GetGlyphTypeface(style, weight, stretch);
}
///
/// Look up device font for the typeface.
///
IDeviceFont IFontFamily.GetDeviceFont(FontStyle style, FontWeight weight, FontStretch stretch)
{
return null;
}
///
/// Indexer that indexes the underlying family name table via CultureInfo
///
///
IDictionary IFontFamily.Names
{
///
/// Critical - calls into critical Text.TextInterface.FontFamily property
/// TreatAsSafe - FamilyNames are safe to expose.
///
[SecurityCritical, SecurityTreatAsSafe]
get
{
if (_familyNames == null)
{
_familyNames = ConvertDictionary(_family.FamilyNames);
}
return _familyNames;
}
}
///
/// Get the matching glyph typeface of a specified style
///
/// font style
/// font weight
/// font stretch
/// matching font face
///
/// Critical - as this returns GlyphTypeface created from internal constructor
/// which exposes windows font information.
/// Safe - as this doesn't allow you to create a GlyphTypeface object for a specific
/// font and thus won't allow you to figure what fonts might be installed on
/// the machine.
///
[SecurityCritical, SecurityTreatAsSafe]
internal GlyphTypeface GetGlyphTypeface(
FontStyle style,
FontWeight weight,
FontStretch stretch
)
{
Text.TextInterface.Font bestMatch = _family.GetFirstMatchingFont((Text.TextInterface.FontWeight)weight.ToOpenTypeWeight(),
(Text.TextInterface.FontStretch)stretch.ToOpenTypeStretch(),
(Text.TextInterface.FontStyle) style.GetStyleForInternalConstruction());
Debug.Assert(bestMatch != null);
return new GlyphTypeface(bestMatch);
}
///
/// Get the matching typeface for the specified target style that also supports
/// glyph mapping of the specified character string.
///
/// font style
/// font weight
/// font stretch
/// character string
/// culture used for digit substitution or null
/// number of characters with valid glyph mapped
/// offset to the character mapping to a valid glyph
/// matching typeface
///
/// Critical - as this returns GlyphTypeface created from internal constructor
/// which exposes windows font information.
/// Safe - as this doesn't allow you to create a GlyphTypeface object for a specific
/// font and thus won't allow you to figure what fonts might be installed on
/// the machine.
///
[SecurityCritical, SecurityTreatAsSafe]
internal GlyphTypeface MapGlyphTypeface(
FontStyle style,
FontWeight weight,
FontStretch stretch,
CharacterBufferRange charString,
CultureInfo digitCulture,
ref int advance,
ref int nextValid
)
{
int smallestInvalid = charString.Length;
// Add all the cached font faces to a priority queue.
MatchingStyle targetStyle = new MatchingStyle(style, weight, stretch);
PriorityQueue queue = new PriorityQueue(
checked((int)_family.Count),
new MatchingFaceComparer(targetStyle));
foreach (Text.TextInterface.Font face in _family)
{
queue.Push(new MatchingFace(face));
}
// Remember the best style match.
MS.Internal.Text.TextInterface.Font bestStyleTypeface = null;
// Iterate in priority order.
for (; queue.Count != 0; queue.Pop())
{
int invalid = 0;
MS.Internal.Text.TextInterface.Font font = queue.Top.FontFace;
int valid = MapCharacters(font, charString, digitCulture, ref invalid);
if (valid > 0)
{
if (smallestInvalid > 0 && smallestInvalid < valid)
{
// advance only to smallestInvalid because there's a better match after that
advance = smallestInvalid;
nextValid = 0;
}
else
{
advance = valid;
nextValid = invalid;
}
return new GlyphTypeface(font);
}
else
{
if (invalid < smallestInvalid)
{
// keep track of the current shortest length of invalid characters,
smallestInvalid = invalid;
}
if (bestStyleTypeface == null)
{
bestStyleTypeface = font;
}
}
}
// no face can map the specified character string,
// fall back to the closest style match
advance = 0;
nextValid = smallestInvalid;
Debug.Assert(bestStyleTypeface != null);
return new GlyphTypeface(bestStyleTypeface);
}
///
/// Element type for priority queue used by MapGlyphTypeface.
///
private struct MatchingFace
{
///
/// Critical - calls into critical Text.TextInterface.Font properties
///
[SecurityCritical]
internal MatchingFace(Text.TextInterface.Font face)
{
_face = face;
_style = new MatchingStyle(new FontStyle((int)face.Style), new FontWeight((int)face.Weight), new FontStretch((int)face.Stretch));
}
internal Text.TextInterface.Font FontFace
{
get { return _face; }
}
internal MatchingStyle MatchingStyle
{
get { return _style; }
}
private Text.TextInterface.Font _face;
private MatchingStyle _style;
}
///
/// Comparer for priority queue used by MapGlyphTypeface.
///
private class MatchingFaceComparer : IComparer
{
internal MatchingFaceComparer(MatchingStyle targetStyle)
{
_targetStyle = targetStyle;
}
int IComparer.Compare(MatchingFace a, MatchingFace b)
{
return a.MatchingStyle.IsBetterMatch(_targetStyle, b.MatchingStyle) ? -1 : 1;
}
private MatchingStyle _targetStyle;
}
///
/// Map character supported by the typeface
///
///
/// Combining mark is considered part of the character that may be supported
/// thru precomposed form or OpenType glyph substitution table.
///
private int MapCharacters(
MS.Internal.Text.TextInterface.Font font,
CharacterBufferRange unicodeString,
CultureInfo digitCulture,
ref int nextValid
)
{
DigitMap digitMap = new DigitMap(digitCulture);
int sizeofChar = 0;
int advance;
// skip all the leading joiner characters. They need to be shaped with the
// surrounding strong characters.
advance = Classification.AdvanceWhile(unicodeString, ItemClass.JoinerClass);
if (advance >= unicodeString.Length)
{
// It is rare that the run only contains joiner characters.
// If it really happens, just return.
return advance;
}
//
// If the run starts with combining marks, we will not be able to find base characters for them
// within the run. These combining marks will be mapped to their best fonts as normal characters.
//
bool hasBaseChar = false;
// Determine how many characters we can advance, i.e., find the first invalid character.
for (; advance < unicodeString.Length; advance += sizeofChar)
{
// Get the character and apply digit substitution, if any.
int originalChar = Classification.UnicodeScalar(
new CharacterBufferRange(unicodeString, advance, unicodeString.Length - advance),
out sizeofChar
);
if (Classification.IsJoiner(originalChar))
continue;
if (!Classification.IsCombining(originalChar))
{
hasBaseChar = true;
}
else if (hasBaseChar)
{
// continue to advance for combining mark with base char
continue;
}
int ch = digitMap[originalChar];
if (font.HasCharacter(checked((uint)ch)))
continue;
// If ch is a substituted character, can we substitute a different character instead?
if (ch != originalChar)
{
ch = DigitMap.GetFallbackCharacter(ch);
if (ch != 0 && font.HasCharacter(checked((uint)ch)))
continue;
}
// If we fall through to here it's invalid.
break;
}
// UnicodeScalar won't return a sizeofChar that exceeds the string length.
Debug.Assert(advance <= unicodeString.Length);
// Find the next valid character.
if (advance < unicodeString.Length)
{
// UnicodeScalar won't return a sizeofChar that exceeds the string length.
Debug.Assert(advance + sizeofChar <= unicodeString.Length);
for (nextValid = advance + sizeofChar; nextValid < unicodeString.Length; nextValid += sizeofChar)
{
// Get the character.
int originalChar = Classification.UnicodeScalar(
new CharacterBufferRange(unicodeString, nextValid, unicodeString.Length - nextValid),
out sizeofChar
);
// Apply digit substitution, if any.
int ch = digitMap[originalChar];
//
// Combining mark should always be shaped by the same font as the base char.
// If the physical font is invalid for the base char, it should also be invalid for the
// following combining mark so that both characters will go onto the same fallback font.
// - When the fallback font is physical font, the font will be valid for both characters
// if and only if it is valid for the base char. Otherwise, it will be invalid for both.
// - When the fallback font is composite font, it maps the combining mark to the same font
// as the base char such that they will eventually be resolved to the same physical font.
// That means FamilyMap for the combining mark is not used when it follows a base char.
//
// The same goes for joiner. Note that "hasBaseChar" here indicates if there is an invalid base
// char in front.
if (Classification.IsJoiner(ch)
|| (hasBaseChar && Classification.IsCombining(ch))
)
continue;
// If we have a glyph it's valid.
if (font.HasCharacter(checked((uint)ch)))
break;
// If ch is a substituted character, can we substitute a different character instead?
if (ch != originalChar)
{
ch = DigitMap.GetFallbackCharacter(ch);
if (ch != 0 && font.HasCharacter(checked((uint)ch)))
break;
}
}
}
return advance;
}
///
/// Distance from character cell top to English baseline relative to em size.
///
///
/// Critical - calls into critical Text.TextInterface.FontFamily property
/// TreatAsSafe - Metrics are safe to expose.
///
[SecurityCritical, SecurityTreatAsSafe]
double IFontFamily.Baseline(double emSize, double toReal, double pixelsPerDip, TextFormattingMode textFormattingMode)
{
if (textFormattingMode == TextFormattingMode.Ideal)
{
return emSize * _family.Metrics.Baseline;
}
else
{
double realEmSize = emSize * toReal;
return TextFormatterImp.RoundDipForDisplayMode(_family.DisplayMetrics((float)(realEmSize), checked((float)pixelsPerDip)).Baseline * realEmSize) / toReal;
}
}
double IFontFamily.BaselineDesign
{
get
{
return ((IFontFamily)this).Baseline(1, 1, 1, TextFormattingMode.Ideal);
}
}
double IFontFamily.LineSpacingDesign
{
get
{
return ((IFontFamily)this).LineSpacing(1, 1, 1, TextFormattingMode.Ideal);
}
}
///
/// Recommended baseline-to-baseline distance for text in this font
///
///
/// Critical - calls into critical Text.TextInterface.FontFamily property
/// TreatAsSafe - Metrics are safe to expose.
///
[SecurityCritical, SecurityTreatAsSafe]
double IFontFamily.LineSpacing(double emSize, double toReal, double pixelsPerDip, TextFormattingMode textFormattingMode)
{
if (textFormattingMode == TextFormattingMode.Ideal)
{
return emSize * _family.Metrics.LineSpacing;
}
else
{
double realEmSize = emSize * toReal;
return TextFormatterImp.RoundDipForDisplayMode(_family.DisplayMetrics((float)(realEmSize), checked((float)pixelsPerDip)).LineSpacing * realEmSize) / toReal;
}
}
ICollection IFontFamily.GetTypefaces(FontFamilyIdentifier familyIdentifier)
{
return new TypefaceCollection(new FontFamily(familyIdentifier), _family);
}
///
/// Get family name correspondent to the first n-characters of the specified character string
///
bool IFontFamily.GetMapTargetFamilyNameAndScale(
CharacterBufferRange unicodeString,
CultureInfo culture,
CultureInfo digitCulture,
double defaultSizeInEm,
out int cchAdvance,
out string targetFamilyName,
out double scaleInEm
)
{
cchAdvance = unicodeString.Length;
targetFamilyName = null;
scaleInEm = defaultSizeInEm;
return false;
}
}
}
// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
// Copyright (c) Microsoft Corporation. All rights reserved.
//----------------------------------------------------------------------------
//
//
// Copyright (C) Microsoft Corporation. All rights reserved.
//
//
//
// Description: The PhysicalFontFamily class
//
// History:
// 03/04/2004 : mleonov - Created a new file for PhysicalFontFamily. It was in FontCollection.cs before.
//
//---------------------------------------------------------------------------
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.Security;
using System.Security.Permissions;
using System.Text;
using System.Windows;
using System.Windows.Markup;
using System.Windows.Media;
using System.Windows.Media.TextFormatting;
using MS.Internal;
using MS.Internal.FontCache;
using MS.Internal.TextFormatting;
namespace MS.Internal.FontFace
{
///
/// PhysicalFontFamily class represents a font family obtained from a collection of OpenType files.
///
internal sealed class PhysicalFontFamily : IFontFamily
{
private Text.TextInterface.FontFamily _family;
private IDictionary _familyNames;
// _family.FamilyNames is of type LocalizedStrings which does not support editing (Adding, Replacing, and Clearing)
// IFontFamily.Names is passed to a LanguageSpecificStringDictionary which is exposed publicly and allows editing
// operations. Thus to convert from IDictionary to IDictionary we had
// 2 approaches:
// - Copying the elements into a new IDictionary
// - Implement a new class that wraps the IDictionary and allow
// editing operations
// The second approach will eventually copy elements into a new structure that allows editing when
// an editing operation is performed. Since this dictionary is not expected to hold a huge number of elements
// we chose to do the copying upfront and not lazily and hence use the first approach.
//
private static IDictionary ConvertDictionary(IDictionary dictionary)
{
Dictionary convertedDictionary = new Dictionary();
foreach (KeyValuePair pair in dictionary)
{
convertedDictionary.Add(XmlLanguage.GetLanguage(pair.Key.Name), pair.Value);
}
return convertedDictionary;
}
internal PhysicalFontFamily(Text.TextInterface.FontFamily family)
{
Invariant.Assert(family != null);
_family = family;
}
///
/// Get typeface metrics of the specified typeface
///
ITypefaceMetrics IFontFamily.GetTypefaceMetrics(
FontStyle style,
FontWeight weight,
FontStretch stretch
)
{
return GetGlyphTypeface(style, weight, stretch);
}
///
/// Look up device font for the typeface.
///
IDeviceFont IFontFamily.GetDeviceFont(FontStyle style, FontWeight weight, FontStretch stretch)
{
return null;
}
///
/// Indexer that indexes the underlying family name table via CultureInfo
///
///
IDictionary IFontFamily.Names
{
///
/// Critical - calls into critical Text.TextInterface.FontFamily property
/// TreatAsSafe - FamilyNames are safe to expose.
///
[SecurityCritical, SecurityTreatAsSafe]
get
{
if (_familyNames == null)
{
_familyNames = ConvertDictionary(_family.FamilyNames);
}
return _familyNames;
}
}
///
/// Get the matching glyph typeface of a specified style
///
/// font style
/// font weight
/// font stretch
/// matching font face
///
/// Critical - as this returns GlyphTypeface created from internal constructor
/// which exposes windows font information.
/// Safe - as this doesn't allow you to create a GlyphTypeface object for a specific
/// font and thus won't allow you to figure what fonts might be installed on
/// the machine.
///
[SecurityCritical, SecurityTreatAsSafe]
internal GlyphTypeface GetGlyphTypeface(
FontStyle style,
FontWeight weight,
FontStretch stretch
)
{
Text.TextInterface.Font bestMatch = _family.GetFirstMatchingFont((Text.TextInterface.FontWeight)weight.ToOpenTypeWeight(),
(Text.TextInterface.FontStretch)stretch.ToOpenTypeStretch(),
(Text.TextInterface.FontStyle) style.GetStyleForInternalConstruction());
Debug.Assert(bestMatch != null);
return new GlyphTypeface(bestMatch);
}
///
/// Get the matching typeface for the specified target style that also supports
/// glyph mapping of the specified character string.
///
/// font style
/// font weight
/// font stretch
/// character string
/// culture used for digit substitution or null
/// number of characters with valid glyph mapped
/// offset to the character mapping to a valid glyph
/// matching typeface
///
/// Critical - as this returns GlyphTypeface created from internal constructor
/// which exposes windows font information.
/// Safe - as this doesn't allow you to create a GlyphTypeface object for a specific
/// font and thus won't allow you to figure what fonts might be installed on
/// the machine.
///
[SecurityCritical, SecurityTreatAsSafe]
internal GlyphTypeface MapGlyphTypeface(
FontStyle style,
FontWeight weight,
FontStretch stretch,
CharacterBufferRange charString,
CultureInfo digitCulture,
ref int advance,
ref int nextValid
)
{
int smallestInvalid = charString.Length;
// Add all the cached font faces to a priority queue.
MatchingStyle targetStyle = new MatchingStyle(style, weight, stretch);
PriorityQueue queue = new PriorityQueue(
checked((int)_family.Count),
new MatchingFaceComparer(targetStyle));
foreach (Text.TextInterface.Font face in _family)
{
queue.Push(new MatchingFace(face));
}
// Remember the best style match.
MS.Internal.Text.TextInterface.Font bestStyleTypeface = null;
// Iterate in priority order.
for (; queue.Count != 0; queue.Pop())
{
int invalid = 0;
MS.Internal.Text.TextInterface.Font font = queue.Top.FontFace;
int valid = MapCharacters(font, charString, digitCulture, ref invalid);
if (valid > 0)
{
if (smallestInvalid > 0 && smallestInvalid < valid)
{
// advance only to smallestInvalid because there's a better match after that
advance = smallestInvalid;
nextValid = 0;
}
else
{
advance = valid;
nextValid = invalid;
}
return new GlyphTypeface(font);
}
else
{
if (invalid < smallestInvalid)
{
// keep track of the current shortest length of invalid characters,
smallestInvalid = invalid;
}
if (bestStyleTypeface == null)
{
bestStyleTypeface = font;
}
}
}
// no face can map the specified character string,
// fall back to the closest style match
advance = 0;
nextValid = smallestInvalid;
Debug.Assert(bestStyleTypeface != null);
return new GlyphTypeface(bestStyleTypeface);
}
///
/// Element type for priority queue used by MapGlyphTypeface.
///
private struct MatchingFace
{
///
/// Critical - calls into critical Text.TextInterface.Font properties
///
[SecurityCritical]
internal MatchingFace(Text.TextInterface.Font face)
{
_face = face;
_style = new MatchingStyle(new FontStyle((int)face.Style), new FontWeight((int)face.Weight), new FontStretch((int)face.Stretch));
}
internal Text.TextInterface.Font FontFace
{
get { return _face; }
}
internal MatchingStyle MatchingStyle
{
get { return _style; }
}
private Text.TextInterface.Font _face;
private MatchingStyle _style;
}
///
/// Comparer for priority queue used by MapGlyphTypeface.
///
private class MatchingFaceComparer : IComparer
{
internal MatchingFaceComparer(MatchingStyle targetStyle)
{
_targetStyle = targetStyle;
}
int IComparer.Compare(MatchingFace a, MatchingFace b)
{
return a.MatchingStyle.IsBetterMatch(_targetStyle, b.MatchingStyle) ? -1 : 1;
}
private MatchingStyle _targetStyle;
}
///
/// Map character supported by the typeface
///
///
/// Combining mark is considered part of the character that may be supported
/// thru precomposed form or OpenType glyph substitution table.
///
private int MapCharacters(
MS.Internal.Text.TextInterface.Font font,
CharacterBufferRange unicodeString,
CultureInfo digitCulture,
ref int nextValid
)
{
DigitMap digitMap = new DigitMap(digitCulture);
int sizeofChar = 0;
int advance;
// skip all the leading joiner characters. They need to be shaped with the
// surrounding strong characters.
advance = Classification.AdvanceWhile(unicodeString, ItemClass.JoinerClass);
if (advance >= unicodeString.Length)
{
// It is rare that the run only contains joiner characters.
// If it really happens, just return.
return advance;
}
//
// If the run starts with combining marks, we will not be able to find base characters for them
// within the run. These combining marks will be mapped to their best fonts as normal characters.
//
bool hasBaseChar = false;
// Determine how many characters we can advance, i.e., find the first invalid character.
for (; advance < unicodeString.Length; advance += sizeofChar)
{
// Get the character and apply digit substitution, if any.
int originalChar = Classification.UnicodeScalar(
new CharacterBufferRange(unicodeString, advance, unicodeString.Length - advance),
out sizeofChar
);
if (Classification.IsJoiner(originalChar))
continue;
if (!Classification.IsCombining(originalChar))
{
hasBaseChar = true;
}
else if (hasBaseChar)
{
// continue to advance for combining mark with base char
continue;
}
int ch = digitMap[originalChar];
if (font.HasCharacter(checked((uint)ch)))
continue;
// If ch is a substituted character, can we substitute a different character instead?
if (ch != originalChar)
{
ch = DigitMap.GetFallbackCharacter(ch);
if (ch != 0 && font.HasCharacter(checked((uint)ch)))
continue;
}
// If we fall through to here it's invalid.
break;
}
// UnicodeScalar won't return a sizeofChar that exceeds the string length.
Debug.Assert(advance <= unicodeString.Length);
// Find the next valid character.
if (advance < unicodeString.Length)
{
// UnicodeScalar won't return a sizeofChar that exceeds the string length.
Debug.Assert(advance + sizeofChar <= unicodeString.Length);
for (nextValid = advance + sizeofChar; nextValid < unicodeString.Length; nextValid += sizeofChar)
{
// Get the character.
int originalChar = Classification.UnicodeScalar(
new CharacterBufferRange(unicodeString, nextValid, unicodeString.Length - nextValid),
out sizeofChar
);
// Apply digit substitution, if any.
int ch = digitMap[originalChar];
//
// Combining mark should always be shaped by the same font as the base char.
// If the physical font is invalid for the base char, it should also be invalid for the
// following combining mark so that both characters will go onto the same fallback font.
// - When the fallback font is physical font, the font will be valid for both characters
// if and only if it is valid for the base char. Otherwise, it will be invalid for both.
// - When the fallback font is composite font, it maps the combining mark to the same font
// as the base char such that they will eventually be resolved to the same physical font.
// That means FamilyMap for the combining mark is not used when it follows a base char.
//
// The same goes for joiner. Note that "hasBaseChar" here indicates if there is an invalid base
// char in front.
if (Classification.IsJoiner(ch)
|| (hasBaseChar && Classification.IsCombining(ch))
)
continue;
// If we have a glyph it's valid.
if (font.HasCharacter(checked((uint)ch)))
break;
// If ch is a substituted character, can we substitute a different character instead?
if (ch != originalChar)
{
ch = DigitMap.GetFallbackCharacter(ch);
if (ch != 0 && font.HasCharacter(checked((uint)ch)))
break;
}
}
}
return advance;
}
///
/// Distance from character cell top to English baseline relative to em size.
///
///
/// Critical - calls into critical Text.TextInterface.FontFamily property
/// TreatAsSafe - Metrics are safe to expose.
///
[SecurityCritical, SecurityTreatAsSafe]
double IFontFamily.Baseline(double emSize, double toReal, double pixelsPerDip, TextFormattingMode textFormattingMode)
{
if (textFormattingMode == TextFormattingMode.Ideal)
{
return emSize * _family.Metrics.Baseline;
}
else
{
double realEmSize = emSize * toReal;
return TextFormatterImp.RoundDipForDisplayMode(_family.DisplayMetrics((float)(realEmSize), checked((float)pixelsPerDip)).Baseline * realEmSize) / toReal;
}
}
double IFontFamily.BaselineDesign
{
get
{
return ((IFontFamily)this).Baseline(1, 1, 1, TextFormattingMode.Ideal);
}
}
double IFontFamily.LineSpacingDesign
{
get
{
return ((IFontFamily)this).LineSpacing(1, 1, 1, TextFormattingMode.Ideal);
}
}
///
/// Recommended baseline-to-baseline distance for text in this font
///
///
/// Critical - calls into critical Text.TextInterface.FontFamily property
/// TreatAsSafe - Metrics are safe to expose.
///
[SecurityCritical, SecurityTreatAsSafe]
double IFontFamily.LineSpacing(double emSize, double toReal, double pixelsPerDip, TextFormattingMode textFormattingMode)
{
if (textFormattingMode == TextFormattingMode.Ideal)
{
return emSize * _family.Metrics.LineSpacing;
}
else
{
double realEmSize = emSize * toReal;
return TextFormatterImp.RoundDipForDisplayMode(_family.DisplayMetrics((float)(realEmSize), checked((float)pixelsPerDip)).LineSpacing * realEmSize) / toReal;
}
}
ICollection IFontFamily.GetTypefaces(FontFamilyIdentifier familyIdentifier)
{
return new TypefaceCollection(new FontFamily(familyIdentifier), _family);
}
///
/// Get family name correspondent to the first n-characters of the specified character string
///
bool IFontFamily.GetMapTargetFamilyNameAndScale(
CharacterBufferRange unicodeString,
CultureInfo culture,
CultureInfo digitCulture,
double defaultSizeInEm,
out int cchAdvance,
out string targetFamilyName,
out double scaleInEm
)
{
cchAdvance = unicodeString.Length;
targetFamilyName = null;
scaleInEm = defaultSizeInEm;
return false;
}
}
}
// 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
- TreeViewTemplateSelector.cs
- RtfControlWordInfo.cs
- DrawingAttributesDefaultValueFactory.cs
- Monitor.cs
- CallbackHandler.cs
- HelpFileFileNameEditor.cs
- TextStore.cs
- StandardCommands.cs
- OutputCacheModule.cs
- CodeArgumentReferenceExpression.cs
- BufferedReadStream.cs
- Exceptions.cs
- ScrollPattern.cs
- SortExpressionBuilder.cs
- XsdDataContractImporter.cs
- ButtonBase.cs
- KnownAssemblyEntry.cs
- RealizationDrawingContextWalker.cs
- PolygonHotSpot.cs
- XmlNavigatorStack.cs
- InternalControlCollection.cs
- SimpleFileLog.cs
- TabItemWrapperAutomationPeer.cs
- NamedPermissionSet.cs
- FormCollection.cs
- System.Data_BID.cs
- webclient.cs
- XmlSchemaSubstitutionGroup.cs
- AbstractDataSvcMapFileLoader.cs
- PersonalizationStateInfo.cs
- ContextMenuStrip.cs
- WebServicesSection.cs
- HtmlWindow.cs
- TextReader.cs
- XmlAnyAttributeAttribute.cs
- SystemDiagnosticsSection.cs
- Registry.cs
- RepeaterItemCollection.cs
- DataStorage.cs
- VSDExceptions.cs
- Stylesheet.cs
- SignerInfo.cs
- ActionFrame.cs
- SqlCharStream.cs
- ProfilePropertyNameValidator.cs
- srgsitem.cs
- CopyCodeAction.cs
- Triplet.cs
- MenuCommands.cs
- MimeImporter.cs
- XslVisitor.cs
- ImmutablePropertyDescriptorGridEntry.cs
- ParameterCollection.cs
- ComboBoxAutomationPeer.cs
- AppearanceEditorPart.cs
- DataControlPagerLinkButton.cs
- TableCellAutomationPeer.cs
- DesignerDataRelationship.cs
- DataConnectionHelper.cs
- StackBuilderSink.cs
- ListBindableAttribute.cs
- XmlNamespaceMappingCollection.cs
- StructuredProperty.cs
- SymbolMethod.cs
- DataServiceHostWrapper.cs
- EmptyStringExpandableObjectConverter.cs
- Parameter.cs
- TreeIterator.cs
- SizeAnimation.cs
- ExpandedWrapper.cs
- ADConnectionHelper.cs
- SQLDateTimeStorage.cs
- __Filters.cs
- TextSegment.cs
- TemplateBuilder.cs
- Operators.cs
- HtmlShimManager.cs
- StateMachineDesignerPaint.cs
- StylusButton.cs
- SplineKeyFrames.cs
- NativeMethods.cs
- ProviderCommandInfoUtils.cs
- SAPICategories.cs
- MatchAllMessageFilter.cs
- ClientProxyGenerator.cs
- RenderDataDrawingContext.cs
- TreeSet.cs
- EmptyWithCancelationCheckWorkItem.cs
- SamlSerializer.cs
- IIS7WorkerRequest.cs
- TextFormattingConverter.cs
- DataBoundControlAdapter.cs
- SocketInformation.cs
- DesignTimeResourceProviderFactoryAttribute.cs
- DbConnectionPoolGroup.cs
- GACIdentityPermission.cs
- HierarchicalDataSourceControl.cs
- XpsColorContext.cs
- SpellerHighlightLayer.cs
- SupportsEventValidationAttribute.cs