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
- XmlHierarchicalEnumerable.cs
- StreamBodyWriter.cs
- ConnectionManagementElementCollection.cs
- RegionInfo.cs
- ImageAnimator.cs
- FontNamesConverter.cs
- TypeElementCollection.cs
- CommentEmitter.cs
- ApplicationInfo.cs
- ItemCheckedEvent.cs
- CustomError.cs
- FormattedTextSymbols.cs
- X509ChainElement.cs
- SqlCrossApplyToCrossJoin.cs
- ContainerSelectorGlyph.cs
- WindowsUserNameSecurityTokenAuthenticator.cs
- WebServiceClientProxyGenerator.cs
- TraceRecord.cs
- OleServicesContext.cs
- RenderData.cs
- CollectionViewGroupRoot.cs
- WebPartPersonalization.cs
- AuthenticationManager.cs
- CryptoApi.cs
- TraceData.cs
- Triplet.cs
- ASCIIEncoding.cs
- UriSection.cs
- InvalidFilterCriteriaException.cs
- EntityTypeEmitter.cs
- TextElement.cs
- MsmqChannelFactory.cs
- Size.cs
- Bits.cs
- Assembly.cs
- Preprocessor.cs
- BackgroundWorker.cs
- XpsFontSerializationService.cs
- SplineQuaternionKeyFrame.cs
- WindowsPrincipal.cs
- EntityDataSourceContextCreatingEventArgs.cs
- SafeThemeHandle.cs
- TextAdaptor.cs
- ColumnHeaderConverter.cs
- ToolStripItemImageRenderEventArgs.cs
- NetworkAddressChange.cs
- MatrixAnimationUsingPath.cs
- HttpDictionary.cs
- WsatAdminException.cs
- HtmlInputImage.cs
- MailWriter.cs
- AsmxEndpointPickerExtension.cs
- LayoutSettings.cs
- QueryContinueDragEvent.cs
- DataList.cs
- CounterSample.cs
- SelectionChangedEventArgs.cs
- LinqDataSourceContextEventArgs.cs
- Solver.cs
- precedingquery.cs
- unsafenativemethodsother.cs
- _KerberosClient.cs
- ComponentCollection.cs
- FollowerQueueCreator.cs
- SplitterPanel.cs
- ScopelessEnumAttribute.cs
- CodeCompiler.cs
- AlgoModule.cs
- CreateDataSourceDialog.cs
- SqlNamer.cs
- EntityContainerRelationshipSetEnd.cs
- WebPartCollection.cs
- BindableTemplateBuilder.cs
- SelectedPathEditor.cs
- DataContractSerializerMessageContractImporter.cs
- XslNumber.cs
- BaseTemplateCodeDomTreeGenerator.cs
- WebService.cs
- DataGridViewCellStyle.cs
- DocumentReferenceCollection.cs
- BorderGapMaskConverter.cs
- HtmlInputRadioButton.cs
- CDSsyncETWBCLProvider.cs
- SchemaSetCompiler.cs
- BaseCodeDomTreeGenerator.cs
- ToolStripItemCollection.cs
- DesignerCapabilities.cs
- DataRecordObjectView.cs
- webproxy.cs
- DragEvent.cs
- WebPartHelpVerb.cs
- ParseNumbers.cs
- HttpHostedTransportConfiguration.cs
- OrderedDictionary.cs
- __ConsoleStream.cs
- InputScope.cs
- ActivityExecutionContext.cs
- AudioLevelUpdatedEventArgs.cs
- SqlColumnizer.cs
- MemberCollection.cs