Code:
/ 4.0 / 4.0 / untmp / DEVDIV_TFS / Dev10 / Releases / RTMRel / wpf / src / Core / CSharp / System / Windows / Media / CharacterMetricsDictionary.cs / 1305600 / CharacterMetricsDictionary.cs
//------------------------------------------------------------------------
//
// Microsoft Windows Client Platform
// Copyright (C) Microsoft Corporation, 2002
//
// File: CharacterMetricsDictionary.cs
//
// Contents: CharacterMetricsDictionary
//
// Created: 6-6-05 Niklas Borson (niklasb)
//
//-----------------------------------------------------------------------
using System;
using SC=System.Collections;
using System.Collections.Generic;
using SR=MS.Internal.PresentationCore.SR;
using SRID=MS.Internal.PresentationCore.SRID;
// Allow suppression of presharp warnings
#pragma warning disable 1634, 1691
namespace System.Windows.Media
{
///
/// Dictionary of character metrics for a device font indexed by Unicode scalar value.
///
public sealed class CharacterMetricsDictionary : IDictionary, SC.IDictionary
{
///
/// Constructs an empty CharacterMetricsDictionary object.
///
internal CharacterMetricsDictionary()
{
}
#region IEnumerable members
///
/// Returns an enumerator that iterates through the collection.
///
[CLSCompliant(false)]
public IEnumerator> GetEnumerator()
{
return new Enumerator(this);
}
SC.IEnumerator SC.IEnumerable.GetEnumerator()
{
return new Enumerator(this);
}
SC.IDictionaryEnumerator SC.IDictionary.GetEnumerator()
{
return new Enumerator(this);
}
///
/// If the dictionary contains an entry for the specified character code, returns true
/// and stores the CharacterMetrics in the value parameter; otherwise returns false and
/// sets value to null.
///
public bool TryGetValue(int key, out CharacterMetrics value)
{
value = GetValue(key);
return value != null;
}
#endregion
#region ICollection members
///
/// Gets the number of objects in the collection.
///
public int Count
{
get
{
if (_count == 0)
{
_count = CountValues();
}
return _count;
}
}
///
/// Gets a value indicating whether the collection is read-only.
///
public bool IsReadOnly
{
get { return false; }
}
///
/// Adds a character code and associated CharacterMetrics to the collection.
///
[CLSCompliant(false)]
public void Add(KeyValuePair item)
{
SetValue(
item.Key,
item.Value,
true // failIfExists
);
}
///
/// Removes all objects from the collection.
///
public void Clear()
{
_count = 0;
_pageTable = null;
}
///
/// Determines whether the collection contains the specified characterCode-CharacterMetrics pair.
///
[CLSCompliant(false)]
public bool Contains(KeyValuePair item)
{
// Suppress PRESharp warning that item.Value can be null; apparently PRESharp
// doesn't understand short circuit evaluation of operator &&.
#pragma warning suppress 56506
return item.Value != null && item.Value.Equals(GetValue(item.Key));
}
///
/// Copies the contents of the collection to the specified array.
///
[CLSCompliant(false)]
public void CopyTo(KeyValuePair[] array, int index)
{
if (array == null)
throw new ArgumentNullException("array");
if (index < 0)
throw new ArgumentOutOfRangeException("index");
if (index >= array.Length)
throw new ArgumentException(SR.Get(SRID.Collection_CopyTo_IndexGreaterThanOrEqualToArrayLength, "index", "array"));
CharacterMetrics[][] pageTable = _pageTable;
if (pageTable != null)
{
int k = index;
for (int i = 0; i < pageTable.Length; ++i)
{
CharacterMetrics[] page = pageTable[i];
if (page != null)
{
for (int j = 0; j < page.Length; ++j)
{
CharacterMetrics metrics = page[j];
if (metrics != null)
{
if (k >= array.Length)
throw new ArgumentException(SR.Get(SRID.Collection_CopyTo_NumberOfElementsExceedsArrayLength, index, "array"));
array[k++] = new KeyValuePair(
(i << PageShift) | j,
metrics
);
}
}
}
}
}
}
///
/// Removes the specified characterCode-CharacterMetrics pair from the collection.
///
[CLSCompliant(false)]
public bool Remove(KeyValuePair item)
{
return item.Value != null && RemoveValue(item.Key, item.Value);
}
bool SC.ICollection.IsSynchronized
{
get { return false; }
}
object SC.ICollection.SyncRoot
{
get { return this; }
}
void SC.ICollection.CopyTo(Array array, int index)
{
if (array == null)
throw new ArgumentNullException("array");
if (index < 0)
throw new ArgumentOutOfRangeException("index");
if (index >= array.Length)
throw new ArgumentException(SR.Get(SRID.Collection_CopyTo_IndexGreaterThanOrEqualToArrayLength, "index", "array"));
if (Count > array.Length - index)
throw new ArgumentException(SR.Get(SRID.Collection_CopyTo_NumberOfElementsExceedsArrayLength, index, "array"));
SC.DictionaryEntry[] typedArray = array as SC.DictionaryEntry[];
if (typedArray != null)
{
// it's an array of the exact type
foreach (KeyValuePair item in this)
{
typedArray[index++] = new SC.DictionaryEntry(item.Key, item.Value);
}
}
else
{
// it's an array of some other type, e.g., object[]; make sure it's one dimensional
if (array.Rank != 1)
throw new ArgumentException(SR.Get(SRID.Collection_CopyTo_ArrayCannotBeMultidimensional));
// make sure the element type is compatible
Type elementType = array.GetType().GetElementType();
if (!elementType.IsAssignableFrom(typeof(SC.DictionaryEntry)))
throw new ArgumentException(SR.Get(SRID.CannotConvertType, typeof(SC.DictionaryEntry), elementType));
foreach (KeyValuePair item in this)
{
array.SetValue(new SC.DictionaryEntry(item.Key, item.Value), index++);
}
}
}
#endregion
#region IDictionary members
///
/// Adds a character code and associated CharacterMetrics to the collection.
///
public void Add(int key, CharacterMetrics value)
{
SetValue(key, value, /* failIfExists = */ true);
}
///
/// Determines whether the collection contains the specified character code.
///
public bool ContainsKey(int key)
{
return GetValue(key) != null;
}
///
/// Removes the specified character code and associated CharacterMetrics.
///
public bool Remove(int key)
{
return RemoveValue(key, null);
}
///
/// Gets or sets the CharacterMetrics associated with the specified character code.
///
public CharacterMetrics this[int key]
{
get { return GetValue(key); }
set { SetValue(key, value, /* failIfExists = */ false); }
}
///
/// Gets a collection containing the keys (character codes) in the dictionary.
///
[CLSCompliant(false)]
public ICollection Keys
{
get { return GetKeys(); }
}
///
/// Gets a collection containing the values (strings) in the dictionary.
///
[CLSCompliant(false)]
public ICollection Values
{
get { return GetValues(); }
}
bool SC.IDictionary.IsFixedSize
{
get { return false; }
}
object SC.IDictionary.this[object key]
{
get
{
return (key is int) ? GetValue((int)key) : null;
}
set
{
SetValue(ConvertKey(key), ConvertValue(value), /* failIfExists = */ false);
}
}
SC.ICollection SC.IDictionary.Keys
{
get { return GetKeys(); }
}
SC.ICollection SC.IDictionary.Values
{
get { return GetValues(); }
}
void SC.IDictionary.Add(object key, object value)
{
SetValue(ConvertKey(key), ConvertValue(value), /* failIfExists = */ false);
}
bool SC.IDictionary.Contains(object key)
{
return key is int && GetValue((int)key) != null;
}
void SC.IDictionary.Remove(object key)
{
if (key is int)
{
RemoveValue((int)key, null);
}
}
#endregion
#region Internal representation
internal const int LastDeviceFontCharacterCode = 0xFFFF;
internal const int PageShift = 8;
internal const int PageSize = 1 << PageShift;
internal const int PageMask = PageSize - 1;
internal const int PageCount = (LastDeviceFontCharacterCode + 1 + (PageSize - 1)) / PageSize;
private CharacterMetrics[][] _pageTable = null;
private int _count = 0;
internal CharacterMetrics[] GetPage(int i)
{
return (_pageTable != null) ? _pageTable[i] : null;
}
private CharacterMetrics[] GetPageFromUnicodeScalar(int unicodeScalar)
{
int i = unicodeScalar >> PageShift;
CharacterMetrics[] page;
if (_pageTable != null)
{
page = _pageTable[i];
if (page == null)
{
_pageTable[i] = page = new CharacterMetrics[PageSize];
}
}
else
{
_pageTable = new CharacterMetrics[PageCount][];
_pageTable[i] = page = new CharacterMetrics[PageSize];
}
return page;
}
private void SetValue(int key, CharacterMetrics value, bool failIfExists)
{
if (key < 0 || key > LastDeviceFontCharacterCode)
throw new ArgumentOutOfRangeException(SR.Get(SRID.CodePointOutOfRange, key));
if (value == null)
throw new ArgumentNullException("value");
CharacterMetrics[] page = GetPageFromUnicodeScalar(key);
int i = key & PageMask;
if (failIfExists && page[i] != null)
throw new ArgumentException(SR.Get(SRID.CollectionDuplicateKey, key));
page[i] = value;
_count = 0;
}
internal CharacterMetrics GetValue(int key)
{
CharacterMetrics metrics = null;
if (key >= 0 && key <= FontFamilyMap.LastUnicodeScalar && _pageTable != null)
{
CharacterMetrics[] page = _pageTable[key >> PageShift];
if (page != null)
metrics = page[key & PageMask];
}
return metrics;
}
private bool RemoveValue(int key, CharacterMetrics value)
{
if (key >= 0 && key <= FontFamilyMap.LastUnicodeScalar && _pageTable != null)
{
CharacterMetrics[] page = _pageTable[key >> PageShift];
if (page != null)
{
int i = key & PageMask;
CharacterMetrics metrics = page[i];
if (metrics != null && (value == null || metrics.Equals(value)))
{
page[i] = null;
_count = 0;
return true;
}
}
}
return false;
}
private CharacterMetrics GetNextValue(ref int unicodeScalar)
{
CharacterMetrics[][] pageTable = _pageTable;
if (pageTable != null)
{
int j = (unicodeScalar + 1) & PageMask;
for (int i = (unicodeScalar + 1) >> PageShift; i < PageCount; ++i)
{
CharacterMetrics[] page = pageTable[i];
if (page != null)
{
for (; j < PageSize; ++j)
{
CharacterMetrics metrics = page[j];
if (metrics != null)
{
unicodeScalar = (i << PageShift) | j;
return metrics;
}
}
j = 0;
}
}
}
unicodeScalar = int.MaxValue;
return null;
}
private int CountValues()
{
int c = 0;
CharacterMetrics[][] pageTable = _pageTable;
if (pageTable != null)
{
for (int i = 0; i < pageTable.Length; ++i)
{
CharacterMetrics[] page = pageTable[i];
if (page != null)
{
for (int j = 0; j < page.Length; ++j)
{
if (page[j] != null)
++c;
}
}
}
}
return c;
}
private int[] GetKeys()
{
int[] result = new int[Count];
int i = 0;
foreach (KeyValuePair pair in this)
{
result[i++] = pair.Key;
}
return result;
}
private CharacterMetrics[] GetValues()
{
CharacterMetrics[] result = new CharacterMetrics[Count];
int i = 0;
foreach (KeyValuePair pair in this)
{
result[i++] = pair.Value;
}
return result;
}
internal static int ConvertKey(object key)
{
if (key == null)
throw new ArgumentNullException("key");
int value;
string s = key as string;
if (s != null)
{
int i = 0;
if (!FontFamilyMap.ParseHexNumber(s, ref i, out value) || i < s.Length)
throw new ArgumentException(SR.Get(SRID.CannotConvertStringToType, s, "int"), "key");
}
else if (key is int)
{
value = (int)key;
}
else
{
throw new ArgumentException(SR.Get(SRID.CannotConvertType, key.GetType(), "int"), "key");
}
if (value < 0 || value > FontFamilyMap.LastUnicodeScalar)
throw new ArgumentException(SR.Get(SRID.CodePointOutOfRange, value), "key");
return value;
}
private CharacterMetrics ConvertValue(object value)
{
CharacterMetrics metrics = value as CharacterMetrics;
if (metrics != null)
return metrics;
if (value != null)
throw new ArgumentException(SR.Get(SRID.CannotConvertType, typeof(CharacterMetrics), value.GetType()));
else
throw new ArgumentNullException("value");
}
private struct Enumerator : SC.IDictionaryEnumerator, IEnumerator>
{
private CharacterMetricsDictionary _dictionary;
private int _unicodeScalar;
private CharacterMetrics _value;
internal Enumerator(CharacterMetricsDictionary dictionary)
{
_dictionary = dictionary;
_unicodeScalar = -1;
_value = null;
}
void IDisposable.Dispose()
{
}
public bool MoveNext()
{
if (_unicodeScalar < int.MaxValue)
{
_value = _dictionary.GetNextValue(ref _unicodeScalar);
}
return _value != null;
}
void SC.IEnumerator.Reset()
{
_unicodeScalar = -1;
}
// Current object in the sequence, which for an IDictionaryEnumerator
// is expected to be a DictionaryEntry.
object SC.IEnumerator.Current
{
get
{
KeyValuePair entry = GetCurrentEntry();
return new SC.DictionaryEntry(entry.Key, entry.Value);
}
}
// Current property for generic enumerator.
public KeyValuePair Current
{
get
{
return new KeyValuePair(_unicodeScalar, _value);
}
}
private KeyValuePair GetCurrentEntry()
{
if (_value != null)
return new KeyValuePair(_unicodeScalar, _value);
else
throw new InvalidOperationException(SR.Get(SRID.Enumerator_VerifyContext));
}
SC.DictionaryEntry SC.IDictionaryEnumerator.Entry
{
get
{
KeyValuePair entry = GetCurrentEntry();
return new SC.DictionaryEntry(entry.Key, entry.Value);
}
}
object SC.IDictionaryEnumerator.Key
{
get
{
return GetCurrentEntry().Key;
}
}
object SC.IDictionaryEnumerator.Value
{
get
{
return GetCurrentEntry().Value;
}
}
}
#endregion
}
}
// 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
- ParserContext.cs
- SqlComparer.cs
- AsymmetricKeyExchangeFormatter.cs
- CodeNamespace.cs
- PtsHost.cs
- MyContact.cs
- Model3DCollection.cs
- SqlDataSourceSelectingEventArgs.cs
- GridViewRowPresenterBase.cs
- DownloadProgressEventArgs.cs
- MergePropertyDescriptor.cs
- RecordConverter.cs
- TypeLoadException.cs
- IteratorFilter.cs
- XmlNamespaceMappingCollection.cs
- LongPath.cs
- DataRelationCollection.cs
- ManifestResourceInfo.cs
- MetadataItem.cs
- AssociationSet.cs
- TracePayload.cs
- ImageKeyConverter.cs
- Grid.cs
- XmlSchemaCompilationSettings.cs
- SqlConnectionHelper.cs
- Parser.cs
- WebHeaderCollection.cs
- ThumbAutomationPeer.cs
- XomlCompilerParameters.cs
- BitmapEffectGeneralTransform.cs
- DetailsViewModeEventArgs.cs
- _AutoWebProxyScriptWrapper.cs
- StringUtil.cs
- LostFocusEventManager.cs
- FragmentQueryKB.cs
- SymbolPair.cs
- SafeMarshalContext.cs
- HttpDebugHandler.cs
- StandardOleMarshalObject.cs
- BadImageFormatException.cs
- HybridDictionary.cs
- OleDbParameterCollection.cs
- CultureInfoConverter.cs
- XmlSchemaSearchPattern.cs
- PathFigure.cs
- DbConnectionPoolCounters.cs
- HashSetEqualityComparer.cs
- UIElementHelper.cs
- CalendarButton.cs
- SchemaElementLookUpTable.cs
- ApplicationInfo.cs
- ServiceDescriptionImporter.cs
- Baml2006ReaderFrame.cs
- ExtentKey.cs
- CreatingCookieEventArgs.cs
- FileDialog.cs
- DataGridViewCellCancelEventArgs.cs
- UrlParameterReader.cs
- CompilerError.cs
- EdmComplexTypeAttribute.cs
- InputMethodStateChangeEventArgs.cs
- unsafeIndexingFilterStream.cs
- ClientScriptManagerWrapper.cs
- SqlRewriteScalarSubqueries.cs
- AuthorizationRule.cs
- HandlerMappingMemo.cs
- RijndaelManaged.cs
- BitmapCache.cs
- HttpHandlerActionCollection.cs
- InstanceStoreQueryResult.cs
- ErrorFormatterPage.cs
- ButtonStandardAdapter.cs
- Transform3D.cs
- CfgArc.cs
- QueryableDataSourceView.cs
- Scheduling.cs
- Graph.cs
- ListBox.cs
- wgx_render.cs
- Slider.cs
- ZipIOLocalFileDataDescriptor.cs
- PrintEvent.cs
- DrawingCollection.cs
- DataBoundControlParameterTarget.cs
- HybridObjectCache.cs
- ISessionStateStore.cs
- SelectorAutomationPeer.cs
- MemberDomainMap.cs
- _AuthenticationState.cs
- ModuleConfigurationInfo.cs
- CFStream.cs
- SqlIdentifier.cs
- BaseParaClient.cs
- SoapWriter.cs
- ComAdminWrapper.cs
- SourceSwitch.cs
- XmlSchemaDatatype.cs
- MimeTypeAttribute.cs
- CellConstant.cs
- Random.cs