FormattedText类中的下标/上标?

时间:2010-05-01 15:52:43

标签: wpf subscript superscript formatted-text

我正在使用FormattedText类创建Text - 但是如何在使用此类时下标oder上标文本?我在使用TextBlock时找到了解决方法,但我使用的是FormattedText,而不是TextBlock):感谢任何提示!

2 个答案:

答案 0 :(得分:11)

FormattedText不能做下标/上标 - 但TextFormatter可以。

TextFormatter是一个低级API,您需要编写大量代码才能使用它 - 但大多数代码只是将用于传递格式化参数int TextFormatter的所有类子类化。 / p>

如何使用TextFormatter

TextFormatter获取TextSource个对象并生成多个TextLine个对象(每行一个),然后可以使用TextLine.Draw方法将线绘制到绘图中上下文。

TextSource类是抽象的,你必须对它进行子类化并覆盖GetTextRun方法,该方法只返回一个位于所提供的字符位置的TextRun对象。

TextRun也是抽象的 - 但它确实有你可以使用的子类 - 有趣的类是TextCharacters,它包含字符串和格式信息。

格式化信息位于TextRunProperties对象中,遗憾的是,这是您必须子类化的另一个抽象类。

TextRunProperties的{​​{1}}属性类型为TypographyProperties

TextRunTypographyProperties是你需要子类的另一个抽象类。

最后,TextRunTypographyProperties具有TextRunTypographyProperties属性,您可以像TextBlock示例一样使用该属性。

代码示例

以下是我可以编写的用于绘制上标文本的最小代码:

首先,我们的TextRunProperties和TextRunTypographyProperties可以返回上标字体变体:

Variants

类似于段落格式的类(从MSDN TextFormatter示例中获取):

class CustomTextRunProperties : TextRunProperties
{
    private bool _superscript;
    public CustomTextRunProperties(bool superscript)
    {
        _superscript = superscript;
    }
    public override System.Windows.Media.Brush BackgroundBrush
    {
        get { return null; }
    }

    public override CultureInfo CultureInfo
    {
        get { return CultureInfo.CurrentCulture; }
    }

    public override double FontHintingEmSize
    {
        get { return 22; }
    }

    public override double FontRenderingEmSize
    {
        get { return 22; }
    }

    public override Brush ForegroundBrush
    {
        get { return Brushes.Black; }
    }

    public override System.Windows.TextDecorationCollection TextDecorations
    {
        get { return new System.Windows.TextDecorationCollection(); }
    }

    public override System.Windows.Media.TextEffectCollection TextEffects
    {
        get { return new TextEffectCollection(); }
    }

    public override System.Windows.Media.Typeface Typeface
    {
        get { return new Typeface("Calibri"); }
    }

    public override TextRunTypographyProperties TypographyProperties
    {
        get
        {
            return new CustomTextRunTypographyProperties(_superscript);
        }
    }

}

class CustomTextRunTypographyProperties : TextRunTypographyProperties
{
    private bool _superscript;

    public CustomTextRunTypographyProperties(bool superscript)
    {
        _superscript = superscript;
    }

    public override int AnnotationAlternates
    {
        get { return 0; }
    }

    public override bool CapitalSpacing
    {
        get { return false; }
    }

    public override System.Windows.FontCapitals Capitals
    {
        get { return FontCapitals.Normal; }
    }

    public override bool CaseSensitiveForms
    {
        get { return false; }
    }

    public override bool ContextualAlternates
    {
        get { return false; }
    }

    public override bool ContextualLigatures
    {
        get { return false; }
    }

    public override int ContextualSwashes
    {
        get { return 0; }
    }

    public override bool DiscretionaryLigatures
    {
        get { return false; }
    }

    public override bool EastAsianExpertForms
    {
        get { return false; }
    }

    public override System.Windows.FontEastAsianLanguage EastAsianLanguage
    {
        get { return FontEastAsianLanguage.Normal; }
    }

    public override System.Windows.FontEastAsianWidths EastAsianWidths
    {
        get { return FontEastAsianWidths.Normal; }
    }

    public override System.Windows.FontFraction Fraction
    {
        get { return FontFraction.Normal; }
    }

    public override bool HistoricalForms
    {
        get { return false; }
    }

    public override bool HistoricalLigatures
    {
        get { return false; }
    }

    public override bool Kerning
    {
        get { return true; }
    }

    public override bool MathematicalGreek
    {
        get { return false; }
    }

    public override System.Windows.FontNumeralAlignment NumeralAlignment
    {
        get { return FontNumeralAlignment.Normal; }
    }

    public override System.Windows.FontNumeralStyle NumeralStyle
    {
        get { return FontNumeralStyle.Normal; }
    }

    public override bool SlashedZero
    {
        get { return false; }
    }

    public override bool StandardLigatures
    {
        get { return false; }
    }

    public override int StandardSwashes
    {
        get { return 0; }
    }

    public override int StylisticAlternates
    {
        get { return 0; }
    }

    public override bool StylisticSet1
    {
        get { return false; }
    }

    public override bool StylisticSet10
    {
        get { return false; }
    }

    public override bool StylisticSet11
    {
        get { return false; }
    }

    public override bool StylisticSet12
    {
        get { return false; }
    }

    public override bool StylisticSet13
    {
        get { return false; }
    }

    public override bool StylisticSet14
    {
        get { return false; }
    }

    public override bool StylisticSet15
    {
        get { return false; }
    }

    public override bool StylisticSet16
    {
        get { return false; }
    }

    public override bool StylisticSet17
    {
        get { return false; }
    }

    public override bool StylisticSet18
    {
        get { return false; }
    }

    public override bool StylisticSet19
    {
        get { return false; }
    }

    public override bool StylisticSet2
    {
        get { return false; }
    }

    public override bool StylisticSet20
    {
        get { return false; }
    }

    public override bool StylisticSet3
    {
        get { return false; }
    }

    public override bool StylisticSet4
    {
        get { return false; }
    }

    public override bool StylisticSet5
    {
        get { return false; }
    }

    public override bool StylisticSet6
    {
        get { return false; }
    }

    public override bool StylisticSet7
    {
        get { return false; }
    }

    public override bool StylisticSet8
    {
        get { return false; }
    }

    public override bool StylisticSet9
    {
        get { return false; }
    }

    public override FontVariants Variants
    {
        get { return _superscript ? FontVariants.Superscript: FontVariants.Normal; }
    }
}

现在TextSource实现:

class GenericTextParagraphProperties : TextParagraphProperties
{
    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 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; }
    }

    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;
}

剩下要做的就是初始化CustomTextSource并绘制文本:

public class CustomTextSourceRun
{
    public string Text;
    public bool IsSuperscript;
    public bool IsEndParagraph;
    public int Length { get { return IsEndParagraph ? 1 : Text.Length; } }
}


class CustomTextSource : TextSource
{
    public List<CustomTextSourceRun> Runs = new List<CustomTextSourceRun>();

    public override TextRun GetTextRun(int textSourceCharacterIndex)
    {
        int pos = 0;
        foreach (var currentRun in Runs)
        {
            if (textSourceCharacterIndex < pos + currentRun.Length)
            {
                if (currentRun.IsEndParagraph)
                {
                    return new TextEndOfParagraph(1);
                }

                var props =
                    new CustomTextRunProperties(currentRun.IsSuperscript);

                return new TextCharacters(
                    currentRun.Text,
                    textSourceCharacterIndex - pos,
                    currentRun.Length - (textSourceCharacterIndex - pos),
                    props);


            }
            pos += currentRun.Length;
        }

        // Return an end-of-paragraph if no more text source.
        return new TextEndOfParagraph(1);
    }

    public override TextSpan<CultureSpecificCharacterBufferRange> GetPrecedingText(int textSourceCharacterIndexLimit)
    {
        throw new Exception("The method or operation is not implemented.");
    }

    public override int GetTextEffectCharacterIndexFromTextSourceCharacterIndex(int textSourceCharacterIndex)
    {
        throw new Exception("The method or operation is not implemented.");
    }

    public int Length
    {
        get
        {
            int r = 0;
            foreach (var currentRun in Runs)
            {
                r += currentRun.Length;
            }
            return r;
        }
    }
}

就是这样 - 我们在绘图环境中有上标文本。

答案 1 :(得分:0)

FormattedText没有办法,请参阅此处的完整参考资料:

  

http://msdn.microsoft.com/en-us/library/system.windows.media.formattedtext_members.aspx

您可以使用TextBlock,因为您已经发现:

  

Set superscript and subscript in formatted text in wpf

或者您可以简单地将FormattedText缩小(SetFontSize)并手动将其置于上方/下方。

如果您可以提供更多关于您使用FormattedText的情况,或者您要解决的问题,或者您无法使用TextBlock的问题,请发送回复这个答案我们很乐意帮助您提供更具体的例子。

希望有所帮助!