Code:
/ DotNET / DotNET / 8.0 / untmp / WIN_WINDOWS / lh_tools_devdiv_wpf / Windows / wcp / Core / MS / Internal / TextFormatting / TextMarkerSource.cs / 1 / TextMarkerSource.cs
//------------------------------------------------------------------------ // // Microsoft Windows Client Platform // Copyright (C) Microsoft Corporation, 2001 // // File: TextMarkerSource.cs // // Contents: Generated content for marker symbol // // Created: 3-10-2003 [....] ([....]) // //----------------------------------------------------------------------- using System; using System.Diagnostics; using System.Windows.Threading; using System.Text; using System.Globalization; using System.Windows; using System.Windows.Media; using System.Windows.Media.TextFormatting; using MS.Internal; using SR=MS.Internal.PresentationCore.SR; using SRID=MS.Internal.PresentationCore.SRID; namespace MS.Internal.TextFormatting { ////// Implementation of TextSource for used by marker /// internal sealed class TextMarkerSource : TextSource { private char[] _characterArray; private TextRunProperties _textRunProperties; private TextParagraphProperties _textParagraphProperties; private const char NumberSuffix = '.'; private const string DecimalNumerics = "0123456789"; private const string LowerLatinNumerics = "abcdefghijklmnopqrstuvwxyz"; private const string UpperLatinNumerics = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; private static string[][] RomanNumerics = new string[][] { new string[] { "m??", "cdm", "xlc", "ivx" }, new string[] { "M??", "CDM", "XLC", "IVX" } }; internal TextMarkerSource( TextParagraphProperties textParagraphProperties, TextMarkerStyle markerStyle, int autoNumberingIndex ) { Debug.Assert(markerStyle != TextMarkerStyle.None); _textParagraphProperties = textParagraphProperties; TextRunProperties defaultRunProperties = _textParagraphProperties.DefaultTextRunProperties; string symbolString = null; if(IsKnownSymbolMarkerStyle(markerStyle)) { switch(markerStyle) { case TextMarkerStyle.Disc: symbolString = "\x9f"; break; case TextMarkerStyle.Circle: symbolString = "\xa1"; break; case TextMarkerStyle.Square: symbolString = "\x71"; break; case TextMarkerStyle.Box: symbolString = "\xa7"; break; } Typeface defaultTypeface = defaultRunProperties.Typeface; // recreate a new marker run properties based on symbol typeface e.g. Wingding _textRunProperties = new GenericTextRunProperties( new Typeface( new FontFamily("Wingdings"), defaultTypeface.Style, defaultTypeface.Weight, defaultTypeface.Stretch ), defaultRunProperties.FontRenderingEmSize, defaultRunProperties.FontHintingEmSize, defaultRunProperties.TextDecorations, defaultRunProperties.ForegroundBrush, defaultRunProperties.BackgroundBrush, defaultRunProperties.BaselineAlignment, CultureMapper.GetSpecificCulture(defaultRunProperties.CultureInfo), null // default number substitution for culture ); } else if(IsKnownIndexMarkerStyle(markerStyle)) { // Internal client code should have already validated this. Debug.Assert(autoNumberingIndex > 0); _textRunProperties = defaultRunProperties; int counter = autoNumberingIndex; switch(markerStyle) { case TextMarkerStyle.Decimal: _characterArray = ConvertNumberToString(counter, false, DecimalNumerics); break; case TextMarkerStyle.LowerLatin: _characterArray = ConvertNumberToString(counter, true, LowerLatinNumerics); break; case TextMarkerStyle.UpperLatin: _characterArray = ConvertNumberToString(counter, true, UpperLatinNumerics); break; case TextMarkerStyle.LowerRoman: symbolString = ConvertNumberToRomanString(counter, false); break; case TextMarkerStyle.UpperRoman: symbolString = ConvertNumberToRomanString(counter, true); break; } } else { Debug.Assert(false, "Invalid marker style"); } if(symbolString != null) { _characterArray = symbolString.ToCharArray(); } Debug.Assert(_characterArray != null); } #region TextSource implementation ////// TextFormatter to get a text run started at specified text source position /// public override TextRun GetTextRun( int textSourceCharacterIndex ) { if (textSourceCharacterIndex < _characterArray.Length) { return new TextCharacters( _characterArray, textSourceCharacterIndex, _characterArray.Length - textSourceCharacterIndex, _textRunProperties ); } // Because LS ignores the character for TextEndOfLine characters in marker, // We must return TextEndOfParagraph to termine fetching. return new TextEndOfParagraph(1); } ////// TextFormatter to get text immediately before specified text source position. /// public override TextSpanGetPrecedingText( int textSourceCharacterIndexLimit ) { CharacterBufferRange charString = CharacterBufferRange.Empty; if (textSourceCharacterIndexLimit > 0) { charString = new CharacterBufferRange( new CharacterBufferReference(_characterArray, 0), Math.Min(_characterArray.Length, textSourceCharacterIndexLimit) ); } return new TextSpan ( textSourceCharacterIndexLimit, new CultureSpecificCharacterBufferRange(CultureMapper.GetSpecificCulture(_textRunProperties.CultureInfo), charString) ); } /// /// TextFormatter to map a text source character index to a text effect character index /// /// text source character index ///the text effect index corresponding to the text effect character index public override int GetTextEffectCharacterIndexFromTextSourceCharacterIndex( int textSourceCharacterIndex ) { throw new NotSupportedException(); } #endregion ////// Convert a number to string, consisting of digits followed by the NumberSuffix character. /// /// Number to convert. /// True if there is no zero digit (e.g., alpha numbering). /// Set of digits (e.g., 0-9 or a-z). ///Returns the number string as an array of characters. private static char[] ConvertNumberToString(int number, bool oneBased, string numericSymbols) { // Whether zero-based or one-based numbering is used affects how we // count and how we determine the maximum number of values for a // given number of digits. // // The following table illustrates how counting differs. In both // cases we're using base-2 numbering (i.e., two distinct digits), // but with 1-based counting each of those two digits can be a // significant leading digit. // // 0-based 1-based // ---------------------------- // 0 0 -- // 1 1 a // 2 10 b // 3 11 aa // 4 100 ab // 5 101 ba // 6 110 bb // 7 111 aaa // 8 1000 aab // 9 1001 aba // 10 1010 abb // 11 1011 baa // 12 1100 bab // 13 1101 bba // 14 1110 bbb // 15 1111 aaaa // 16 10000 aaab // // For zero-based counting, adding a leading zero does not change // the value of a number. Thus, the set of all N-digit numbers is // a proper subset of the set of (N+1)-digit numbers. Thus the set // of values that can be represented by N *or fewer* digits is the // same as the number of combinations of exactly N digits, i.e., // // b ^ N // // where b is the base of the numbering system. // // For one-based counting, there is no zero digit. Thus, the set // of N-digit numbers and the set of (N+1)-digit numbers are // disjoint sets. Thus, while the number of combinations of // *exactly* N digits is still b ^ N, the maximum value that // can be represented by N *or fewer* digits is: // // Max(N) // where N = 1 : b // where N > 1 : (b ^ N) + Max(N - 1) // if (oneBased) { // Subtract 1 from 1-based numbers so we can use zero-based // indexing. The formula for Max(N) given above should now be // thought of as a limit rather than a maximum. --number; } Debug.Assert(number >= 0); char[] result; int b = numericSymbols.Length; if (number < b) { // Optimize common case of single-digit numbers. result = new char[2]; // digit + suffix result[0] = numericSymbols[number]; result[1] = NumberSuffix; } else { // Disjoint is 1 if and only if the set of numbers with N // digits and the set of numbers with (N+1) digits are // disjoint (see comment above). Otherwise it is zero. int disjoint = oneBased ? 1 : 0; // Count digits. We stop when the limit (i.e., 1 + the max value // for the current number of digits) exceeds the specified number. int digits = 1; for (long limit = b, pow = b; (long)number >= limit; ++digits) { // Neither of the following calculations can overflow because // we know both pow and limit are <= number (which is an int) // and b is at most 26. pow *= b; limit = pow + (limit * disjoint); } // Build string in reverse order starting with suffix. result = new char[digits + 1]; // digits + suffix result[digits] = NumberSuffix; for (int i = digits - 1; i >= 0; --i) { result[i] = numericSymbols[number % b]; number = (number / b) - disjoint; } } return result; } ////// Convert 1-based number to a Roman numeric string /// followed by NumberSuffix character. /// ////// Roman number is 1-based. The Roman numeric string is a series of symbols. Following /// is the list of symbols and its value. /// /// Symbol Value /// I 1 /// V 5 /// X 10 /// L 50 /// C 100 /// D 500 /// M 1000 /// /// The rule of Roman number prohibits the use of more than 3 consecutive identical symbol /// but using subtraction of symbol standing for multiples of 10, so the value 4 is written /// as IV (5-1) rather than IIII. /// /// Due to the writing rule and the fact that the symbol represents not the numeral digit /// but the value of the number. Roman number system cannot represent value larger than 3999. /// /// See, http://www.ccsn.nevada.edu/math/ancient_systems.htm /// /// However, there exists a more relaxing use of Roman numbers to represent values 4000 and /// 4999 by using 4 consecutive M. The value 4999 is than written as 'MMMMCMXCIX'. Such use /// however is not widely accepted. /// /// See, http://www.guernsey.net/~sgibbs/roman.html /// /// For values larger than 3999, an overscore is used on the symbol to indicate 1000 multiplication. /// ___ /// So, value 7000 would be written as VII. This writing rule has a fair amount of disagreement /// since it is widely understood that it is not invented by the Romans and they rarely had a /// need for large numbers during their time. Furthermore, accepting this writing rule just /// for the sake of being able to write larger number would create a new limitation of the values /// greater than 3,999,999. Unicode 4.0 does not encode these overscore symbols. /// /// See, http://www.gwydir.demon.co.uk/jo/roman/number.htm /// http://www.novaroma.org/via_romana/numbers.html /// /// Implementation-wise, IE adopts a general limitation of 3999 and simply convert the value /// into a regular numeric form. /// /// We'll follow the mainstream and adopt the 3999 limit. The fallback would also do would IE does. /// /// private static string ConvertNumberToRomanString( int number, bool uppercase ) { if (number > 3999) { // Roman numeric string not supported return number.ToString(CultureInfo.InvariantCulture); } StringBuilder builder = new StringBuilder(); AddRomanNumeric(builder, number / 1000, RomanNumerics[uppercase ? 1 : 0][0]); number %= 1000; AddRomanNumeric(builder, number / 100, RomanNumerics[uppercase ? 1 : 0][1]); number %= 100; AddRomanNumeric(builder, number / 10, RomanNumerics[uppercase ? 1 : 0][2]); number %= 10; AddRomanNumeric(builder, number, RomanNumerics[uppercase ? 1 : 0][3]); builder.Append(NumberSuffix); return builder.ToString(); } ////// Convert number 0 - 9 into Roman numeric /// /// string builder /// number to convert /// Roman numeric char for one five and ten private static void AddRomanNumeric( StringBuilder builder, int number, string oneFiveTen ) { Debug.Assert(number >= 0 && number <= 9); if (number >= 1 && number <= 9) { if (number == 4 || number == 9) builder.Append(oneFiveTen[0]); if (number == 9) { builder.Append(oneFiveTen[2]); } else { if (number >= 4) builder.Append(oneFiveTen[1]); for (int i = number % 5; i > 0 && i < 4; i--) builder.Append(oneFiveTen[0]); } } } internal static bool IsKnownSymbolMarkerStyle(TextMarkerStyle markerStyle) { return ( markerStyle == TextMarkerStyle.Disc || markerStyle == TextMarkerStyle.Circle || markerStyle == TextMarkerStyle.Square || markerStyle == TextMarkerStyle.Box ); } internal static bool IsKnownIndexMarkerStyle(TextMarkerStyle markerStyle) { return ( markerStyle == TextMarkerStyle.Decimal || markerStyle == TextMarkerStyle.LowerLatin || markerStyle == TextMarkerStyle.UpperLatin || markerStyle == TextMarkerStyle.LowerRoman || markerStyle == TextMarkerStyle.UpperRoman ); } } } // 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
- LabelDesigner.cs
- WebPartsPersonalizationAuthorization.cs
- PixelFormat.cs
- srgsitem.cs
- XmlSchemaValidator.cs
- HttpListenerException.cs
- XmlSchemaSimpleTypeList.cs
- OLEDB_Enum.cs
- SweepDirectionValidation.cs
- SymDocumentType.cs
- SmiGettersStream.cs
- ConfigPathUtility.cs
- XPathParser.cs
- JoinCqlBlock.cs
- Control.cs
- CompilerResults.cs
- SimpleFileLog.cs
- ViewGenerator.cs
- SrgsNameValueTag.cs
- AccessibleObject.cs
- PageAdapter.cs
- GridSplitter.cs
- TransactionState.cs
- EnumValidator.cs
- XsdDataContractImporter.cs
- FullTextBreakpoint.cs
- XmlDomTextWriter.cs
- RuleRef.cs
- HttpProfileGroupBase.cs
- Style.cs
- NullableIntAverageAggregationOperator.cs
- RestHandler.cs
- NetStream.cs
- EdmComplexTypeAttribute.cs
- EllipseGeometry.cs
- StrokeDescriptor.cs
- ReversePositionQuery.cs
- BitmapEffectGroup.cs
- CacheAxisQuery.cs
- IUnknownConstantAttribute.cs
- ServiceHostingEnvironment.cs
- HelpProvider.cs
- WebHeaderCollection.cs
- ExpressionNormalizer.cs
- CompiledAction.cs
- ContainerParagraph.cs
- Input.cs
- ColorAnimationUsingKeyFrames.cs
- BamlLocalizabilityResolver.cs
- ObjectFullSpanRewriter.cs
- DataGridViewRow.cs
- XamlTemplateSerializer.cs
- GridViewRowEventArgs.cs
- OdbcConnectionString.cs
- EtwProvider.cs
- VoiceSynthesis.cs
- MetadataItemEmitter.cs
- ListViewCommandEventArgs.cs
- OleDbEnumerator.cs
- AnimatedTypeHelpers.cs
- ManifestResourceInfo.cs
- BlurEffect.cs
- SpeechSeg.cs
- Label.cs
- ProtocolViolationException.cs
- CellNormalizer.cs
- ManifestSignedXml.cs
- DomNameTable.cs
- DecoratedNameAttribute.cs
- OdbcErrorCollection.cs
- ParserOptions.cs
- WindowsStatusBar.cs
- SqlClientWrapperSmiStreamChars.cs
- CounterSetInstance.cs
- ExeContext.cs
- LinqDataSourceHelper.cs
- SQLByteStorage.cs
- _CacheStreams.cs
- Suspend.cs
- activationcontext.cs
- StorageComplexTypeMapping.cs
- PromptBuilder.cs
- ObjectDataSourceSelectingEventArgs.cs
- View.cs
- TextContainerChangeEventArgs.cs
- ZeroOpNode.cs
- HealthMonitoringSectionHelper.cs
- SerializableAttribute.cs
- LateBoundBitmapDecoder.cs
- UnauthorizedWebPart.cs
- InputEventArgs.cs
- GeometryGroup.cs
- ResourcePermissionBase.cs
- BaseValidator.cs
- Clipboard.cs
- Opcode.cs
- EntityWrapper.cs
- SafeFileMappingHandle.cs
- ConfigXmlDocument.cs
- Win32MouseDevice.cs