Code:
/ Net / Net / 3.5.50727.3053 / DEVDIV / depot / DevDiv / releases / Orcas / SP / wpf / src / Core / CSharp / MS / Internal / FontFace / FontFamilyIdentifier.cs / 1 / FontFamilyIdentifier.cs
//----------------------------------------------------------------------------
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
// Description: FontFamilyIdentifier type
//
// History:
// 5/6/2005 : niklasb - Created
//
//---------------------------------------------------------------------------
using System;
using System.Diagnostics;
using System.Security;
using System.Text;
using System.Windows;
using System.Windows.Media;
using System.Windows.Media.TextFormatting;
using MS.Utility;
using MS.Internal;
using MS.Internal.Shaping;
using MS.Internal.FontCache;
using MS.Internal.TextFormatting;
namespace MS.Internal.FontFace
{
///
/// The FontFamilyIdentifier value type encapsulates a friendly name and base Uri
/// and provides access to the corresponding canonical name(s) via an indexer.
///
//
// The friendly name is a string in the format passed to the FontFamily constructor and the
// corresponding type converter. It comprises one or more font family references separated by
// commas (with literal commas escaped by doubling). Each font family reference comprises a
// family name and an optional location.
//
// Pseudo-BNF:
//
// friendlyName = ESCAPED(fontFamilyReference) *( "," ESCAPED(fontFamilyReference) )
// fontFamilyReference = [ location "#" ] escapedFamilyName
// location = "" | relativeUri | absoluteUri
//
// where ESCAPED(fontFamilyReference) denotes a fontFamilyReference in which comma characters (",")
// have been replaced by doubled commas (",,").
//
// Both the location (if present) and the escapedFamilyName may contain hexadecimal escape
// sequences in the form %XX as in URI references.
//
// The location may be an empty string so "#ARIAL" is a valid font family reference;
// in fact it is the normalized form of "Arial".
//
// Canonicalization
//
// Canonicalization is the process of converting a font family reference to an absolute URI
// which specifies the font family location, plus a fragment which specifies the family name.
// The family name is converted to uppercase (since family names are not case-sensitive) but
// the rest of the URI is not.
//
// The process for canonicalizing the entire friendly name is as follows:
//
// 1. Split the friendly name into font family references.
// Treat single commas (",") as delimiters, and unescape double commas (",,").
//
// 2. Convert each font family reference to a normalized form.
// See Util.NormalizeFontFamilyReference.
//
// 3. Canonicalize the normalized font family reference.
// See Util.GetCanonicalUriForFamily.
//
// This is essentially what the Canonicalize method does, with addition of caching the resulting
// canonical names in the TypefaceMetricsCache. To save working set, the result of canonicalization
// is stored as a single null-delimited string rather than an array of strings.
//
// Since canonicalization is potentially expensive, we do not always canonicalize the entire
// friendly name. In this case, the indexer canonicalizes the requested font family reference
// on demand. However, we still cache the result in the TypefaceMetricsCache.
//
internal struct FontFamilyIdentifier
{
///
/// FontFamilyIdentifier constructor
///
/// friendly name in the format passed to
/// FontFamily constructor and type converter.
/// Base Uri used to resolve the location part of a font family reference
/// if one exists and is relative
internal FontFamilyIdentifier(string friendlyName, Uri baseUri)
{
_friendlyName = friendlyName;
_baseUri = baseUri;
_tokenCount = (friendlyName != null) ? -1 : 0;
_canonicalReferences = null;
}
///
/// Create a FontFamilyIdentifier by concatenating two existing identifiers.
///
internal FontFamilyIdentifier(FontFamilyIdentifier first, FontFamilyIdentifier second)
{
first.Canonicalize();
second.Canonicalize();
_friendlyName = null;
_tokenCount = first._tokenCount + second._tokenCount;
_baseUri = null;
if (first._tokenCount == 0)
{
_canonicalReferences = second._canonicalReferences;
}
else if (second._tokenCount == 0)
{
_canonicalReferences = first._canonicalReferences;
}
else
{
_canonicalReferences = new CanonicalFontFamilyReference[_tokenCount];
int i = 0;
foreach (CanonicalFontFamilyReference family in first._canonicalReferences)
{
_canonicalReferences[i++] = family;
}
foreach (CanonicalFontFamilyReference family in second._canonicalReferences)
{
_canonicalReferences[i++] = family;
}
}
}
internal string Source
{
get { return _friendlyName; }
}
internal Uri BaseUri
{
get { return _baseUri; }
}
public bool Equals(FontFamilyIdentifier other)
{
if (_friendlyName == other._friendlyName && _baseUri == other._baseUri)
return true;
int c = Count;
if (other.Count != c)
return false;
if (c != 0)
{
Canonicalize();
other.Canonicalize();
for (int i = 0; i < c; ++i)
{
if (!_canonicalReferences[i].Equals(other._canonicalReferences[i]))
return false;
}
}
return true;
}
public override bool Equals(object obj)
{
return obj is FontFamilyIdentifier && Equals((FontFamilyIdentifier)obj);
}
public override int GetHashCode()
{
int hash = 1;
if (Count != 0)
{
Canonicalize();
foreach (CanonicalFontFamilyReference family in _canonicalReferences)
{
hash = HashFn.HashMultiply(hash) + family.GetHashCode();
}
}
return HashFn.HashScramble(hash);
}
internal int Count
{
get
{
// negative value represents uninitialized count
if (_tokenCount < 0)
{
_tokenCount = CountTokens(_friendlyName);
}
return _tokenCount;
}
}
internal CanonicalFontFamilyReference this[int tokenIndex]
{
get
{
if (tokenIndex < 0 || tokenIndex >= Count)
throw new ArgumentOutOfRangeException("tokenIndex");
// Have we already been canonicalized?
if (_canonicalReferences != null)
{
// We have already canonicalized. This is typically the case for longer-lived
// identifiers such as belong to FontFamily objects.
return _canonicalReferences[tokenIndex];
}
else
{
// We have not already canonicalized. This is probably a short-lived object so
// it's not worthwhile to canonicalize all the names up front and cache them for
// later use. Just canonicalize each name as we need it.
// find the Nth font family reference.
int i, length;
int j = FindToken(_friendlyName, 0, out i, out length);
for (int k = 0; k < tokenIndex; ++k)
{
j = FindToken(_friendlyName, j, out i, out length);
}
// canonicalize just this font family reference
return GetCanonicalReference(i, length);
}
}
}
///
/// Critical - as it accesses canonical names as raw strings
/// Safe - as information is not returned but stored in SecurityCritical _canonicalReferences field
///
[SecurityCritical, SecurityTreatAsSafe]
internal void Canonicalize()
{
if (_canonicalReferences != null)
return;
int count = this.Count;
if (count == 0)
return;
// First look up the entire friendly name in the cache; this may enable us to
// save working set by sharing the same array of may equal FontFamilyIdentifier.
BasedFriendlyName hashKey = new BasedFriendlyName(_baseUri, _friendlyName);
CanonicalFontFamilyReference[] canonicalReferences = TypefaceMetricsCache.ReadonlyLookup(hashKey) as CanonicalFontFamilyReference[];
if (canonicalReferences == null)
{
// We need to construct a new array.
canonicalReferences = new CanonicalFontFamilyReference[count];
// Add the first canonical family reference.
int i, length;
int j = FindToken(_friendlyName, 0, out i, out length);
canonicalReferences[0] = GetCanonicalReference(i, length);
// Add subsequent family references.
for (int k = 1; k < count; ++k)
{
j = FindToken(_friendlyName, j, out i, out length);
canonicalReferences[k] = GetCanonicalReference(i, length);
}
// Add the array to the cache.
TypefaceMetricsCache.Add(hashKey, canonicalReferences);
}
// for thread safety, we assign to the field only after the array is fully initialized
_canonicalReferences = canonicalReferences;
}
#region Friendly name parsing methods
private static int CountTokens(string friendlyName)
{
int count = 0;
int i, length;
int j = FindToken(friendlyName, 0, out i, out length);
while (j >= 0)
{
// Limit the number of family names in a single string.
if (++count == MaxFamilyNamePerFamilyMapTarget)
break;
j = FindToken(friendlyName, j, out i, out length);
}
return count;
}
///
/// Scans the specified friendly name starting at the specified index and gets the index and
/// length of the first token it finds.
///
/// friendly name containing zero or more comma-delimited tokens
/// character index to scan from
/// receives the index of the token (or zero if none)
/// receives the length of the token (or zero if none)
/// If a token was found, the return value is a positive integer specifying where to begin
/// scanning for the next token; if no token was found, the return value is -1.
private static int FindToken(string friendlyName, int i, out int tokenIndex, out int tokenLength)
{
int length = friendlyName.Length;
while (i < length)
{
// skip leading whitespace
while (i < length && char.IsWhiteSpace(friendlyName[i]))
++i;
int begin = i;
// find delimiter or end of string
while (i < length)
{
if (friendlyName[i] == FamilyNameDelimiter)
{
if (i + 1 < length && friendlyName[i + 1] == FamilyNameDelimiter)
{
// Don't treat double commas as the family name delimiter.
i += 2;
}
else
{
break; // single comma delimiter
}
}
else if (friendlyName[i] == '\0')
{
break; // might as well treat null as a delimiter too
}
else
{
++i;
}
}
// exclude trailing whitespace
int end = i;
while (end > begin && char.IsWhiteSpace(friendlyName[end - 1]))
--end;
// make sure it's not an empty string
if (begin < end)
{
tokenIndex = begin;
tokenLength = end - begin;
return i + 1;
}
// continue after delimiter
++i;
}
// no token
tokenIndex = length;
tokenLength = 0;
return -1;
}
private CanonicalFontFamilyReference GetCanonicalReference(int startIndex, int length)
{
string normalizedString = Util.GetNormalizedFontFamilyReference(_friendlyName, startIndex, length);
// For caching normalized names, we use a different type of key which does not compare equal
// to the keys we used for caching friendly names.
BasedNormalizedName hashKey = new BasedNormalizedName(_baseUri, normalizedString);
// Look up the normalized string and base URI in the cache?
CanonicalFontFamilyReference canonicalReference = TypefaceMetricsCache.ReadonlyLookup(hashKey) as CanonicalFontFamilyReference;
// Do we already have a cached font family reference?
if (canonicalReference == null)
{
// Not in cache. Construct a new font family reference.
canonicalReference = CanonicalFontFamilyReference.Create(_baseUri, normalizedString);
// Add it to the cache.
TypefaceMetricsCache.Add(hashKey, canonicalReference);
}
return canonicalReference;
}
#endregion
#region BasedFriendlyName and BasedNormalizedName
///
/// BasedFriendlyName represents a friendly name with an associated URI or use as a hash key.
///
private sealed class BasedFriendlyName : BasedName
{
public BasedFriendlyName(Uri baseUri, string name)
: base(baseUri, name)
{
}
public override int GetHashCode()
{
// Specify a different seed than BasedNormalizedName
return InternalGetHashCode(1);
}
public override bool Equals(object obj)
{
// Only compare equal to other BasedFriendlyName objects
return InternalEquals(obj as BasedFriendlyName);
}
}
///
/// BasedNormalizedName represents a normalized name with an associated URI or use as a hash key.
///
private sealed class BasedNormalizedName : BasedName
{
public BasedNormalizedName(Uri baseUri, string name)
: base(baseUri, name)
{
}
public override int GetHashCode()
{
// Specify a different seed than BasedFriendlyName
return InternalGetHashCode(int.MaxValue);
}
public override bool Equals(object obj)
{
// Only compare equal to other BasedNormalizedName objects
return InternalEquals(obj as BasedNormalizedName);
}
}
///
/// BasedName implements shared functionality of BasedFriendlyName and BasedNormalizedName.
/// The reason for the two derived classes (and for not just using Pair) is that we don't
/// want these two different types of keys to compare equal.
///
private abstract class BasedName
{
private Uri _baseUri;
private string _name;
protected BasedName(Uri baseUri, string name)
{
_baseUri = baseUri;
_name = name;
}
public abstract override int GetHashCode();
public abstract override bool Equals(object obj);
protected int InternalGetHashCode(int seed)
{
int hash = seed;
if (_baseUri != null)
hash += HashFn.HashMultiply(_baseUri.GetHashCode());
if (_name != null)
hash = HashFn.HashMultiply(hash) + _name.GetHashCode();
return HashFn.HashScramble(hash);
}
protected bool InternalEquals(BasedName other)
{
return other != null &&
other._baseUri == _baseUri &&
other._name == _name;
}
}
#endregion
private string _friendlyName;
private Uri _baseUri;
private int _tokenCount;
private CanonicalFontFamilyReference[] _canonicalReferences;
internal const char FamilyNameDelimiter = ',';
internal const int MaxFamilyNamePerFamilyMapTarget = 32;
}
}
// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
//----------------------------------------------------------------------------
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
// Description: FontFamilyIdentifier type
//
// History:
// 5/6/2005 : niklasb - Created
//
//---------------------------------------------------------------------------
using System;
using System.Diagnostics;
using System.Security;
using System.Text;
using System.Windows;
using System.Windows.Media;
using System.Windows.Media.TextFormatting;
using MS.Utility;
using MS.Internal;
using MS.Internal.Shaping;
using MS.Internal.FontCache;
using MS.Internal.TextFormatting;
namespace MS.Internal.FontFace
{
///
/// The FontFamilyIdentifier value type encapsulates a friendly name and base Uri
/// and provides access to the corresponding canonical name(s) via an indexer.
///
//
// The friendly name is a string in the format passed to the FontFamily constructor and the
// corresponding type converter. It comprises one or more font family references separated by
// commas (with literal commas escaped by doubling). Each font family reference comprises a
// family name and an optional location.
//
// Pseudo-BNF:
//
// friendlyName = ESCAPED(fontFamilyReference) *( "," ESCAPED(fontFamilyReference) )
// fontFamilyReference = [ location "#" ] escapedFamilyName
// location = "" | relativeUri | absoluteUri
//
// where ESCAPED(fontFamilyReference) denotes a fontFamilyReference in which comma characters (",")
// have been replaced by doubled commas (",,").
//
// Both the location (if present) and the escapedFamilyName may contain hexadecimal escape
// sequences in the form %XX as in URI references.
//
// The location may be an empty string so "#ARIAL" is a valid font family reference;
// in fact it is the normalized form of "Arial".
//
// Canonicalization
//
// Canonicalization is the process of converting a font family reference to an absolute URI
// which specifies the font family location, plus a fragment which specifies the family name.
// The family name is converted to uppercase (since family names are not case-sensitive) but
// the rest of the URI is not.
//
// The process for canonicalizing the entire friendly name is as follows:
//
// 1. Split the friendly name into font family references.
// Treat single commas (",") as delimiters, and unescape double commas (",,").
//
// 2. Convert each font family reference to a normalized form.
// See Util.NormalizeFontFamilyReference.
//
// 3. Canonicalize the normalized font family reference.
// See Util.GetCanonicalUriForFamily.
//
// This is essentially what the Canonicalize method does, with addition of caching the resulting
// canonical names in the TypefaceMetricsCache. To save working set, the result of canonicalization
// is stored as a single null-delimited string rather than an array of strings.
//
// Since canonicalization is potentially expensive, we do not always canonicalize the entire
// friendly name. In this case, the indexer canonicalizes the requested font family reference
// on demand. However, we still cache the result in the TypefaceMetricsCache.
//
internal struct FontFamilyIdentifier
{
///
/// FontFamilyIdentifier constructor
///
/// friendly name in the format passed to
/// FontFamily constructor and type converter.
/// Base Uri used to resolve the location part of a font family reference
/// if one exists and is relative
internal FontFamilyIdentifier(string friendlyName, Uri baseUri)
{
_friendlyName = friendlyName;
_baseUri = baseUri;
_tokenCount = (friendlyName != null) ? -1 : 0;
_canonicalReferences = null;
}
///
/// Create a FontFamilyIdentifier by concatenating two existing identifiers.
///
internal FontFamilyIdentifier(FontFamilyIdentifier first, FontFamilyIdentifier second)
{
first.Canonicalize();
second.Canonicalize();
_friendlyName = null;
_tokenCount = first._tokenCount + second._tokenCount;
_baseUri = null;
if (first._tokenCount == 0)
{
_canonicalReferences = second._canonicalReferences;
}
else if (second._tokenCount == 0)
{
_canonicalReferences = first._canonicalReferences;
}
else
{
_canonicalReferences = new CanonicalFontFamilyReference[_tokenCount];
int i = 0;
foreach (CanonicalFontFamilyReference family in first._canonicalReferences)
{
_canonicalReferences[i++] = family;
}
foreach (CanonicalFontFamilyReference family in second._canonicalReferences)
{
_canonicalReferences[i++] = family;
}
}
}
internal string Source
{
get { return _friendlyName; }
}
internal Uri BaseUri
{
get { return _baseUri; }
}
public bool Equals(FontFamilyIdentifier other)
{
if (_friendlyName == other._friendlyName && _baseUri == other._baseUri)
return true;
int c = Count;
if (other.Count != c)
return false;
if (c != 0)
{
Canonicalize();
other.Canonicalize();
for (int i = 0; i < c; ++i)
{
if (!_canonicalReferences[i].Equals(other._canonicalReferences[i]))
return false;
}
}
return true;
}
public override bool Equals(object obj)
{
return obj is FontFamilyIdentifier && Equals((FontFamilyIdentifier)obj);
}
public override int GetHashCode()
{
int hash = 1;
if (Count != 0)
{
Canonicalize();
foreach (CanonicalFontFamilyReference family in _canonicalReferences)
{
hash = HashFn.HashMultiply(hash) + family.GetHashCode();
}
}
return HashFn.HashScramble(hash);
}
internal int Count
{
get
{
// negative value represents uninitialized count
if (_tokenCount < 0)
{
_tokenCount = CountTokens(_friendlyName);
}
return _tokenCount;
}
}
internal CanonicalFontFamilyReference this[int tokenIndex]
{
get
{
if (tokenIndex < 0 || tokenIndex >= Count)
throw new ArgumentOutOfRangeException("tokenIndex");
// Have we already been canonicalized?
if (_canonicalReferences != null)
{
// We have already canonicalized. This is typically the case for longer-lived
// identifiers such as belong to FontFamily objects.
return _canonicalReferences[tokenIndex];
}
else
{
// We have not already canonicalized. This is probably a short-lived object so
// it's not worthwhile to canonicalize all the names up front and cache them for
// later use. Just canonicalize each name as we need it.
// find the Nth font family reference.
int i, length;
int j = FindToken(_friendlyName, 0, out i, out length);
for (int k = 0; k < tokenIndex; ++k)
{
j = FindToken(_friendlyName, j, out i, out length);
}
// canonicalize just this font family reference
return GetCanonicalReference(i, length);
}
}
}
///
/// Critical - as it accesses canonical names as raw strings
/// Safe - as information is not returned but stored in SecurityCritical _canonicalReferences field
///
[SecurityCritical, SecurityTreatAsSafe]
internal void Canonicalize()
{
if (_canonicalReferences != null)
return;
int count = this.Count;
if (count == 0)
return;
// First look up the entire friendly name in the cache; this may enable us to
// save working set by sharing the same array of may equal FontFamilyIdentifier.
BasedFriendlyName hashKey = new BasedFriendlyName(_baseUri, _friendlyName);
CanonicalFontFamilyReference[] canonicalReferences = TypefaceMetricsCache.ReadonlyLookup(hashKey) as CanonicalFontFamilyReference[];
if (canonicalReferences == null)
{
// We need to construct a new array.
canonicalReferences = new CanonicalFontFamilyReference[count];
// Add the first canonical family reference.
int i, length;
int j = FindToken(_friendlyName, 0, out i, out length);
canonicalReferences[0] = GetCanonicalReference(i, length);
// Add subsequent family references.
for (int k = 1; k < count; ++k)
{
j = FindToken(_friendlyName, j, out i, out length);
canonicalReferences[k] = GetCanonicalReference(i, length);
}
// Add the array to the cache.
TypefaceMetricsCache.Add(hashKey, canonicalReferences);
}
// for thread safety, we assign to the field only after the array is fully initialized
_canonicalReferences = canonicalReferences;
}
#region Friendly name parsing methods
private static int CountTokens(string friendlyName)
{
int count = 0;
int i, length;
int j = FindToken(friendlyName, 0, out i, out length);
while (j >= 0)
{
// Limit the number of family names in a single string.
if (++count == MaxFamilyNamePerFamilyMapTarget)
break;
j = FindToken(friendlyName, j, out i, out length);
}
return count;
}
///
/// Scans the specified friendly name starting at the specified index and gets the index and
/// length of the first token it finds.
///
/// friendly name containing zero or more comma-delimited tokens
/// character index to scan from
/// receives the index of the token (or zero if none)
/// receives the length of the token (or zero if none)
/// If a token was found, the return value is a positive integer specifying where to begin
/// scanning for the next token; if no token was found, the return value is -1.
private static int FindToken(string friendlyName, int i, out int tokenIndex, out int tokenLength)
{
int length = friendlyName.Length;
while (i < length)
{
// skip leading whitespace
while (i < length && char.IsWhiteSpace(friendlyName[i]))
++i;
int begin = i;
// find delimiter or end of string
while (i < length)
{
if (friendlyName[i] == FamilyNameDelimiter)
{
if (i + 1 < length && friendlyName[i + 1] == FamilyNameDelimiter)
{
// Don't treat double commas as the family name delimiter.
i += 2;
}
else
{
break; // single comma delimiter
}
}
else if (friendlyName[i] == '\0')
{
break; // might as well treat null as a delimiter too
}
else
{
++i;
}
}
// exclude trailing whitespace
int end = i;
while (end > begin && char.IsWhiteSpace(friendlyName[end - 1]))
--end;
// make sure it's not an empty string
if (begin < end)
{
tokenIndex = begin;
tokenLength = end - begin;
return i + 1;
}
// continue after delimiter
++i;
}
// no token
tokenIndex = length;
tokenLength = 0;
return -1;
}
private CanonicalFontFamilyReference GetCanonicalReference(int startIndex, int length)
{
string normalizedString = Util.GetNormalizedFontFamilyReference(_friendlyName, startIndex, length);
// For caching normalized names, we use a different type of key which does not compare equal
// to the keys we used for caching friendly names.
BasedNormalizedName hashKey = new BasedNormalizedName(_baseUri, normalizedString);
// Look up the normalized string and base URI in the cache?
CanonicalFontFamilyReference canonicalReference = TypefaceMetricsCache.ReadonlyLookup(hashKey) as CanonicalFontFamilyReference;
// Do we already have a cached font family reference?
if (canonicalReference == null)
{
// Not in cache. Construct a new font family reference.
canonicalReference = CanonicalFontFamilyReference.Create(_baseUri, normalizedString);
// Add it to the cache.
TypefaceMetricsCache.Add(hashKey, canonicalReference);
}
return canonicalReference;
}
#endregion
#region BasedFriendlyName and BasedNormalizedName
///
/// BasedFriendlyName represents a friendly name with an associated URI or use as a hash key.
///
private sealed class BasedFriendlyName : BasedName
{
public BasedFriendlyName(Uri baseUri, string name)
: base(baseUri, name)
{
}
public override int GetHashCode()
{
// Specify a different seed than BasedNormalizedName
return InternalGetHashCode(1);
}
public override bool Equals(object obj)
{
// Only compare equal to other BasedFriendlyName objects
return InternalEquals(obj as BasedFriendlyName);
}
}
///
/// BasedNormalizedName represents a normalized name with an associated URI or use as a hash key.
///
private sealed class BasedNormalizedName : BasedName
{
public BasedNormalizedName(Uri baseUri, string name)
: base(baseUri, name)
{
}
public override int GetHashCode()
{
// Specify a different seed than BasedFriendlyName
return InternalGetHashCode(int.MaxValue);
}
public override bool Equals(object obj)
{
// Only compare equal to other BasedNormalizedName objects
return InternalEquals(obj as BasedNormalizedName);
}
}
///
/// BasedName implements shared functionality of BasedFriendlyName and BasedNormalizedName.
/// The reason for the two derived classes (and for not just using Pair) is that we don't
/// want these two different types of keys to compare equal.
///
private abstract class BasedName
{
private Uri _baseUri;
private string _name;
protected BasedName(Uri baseUri, string name)
{
_baseUri = baseUri;
_name = name;
}
public abstract override int GetHashCode();
public abstract override bool Equals(object obj);
protected int InternalGetHashCode(int seed)
{
int hash = seed;
if (_baseUri != null)
hash += HashFn.HashMultiply(_baseUri.GetHashCode());
if (_name != null)
hash = HashFn.HashMultiply(hash) + _name.GetHashCode();
return HashFn.HashScramble(hash);
}
protected bool InternalEquals(BasedName other)
{
return other != null &&
other._baseUri == _baseUri &&
other._name == _name;
}
}
#endregion
private string _friendlyName;
private Uri _baseUri;
private int _tokenCount;
private CanonicalFontFamilyReference[] _canonicalReferences;
internal const char FamilyNameDelimiter = ',';
internal const int MaxFamilyNamePerFamilyMapTarget = 32;
}
}
// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
Link Menu

This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- WebPartUserCapability.cs
- SmiEventSink.cs
- CharConverter.cs
- SafeCryptHandles.cs
- Timer.cs
- CustomAttributeBuilder.cs
- ReferenceEqualityComparer.cs
- SqlDataSource.cs
- ScrollViewer.cs
- InputLanguage.cs
- OutputCacheProfile.cs
- ConnectionsZone.cs
- ProjectionCamera.cs
- wgx_commands.cs
- ColorDialog.cs
- Expression.DebuggerProxy.cs
- ConsumerConnectionPoint.cs
- XmlAttributeProperties.cs
- Column.cs
- StateMachine.cs
- Line.cs
- ActiveXHost.cs
- versioninfo.cs
- UserControlDocumentDesigner.cs
- ExtensionDataObject.cs
- CqlLexerHelpers.cs
- Facet.cs
- CacheEntry.cs
- Authorization.cs
- MailDefinitionBodyFileNameEditor.cs
- XmlUtf8RawTextWriter.cs
- KeyInstance.cs
- CqlWriter.cs
- QilUnary.cs
- FactoryMaker.cs
- MouseEventArgs.cs
- UrlMapping.cs
- ResXResourceReader.cs
- DBCommandBuilder.cs
- AuthenticateEventArgs.cs
- COM2ICategorizePropertiesHandler.cs
- wmiprovider.cs
- FormattedText.cs
- TimeSpanSecondsOrInfiniteConverter.cs
- FillBehavior.cs
- _PooledStream.cs
- SqlFactory.cs
- MediaScriptCommandRoutedEventArgs.cs
- SyndicationFeed.cs
- DefaultWorkflowSchedulerService.cs
- SqlDataSourceAdvancedOptionsForm.cs
- SimpleWorkerRequest.cs
- CngProvider.cs
- CompilerState.cs
- Message.cs
- safesecurityhelperavalon.cs
- DBDataPermission.cs
- TableDetailsRow.cs
- WSFederationHttpSecurityMode.cs
- TimerEventSubscription.cs
- RotateTransform.cs
- WebMessageFormatHelper.cs
- SqlEnums.cs
- OracleCommandBuilder.cs
- PrintDialog.cs
- UserNameSecurityToken.cs
- Task.cs
- TypeConverterHelper.cs
- HttpListenerException.cs
- MSG.cs
- ContextMenu.cs
- IndependentlyAnimatedPropertyMetadata.cs
- PreviewKeyDownEventArgs.cs
- BuildProvidersCompiler.cs
- UtilityExtension.cs
- EqualityComparer.cs
- RuleCache.cs
- EasingKeyFrames.cs
- ListSortDescriptionCollection.cs
- ApplyHostConfigurationBehavior.cs
- CodeStatement.cs
- BitmapEffectDrawingContextState.cs
- XmlCharType.cs
- COAUTHINFO.cs
- ProviderUtil.cs
- ParameterDataSourceExpression.cs
- TextTreeText.cs
- XmlUrlResolver.cs
- XmlSchemaFacet.cs
- ColumnTypeConverter.cs
- CodeFieldReferenceExpression.cs
- FixedLineResult.cs
- ReflectionTypeLoadException.cs
- TabletDeviceInfo.cs
- FamilyMapCollection.cs
- ClientType.cs
- Int64Animation.cs
- Error.cs
- TypeUsageBuilder.cs
- MiniCustomAttributeInfo.cs