c# - StringFormat.Trimming 改变文本的垂直位置
问题描述
这是用于打印页面上的页眉/页脚。下面的代码正在绘制页眉/页脚的左侧和中心部分(我省略了绘制右侧的代码)并简化了逻辑以更好地说明问题。StringTrimming.EllipsisPath
这个想法是标题的中心部分优先,如果中心太大而无法容纳,则左右将被修剪。这一切都有效,除了每当修剪发生时,GDI+ 正在垂直移动修剪的文本。
编辑:我写了一个专门的示例来说明这个问题,因为我的原始帖子对人们来说不够清楚。这是示例的完整代码。这是一个使用 VS19 创建的 .NET Framework Winforms 应用程序。
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void Form1_Paint(object sender, PaintEventArgs e)
{
e.Graphics.TextRenderingHint = TextRenderingHint.ClearTypeGridFit;
Font font = new Font("Century Gothic", 24F, FontStyle.Regular, GraphicsUnit.Point);
string demo = "[Emergency 123]";
StringFormat fmtTrimmed = new StringFormat(StringFormat.GenericTypographic)
{
Alignment = StringAlignment.Near,
LineAlignment = StringAlignment.Near,
Trimming = StringTrimming.EllipsisCharacter,
};
StringFormat fmtNotTrimmed = new StringFormat(StringFormat.GenericTypographic)
{
Alignment = StringAlignment.Center,
LineAlignment = StringAlignment.Near,
};
try
{
Rectangle boundsHeader = new Rectangle(10, 10, this.ClientSize.Width - 20, (int)font.GetHeight() + 8);
SizeF textSize = e.Graphics.MeasureString(demo, font, boundsHeader.Size, fmtNotTrimmed);
boundsHeader.Inflate(1, 1);
e.Graphics.DrawRectangle(Pens.Blue, boundsHeader);
float textCenterBounds = (boundsHeader.Width - textSize.Width) / 2;
e.Graphics.DrawRectangle(Pens.Green, boundsHeader.X + textCenterBounds, boundsHeader.Y, textSize.Width, textSize.Height);
e.Graphics.DrawString(demo, font, Brushes.Black, boundsHeader, fmtNotTrimmed);
RectangleF boundsLeft = new RectangleF(boundsHeader.X, boundsHeader.Y, textCenterBounds, boundsHeader.Height);
SizeF sizeLeft = e.Graphics.MeasureString(demo, font, boundsLeft.Size, fmtTrimmed);
e.Graphics.DrawRectangle(Pens.Red, boundsLeft.X, boundsLeft.Y, boundsLeft.Width, textSize.Height);
e.Graphics.DrawString(demo, font, Brushes.Black, boundsLeft, fmtTrimmed);
}
finally
{
font.Dispose();
fmtTrimmed.Dispose();
fmtNotTrimmed.Dispose();
}
}
在这里,应用程序显示如果left
不发生修剪的大小,则垂直正确对齐:
如果left
is 具有发生修剪的长度(注意省略号),则垂直对齐会略微向上移动(注意代码用于Form1_Resize
调整矩形大小)。
通过查看 、 和 括号,您可以最清楚地看到这y
一点g
。
我已经尝试了, 和的所有组合StringTrimming
,但无法解决这个问题。请注意,在当前实现中,我还尝试使 Rectangle 的高度为 0。如果是字体高度、或更大,则会出现同样的问题。LineAlignment
FormatFlags
bounds.Height
sizeCenter.Height
我不敢相信这是 GDI+ 中的错误,所以我一定是做错了什么。许多搜索和重新阅读文档都没有帮助。我无计可施。
编辑:根据@HansPassant 下面的评论,我发现不同的字体表现不同。在上面的图片中,我使用的是“Microsoft Sans Serif”。
- “Arial”有同样的问题(粗体或常规)
- “Tahoma”确实重现了这个问题。
- “卡斯卡迪亚密码”确实重现(它是新的固定音高)
- “露西达控制台”不!?!?!复制
- “新快递”可以。
我已经确定某些字体比其他字体差。例如,如果我将上面的代码更改为24F
用作字体大小,我无法使用Microsoft Sans Serif
) 重现它。
我还确定并且StringTrimming.Character
所有行为都以相同的方式进行(因此省略号字符似乎不是原因)。StringTrimming.ElipsisCharacter
StringTrimming.ElipsisPath
Century Gothic
编辑:在这里使用常规
显示另一个示例:
编辑:此示例说明e.Graphics.TextRenderingHint = TextRenderingHint.AntiAlias
当LineAlignment = StringAlignment.Far
.
解决方案
推荐阅读
- jquery - 检索到的会话存储变量在 jquery 条件中未被识别
- bash - youtube-dl 下载脚本调试
- mysql - 如何使用 JPA 向 MySQL 添加前缀索引?
- excel - 我忘记了将文本更改为 URL 格式的 Excel 公式
- html - 运行代码后有时宏无法设置 htmldiv
- angular - 如何仅允许数字指令角度 9 的复制粘贴
- powershell - powershell - 在文件中匹配后删除 n 行
- php - 在php中构建rest中间件的最佳方法
- ansible - blockinfile 模块中的 jinja 变量替换
- json - 将具有多个嵌套值的字段从 JSON 导出到 CSV