Code:
/ Dotnetfx_Vista_SP2 / Dotnetfx_Vista_SP2 / 8.0.50727.4016 / DEVDIV / depot / DevDiv / releases / Orcas / QFE / wpf / src / Core / CSharp / System / Windows / Media / CharacterMetrics.cs / 1 / 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) { 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(CultureInfo.InvariantCulture)); s.Append(','); s.Append(_blackBoxHeight.ToString(CultureInfo.InvariantCulture)); // 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); } } 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, CultureInfo.InvariantCulture, 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 } ////// Compates 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. //------------------------------------------------------------------------ // // 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) { 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(CultureInfo.InvariantCulture)); s.Append(','); s.Append(_blackBoxHeight.ToString(CultureInfo.InvariantCulture)); // 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); } } 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, CultureInfo.InvariantCulture, 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 } ////// Compates 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
- SqlExpander.cs
- SpecialNameAttribute.cs
- TickBar.cs
- ZoomPercentageConverter.cs
- DefaultProfileManager.cs
- ActivityExecutionContextCollection.cs
- CodeDirectoryCompiler.cs
- DbParameterHelper.cs
- WsdlBuildProvider.cs
- WebPartTransformer.cs
- FixUpCollection.cs
- XmlNode.cs
- TypedAsyncResult.cs
- DataSpaceManager.cs
- GridToolTip.cs
- EmptyControlCollection.cs
- ApplicationSecurityManager.cs
- Int32AnimationUsingKeyFrames.cs
- SchemaMerger.cs
- CodeDomSerializationProvider.cs
- CalendarTable.cs
- _ListenerResponseStream.cs
- ThreadSafeList.cs
- ImportedNamespaceContextItem.cs
- ControlCachePolicy.cs
- Object.cs
- SwitchDesigner.xaml.cs
- PaginationProgressEventArgs.cs
- KernelTypeValidation.cs
- LiteralText.cs
- FontConverter.cs
- AsyncOperationManager.cs
- CacheOutputQuery.cs
- InternalTypeHelper.cs
- AnnotationHelper.cs
- ColorKeyFrameCollection.cs
- KeyValueInternalCollection.cs
- IssuanceTokenProviderState.cs
- IImplicitResourceProvider.cs
- AttributeCollection.cs
- ReachDocumentPageSerializerAsync.cs
- WpfKnownMemberInvoker.cs
- EmptyImpersonationContext.cs
- SelectionChangedEventArgs.cs
- DispatcherExceptionEventArgs.cs
- Deserializer.cs
- RadioButtonList.cs
- ModelServiceImpl.cs
- XmlSchemaCompilationSettings.cs
- DiscoveryEndpointValidator.cs
- ByteStorage.cs
- SHA384Managed.cs
- EntryPointNotFoundException.cs
- TargetControlTypeAttribute.cs
- TopClause.cs
- WinFormsUtils.cs
- AttributeSetAction.cs
- DesignerVerbCollection.cs
- UnknownExceptionActionHelper.cs
- ObjectDataSource.cs
- PeerDuplexChannel.cs
- DataGridBoolColumn.cs
- SqlRemoveConstantOrderBy.cs
- ProfileProvider.cs
- AppDomainManager.cs
- AuthenticationSection.cs
- TypedRowHandler.cs
- AssemblyName.cs
- SchemaNamespaceManager.cs
- ConstraintEnumerator.cs
- LinkedList.cs
- BaseTemplateCodeDomTreeGenerator.cs
- Popup.cs
- ChannelServices.cs
- BindingExpressionUncommonField.cs
- KeyConverter.cs
- DoubleLinkListEnumerator.cs
- OleDbConnectionFactory.cs
- WaveHeader.cs
- SmiGettersStream.cs
- TimerEventSubscriptionCollection.cs
- WebPartConnectionCollection.cs
- XMLDiffLoader.cs
- AuthorizationSection.cs
- DbDataRecord.cs
- MetadataCache.cs
- ImageFormat.cs
- webproxy.cs
- Scripts.cs
- CacheChildrenQuery.cs
- ToolStripRendererSwitcher.cs
- Invariant.cs
- TreeNodeCollection.cs
- TableLayoutPanelCodeDomSerializer.cs
- DateTime.cs
- VBCodeProvider.cs
- ListBindingConverter.cs
- FunctionImportElement.cs
- XamlTypeMapper.cs
- PackageStore.cs