zoukankan      html  css  js  c++  java
  • WPF 文本呈现(1)

    WPF呈现文本的控件有TextBlock,TextBox,RichTextBox.再者复杂一些的有如visual studio 2010的wpf编辑器,wpf提供了一套可扩展的文本的api用于文本呈现管理.

    下面我们还是以呈现Hello World为目标

    文本段落

    image

    我们都写过作文,一般写作文都会分段落,很少会整篇作文是只有一个段落的.

    那么一个段落的文本也具备了一些属性,TextParagraphProperties定义了一系列有关于文本的属性,其属性不允许动态更改即只读的
    image

    单个字符TextRun

    比如Hello,其中H,e,l,l,o都是单个字符,其也用于自己的属性,比如文本大小,颜色等.比较以下xaml

            <TextBlock Text="Hello World"></TextBlock>
            <TextBlock Margin="5">
                <Run Foreground="Gray">H</Run>
                <Run Foreground="Blue">e</Run>
                <Run Foreground="Red">l</Run>
                <Run Foreground="Yellow">l</Run>
                <Run Foreground="Violet">o</Run>
            </TextBlock>
    

    第二段xaml显示样式

    image

    image

    定义TextRunProperties

    class GenericTextRunProperties : TextRunProperties
        {
            #region Constructors
            public GenericTextRunProperties(
               Typeface typeface,
               double size,
               double hintingSize,
               TextDecorationCollection textDecorations,
               Brush forgroundBrush,
               Brush backgroundBrush,
               BaselineAlignment baselineAlignment,
               CultureInfo culture)
            {
                if (typeface == null)
                    throw new ArgumentNullException("typeface");
    
                ValidateCulture(culture);
                _typeface = typeface;
                _emSize = size;
                _emHintingSize = hintingSize;
                _textDecorations = textDecorations;
                _foregroundBrush = forgroundBrush;
                _backgroundBrush = backgroundBrush;
                _baselineAlignment = baselineAlignment;
                _culture = culture;
            }
    
            public GenericTextRunProperties(FontRendering newRender)
            {
                _typeface = newRender.Typeface;
                _emSize = newRender.FontSize;
                _emHintingSize = newRender.FontSize;
                _textDecorations = newRender.TextDecorations;
                _foregroundBrush = newRender.TextColor;
                _backgroundBrush = null;
                _baselineAlignment = BaselineAlignment.Baseline;
                _culture = CultureInfo.CurrentUICulture;
            }
            #endregion
    
            #region Private Methods
            private static void ValidateCulture(CultureInfo culture)
            {
                if (culture == null)
                    throw new ArgumentNullException("culture");
                if (culture.IsNeutralCulture || culture.Equals(CultureInfo.InvariantCulture))
                    throw new ArgumentException("Specific Culture Required", "culture");
            }
    
            private static void ValidateFontSize(double emSize)
            {
                if (emSize <= 0)
                    throw new ArgumentOutOfRangeException("emSize", "Parameter Must Be Greater Than Zero.");
                //if (emSize > MaxFontEmSize)
                //   throw new ArgumentOutOfRangeException("emSize", "Parameter Is Too Large.");
                if (double.IsNaN(emSize))
                    throw new ArgumentOutOfRangeException("emSize", "Parameter Cannot Be NaN.");
            }
            #endregion
    
            #region Properties
            public override Typeface Typeface
            {
                get { return _typeface; }
            }
    
            public override double FontRenderingEmSize
            {
                get { return _emSize; }
            }
    
            public override double FontHintingEmSize
            {
                get { return _emHintingSize; }
            }
    
            public override TextDecorationCollection TextDecorations
            {
                get { return _textDecorations; }
            }
    
            public override Brush ForegroundBrush
            {
                get { return _foregroundBrush; }
            }
    
            public override Brush BackgroundBrush
            {
                get { return _backgroundBrush; }
            }
    
            public override BaselineAlignment BaselineAlignment
            {
                get { return _baselineAlignment; }
            }
    
            public override CultureInfo CultureInfo
            {
                get { return _culture; }
            }
    
            public override TextRunTypographyProperties TypographyProperties
            {
                get { return null; }
            }
    
            public override TextEffectCollection TextEffects
            {
                get { return null; }
            }
    
            public override NumberSubstitution NumberSubstitution
            {
                get { return null; }
            }
            #endregion
    
            #region Private Fields
            private Typeface _typeface;
            private double _emSize;
            private double _emHintingSize;
            private TextDecorationCollection _textDecorations;
            private Brush _foregroundBrush;
            private Brush _backgroundBrush;
            private BaselineAlignment _baselineAlignment;
            private CultureInfo _culture;
            #endregion
        }

    定义TextParagraphProperties

    /// <summary>
    /// Class to implement TextParagraphProperties, used by TextSource
    /// </summary>
    class GenericTextParagraphProperties : TextParagraphProperties
    {
        #region Constructors
        public GenericTextParagraphProperties(
           FlowDirection flowDirection,
           TextAlignment textAlignment,
           bool firstLineInParagraph,
           bool alwaysCollapsible,
           TextRunProperties defaultTextRunProperties,
           TextWrapping textWrap,
           double lineHeight,
           double indent)
        {
            _flowDirection = flowDirection;
            _textAlignment = textAlignment;
            _firstLineInParagraph = firstLineInParagraph;
            _alwaysCollapsible = alwaysCollapsible;
            _defaultTextRunProperties = defaultTextRunProperties;
            _textWrap = textWrap;
            _lineHeight = lineHeight;
            _indent = indent;
        }
    
        public GenericTextParagraphProperties(FontRendering newRendering)
        {
            _flowDirection = FlowDirection.LeftToRight;
            _textAlignment = newRendering.TextAlignment;
            _firstLineInParagraph = false;
            _alwaysCollapsible = false;
            _defaultTextRunProperties = new GenericTextRunProperties(
               newRendering.Typeface, newRendering.FontSize, newRendering.FontSize,
               newRendering.TextDecorations, newRendering.TextColor, null,
               BaselineAlignment.Baseline, CultureInfo.CurrentUICulture);
            _textWrap = TextWrapping.Wrap;
            _lineHeight = 0;
            _indent = 0;
            _paragraphIndent = 0;
        }
        #endregion
    
        #region Properties
        public override FlowDirection FlowDirection
        {
            get { return _flowDirection; }
        }
    
        public override TextAlignment TextAlignment
        {
            get { return _textAlignment; }
        }
    
        public override bool FirstLineInParagraph
        {
            get { return _firstLineInParagraph; }
        }
    
        public override bool AlwaysCollapsible
        {
            get { return _alwaysCollapsible; }
        }
    
        public override TextRunProperties DefaultTextRunProperties
        {
            get { return _defaultTextRunProperties; }
        }
    
        public override TextWrapping TextWrapping
        {
            get { return _textWrap; }
        }
    
        public override double LineHeight
        {
            get { return _lineHeight; }
        }
    
        public override double Indent
        {
            get { return _indent; }
        }
    
        public override TextMarkerProperties TextMarkerProperties
        {
            get { return null; }
        }
    
        public override double ParagraphIndent
        {
            get { return _paragraphIndent; }
        }
        #endregion
    
        #region Private Fields
        private FlowDirection _flowDirection;
        private TextAlignment _textAlignment;
        private bool _firstLineInParagraph;
        private bool _alwaysCollapsible;
        private TextRunProperties _defaultTextRunProperties;
        private TextWrapping _textWrap;
        private double _indent;
        private double _paragraphIndent;
        private double _lineHeight;
        #endregion
    }

    段落划分

    比如输出Hello,可以5个字符一起输出,也可以一个字符输出由TextSource的GetTextRun方法负责输出字符

    class CustomTextSource : TextSource
    {
        // Used by the TextFormatter object to retrieve a run of text from the text source.
        public override TextRun GetTextRun(int textSourceCharacterIndex)
        {
            if (textSourceCharacterIndex >= _text.Length)
            {
                return new TextEndOfParagraph(1);
            }
    
            // Create TextCharacters using the current font rendering properties.
            if (textSourceCharacterIndex < _text.Length)
            {
                return new TextCharacters(
                   _text,
                   textSourceCharacterIndex,
                   _text.Length - textSourceCharacterIndex,
                   new GenericTextRunProperties(_currentRendering));
            }
    
            // Return an end-of-paragraph if no more text source.
            return new TextEndOfParagraph(1);
        }
    
        public override TextSpan<CultureSpecificCharacterBufferRange> GetPrecedingText(int textSourceCharacterIndexLimit)
        {
            CharacterBufferRange cbr = new CharacterBufferRange(_text, 0, textSourceCharacterIndexLimit);
            return new TextSpan<CultureSpecificCharacterBufferRange>(
             textSourceCharacterIndexLimit,
             new CultureSpecificCharacterBufferRange(CultureInfo.CurrentUICulture, cbr)
             );
        }
    
        public override int GetTextEffectCharacterIndexFromTextSourceCharacterIndex(int textSourceCharacterIndex)
        {
            throw new Exception("The method or operation is not implemented.");
        }
    
        #region Properties
        public string Text
        {
            get { return _text; }
            set { _text = value; }
        }
    
        public FontRendering FontRendering
        {
            get { return _currentRendering; }
            set { _currentRendering = value; }
        }
        #endregion
    
        #region Private Fields
    
        private string _text;      //text store
        private FontRendering _currentRendering;
    
        #endregion
    }

    特别要关注GetTextRun方法,这里TextRun用到了定义的TextParagraphProperties 的属性

    输出Hello

    protected override void OnRender(DrawingContext dc)
    {
        TextFormatter formatter= TextFormatter.Create();
    
    
        var textStore = new CustomTextSource();
        var currentRendering = new FontRendering(
           12,
           TextAlignment.Left,
           null,
           Brushes.Black,
           new Typeface("Arial"));
        textStore.FontRendering = currentRendering;
        textStore.Text = "Hello";
        using (TextLine myTextLine = formatter.FormatLine(
            textStore,
            0,
            100,
            new GenericTextParagraphProperties(currentRendering),
            null))
        {
            // Draw the formatted text into the drawing context.
            myTextLine.Draw(dc, new Point(0, 0), InvertAxes.None);
        }
       
    }
    1. 创建TextFormatter
    2. 创建TextLine
    3. 绘制一行Text文本

    代码太多先停

    输出结果

    image

  • 相关阅读:
    CSS的未来:游戏的变革Flexbox
    2013年第8周一JAVA对象序列化及TODO标签等
    大年初七回杭州
    2013年2月20日星期三
    2013年周六加班杂记
    大家初八但杭州收拾准备开始工作
    大家初六去香山
    2013年第8周四又是低效的一天
    2013年第8周二Delphi中Union结构
    2013年第8周日元宵节
  • 原文地址:https://www.cnblogs.com/Clingingboy/p/1895326.html
Copyright © 2011-2022 走看看