gpt4 book ai didi

wpf - FormattedText 类中的下标/上标?

转载 作者:行者123 更新时间:2023-12-04 21:52:30 28 4
gpt4 key购买 nike

我正在使用 FormattedText 类创建文本 - 但是在使用此类时如何下标或上标文本?我找到了有关如何在使用 TextBlock 时执行此操作的解决方案,但我使用的是 FormattedText 而不是 TextBlock ):感谢您的提示!

最佳答案

FormattedText不能做下标/上标 - 但 TextFormatter能够。
TextFormatter是一个低级的API,你需要写很多代码来使用它——但大部分代码只是子类化了所有用于传递格式化参数的类 int TextFormatter .

如何使用 TextFormatter
TextFormatter需要一个 TextSource对象并产生多个 TextLine对象(每行一个),TextLine.Draw然后可以使用方法将线绘制到绘图上下文。
TextSource类是抽象的,你必须继承它并覆盖 GetTextRun方法只返回 TextRun位于提供的字符位置的对象。
TextRun也是抽象的 - 但它确实有你可以使用的子类 - 有趣的类是 TextCharacters包含字符串和格式信息。

格式信息在 TextRunProperties 中对象,不幸的是,这是另一个您必须子类化的抽象类。
TextRunProperties有一个 TypographyProperties类型的属性 TextRunTypographyProperties .
TextRunTypographyProperties是另一个需要子类化的抽象类。

最后 TextRunTypographyPropertiesVariants您可以像 TextBlock 示例一样使用属性。

代码示例

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

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

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

还有一个类似的段落格式类(取自 MSDN TextFormatter 示例):
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;
}

现在 TextSource 实现:
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;
}
}
}

剩下要做的就是初始化 CustomTextSource 并绘制文本:
     var textStore = new CustomTextSource();
textStore.Runs.Add(new CustomTextSourceRun() { Text = "3" });
textStore.Runs.Add(new CustomTextSourceRun() { Text = "rd", IsSuperscript = true });
textStore.Runs.Add(new CustomTextSourceRun() { IsEndParagraph = true });
textStore.Runs.Add(new CustomTextSourceRun() { Text = "4" });
textStore.Runs.Add(new CustomTextSourceRun() { Text = "th", IsSuperscript = true });

int textStorePosition = 0;
System.Windows.Point linePosition = new System.Windows.Point(0, 0);

textDest = new DrawingGroup();
DrawingContext dc = textDest.Open();

TextFormatter formatter = TextFormatter.Create();

while (textStorePosition < textStore.Length)
{
using (TextLine myTextLine = formatter.FormatLine(
textStore,
textStorePosition,
96*6,
new GenericTextParagraphProperties(FlowDirection.LeftToRight,
TextAlignment.Left,true,false, new CustomTextRunProperties(false), TextWrapping.Wrap,
30,0), null))
{
myTextLine.Draw(dc, linePosition, InvertAxes.None);
textStorePosition += myTextLine.Length;
linePosition.Y += myTextLine.Height;
}
}

dc.Close();

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

关于wpf - FormattedText 类中的下标/上标?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2750576/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com