public static double[] GetCharWidths(this FormattedText formattedText, RichTextBlock richTextBlock, RuleText rule)
        {
            richTextBlock.ValidateDefaultRule(rule);
            var text   = formattedText.Text;
            var result = new double[text.Length];

            for (int i = 0; i < text.Length; i++)
            {
                var ft = new FormattedText(text[i].ToString(), CultureInfo.CurrentUICulture, richTextBlock.FlowDirection, new Typeface(rule.FontFamily, rule.FontStyle, rule.FontWeight, rule.FontStretch), rule.FontSize, rule.Foreground);
                result[i] = ft.Width;
            }
            return(result);
        }
 public static FormattedText BuildFormattedText(this RichTextBlock richTextBlock, string value, RuleText currentRule = null)
 {
     if (currentRule == null)
     {
         currentRule = richTextBlock.BuildDefaultRule();
     }
     else
     {
         richTextBlock.ValidateDefaultRule(currentRule);
     }
     return(new FormattedText(value, CultureInfo.InvariantCulture,
                              richTextBlock.FlowDirection,
                              new Typeface(currentRule.FontFamily, currentRule.FontStyle,
                                           currentRule.FontWeight, currentRule.FontStretch),
                              currentRule.FontSize, currentRule.Foreground));
 }
        public void SetUpRichTextHost(RichTextBlock block)
        {
            host = block;
            var rulesSource = host.Rules;

            RichText = host.Text;
            if (ParserDic == null)
            {
                ParserDic = new Dictionary <RichTextRule, RichTextRuleParser>();
            }
            else
            {
                ParserDic.Clear();
            }
            foreach (var richTextRule in rulesSource)
            {
                var parser = new RichTextRuleParser(richTextRule);
                ParserDic.Add(richTextRule, parser);
            }
        }
        public void FormatBlock(RichTextBlock richTextBlock)
        {
            var text = richTextBlock.Text;

            if (string.IsNullOrEmpty(text))
            {
                return;
            }

            if (richTextBlock.Rules.Any())
            {
                FormatCache.Clear();
                FormatterImpl.SetUpRichTextHost(richTextBlock);
                BuildFormatText(richTextBlock, FormatterImpl.Format());
            }
            else
            {
                var formatText = richTextBlock.BuildFormattedText(text);
                FormatCache.Add(new TextFormatCache(formatText, new Point()));
            }
        }
 public static RuleText ValidateDefaultRule(this RichTextBlock richTextBlock, RuleText currentRule)
 {
     if (currentRule == null)
     {
         currentRule             = new RuleText();
         currentRule.IsUnMatched = true;
     }
     if (!currentRule.FontStyleSet)
     {
         currentRule.FontStyle = richTextBlock.FontStyle;
     }
     if (!currentRule.FontWeightSet)
     {
         currentRule.FontWeight = richTextBlock.FontWeight;
     }
     if (currentRule.FontFamily == null)
     {
         currentRule.FontFamily = richTextBlock.FontFamily;
     }
     if (!currentRule.FontStretchSet)
     {
         currentRule.FontStretch = richTextBlock.FontStretch;
     }
     if (currentRule.Background == null)
     {
         currentRule.Background = richTextBlock.Background;
     }
     if (currentRule.Foreground == null)
     {
         currentRule.Foreground = richTextBlock.Foreground;
     }
     if (!currentRule.FontSizeSet)
     {
         currentRule.FontSize = richTextBlock.FontSize;
     }
     return(currentRule);
 }
 public static RuleText BuildDefaultRule(this RichTextBlock richTextBlock)
 {
     return(richTextBlock.ValidateDefaultRule(null));
 }
        private void BuildFormatText(RichTextBlock richTextBlock, List <RuleText> tempRules)
        {
            var offset = new Point(0, 0);

            foreach (var tempRule in tempRules)
            {
                var formatText = richTextBlock.BuildFormattedText(tempRule.Value, tempRule);
                var ftext      = formatText.Text;
                if (offset.X + formatText.Width > richTextBlock.ActualWidth)
                {
                    if (richTextBlock.AutoWrap)
                    {
                        while (offset.X + formatText.Width > richTextBlock.ActualWidth)
                        {
                            var    eachWidths      = formatText.GetCharWidths(richTextBlock, tempRule).ToArray();
                            double width           = 0;
                            var    needRemoveCount = eachWidths.Length;
                            do
                            {
                                needRemoveCount--;
                                width = eachWidths.Take(needRemoveCount).Sum();
                                if (needRemoveCount < 0)
                                {
                                    break;
                                }
                            } while (offset.X + width > richTextBlock.ActualWidth);

                            var renderText = ftext.Substring(0, needRemoveCount);
                            formatText = richTextBlock.BuildFormattedText(renderText, tempRule);
                            FormatCache.Add(new TextFormatCache(formatText, offset));
                            offset.Offset(formatText.Width, 0);
                            formatText = null;
                            ftext      = ftext.Substring(needRemoveCount, ftext.Length - needRemoveCount);
                            if (string.IsNullOrEmpty(ftext))
                            {
                                break;
                            }
                            formatText = richTextBlock.BuildFormattedText(ftext, tempRule);
                            offset.Offset(-offset.X, formatText.Height);
                        }

                        if (formatText != null)
                        {
                            FormatCache.Add(new TextFormatCache(formatText, offset));
                            offset.Offset(formatText.Width, 0);
                        }
                    }
                    else
                    {
                        offset.Offset(-offset.X, formatText.Height);
                        FormatCache.Add(new TextFormatCache(formatText, offset));
                        offset.Offset(formatText.Width, 0);
                    }
                }
                else
                {
                    FormatCache.Add(new TextFormatCache(formatText, offset));
                    offset.Offset(formatText.Width, 0);
                }
            }
        }