Code:
/ 4.0 / 4.0 / untmp / DEVDIV_TFS / Dev10 / Releases / RTMRel / wpf / src / Core / CSharp / System / Windows / Media / CharacterMetrics.cs / 1305600 / CharacterMetrics.cs
//------------------------------------------------------------------------
//
// Microsoft Windows Client Platform
// Copyright (C) Microsoft Corporation, 2002
//
// File: CharacterMetrics.cs
//
// Contents: CharacterMetrics
//
// Created: 6-6-05 Niklas Borson (niklasb)
//
//-----------------------------------------------------------------------
using System;
using System.Globalization;
using StringBuilder = System.Text.StringBuilder;
using CompositeFontParser = MS.Internal.FontFace.CompositeFontParser;
using Constants = MS.Internal.TextFormatting.Constants;
using SR = MS.Internal.PresentationCore.SR;
using SRID = MS.Internal.PresentationCore.SRID;
#pragma warning disable 1634, 1691 // suppressing PreSharp warnings
namespace System.Windows.Media
{
///
/// Metrics used to lay out a character in a device font.
///
public class CharacterMetrics
{
private double _blackBoxWidth;
private double _blackBoxHeight;
private double _baseline;
private double _leftSideBearing;
private double _rightSideBearing;
private double _topSideBearing;
private double _bottomSideBearing;
private enum FieldIndex
{
BlackBoxWidth,
BlackBoxHeight,
Baseline,
LeftSideBearing,
RightSideBearing,
TopSideBearing,
BottomSideBearing
}
private const int NumFields = (int)FieldIndex.BottomSideBearing + 1;
private const int NumRequiredFields = (int)FieldIndex.BlackBoxHeight + 1;
///
/// Constructs a CharacterMetrics object with default values.
///
public CharacterMetrics()
{
}
///
/// Constructs a CharacterMetrics with the specified values.
///
/// Value of the Metrics property.
public CharacterMetrics(string metrics)
{
if (metrics == null)
throw new ArgumentNullException("metrics");
Metrics = metrics;
}
///
/// String specifying the following properties in the following order: BlackBoxWidth, BlackBoxHeight,
/// Baseline, LeftSideBearing, RightSideBearing, TopSideBearing, BottomSideBearing. Property values
/// are delimited by commas, and the first two properties are required. The remaining properties may
/// be omitted and default to zero. For example, "0.75,0.75,,0.1" sets the first, second, and fourth
/// properties to the specified values and the rest to zero.
///
public string Metrics
{
get
{
StringBuilder s = new StringBuilder();
// The following fields are required.
s.Append(_blackBoxWidth.ToString(System.Windows.Markup.TypeConverterHelper.InvariantEnglishUS));
s.Append(',');
s.Append(_blackBoxHeight.ToString(System.Windows.Markup.TypeConverterHelper.InvariantEnglishUS));
// Index of the last field we added to the string; this tells us how many commas to
// insert before the next optional field we add.
int lastIndex = (int)FieldIndex.BlackBoxHeight;
// The following fields are optional, but must be in ascending order of field index.
AppendField(_baseline, FieldIndex.Baseline, ref lastIndex, s);
AppendField(_leftSideBearing, FieldIndex.LeftSideBearing, ref lastIndex, s);
AppendField(_rightSideBearing, FieldIndex.RightSideBearing, ref lastIndex, s);
AppendField(_topSideBearing, FieldIndex.TopSideBearing, ref lastIndex, s);
AppendField(_bottomSideBearing, FieldIndex.BottomSideBearing, ref lastIndex, s);
return s.ToString();
}
set
{
double[] metrics = ParseMetrics(value);
// Validate all the values before we assign to any field.
CompositeFontParser.VerifyNonNegativeMultiplierOfEm("BlackBoxWidth", ref metrics[(int)FieldIndex.BlackBoxWidth]);
CompositeFontParser.VerifyNonNegativeMultiplierOfEm("BlackBoxHeight", ref metrics[(int)FieldIndex.BlackBoxHeight]);
CompositeFontParser.VerifyMultiplierOfEm("Baseline", ref metrics[(int)FieldIndex.Baseline]);
CompositeFontParser.VerifyMultiplierOfEm("LeftSideBearing", ref metrics[(int)FieldIndex.LeftSideBearing]);
CompositeFontParser.VerifyMultiplierOfEm("RightSideBearing", ref metrics[(int)FieldIndex.RightSideBearing]);
CompositeFontParser.VerifyMultiplierOfEm("TopSideBearing", ref metrics[(int)FieldIndex.TopSideBearing]);
CompositeFontParser.VerifyMultiplierOfEm("BottomSideBearing", ref metrics[(int)FieldIndex.BottomSideBearing]);
double horizontalAdvance = metrics[(int)FieldIndex.BlackBoxWidth]
+ metrics[(int)FieldIndex.LeftSideBearing]
+ metrics[(int)FieldIndex.RightSideBearing];
if (horizontalAdvance < 0)
throw new ArgumentException(SR.Get(SRID.CharacterMetrics_NegativeHorizontalAdvance));
double verticalAdvance = metrics[(int)FieldIndex.BlackBoxHeight]
+ metrics[(int)FieldIndex.TopSideBearing]
+ metrics[(int)FieldIndex.BottomSideBearing];
if (verticalAdvance < 0)
throw new ArgumentException(SR.Get(SRID.CharacterMetrics_NegativeVerticalAdvance));
// Set all the properties.
_blackBoxWidth = metrics[(int)FieldIndex.BlackBoxWidth];
_blackBoxHeight = metrics[(int)FieldIndex.BlackBoxHeight];
_baseline = metrics[(int)FieldIndex.Baseline];
_leftSideBearing = metrics[(int)FieldIndex.LeftSideBearing];
_rightSideBearing = metrics[(int)FieldIndex.RightSideBearing];
_topSideBearing = metrics[(int)FieldIndex.TopSideBearing];
_bottomSideBearing = metrics[(int)FieldIndex.BottomSideBearing];
}
}
private static void AppendField(double value, FieldIndex fieldIndex, ref int lastIndex, StringBuilder s)
{
if (value != 0)
{
s.Append(',', (int)fieldIndex - lastIndex);
lastIndex = (int)fieldIndex;
s.Append(value.ToString(System.Windows.Markup.TypeConverterHelper.InvariantEnglishUS));
}
}
private static double[] ParseMetrics(string s)
{
double[] metrics = new double[NumFields];
int i = 0, fieldIndex = 0;
for (; ; )
{
// Let i be first non-whitespace character or end-of-string.
while (i < s.Length && s[i] == ' ')
++i;
// Let j be delimiter or end-of-string.
int j = i;
while (j < s.Length && s[j] != ',')
++j;
// Let k be end-of-field without trailing whitespace.
int k = j;
while (k > i && s[k - 1] == ' ')
--k;
if (k > i)
{
// Non-empty field; convert it to double.
string field = s.Substring(i, k - i);
if (!double.TryParse(
field,
NumberStyles.AllowDecimalPoint | NumberStyles.AllowLeadingSign,
System.Windows.Markup.TypeConverterHelper.InvariantEnglishUS,
out metrics[fieldIndex]
))
{
throw new ArgumentException(SR.Get(SRID.CannotConvertStringToType, field, "double"));
}
}
else if (fieldIndex < NumRequiredFields)
{
// Empty field; make sure it's an optional one.
throw new ArgumentException(SR.Get(SRID.CharacterMetrics_MissingRequiredField));
}
++fieldIndex;
if (j < s.Length)
{
// There's a comma so check if we've exceeded the number of fields.
if (fieldIndex == NumFields)
throw new ArgumentException(SR.Get(SRID.CharacterMetrics_TooManyFields));
// Initialize character index for next iteration.
i = j + 1;
}
else
{
// No more fields; check if we have all required fields.
if (fieldIndex < NumRequiredFields)
{
throw new ArgumentException(SR.Get(SRID.CharacterMetrics_MissingRequiredField));
}
break;
}
}
return metrics;
}
///
/// Width of the black box for the character.
///
public double BlackBoxWidth
{
get { return _blackBoxWidth; }
}
///
/// Height of the black box for the character.
///
public double BlackBoxHeight
{
get { return _blackBoxHeight; }
}
///
/// Vertical offset from the bottom of the black box to the baseline. A positive
/// value indicates the baseline is above the bottom of the black box, and a negative
/// value indicates the baseline is below the bottom of the black box.
///
public double Baseline
{
get { return _baseline; }
}
///
/// Recommended white space to the left of the black box. A negative value results in
/// an overhang. The horizontal advance for the character is LeftSideBearing +
/// BlackBoxWidth + RightSideBearing, and cannot be less than zero.
///
public double LeftSideBearing
{
get { return _leftSideBearing; }
}
///
/// Recommended white space to the right of the black box. A negative value results in
/// an overhang. The horizontal advance for the character is LeftSideBearing +
/// BlackBoxWidth + RightSideBearing, and cannot be less than zero.
///
public double RightSideBearing
{
get { return _rightSideBearing; }
}
///
/// Recommended white space above the black box. A negative value results in
/// an overhang. The vertical advance for the character is TopSideBearing +
/// BlackBoxHeight + BottomSideBearing, and cannot be less than zero.
///
public double TopSideBearing
{
get { return _topSideBearing; }
}
///
/// Recommended white space below the black box. A negative value results in
/// an overhang. The vertical advance for the character is TopSideBearing +
/// BlackBoxHeight + BottomSideBearing, and cannot be less than zero.
///
public double BottomSideBearing
{
get { return _bottomSideBearing; }
}
///
/// Compares two CharacterMetrics for equality.
///
public override bool Equals(object obj)
{
CharacterMetrics other = obj as CharacterMetrics;
// Suppress PRESharp warning that other can be null; apparently PRESharp
// doesn't understand short circuit evaluation of operator &&.
#pragma warning disable 6506
return other != null &&
other._blackBoxWidth == _blackBoxWidth &&
other._blackBoxHeight == _blackBoxHeight &&
other._leftSideBearing == _leftSideBearing &&
other._rightSideBearing == _rightSideBearing &&
other._topSideBearing == _topSideBearing &&
other._bottomSideBearing == _bottomSideBearing;
#pragma warning restore 6506
}
///
/// Computes a hash value for a CharacterMetrics.
///
public override int GetHashCode()
{
int hash = (int)(_blackBoxWidth * Constants.DefaultRealToIdeal);
hash = (hash * HashMultiplier) + (int)(_blackBoxHeight * Constants.DefaultRealToIdeal);
hash = (hash * HashMultiplier) + (int)(_baseline * Constants.DefaultRealToIdeal);
hash = (hash * HashMultiplier) + (int)(_leftSideBearing * Constants.DefaultRealToIdeal);
hash = (hash * HashMultiplier) + (int)(_rightSideBearing * Constants.DefaultRealToIdeal);
hash = (hash * HashMultiplier) + (int)(_topSideBearing * Constants.DefaultRealToIdeal);
hash = (hash * HashMultiplier) + (int)(_bottomSideBearing * Constants.DefaultRealToIdeal);
return hash;
}
private const int HashMultiplier = 101;
}
}
// 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
- TrackingServices.cs
- StringFreezingAttribute.cs
- BevelBitmapEffect.cs
- StopStoryboard.cs
- PackUriHelper.cs
- NestedContainer.cs
- DatasetMethodGenerator.cs
- State.cs
- SqlTypeConverter.cs
- AssemblyEvidenceFactory.cs
- ConfigurationValue.cs
- SpeakProgressEventArgs.cs
- SubMenuStyle.cs
- DataServiceProviderWrapper.cs
- SoapHeaderAttribute.cs
- UnsafeMethods.cs
- NamespaceMapping.cs
- ImpersonationContext.cs
- DependencyObject.cs
- PeerHelpers.cs
- FlowLayoutPanel.cs
- FixedBufferAttribute.cs
- ReachFixedPageSerializer.cs
- CharEntityEncoderFallback.cs
- DataGridViewCellContextMenuStripNeededEventArgs.cs
- MediaElementAutomationPeer.cs
- CaseInsensitiveComparer.cs
- PreservationFileReader.cs
- CollectionViewGroupRoot.cs
- ConfigurationConverterBase.cs
- CachedPathData.cs
- TreeViewItemAutomationPeer.cs
- RadioButton.cs
- FormClosedEvent.cs
- MouseActionConverter.cs
- UDPClient.cs
- JapaneseCalendar.cs
- DbBuffer.cs
- HTMLTagNameToTypeMapper.cs
- OutputWindow.cs
- XmlElementElement.cs
- KeyPressEvent.cs
- EntityViewGenerationConstants.cs
- RefreshPropertiesAttribute.cs
- Menu.cs
- RoleService.cs
- XmlQueryOutput.cs
- EncryptedType.cs
- DataGridToolTip.cs
- TextSchema.cs
- EntityDataSourceConfigureObjectContextPanel.cs
- XmlTextEncoder.cs
- EventManager.cs
- RelativeSource.cs
- UniqueIdentifierService.cs
- TextServicesHost.cs
- LoginCancelEventArgs.cs
- PrePostDescendentsWalker.cs
- ExpandableObjectConverter.cs
- XmlWellformedWriter.cs
- AuthorizationPolicyTypeElementCollection.cs
- TreeNodeStyle.cs
- ExpressionBindingCollection.cs
- ParameterModifier.cs
- DockPanel.cs
- OdbcParameter.cs
- DbParameterCollection.cs
- ReadOnlyDataSource.cs
- SessionStateModule.cs
- CqlParserHelpers.cs
- MSAAEventDispatcher.cs
- MasterPageCodeDomTreeGenerator.cs
- BlobPersonalizationState.cs
- UMPAttributes.cs
- CompleteWizardStep.cs
- Permission.cs
- uribuilder.cs
- TableLayoutPanel.cs
- FileInfo.cs
- EventMappingSettingsCollection.cs
- Assembly.cs
- XmlDocumentType.cs
- XmlSchema.cs
- Models.cs
- ToolTip.cs
- DataFormat.cs
- UIElementAutomationPeer.cs
- WebPartVerbCollection.cs
- SafeEventHandle.cs
- IndentedTextWriter.cs
- TextRange.cs
- NetMsmqBindingElement.cs
- ISAPIApplicationHost.cs
- SvcMapFile.cs
- InitializationEventAttribute.cs
- RemotingAttributes.cs
- HtmlSelectionListAdapter.cs
- ZipIOLocalFileDataDescriptor.cs
- DecoderExceptionFallback.cs
- SqlTypeSystemProvider.cs